| author | |
| committer | |
| log | a48e5af69df17f225cc06658f8a616d54f31d090 |
| tree | cf2d4a3e98ea8ea598799a2cac21b1862cb96805 |
| parent | fd2c1d860503ec6cd71ab9a692ad2dbf6bd3c269 |
| parent | 5672ee4ed7de11fa3c39ba43619035fdbfc507a5 |
| signature | Signed by PGP key 4AEE18F83AFDEB23 |
AstGen: use string index as key for string table4 files changed, 69 insertions(+), 63 deletions(-)
lib/std/hash_map.zig+28| ... | ... | @@ -92,6 +92,34 @@ pub fn hashString(s: []const u8) u64 { |
| 92 | 92 | return std.hash.Wyhash.hash(0, s); |
| 93 | 93 | } |
| 94 | 94 | |
| 95 | pub const StringIndexContext = struct { | |
| 96 | bytes: *std.ArrayListUnmanaged(u8), | |
| 97 | ||
| 98 | pub fn eql(self: @This(), a: u32, b: u32) bool { | |
| 99 | _ = self; | |
| 100 | return a == b; | |
| 101 | } | |
| 102 | ||
| 103 | pub fn hash(self: @This(), x: u32) u64 { | |
| 104 | const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + x); | |
| 105 | return hashString(x_slice); | |
| 106 | } | |
| 107 | }; | |
| 108 | ||
| 109 | pub const StringIndexAdapter = struct { | |
| 110 | bytes: *std.ArrayListUnmanaged(u8), | |
| 111 | ||
| 112 | pub fn eql(self: @This(), a_slice: []const u8, b: u32) bool { | |
| 113 | const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.bytes.items.ptr) + b); | |
| 114 | return mem.eql(u8, a_slice, b_slice); | |
| 115 | } | |
| 116 | ||
| 117 | pub fn hash(self: @This(), adapted_key: []const u8) u64 { | |
| 118 | _ = self; | |
| 119 | return hashString(adapted_key); | |
| 120 | } | |
| 121 | }; | |
| 122 | ||
| 95 | 123 | /// Deprecated use `default_max_load_percentage` |
| 96 | 124 | pub const DefaultMaxLoadPercentage = default_max_load_percentage; |
| 97 | 125 |
src/AstGen.zig+17-15| ... | ... | @@ -7,6 +7,8 @@ const mem = std.mem; |
| 7 | 7 | const Allocator = std.mem.Allocator; |
| 8 | 8 | const assert = std.debug.assert; |
| 9 | 9 | const ArrayListUnmanaged = std.ArrayListUnmanaged; |
| 10 | const StringIndexAdapter = std.hash_map.StringIndexAdapter; | |
| 11 | const StringIndexContext = std.hash_map.StringIndexContext; | |
| 10 | 12 | |
| 11 | 13 | const Zir = @import("Zir.zig"); |
| 12 | 14 | const trace = @import("tracy.zig").trace; |
| ... | ... | @@ -30,7 +32,7 @@ source_column: u32 = 0, |
| 30 | 32 | /// Used for temporary allocations; freed after AstGen is complete. |
| 31 | 33 | /// The resulting ZIR code has no references to anything in this arena. |
| 32 | 34 | arena: *Allocator, |
| 33 | string_table: std.StringHashMapUnmanaged(u32) = .{}, | |
| 35 | string_table: std.HashMapUnmanaged(u32, void, StringIndexContext, std.hash_map.default_max_load_percentage) = .{}, | |
| 34 | 36 | compile_errors: ArrayListUnmanaged(Zir.Inst.CompileErrors.Item) = .{}, |
| 35 | 37 | /// The topmost block of the current function. |
| 36 | 38 | fn_block: ?*GenZir = null, |
| ... | ... | @@ -8781,16 +8783,16 @@ fn identAsString(astgen: *AstGen, ident_token: Ast.TokenIndex) !u32 { |
| 8781 | 8783 | const str_index = @intCast(u32, string_bytes.items.len); |
| 8782 | 8784 | try astgen.appendIdentStr(ident_token, string_bytes); |
| 8783 | 8785 | const key = string_bytes.items[str_index..]; |
| 8784 | const gop = try astgen.string_table.getOrPut(gpa, key); | |
| 8786 | const gop = try astgen.string_table.getOrPutContextAdapted(gpa, @as([]const u8, key), StringIndexAdapter{ | |
| 8787 | .bytes = string_bytes, | |
| 8788 | }, StringIndexContext{ | |
| 8789 | .bytes = string_bytes, | |
| 8790 | }); | |
| 8785 | 8791 | if (gop.found_existing) { |
| 8786 | 8792 | string_bytes.shrinkRetainingCapacity(str_index); |
| 8787 | return gop.value_ptr.*; | |
| 8793 | return gop.key_ptr.*; | |
| 8788 | 8794 | } else { |
| 8789 | // We have to dupe the key into the arena, otherwise the memory | |
| 8790 | // becomes invalidated when string_bytes gets data appended. | |
| 8791 | // TODO https://github.com/ziglang/zig/issues/8528 | |
| 8792 | gop.key_ptr.* = try astgen.arena.dupe(u8, key); | |
| 8793 | gop.value_ptr.* = str_index; | |
| 8795 | gop.key_ptr.* = str_index; | |
| 8794 | 8796 | try string_bytes.append(gpa, 0); |
| 8795 | 8797 | return str_index; |
| 8796 | 8798 | } |
| ... | ... | @@ -8805,19 +8807,19 @@ fn strLitAsString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !IndexSlice { |
| 8805 | 8807 | const token_bytes = astgen.tree.tokenSlice(str_lit_token); |
| 8806 | 8808 | try astgen.parseStrLit(str_lit_token, string_bytes, token_bytes, 0); |
| 8807 | 8809 | const key = string_bytes.items[str_index..]; |
| 8808 | const gop = try astgen.string_table.getOrPut(gpa, key); | |
| 8810 | const gop = try astgen.string_table.getOrPutContextAdapted(gpa, @as([]const u8, key), StringIndexAdapter{ | |
| 8811 | .bytes = string_bytes, | |
| 8812 | }, StringIndexContext{ | |
| 8813 | .bytes = string_bytes, | |
| 8814 | }); | |
| 8809 | 8815 | if (gop.found_existing) { |
| 8810 | 8816 | string_bytes.shrinkRetainingCapacity(str_index); |
| 8811 | 8817 | return IndexSlice{ |
| 8812 | .index = gop.value_ptr.*, | |
| 8818 | .index = gop.key_ptr.*, | |
| 8813 | 8819 | .len = @intCast(u32, key.len), |
| 8814 | 8820 | }; |
| 8815 | 8821 | } else { |
| 8816 | // We have to dupe the key into the arena, otherwise the memory | |
| 8817 | // becomes invalidated when string_bytes gets data appended. | |
| 8818 | // TODO https://github.com/ziglang/zig/issues/8528 | |
| 8819 | gop.key_ptr.* = try astgen.arena.dupe(u8, key); | |
| 8820 | gop.value_ptr.* = str_index; | |
| 8822 | gop.key_ptr.* = str_index; | |
| 8821 | 8823 | // Still need a null byte because we are using the same table |
| 8822 | 8824 | // to lookup null terminated strings, so if we get a match, it has to |
| 8823 | 8825 | // be null terminated for that to work. |
src/link/MachO.zig+19-44| ... | ... | @@ -37,6 +37,8 @@ const LlvmObject = @import("../codegen/llvm.zig").Object; |
| 37 | 37 | const LoadCommand = commands.LoadCommand; |
| 38 | 38 | const Module = @import("../Module.zig"); |
| 39 | 39 | const SegmentCommand = commands.SegmentCommand; |
| 40 | const StringIndexAdapter = std.hash_map.StringIndexAdapter; | |
| 41 | const StringIndexContext = std.hash_map.StringIndexContext; | |
| 40 | 42 | pub const TextBlock = @import("MachO/TextBlock.zig"); |
| 41 | 43 | const Trie = @import("MachO/Trie.zig"); |
| 42 | 44 | |
| ... | ... | @@ -224,33 +226,6 @@ decls: std.AutoArrayHashMapUnmanaged(*Module.Decl, void) = .{}, |
| 224 | 226 | /// somewhere else in the codegen. |
| 225 | 227 | active_decl: ?*Module.Decl = null, |
| 226 | 228 | |
| 227 | const StringIndexContext = struct { | |
| 228 | strtab: *std.ArrayListUnmanaged(u8), | |
| 229 | ||
| 230 | pub fn eql(_: StringIndexContext, a: u32, b: u32) bool { | |
| 231 | return a == b; | |
| 232 | } | |
| 233 | ||
| 234 | pub fn hash(self: StringIndexContext, x: u32) u64 { | |
| 235 | const x_slice = mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr) + x); | |
| 236 | return std.hash_map.hashString(x_slice); | |
| 237 | } | |
| 238 | }; | |
| 239 | ||
| 240 | pub const StringSliceAdapter = struct { | |
| 241 | strtab: *std.ArrayListUnmanaged(u8), | |
| 242 | ||
| 243 | pub fn eql(self: StringSliceAdapter, a_slice: []const u8, b: u32) bool { | |
| 244 | const b_slice = mem.spanZ(@ptrCast([*:0]const u8, self.strtab.items.ptr) + b); | |
| 245 | return mem.eql(u8, a_slice, b_slice); | |
| 246 | } | |
| 247 | ||
| 248 | pub fn hash(self: StringSliceAdapter, adapted_key: []const u8) u64 { | |
| 249 | _ = self; | |
| 250 | return std.hash_map.hashString(adapted_key); | |
| 251 | } | |
| 252 | }; | |
| 253 | ||
| 254 | 229 | const SymbolWithLoc = struct { |
| 255 | 230 | // Table where the symbol can be found. |
| 256 | 231 | where: enum { |
| ... | ... | @@ -938,8 +913,8 @@ fn linkWithZld(self: *MachO, comp: *Compilation) !void { |
| 938 | 913 | |
| 939 | 914 | { |
| 940 | 915 | // Add dyld_stub_binder as the final GOT entry. |
| 941 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 942 | .strtab = &self.strtab, | |
| 916 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{ | |
| 917 | .bytes = &self.strtab, | |
| 943 | 918 | }) orelse unreachable; |
| 944 | 919 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| 945 | 920 | const got_index = @intCast(u32, self.got_entries.items.len); |
| ... | ... | @@ -1966,8 +1941,8 @@ fn writeStubHelperCommon(self: *MachO) !void { |
| 1966 | 1941 | code[9] = 0xff; |
| 1967 | 1942 | code[10] = 0x25; |
| 1968 | 1943 | { |
| 1969 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 1970 | .strtab = &self.strtab, | |
| 1944 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{ | |
| 1945 | .bytes = &self.strtab, | |
| 1971 | 1946 | }) orelse unreachable; |
| 1972 | 1947 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| 1973 | 1948 | const got_index = self.got_entries_map.get(.{ |
| ... | ... | @@ -2017,8 +1992,8 @@ fn writeStubHelperCommon(self: *MachO) !void { |
| 2017 | 1992 | code[10] = 0xbf; |
| 2018 | 1993 | code[11] = 0xa9; |
| 2019 | 1994 | binder_blk_outer: { |
| 2020 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 2021 | .strtab = &self.strtab, | |
| 1995 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{ | |
| 1996 | .bytes = &self.strtab, | |
| 2022 | 1997 | }) orelse unreachable; |
| 2023 | 1998 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| 2024 | 1999 | const got_index = self.got_entries_map.get(.{ |
| ... | ... | @@ -2435,8 +2410,8 @@ fn resolveSymbols(self: *MachO) !void { |
| 2435 | 2410 | } |
| 2436 | 2411 | |
| 2437 | 2412 | // Fourth pass, handle synthetic symbols and flag any undefined references. |
| 2438 | if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringSliceAdapter{ | |
| 2439 | .strtab = &self.strtab, | |
| 2413 | if (self.strtab_dir.getKeyAdapted(@as([]const u8, "___dso_handle"), StringIndexAdapter{ | |
| 2414 | .bytes = &self.strtab, | |
| 2440 | 2415 | })) |n_strx| blk: { |
| 2441 | 2416 | const resolv = self.symbol_resolver.getPtr(n_strx) orelse break :blk; |
| 2442 | 2417 | if (resolv.where != .undef) break :blk; |
| ... | ... | @@ -2985,8 +2960,8 @@ fn setEntryPoint(self: *MachO) !void { |
| 2985 | 2960 | // TODO we should respect the -entry flag passed in by the user to set a custom |
| 2986 | 2961 | // entrypoint. For now, assume default of `_main`. |
| 2987 | 2962 | const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 2988 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringSliceAdapter{ | |
| 2989 | .strtab = &self.strtab, | |
| 2963 | const n_strx = self.strtab_dir.getKeyAdapted(@as([]const u8, "_main"), StringIndexAdapter{ | |
| 2964 | .bytes = &self.strtab, | |
| 2990 | 2965 | }) orelse { |
| 2991 | 2966 | log.err("'_main' export not found", .{}); |
| 2992 | 2967 | return error.MissingMainEntrypoint; |
| ... | ... | @@ -4475,8 +4450,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4475 | 4450 | }); |
| 4476 | 4451 | self.load_commands_dirty = true; |
| 4477 | 4452 | } |
| 4478 | if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringSliceAdapter{ | |
| 4479 | .strtab = &self.strtab, | |
| 4453 | if (!self.strtab_dir.containsAdapted(@as([]const u8, "dyld_stub_binder"), StringIndexAdapter{ | |
| 4454 | .bytes = &self.strtab, | |
| 4480 | 4455 | })) { |
| 4481 | 4456 | const import_sym_index = @intCast(u32, self.undefs.items.len); |
| 4482 | 4457 | const n_strx = try self.makeString("dyld_stub_binder"); |
| ... | ... | @@ -4616,8 +4591,8 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 { |
| 4616 | 4591 | const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name}); |
| 4617 | 4592 | defer self.base.allocator.free(sym_name); |
| 4618 | 4593 | |
| 4619 | if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringSliceAdapter{ | |
| 4620 | .strtab = &self.strtab, | |
| 4594 | if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{ | |
| 4595 | .bytes = &self.strtab, | |
| 4621 | 4596 | })) |n_strx| { |
| 4622 | 4597 | const resolv = self.symbol_resolver.get(n_strx) orelse unreachable; |
| 4623 | 4598 | return resolv.where_index; |
| ... | ... | @@ -5858,10 +5833,10 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 5858 | 5833 | } |
| 5859 | 5834 | |
| 5860 | 5835 | pub fn makeString(self: *MachO, string: []const u8) !u32 { |
| 5861 | const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringSliceAdapter{ | |
| 5862 | .strtab = &self.strtab, | |
| 5836 | const gop = try self.strtab_dir.getOrPutContextAdapted(self.base.allocator, @as([]const u8, string), StringIndexAdapter{ | |
| 5837 | .bytes = &self.strtab, | |
| 5863 | 5838 | }, StringIndexContext{ |
| 5864 | .strtab = &self.strtab, | |
| 5839 | .bytes = &self.strtab, | |
| 5865 | 5840 | }); |
| 5866 | 5841 | if (gop.found_existing) { |
| 5867 | 5842 | const off = gop.key_ptr.*; |
src/link/MachO/TextBlock.zig+5-4| ... | ... | @@ -14,6 +14,7 @@ const Allocator = mem.Allocator; |
| 14 | 14 | const Arch = std.Target.Cpu.Arch; |
| 15 | 15 | const MachO = @import("../MachO.zig"); |
| 16 | 16 | const Object = @import("Object.zig"); |
| 17 | const StringIndexAdapter = std.hash_map.StringIndexAdapter; | |
| 17 | 18 | |
| 18 | 19 | /// Each decl always gets a local symbol with the fully qualified name. |
| 19 | 20 | /// The vaddr and size are found here directly. |
| ... | ... | @@ -656,8 +657,8 @@ fn initRelocFromObject(rel: macho.relocation_info, context: RelocContext) !Reloc |
| 656 | 657 | parsed_rel.where = .local; |
| 657 | 658 | parsed_rel.where_index = where_index; |
| 658 | 659 | } else { |
| 659 | const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{ | |
| 660 | .strtab = &context.macho_file.strtab, | |
| 660 | const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{ | |
| 661 | .bytes = &context.macho_file.strtab, | |
| 661 | 662 | }) orelse unreachable; |
| 662 | 663 | const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable; |
| 663 | 664 | switch (resolv.where) { |
| ... | ... | @@ -717,8 +718,8 @@ pub fn parseRelocs(self: *TextBlock, relocs: []macho.relocation_info, context: R |
| 717 | 718 | const where_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable; |
| 718 | 719 | subtractor = where_index; |
| 719 | 720 | } else { |
| 720 | const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), MachO.StringSliceAdapter{ | |
| 721 | .strtab = &context.macho_file.strtab, | |
| 721 | const n_strx = context.macho_file.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{ | |
| 722 | .bytes = &context.macho_file.strtab, | |
| 722 | 723 | }) orelse unreachable; |
| 723 | 724 | const resolv = context.macho_file.symbol_resolver.get(n_strx) orelse unreachable; |
| 724 | 725 | assert(resolv.where == .global); |