mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
link/wasm: Sort data segments
We now ensure the "bss" section is last, which allows us to not emit this section and let the runtime initialize the memory with 0's instead. This allows for smaller binaries. The order of the other segments is arbitrary and does not matter, this may change in the future.
This commit is contained in:
parent
e32a5ba78b
commit
140bac6395
@ -1255,6 +1255,9 @@ fn parseAtom(self: *Wasm, atom: *Atom, kind: Kind) !void {
|
||||
}
|
||||
|
||||
fn allocateAtoms(self: *Wasm) !void {
|
||||
// first sort the data segments
|
||||
try sortDataSegments(self);
|
||||
|
||||
var it = self.atoms.iterator();
|
||||
while (it.next()) |entry| {
|
||||
const segment = &self.segments.items[entry.key_ptr.*];
|
||||
@ -1278,6 +1281,36 @@ fn allocateAtoms(self: *Wasm) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn sortDataSegments(self: *Wasm) !void {
|
||||
var new_mapping: std.StringArrayHashMapUnmanaged(u32) = .{};
|
||||
try new_mapping.ensureUnusedCapacity(self.base.allocator, self.data_segments.count());
|
||||
errdefer new_mapping.deinit(self.base.allocator);
|
||||
|
||||
const keys = try self.base.allocator.dupe([]const u8, self.data_segments.keys());
|
||||
defer self.base.allocator.free(keys);
|
||||
|
||||
const SortContext = struct {
|
||||
fn sort(_: void, lhs: []const u8, rhs: []const u8) bool {
|
||||
return order(lhs) <= order(rhs);
|
||||
}
|
||||
|
||||
fn order(name: []const u8) u8 {
|
||||
if (mem.startsWith(u8, name, ".rodata")) return 0;
|
||||
if (mem.startsWith(u8, name, ".data")) return 1;
|
||||
if (mem.startsWith(u8, name, ".text")) return 2;
|
||||
return 3;
|
||||
}
|
||||
};
|
||||
|
||||
std.sort.sort([]const u8, keys, {}, SortContext.sort);
|
||||
for (keys) |key| {
|
||||
const segment_index = self.data_segments.get(key).?;
|
||||
new_mapping.putAssumeCapacity(key, segment_index);
|
||||
}
|
||||
self.data_segments.deinit(self.base.allocator);
|
||||
self.data_segments = new_mapping;
|
||||
}
|
||||
|
||||
fn setupImports(self: *Wasm) !void {
|
||||
log.debug("Merging imports", .{});
|
||||
var discarded_it = self.discarded.keyIterator();
|
||||
@ -2337,8 +2370,13 @@ fn emitNameSection(self: *Wasm, file: fs.File, arena: Allocator) !void {
|
||||
}
|
||||
}
|
||||
// data segments are already 'ordered'
|
||||
for (self.data_segments.keys()) |key, index| {
|
||||
segments.appendAssumeCapacity(.{ .index = @intCast(u32, index), .name = key });
|
||||
var data_segment_index: u32 = 0;
|
||||
for (self.data_segments.keys()) |key| {
|
||||
// bss section is not emitted when this condition holds true, so we also
|
||||
// do not output a name for it.
|
||||
if (!self.base.options.import_memory and std.mem.eql(u8, key, ".bss")) continue;
|
||||
segments.appendAssumeCapacity(.{ .index = data_segment_index, .name = key });
|
||||
data_segment_index += 1;
|
||||
}
|
||||
|
||||
std.sort.sort(Name, funcs.values(), {}, Name.lessThan);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user