| ... | ... | @@ -2054,6 +2054,7 @@ pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void { |
| 2054 | 2054 | const decl = mod.declPtr(decl_index); |
| 2055 | 2055 | const atom_index = wasm.decls.get(decl_index).?; |
| 2056 | 2056 | const atom = wasm.getAtomPtr(atom_index); |
| 2057 | atom.prev = null; |
| 2057 | 2058 | wasm.symbols_free_list.append(gpa, atom.sym_index) catch {}; |
| 2058 | 2059 | _ = wasm.decls.remove(decl_index); |
| 2059 | 2060 | wasm.symbols.items[atom.sym_index].tag = .dead; |
| ... | ... | @@ -2076,16 +2077,6 @@ pub fn freeDecl(wasm: *Wasm, decl_index: InternPool.DeclIndex) void { |
| 2076 | 2077 | // dwarf.freeDecl(decl_index); |
| 2077 | 2078 | // } |
| 2078 | 2079 | |
| 2079 | | if (atom.next) |next_atom_index| { |
| 2080 | | const next_atom = wasm.getAtomPtr(next_atom_index); |
| 2081 | | next_atom.prev = atom.prev; |
| 2082 | | atom.next = null; |
| 2083 | | } |
| 2084 | | if (atom.prev) |prev_index| { |
| 2085 | | const prev_atom = wasm.getAtomPtr(prev_index); |
| 2086 | | prev_atom.next = atom.next; |
| 2087 | | atom.prev = null; |
| 2088 | | } |
| 2089 | 2080 | } |
| 2090 | 2081 | |
| 2091 | 2082 | /// Appends a new entry to the indirect function table |
| ... | ... | @@ -2327,8 +2318,6 @@ pub fn appendAtomAtIndex(wasm: *Wasm, index: u32, atom_index: Atom.Index) !void |
| 2327 | 2318 | const gpa = wasm.base.comp.gpa; |
| 2328 | 2319 | const atom = wasm.getAtomPtr(atom_index); |
| 2329 | 2320 | if (wasm.atoms.getPtr(index)) |last_index_ptr| { |
| 2330 | | const last = wasm.getAtomPtr(last_index_ptr.*); |
| 2331 | | last.*.next = atom_index; |
| 2332 | 2321 | atom.prev = last_index_ptr.*; |
| 2333 | 2322 | last_index_ptr.* = atom_index; |
| 2334 | 2323 | } else { |
| ... | ... | @@ -2375,6 +2364,11 @@ fn allocateAtoms(wasm: *Wasm) !void { |
| 2375 | 2364 | while (it.next()) |entry| { |
| 2376 | 2365 | const segment = &wasm.segments.items[entry.key_ptr.*]; |
| 2377 | 2366 | var atom_index = entry.value_ptr.*; |
| 2367 | if (entry.key_ptr.* == wasm.code_section_index) { |
| 2368 | // Code section is allocated upon writing as they are required to be ordered |
| 2369 | // to synchronise with the function section. |
| 2370 | continue; |
| 2371 | } |
| 2378 | 2372 | var offset: u32 = 0; |
| 2379 | 2373 | while (true) { |
| 2380 | 2374 | const atom = wasm.getAtomPtr(atom_index); |
| ... | ... | @@ -2387,28 +2381,17 @@ fn allocateAtoms(wasm: *Wasm) !void { |
| 2387 | 2381 | break :sym object.symtable[symbol_loc.index]; |
| 2388 | 2382 | } else wasm.symbols.items[symbol_loc.index]; |
| 2389 | 2383 | |
| 2384 | // Dead symbols must be unlinked from the linked-list to prevent them |
| 2385 | // from being emit into the binary. |
| 2390 | 2386 | if (sym.isDead()) { |
| 2391 | | // Dead symbols must be unlinked from the linked-list to prevent them |
| 2392 | | // from being emit into the binary. |
| 2393 | | if (atom.next) |next_index| { |
| 2394 | | const next = wasm.getAtomPtr(next_index); |
| 2395 | | next.prev = atom.prev; |
| 2396 | | } else if (entry.value_ptr.* == atom_index) { |
| 2387 | if (entry.value_ptr.* == atom_index and atom.prev != null) { |
| 2397 | 2388 | // When the atom is dead and is also the first atom retrieved from wasm.atoms(index) we update |
| 2398 | 2389 | // the entry to point it to the previous atom to ensure we do not start with a dead symbol that |
| 2399 | 2390 | // was removed and therefore do not emit any code at all. |
| 2400 | | if (atom.prev) |prev| { |
| 2401 | | entry.value_ptr.* = prev; |
| 2402 | | } |
| 2391 | entry.value_ptr.* = atom.prev.?; |
| 2403 | 2392 | } |
| 2404 | | atom_index = atom.prev orelse { |
| 2405 | | atom.next = null; |
| 2406 | | break; |
| 2407 | | }; |
| 2408 | | const prev = wasm.getAtomPtr(atom_index); |
| 2409 | | prev.next = atom.next; |
| 2393 | atom_index = atom.prev orelse break; |
| 2410 | 2394 | atom.prev = null; |
| 2411 | | atom.next = null; |
| 2412 | 2395 | continue; |
| 2413 | 2396 | } |
| 2414 | 2397 | offset = @intCast(atom.alignment.forward(offset)); |
| ... | ... | @@ -2546,16 +2529,6 @@ fn setupErrorsLen(wasm: *Wasm) !void { |
| 2546 | 2529 | // if not, allcoate a new atom. |
| 2547 | 2530 | const atom_index = if (wasm.symbol_atom.get(loc)) |index| blk: { |
| 2548 | 2531 | const atom = wasm.getAtomPtr(index); |
| 2549 | | if (atom.next) |next_atom_index| { |
| 2550 | | const next_atom = wasm.getAtomPtr(next_atom_index); |
| 2551 | | next_atom.prev = atom.prev; |
| 2552 | | atom.next = null; |
| 2553 | | } |
| 2554 | | if (atom.prev) |prev_index| { |
| 2555 | | const prev_atom = wasm.getAtomPtr(prev_index); |
| 2556 | | prev_atom.next = atom.next; |
| 2557 | | atom.prev = null; |
| 2558 | | } |
| 2559 | 2532 | atom.deinit(gpa); |
| 2560 | 2533 | break :blk index; |
| 2561 | 2534 | } else new_atom: { |
| ... | ... | @@ -2658,18 +2631,12 @@ fn createSyntheticFunction( |
| 2658 | 2631 | .sym_index = loc.index, |
| 2659 | 2632 | .file = null, |
| 2660 | 2633 | .alignment = .@"1", |
| 2661 | | .next = null, |
| 2662 | 2634 | .prev = null, |
| 2663 | 2635 | .code = function_body.moveToUnmanaged(), |
| 2664 | 2636 | .original_offset = 0, |
| 2665 | 2637 | }; |
| 2666 | 2638 | try wasm.appendAtomAtIndex(wasm.code_section_index.?, atom_index); |
| 2667 | 2639 | try wasm.symbol_atom.putNoClobber(gpa, loc, atom_index); |
| 2668 | | |
| 2669 | | // `allocateAtoms` has already been called, set the atom's offset manually. |
| 2670 | | // This is fine to do manually as we insert the atom at the very end. |
| 2671 | | const prev_atom = wasm.getAtom(atom.prev.?); |
| 2672 | | atom.offset = prev_atom.offset + prev_atom.size; |
| 2673 | 2640 | } |
| 2674 | 2641 | |
| 2675 | 2642 | /// Unlike `createSyntheticFunction` this function is to be called by |
| ... | ... | @@ -2695,7 +2662,6 @@ pub fn createFunction( |
| 2695 | 2662 | .sym_index = loc.index, |
| 2696 | 2663 | .file = null, |
| 2697 | 2664 | .alignment = .@"1", |
| 2698 | | .next = null, |
| 2699 | 2665 | .prev = null, |
| 2700 | 2666 | .code = function_body.moveToUnmanaged(), |
| 2701 | 2667 | .relocs = relocations.moveToUnmanaged(), |
| ... | ... | @@ -3260,7 +3226,7 @@ pub fn getMatchingSegment(wasm: *Wasm, object_index: u16, symbol_index: u32) !u3 |
| 3260 | 3226 | break :blk index; |
| 3261 | 3227 | }; |
| 3262 | 3228 | } else if (mem.eql(u8, section_name, ".debug_ranges")) { |
| 3263 | | return wasm.debug_line_index orelse blk: { |
| 3229 | return wasm.debug_ranges_index orelse blk: { |
| 3264 | 3230 | wasm.debug_ranges_index = index; |
| 3265 | 3231 | try wasm.appendDummySegment(); |
| 3266 | 3232 | break :blk index; |
| ... | ... | @@ -3452,12 +3418,10 @@ fn resetState(wasm: *Wasm) void { |
| 3452 | 3418 | var atom_it = wasm.decls.valueIterator(); |
| 3453 | 3419 | while (atom_it.next()) |atom_index| { |
| 3454 | 3420 | const atom = wasm.getAtomPtr(atom_index.*); |
| 3455 | | atom.next = null; |
| 3456 | 3421 | atom.prev = null; |
| 3457 | 3422 | |
| 3458 | 3423 | for (atom.locals.items) |local_atom_index| { |
| 3459 | 3424 | const local_atom = wasm.getAtomPtr(local_atom_index); |
| 3460 | | local_atom.next = null; |
| 3461 | 3425 | local_atom.prev = null; |
| 3462 | 3426 | } |
| 3463 | 3427 | } |
| ... | ... | @@ -4085,46 +4049,29 @@ fn writeToFile( |
| 4085 | 4049 | } |
| 4086 | 4050 | |
| 4087 | 4051 | // Code section |
| 4088 | | var code_section_size: u32 = 0; |
| 4089 | | if (wasm.code_section_index) |code_index| { |
| 4052 | if (wasm.code_section_index != null) { |
| 4090 | 4053 | const header_offset = try reserveVecSectionHeader(&binary_bytes); |
| 4091 | | var atom_index = wasm.atoms.get(code_index).?; |
| 4054 | const start_offset = binary_bytes.items.len - 5; // minus 5 so start offset is 5 to include entry count |
| 4092 | 4055 | |
| 4093 | | // The code section must be sorted in line with the function order. |
| 4094 | | var sorted_atoms = try std.ArrayList(*const Atom).initCapacity(gpa, wasm.functions.count()); |
| 4095 | | defer sorted_atoms.deinit(); |
| 4096 | | |
| 4097 | | while (true) { |
| 4056 | var func_it = wasm.functions.iterator(); |
| 4057 | while (func_it.next()) |entry| { |
| 4058 | const sym_loc: SymbolLoc = .{ .index = entry.value_ptr.sym_index, .file = entry.key_ptr.file }; |
| 4059 | const atom_index = wasm.symbol_atom.get(sym_loc).?; |
| 4098 | 4060 | const atom = wasm.getAtomPtr(atom_index); |
| 4061 | |
| 4099 | 4062 | if (!is_obj) { |
| 4100 | 4063 | atom.resolveRelocs(wasm); |
| 4101 | 4064 | } |
| 4102 | | sorted_atoms.appendAssumeCapacity(atom); // found more code atoms than functions |
| 4103 | | atom_index = atom.prev orelse break; |
| 4104 | | } |
| 4105 | | assert(wasm.functions.count() == sorted_atoms.items.len); |
| 4106 | | |
| 4107 | | const atom_sort_fn = struct { |
| 4108 | | fn sort(ctx: *const Wasm, lhs: *const Atom, rhs: *const Atom) bool { |
| 4109 | | const lhs_sym = lhs.symbolLoc().getSymbol(ctx); |
| 4110 | | const rhs_sym = rhs.symbolLoc().getSymbol(ctx); |
| 4111 | | return lhs_sym.index < rhs_sym.index; |
| 4112 | | } |
| 4113 | | }.sort; |
| 4114 | | |
| 4115 | | mem.sort(*const Atom, sorted_atoms.items, wasm, atom_sort_fn); |
| 4116 | | |
| 4117 | | for (sorted_atoms.items) |sorted_atom| { |
| 4118 | | try leb.writeULEB128(binary_writer, sorted_atom.size); |
| 4119 | | try binary_writer.writeAll(sorted_atom.code.items); |
| 4065 | atom.offset = @intCast(binary_bytes.items.len - start_offset); |
| 4066 | try leb.writeULEB128(binary_writer, atom.size); |
| 4067 | try binary_writer.writeAll(atom.code.items); |
| 4120 | 4068 | } |
| 4121 | 4069 | |
| 4122 | | code_section_size = @as(u32, @intCast(binary_bytes.items.len - header_offset - header_size)); |
| 4123 | 4070 | try writeVecSectionHeader( |
| 4124 | 4071 | binary_bytes.items, |
| 4125 | 4072 | header_offset, |
| 4126 | 4073 | .code, |
| 4127 | | code_section_size, |
| 4074 | @intCast(binary_bytes.items.len - header_offset - header_size), |
| 4128 | 4075 | @intCast(wasm.functions.count()), |
| 4129 | 4076 | ); |
| 4130 | 4077 | code_section_index = section_count; |
| ... | ... | @@ -5301,14 +5248,8 @@ fn markReferences(wasm: *Wasm) !void { |
| 5301 | 5248 | const object = &wasm.objects.items[file]; |
| 5302 | 5249 | const atom_index = try Object.parseSymbolIntoAtom(object, file, sym_loc.index, wasm); |
| 5303 | 5250 | const atom = wasm.getAtom(atom_index); |
| 5304 | | for (atom.relocs.items) |reloc| { |
| 5305 | | const target_loc: SymbolLoc = .{ .index = reloc.index, .file = atom.file }; |
| 5306 | | const target_sym = target_loc.getSymbol(wasm); |
| 5307 | | if (target_sym.isAlive() or !do_garbage_collect) { |
| 5308 | | sym.mark(); |
| 5309 | | continue; // Skip all other relocations as this debug atom is already marked now |
| 5310 | | } |
| 5311 | | } |
| 5251 | const atom_sym = atom.symbolLoc().getSymbol(wasm); |
| 5252 | atom_sym.mark(); |
| 5312 | 5253 | } |
| 5313 | 5254 | } |
| 5314 | 5255 | } |