| 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 | 674 | .addend = @intCast(offset), |
| 675 | 675 | }); |
| 676 | 676 | } else { |
| 677 | try wasm.uav_fixups.append(gpa, .{ | |
| 678 | .ip_index = uav.val, | |
| 677 | try wasm.uav_fixups.ensureUnusedCapacity(gpa, 1); | |
| 678 | wasm.uav_fixups.appendAssumeCapacity(.{ | |
| 679 | .uavs_exe_index = try wasm.refUavExe(pt, uav.val), | |
| 679 | 680 | .offset = @intCast(code.items.len), |
| 680 | 681 | }); |
| 681 | 682 | } |
| ... | ... | @@ -745,8 +746,9 @@ fn lowerNavRef( |
| 745 | 746 | .addend = @intCast(offset), |
| 746 | 747 | }); |
| 747 | 748 | } else { |
| 748 | try wasm.nav_fixups.append(gpa, .{ | |
| 749 | .nav_index = nav_index, | |
| 749 | try wasm.nav_fixups.ensureUnusedCapacity(gpa, 1); | |
| 750 | wasm.nav_fixups.appendAssumeCapacity(.{ | |
| 751 | .navs_exe_index = try wasm.refNavExe(nav_index), | |
| 750 | 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 | 259 | returns_scratch: std.ArrayListUnmanaged(std.wasm.Valtype) = .empty, |
| 260 | 260 | |
| 261 | 261 | pub const UavFixup = extern struct { |
| 262 | ip_index: InternPool.Index, | |
| 262 | uavs_exe_index: UavsExeIndex, | |
| 263 | 263 | /// Index into `string_bytes`. |
| 264 | 264 | offset: u32, |
| 265 | 265 | }; |
| 266 | 266 | |
| 267 | 267 | pub const NavFixup = extern struct { |
| 268 | nav_index: InternPool.Nav.Index, | |
| 268 | navs_exe_index: NavsExeIndex, | |
| 269 | 269 | /// Index into `string_bytes`. |
| 270 | 270 | offset: u32, |
| 271 | 271 | }; |
| ... | ... | @@ -2379,7 +2379,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 2379 | 2379 | const gop = try wasm.navs_exe.getOrPut(gpa, nav_index); |
| 2380 | 2380 | gop.value_ptr.* = .{ |
| 2381 | 2381 | .code = zcu_data.code, |
| 2382 | .count = 0, | |
| 2382 | .count = if (gop.found_existing) gop.value_ptr.count else 0, | |
| 2383 | 2383 | }; |
| 2384 | 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 | 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 | 3397 | /// Asserts it is called after `Flush.data_segments` is fully populated and sorted. |
| 3380 | 3398 | pub fn uavAddr(wasm: *Wasm, uav_index: UavsExeIndex) u32 { |
| 3381 | 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 | 60 | const import_memory = comp.config.import_memory; |
| 61 | 61 | const export_memory = comp.config.export_memory; |
| 62 | 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 | 68 | const is_obj = comp.config.output_mode == .Obj; |
| 64 | 69 | const allow_undefined = is_obj or wasm.import_symbols; |
| 65 | 70 | const zcu = wasm.base.comp.zcu.?; |
| ... | ... | @@ -650,6 +655,27 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 650 | 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 | 679 | // Data section. |
| 654 | 680 | if (f.data_segment_groups.items.len != 0) { |
| 655 | 681 | const header_offset = try reserveVecSectionHeader(gpa, binary_bytes); |