| author | |
| committer | |
| log | 4f8a6b0888c8d1df87d254b68344bb99edcfe57c |
| tree | 2685575e3ef8de7a9134e8a35a9067a67d8d365c |
| parent | 5fac6f380ef77a7650047c65450aec0d3215da2d |
one hash table lookup per fixup3 files changed, 53 insertions(+), 7 deletions(-)
src/codegen.zig+6-4| ... | @@ -674,8 +674,9 @@ fn lowerUavRef( | ... | @@ -674,8 +674,9 @@ fn lowerUavRef( |
| 674 | .addend = @intCast(offset), | 674 | .addend = @intCast(offset), |
| 675 | }); | 675 | }); |
| 676 | } else { | 676 | } else { |
| 677 | try wasm.uav_fixups.append(gpa, .{ | 677 | try wasm.uav_fixups.ensureUnusedCapacity(gpa, 1); |
| 678 | .ip_index = uav.val, | 678 | wasm.uav_fixups.appendAssumeCapacity(.{ |
| 679 | .uavs_exe_index = try wasm.refUavExe(pt, uav.val), | ||
| 679 | .offset = @intCast(code.items.len), | 680 | .offset = @intCast(code.items.len), |
| 680 | }); | 681 | }); |
| 681 | } | 682 | } |
| ... | @@ -745,8 +746,9 @@ fn lowerNavRef( | ... | @@ -745,8 +746,9 @@ fn lowerNavRef( |
| 745 | .addend = @intCast(offset), | 746 | .addend = @intCast(offset), |
| 746 | }); | 747 | }); |
| 747 | } else { | 748 | } else { |
| 748 | try wasm.nav_fixups.append(gpa, .{ | 749 | try wasm.nav_fixups.ensureUnusedCapacity(gpa, 1); |
| 749 | .nav_index = nav_index, | 750 | wasm.nav_fixups.appendAssumeCapacity(.{ |
| 751 | .navs_exe_index = try wasm.refNavExe(nav_index), | ||
| 750 | .offset = @intCast(code.items.len), | 752 | .offset = @intCast(code.items.len), |
| 751 | }); | 753 | }); |
| 752 | } | 754 | } |
src/link/Wasm.zig+21-3| ... | @@ -259,13 +259,13 @@ params_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty, | ... | @@ -259,13 +259,13 @@ params_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty, |
| 259 | returns_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty, | 259 | returns_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty, |
| 260 | 260 | ||
| 261 | pub const UavFixup = extern struct { | 261 | pub const UavFixup = extern struct { |
| 262 | ip_index: InternPool.Index, | 262 | uavs_exe_index: UavsExeIndex, |
| 263 | /// Index into `string_bytes`. | 263 | /// Index into `string_bytes`. |
| 264 | offset: u32, | 264 | offset: u32, |
| 265 | }; | 265 | }; |
| 266 | 266 | ||
| 267 | pub const NavFixup = extern struct { | 267 | pub const NavFixup = extern struct { |
| 268 | nav_index: InternPool.Nav.Index, | 268 | navs_exe_index: NavsExeIndex, |
| 269 | /// Index into `string_bytes`. | 269 | /// Index into `string_bytes`. |
| 270 | offset: u32, | 270 | offset: u32, |
| 271 | }; | 271 | }; |
| ... | @@ -2379,7 +2379,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index | ... | @@ -2379,7 +2379,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 2379 | const gop = try wasm.navs_exe.getOrPut(gpa, nav_index); | 2379 | const gop = try wasm.navs_exe.getOrPut(gpa, nav_index); |
| 2380 | gop.value_ptr.* = .{ | 2380 | gop.value_ptr.* = .{ |
| 2381 | .code = zcu_data.code, | 2381 | .code = zcu_data.code, |
| 2382 | .count = 0, | 2382 | .count = if (gop.found_existing) gop.value_ptr.count else 0, |
| 2383 | }; | 2383 | }; |
| 2384 | wasm.data_segments.putAssumeCapacity(.pack(wasm, .{ .nav_exe = @enumFromInt(gop.index) }), {}); | 2384 | wasm.data_segments.putAssumeCapacity(.pack(wasm, .{ .nav_exe = @enumFromInt(gop.index) }), {}); |
| 2385 | } | 2385 | } |
| ... | @@ -3376,6 +3376,24 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua | ... | @@ -3376,6 +3376,24 @@ pub fn refUavExe(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Ua |
| 3376 | return uav_index; | 3376 | return uav_index; |
| 3377 | } | 3377 | } |
| 3378 | 3378 | ||
| 3379 | pub fn refNavExe(wasm: *Wasm, nav_index: InternPool.Nav.Index) !NavsExeIndex { | ||
| 3380 | const comp = wasm.base.comp; | ||
| 3381 | const gpa = comp.gpa; | ||
| 3382 | assert(comp.config.output_mode != .Obj); | ||
| 3383 | const gop = try wasm.navs_exe.getOrPut(gpa, nav_index); | ||
| 3384 | if (gop.found_existing) { | ||
| 3385 | gop.value_ptr.count += 1; | ||
| 3386 | } else { | ||
| 3387 | gop.value_ptr.* = .{ | ||
| 3388 | .code = undefined, | ||
| 3389 | .count = 1, | ||
| 3390 | }; | ||
| 3391 | } | ||
| 3392 | const navs_exe_index: NavsExeIndex = @enumFromInt(gop.index); | ||
| 3393 | try wasm.data_segments.put(gpa, .pack(wasm, .{ .nav_exe = navs_exe_index }), {}); | ||
| 3394 | return navs_exe_index; | ||
| 3395 | } | ||
| 3396 | |||
| 3379 | /// Asserts it is called after `Flush.data_segments` is fully populated and sorted. | 3397 | /// Asserts it is called after `Flush.data_segments` is fully populated and sorted. |
| 3380 | pub fn uavAddr(wasm: *Wasm, uav_index: UavsExeIndex) u32 { | 3398 | pub fn uavAddr(wasm: *Wasm, uav_index: UavsExeIndex) u32 { |
| 3381 | assert(wasm.flush_buffer.memory_layout_finished); | 3399 | assert(wasm.flush_buffer.memory_layout_finished); |
src/link/Wasm/Flush.zig+26| ... | @@ -60,6 +60,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -60,6 +60,11 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 60 | const import_memory = comp.config.import_memory; | 60 | const import_memory = comp.config.import_memory; |
| 61 | const export_memory = comp.config.export_memory; | 61 | const export_memory = comp.config.export_memory; |
| 62 | const target = &comp.root_mod.resolved_target.result; | 62 | const target = &comp.root_mod.resolved_target.result; |
| 63 | const is64 = switch (target.cpu.arch) { | ||
| 64 | .wasm32 => false, | ||
| 65 | .wasm64 => true, | ||
| 66 | else => unreachable, | ||
| 67 | }; | ||
| 63 | const is_obj = comp.config.output_mode == .Obj; | 68 | const is_obj = comp.config.output_mode == .Obj; |
| 64 | const allow_undefined = is_obj or wasm.import_symbols; | 69 | const allow_undefined = is_obj or wasm.import_symbols; |
| 65 | const zcu = wasm.base.comp.zcu.?; | 70 | const zcu = wasm.base.comp.zcu.?; |
| ... | @@ -650,6 +655,27 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { | ... | @@ -650,6 +655,27 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 650 | section_index += 1; | 655 | section_index += 1; |
| 651 | } | 656 | } |
| 652 | 657 | ||
| 658 | if (!is_obj) { | ||
| 659 | for (wasm.uav_fixups.items) |uav_fixup| { | ||
| 660 | const ds_id: Wasm.DataSegment.Id = .pack(wasm, .{ .uav_exe = uav_fixup.uavs_exe_index }); | ||
| 661 | const vaddr = f.data_segments.get(ds_id).?; | ||
| 662 | if (!is64) { | ||
| 663 | mem.writeInt(u32, wasm.string_bytes.items[uav_fixup.offset..][0..4], vaddr, .little); | ||
| 664 | } else { | ||
| 665 | mem.writeInt(u64, wasm.string_bytes.items[uav_fixup.offset..][0..8], vaddr, .little); | ||
| 666 | } | ||
| 667 | } | ||
| 668 | for (wasm.nav_fixups.items) |nav_fixup| { | ||
| 669 | const ds_id: Wasm.DataSegment.Id = .pack(wasm, .{ .nav_exe = nav_fixup.navs_exe_index }); | ||
| 670 | const vaddr = f.data_segments.get(ds_id).?; | ||
| 671 | if (!is64) { | ||
| 672 | mem.writeInt(u32, wasm.string_bytes.items[nav_fixup.offset..][0..4], vaddr, .little); | ||
| 673 | } else { | ||
| 674 | mem.writeInt(u64, wasm.string_bytes.items[nav_fixup.offset..][0..8], vaddr, .little); | ||
| 675 | } | ||
| 676 | } | ||
| 677 | } | ||
| 678 | |||
| 653 | // Data section. | 679 | // Data section. |
| 654 | if (f.data_segment_groups.items.len != 0) { | 680 | if (f.data_segment_groups.items.len != 0) { |
| 655 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); | 681 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |