stage2: fix Decl garbage collection not marking enough

It is the job of codegen backends to mark Decls that are referenced as
alive so that the frontend does not sweep them with the garbage. This
commit unifies the code between the backends with an added method on
Decl.

The implementation is more complete than before, switching on the Decl
val tag and recursing into sub-values.

As a result, two more array tests are passing.
This commit is contained in:
Andrew Kelley
2022-01-15 00:17:25 -07:00
parent 41f3799bf0
commit a5c7742ba6
8 changed files with 152 additions and 149 deletions

View File

@@ -1746,6 +1746,55 @@ pub const Value = extern union {
};
}
pub fn markReferencedDeclsAlive(val: Value) void {
switch (val.tag()) {
.decl_ref_mut => return val.castTag(.decl_ref_mut).?.data.decl.markAlive(),
.extern_fn, .decl_ref => return val.cast(Payload.Decl).?.data.markAlive(),
.function => return val.castTag(.function).?.data.owner_decl.markAlive(),
.variable => return val.castTag(.variable).?.data.owner_decl.markAlive(),
.repeated,
.eu_payload,
.eu_payload_ptr,
.opt_payload,
.opt_payload_ptr,
.empty_array_sentinel,
=> return markReferencedDeclsAlive(val.cast(Payload.SubValue).?.data),
.array => {
for (val.cast(Payload.Array).?.data) |elem_val| {
markReferencedDeclsAlive(elem_val);
}
},
.slice => {
const slice = val.cast(Payload.Slice).?.data;
markReferencedDeclsAlive(slice.ptr);
markReferencedDeclsAlive(slice.len);
},
.elem_ptr => {
const elem_ptr = val.cast(Payload.ElemPtr).?.data;
return markReferencedDeclsAlive(elem_ptr.array_ptr);
},
.field_ptr => {
const field_ptr = val.cast(Payload.FieldPtr).?.data;
return markReferencedDeclsAlive(field_ptr.container_ptr);
},
.@"struct" => {
for (val.cast(Payload.Struct).?.data) |field_val| {
markReferencedDeclsAlive(field_val);
}
},
.@"union" => {
const data = val.cast(Payload.Union).?.data;
markReferencedDeclsAlive(data.tag);
markReferencedDeclsAlive(data.val);
},
else => {},
}
}
pub fn slicePtr(val: Value) Value {
return switch (val.tag()) {
.slice => val.castTag(.slice).?.data.ptr,