authorgravatar for contact@fengb.meBenjamin Feng <contact@fengb.me> 2019-12-03 17:24:50-06:00
committergravatar for contact@fengb.meBenjamin Feng <contact@fengb.me> 2019-12-03 17:24:50-06:00
logb33211ed51901bfbc36d23cb5a02d1c8ca3b072e
tree33d3ff02ce8a6379747fe1cb60b6e39718f3da04
parent45e04412786db37ecaf31a5fe6c4c1f4186e6d13

Implement block-based skipping


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

lib/std/heap.zig+29-18
......@@ -254,43 +254,54 @@ extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32;
254254
255255const WasmPageAllocator = struct {
256256 // TODO: figure out why __heap_base cannot be found
257 var heap_base_wannabe: [256]u8 = undefined;
257 var heap_base_wannabe: [256]u8 align(16) = undefined;
258258
259259 const FreeBlock = struct {
260260 offset: usize = 0,
261261 packed_data: std.PackedIntSlice(u1) = std.PackedIntSlice(u1).init(&[_]u8{}, 0),
262 block_data: []u128 = &[_]u128{},
262263
263 fn initData(self: *FreeBlock, data: []u8) void {
264 fn initData(self: *FreeBlock, data: []align(16) u8) void {
264265 // 0 == used, 1 == free
265266 std.mem.set(u8, data, 0);
266267 self.packed_data = std.PackedIntSlice(u1).init(data, data.len * 8);
268 self.block_data = @bytesToSlice(u128, data);
267269 }
268270
269271 fn totalPages(self: FreeBlock) usize {
270272 return self.packed_data.int_count;
271273 }
272274
273 // TODO: optimize this terribleness
274275 fn useRecycled(self: *FreeBlock, num_pages: usize) ?[*]u8 {
275276 var found_idx: usize = 0;
276277 var found_size: usize = 0;
277278
278 var i: usize = 0;
279 while (i < self.packed_data.int_count) : (i += 1) {
280 if (self.packed_data.get(i) == 0) {
281 found_size = 0;
282 } else {
283 if (found_size == 0) {
284 found_idx = i;
285 }
286 found_size += 1;
279 for (self.block_data) |segment, i| {
280 const spills_into_next = @bitCast(i128, segment) < 0;
281 const has_enough_bits = @popCount(u128, segment) >= num_pages;
282
283 if (!spills_into_next and !has_enough_bits) continue;
287284
288 if (found_size >= num_pages) {
289 while (found_size > 0) {
290 found_size -= 1;
291 self.packed_data.set(found_idx + found_size, 0);
285 var j: usize = i * 128;
286 while (j < self.packed_data.int_count) : (j += 1) {
287 if (self.packed_data.get(j) == 0) {
288 found_size = 0;
289 if (j > (i + 1) * 128) {
290 break;
291 }
292 } else {
293 if (found_size == 0) {
294 found_idx = j;
295 }
296 found_size += 1;
297
298 if (found_size >= num_pages) {
299 while (found_size > 0) {
300 found_size -= 1;
301 self.packed_data.set(found_idx + found_size, 0);
302 }
303 return @intToPtr([*]u8, (found_idx + self.offset) * std.mem.page_size);
292304 }
293 return @intToPtr([*]u8, (found_idx + self.offset) * std.mem.page_size);
294305 }
295306 }
296307 }
......@@ -365,7 +376,7 @@ const WasmPageAllocator = struct {
365376
366377 // Steal the last page from the memory currently being recycled
367378 free_end -= 1;
368 extended.initData(@intToPtr([*]u8, free_end * std.mem.page_size)[0..std.mem.page_size]);
379 extended.initData(@intToPtr([*]align(16) u8, free_end * std.mem.page_size)[0..std.mem.page_size]);
369380 }
370381 extended.recycle(free_start, free_end);
371382 }