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;...@@ -254,43 +254,54 @@ extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32;
254254
255const WasmPageAllocator = struct {255const WasmPageAllocator = struct {
256 // TODO: figure out why __heap_base cannot be found256 // 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
259 const FreeBlock = struct {259 const FreeBlock = struct {
260 offset: usize = 0,260 offset: usize = 0,
261 packed_data: std.PackedIntSlice(u1) = std.PackedIntSlice(u1).init(&[_]u8{}, 0),261 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 {
264 // 0 == used, 1 == free265 // 0 == used, 1 == free
265 std.mem.set(u8, data, 0);266 std.mem.set(u8, data, 0);
266 self.packed_data = std.PackedIntSlice(u1).init(data, data.len * 8);267 self.packed_data = std.PackedIntSlice(u1).init(data, data.len * 8);
268 self.block_data = @bytesToSlice(u128, data);
267 }269 }
268270
269 fn totalPages(self: FreeBlock) usize {271 fn totalPages(self: FreeBlock) usize {
270 return self.packed_data.int_count;272 return self.packed_data.int_count;
271 }273 }
272274
273 // TODO: optimize this terribleness
274 fn useRecycled(self: *FreeBlock, num_pages: usize) ?[*]u8 {275 fn useRecycled(self: *FreeBlock, num_pages: usize) ?[*]u8 {
275 var found_idx: usize = 0;276 var found_idx: usize = 0;
276 var found_size: usize = 0;277 var found_size: usize = 0;
277278
278 var i: usize = 0;279 for (self.block_data) |segment, i| {
279 while (i < self.packed_data.int_count) : (i += 1) {280 const spills_into_next = @bitCast(i128, segment) < 0;
280 if (self.packed_data.get(i) == 0) {281 const has_enough_bits = @popCount(u128, segment) >= num_pages;
281 found_size = 0;282
282 } else {283 if (!spills_into_next and !has_enough_bits) continue;
283 if (found_size == 0) {
284 found_idx = i;
285 }
286 found_size += 1;
287284
288 if (found_size >= num_pages) {285 var j: usize = i * 128;
289 while (found_size > 0) {286 while (j < self.packed_data.int_count) : (j += 1) {
290 found_size -= 1;287 if (self.packed_data.get(j) == 0) {
291 self.packed_data.set(found_idx + found_size, 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);
292 }304 }
293 return @intToPtr([*]u8, (found_idx + self.offset) * std.mem.page_size);
294 }305 }
295 }306 }
296 }307 }
...@@ -365,7 +376,7 @@ const WasmPageAllocator = struct {...@@ -365,7 +376,7 @@ const WasmPageAllocator = struct {
365376
366 // Steal the last page from the memory currently being recycled377 // Steal the last page from the memory currently being recycled
367 free_end -= 1;378 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]);
369 }380 }
370 extended.recycle(free_start, free_end);381 extended.recycle(free_start, free_end);
371 }382 }