authorgravatar for contact@fengb.meBenjamin Feng <contact@fengb.me> 2019-12-04 21:21:54-06:00
committergravatar for contact@fengb.meBenjamin Feng <contact@fengb.me> 2019-12-04 21:22:36-06:00
log5784985bb8a4c6aa686ad0b9fb98532c44c74b85
tree526e2de350856f970f62c9b2b1462950c3fca0c2
parenta910a6c871d1840c900287d68f0d5c9f8888247d

Use raw PackedIo to shave ~150b


1 files changed, 18 insertions(+), 13 deletions(-)

lib/std/heap.zig+18-13
...@@ -257,24 +257,28 @@ const WasmPageAllocator = struct {...@@ -257,24 +257,28 @@ const WasmPageAllocator = struct {
257 var heap_base_wannabe: [256]u8 align(16) = undefined;257 var heap_base_wannabe: [256]u8 align(16) = undefined;
258258
259 const FreeBlock = struct {259 const FreeBlock = struct {
260 packed_data: std.PackedIntSlice(u1) = std.PackedIntSlice(u1).init(&[_]u8{}, 0),260 const Io = std.packed_int_array.PackedIntIo(u1, .Little);
261 block_data: []u128 = &[_]u128{},
262261
263 fn initData(self: *FreeBlock, data: []align(16) u8) void {262 bytes: []align(16) u8,
263
264 fn initData(self: *FreeBlock, bytes: []align(16) u8) void {
264 // 0 == used, 1 == free265 // 0 == used, 1 == free
265 std.mem.set(u8, data, 0);266 std.mem.set(u8, bytes, 0);
266 self.packed_data = std.PackedIntSlice(u1).init(data, data.len * 8);267 self.bytes = bytes;
267 self.block_data = @bytesToSlice(u128, data);
268 }268 }
269269
270 fn totalPages(self: FreeBlock) usize {270 fn totalPages(self: FreeBlock) usize {
271 return self.packed_data.int_count;271 return self.bytes.len * 8;
272 }
273
274 fn getBit(self: *FreeBlock, idx: usize) u1 {
275 return Io.get(self.bytes, idx, 0);
272 }276 }
273277
274 fn setBits(self: *FreeBlock, start_idx: usize, len: usize, val: u1) void {278 fn setBits(self: *FreeBlock, start_idx: usize, len: usize, val: u1) void {
275 var i: usize = 0;279 var i: usize = 0;
276 while (i < len) : (i += 1) {280 while (i < len) : (i += 1) {
277 self.packed_data.set(i + start_idx, val);281 Io.set(self.bytes, start_idx + i, 0, val);
278 }282 }
279 }283 }
280284
...@@ -282,14 +286,15 @@ const WasmPageAllocator = struct {...@@ -282,14 +286,15 @@ const WasmPageAllocator = struct {
282 // This saves ~50 bytes compared to returning a nullable286 // This saves ~50 bytes compared to returning a nullable
283287
284 // We can guarantee that conventional memory never gets this big,288 // We can guarantee that conventional memory never gets this big,
285 // and wasm32 would not be able to address this block (32 GB > usize).289 // and wasm32 would not be able to address this memory (32 GB > usize).
286290
287 // Revisit if this is settled: https://github.com/ziglang/zig/issues/3806291 // Revisit if this is settled: https://github.com/ziglang/zig/issues/3806
288 const not_found = std.math.maxInt(usize);292 const not_found = std.math.maxInt(usize);
289293
290 fn useRecycled(self: *FreeBlock, num_pages: usize) usize {294 fn useRecycled(self: *FreeBlock, num_pages: usize) usize {
291 @setCold(true);295 @setCold(true);
292 for (self.block_data) |segment, i| {296 const segments = @bytesToSlice(u128, self.bytes);
297 for (segments) |segment, i| {
293 const spills_into_next = @bitCast(i128, segment) < 0;298 const spills_into_next = @bitCast(i128, segment) < 0;
294 const has_enough_bits = @popCount(u128, segment) >= num_pages;299 const has_enough_bits = @popCount(u128, segment) >= num_pages;
295300
...@@ -298,7 +303,7 @@ const WasmPageAllocator = struct {...@@ -298,7 +303,7 @@ const WasmPageAllocator = struct {
298 var j: usize = i * 128;303 var j: usize = i * 128;
299 while (j < (i + 1) * 128) : (j += 1) {304 while (j < (i + 1) * 128) : (j += 1) {
300 var count: usize = 0;305 var count: usize = 0;
301 while (j + count < self.packed_data.int_count and self.packed_data.get(j + count) == 1) {306 while (j + count < self.totalPages() and self.getBit(j + count) == 1) {
302 count += 1;307 count += 1;
303 if (count >= num_pages) {308 if (count >= num_pages) {
304 self.setBits(j, num_pages, 0);309 self.setBits(j, num_pages, 0);
...@@ -316,8 +321,8 @@ const WasmPageAllocator = struct {...@@ -316,8 +321,8 @@ const WasmPageAllocator = struct {
316 }321 }
317 };322 };
318323
319 var conventional = FreeBlock{};324 var conventional = FreeBlock{ .bytes = &[_]u8{} };
320 var extended = FreeBlock{};325 var extended = FreeBlock{ .bytes = &[_]u8{} };
321326
322 fn extendedOffset() usize {327 fn extendedOffset() usize {
323 return conventional.totalPages();328 return conventional.totalPages();