From accd5701c251c2741479fe08e56c8271c444f021 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 24 Aug 2023 20:43:43 -0700 Subject: compiler: move struct types into InternPool proper Structs were previously using `SegmentedList` to be given indexes, but were not actually backed by the InternPool arrays. After this, the only remaining uses of `SegmentedList` in the compiler are `Module.Decl` and `Module.Namespace`. Once those last two are migrated to become backed by InternPool arrays as well, we can introduce state serialization via writing these arrays to disk all at once. Unfortunately there are a lot of source code locations that touch the struct type API, so this commit is still work-in-progress. Once I get it compiling and passing the test suite, I can provide some interesting data points such as how it affected the InternPool memory size and performance comparison against master branch. I also couldn't resist migrating over a bunch of alignment API over to use the log2 Alignment type rather than a mismash of u32 and u64 byte units with 0 meaning something implicitly different and special at every location. Turns out you can do all the math you need directly on the log2 representation of alignments. --- src/link/Dwarf.zig | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'src/link/Dwarf.zig') diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 52d6550bcb..70654662b4 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -341,23 +341,22 @@ pub const DeclState = struct { try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); } }, - .struct_type => |struct_type| s: { - const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse break :s; + .struct_type => |struct_type| { // DW.AT.name, DW.FORM.string try ty.print(dbg_info_buffer.writer(), mod); try dbg_info_buffer.append(0); - if (struct_obj.layout == .Packed) { + if (struct_type.layout == .Packed) { log.debug("TODO implement .debug_info for packed structs", .{}); break :blk; } for ( - struct_obj.fields.keys(), - struct_obj.fields.values(), - 0.., - ) |field_name_ip, field, field_index| { - if (!field.ty.hasRuntimeBits(mod)) continue; + struct_type.field_names.get(ip), + struct_type.field_types.get(ip), + struct_type.offsets.get(ip), + ) |field_name_ip, field_ty, field_off| { + if (!field_ty.toType().hasRuntimeBits(mod)) continue; const field_name = ip.stringToSlice(field_name_ip); // DW.AT.member try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2); @@ -368,9 +367,8 @@ pub const DeclState = struct { // DW.AT.type, DW.FORM.ref4 var index = dbg_info_buffer.items.len; try dbg_info_buffer.resize(index + 4); - try self.addTypeRelocGlobal(atom_index, field.ty, @as(u32, @intCast(index))); + try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index)); // DW.AT.data_member_location, DW.FORM.udata - const field_off = ty.structFieldOffset(field_index, mod); try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); } }, @@ -416,8 +414,8 @@ pub const DeclState = struct { .Union => { const union_obj = mod.typeToUnion(ty).?; const layout = mod.getUnionLayout(union_obj); - const payload_offset = if (layout.tag_align >= layout.payload_align) layout.tag_size else 0; - const tag_offset = if (layout.tag_align >= layout.payload_align) 0 else layout.payload_size; + const payload_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) layout.tag_size else 0; + const tag_offset = if (layout.tag_align.compare(.gte, layout.payload_align)) 0 else layout.payload_size; // TODO this is temporary to match current state of unions in Zig - we don't yet have // safety checks implemented meaning the implicit tag is not yet stored and generated // for untagged unions. @@ -496,11 +494,11 @@ pub const DeclState = struct { .ErrorUnion => { const error_ty = ty.errorUnionSet(mod); const payload_ty = ty.errorUnionPayload(mod); - const payload_align = if (payload_ty.isNoReturn(mod)) 0 else payload_ty.abiAlignment(mod); + const payload_align = if (payload_ty.isNoReturn(mod)) .none else payload_ty.abiAlignment(mod); const error_align = Type.anyerror.abiAlignment(mod); const abi_size = ty.abiSize(mod); - const payload_off = if (error_align >= payload_align) Type.anyerror.abiSize(mod) else 0; - const error_off = if (error_align >= payload_align) 0 else payload_ty.abiSize(mod); + const payload_off = if (error_align.compare(.gte, payload_align)) Type.anyerror.abiSize(mod) else 0; + const error_off = if (error_align.compare(.gte, payload_align)) 0 else payload_ty.abiSize(mod); // DW.AT.structure_type try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_type)); -- cgit v1.2.3