| ... | @@ -254,31 +254,30 @@ extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32; | ... | @@ -254,31 +254,30 @@ extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32; |
| 254 | | 254 | |
| 255 | const WasmPageAllocator = struct { | 255 | const WasmPageAllocator = struct { |
| 256 | // TODO: figure out why __heap_base cannot be found | 256 | // TODO: figure out why __heap_base cannot be found |
| 257 | var heap_base_wannabe: [256]u8 align(16) = undefined; | 257 | var heap_base_wannabe align(16) = [_]u8{0} ** 256; |
| 258 | | 258 | |
| 259 | const FreeBlock = struct { | 259 | const FreeBlock = struct { |
| 260 | const Io = std.packed_int_array.PackedIntIo(u1, .Little); | | |
| 261 | | | |
| 262 | bytes: []align(16) u8, | 260 | bytes: []align(16) u8, |
| 263 | | 261 | |
| 264 | fn initData(self: *FreeBlock, bytes: []align(16) u8) void { | 262 | const Io = std.packed_int_array.PackedIntIo(u1, .Little); |
| 265 | // 0 == used, 1 == free | 263 | |
| 266 | std.mem.set(u8, bytes, 0); | 264 | const used = 0; |
| 267 | self.bytes = bytes; | 265 | const free = 1; |
| 268 | } | | |
| 269 | | 266 | |
| 270 | fn totalPages(self: FreeBlock) usize { | 267 | fn totalPages(self: FreeBlock) usize { |
| 271 | return self.bytes.len * 8; | 268 | return self.bytes.len * 8; |
| 272 | } | 269 | } |
| 273 | | 270 | |
| 274 | fn getBit(self: *FreeBlock, idx: usize) u1 { | 271 | fn getBit(self: *FreeBlock, idx: usize) u1 { |
| 275 | return Io.get(self.bytes, idx, 0); | 272 | const bit_offset = 0; |
| | 273 | return Io.get(self.bytes, idx, bit_offset); |
| 276 | } | 274 | } |
| 277 | | 275 | |
| 278 | fn setBits(self: *FreeBlock, start_idx: usize, len: usize, val: u1) void { | 276 | fn setBits(self: *FreeBlock, start_idx: usize, len: usize, val: u1) void { |
| | 277 | const bit_offset = 0; |
| 279 | var i: usize = 0; | 278 | var i: usize = 0; |
| 280 | while (i < len) : (i += 1) { | 279 | while (i < len) : (i += 1) { |
| 281 | Io.set(self.bytes, start_idx + i, 0, val); | 280 | Io.set(self.bytes, start_idx + i, bit_offset, val); |
| 282 | } | 281 | } |
| 283 | } | 282 | } |
| 284 | | 283 | |
| ... | @@ -306,7 +305,7 @@ const WasmPageAllocator = struct { | ... | @@ -306,7 +305,7 @@ const WasmPageAllocator = struct { |
| 306 | while (j + count < self.totalPages() and self.getBit(j + count) == 1) { | 305 | while (j + count < self.totalPages() and self.getBit(j + count) == 1) { |
| 307 | count += 1; | 306 | count += 1; |
| 308 | if (count >= num_pages) { | 307 | if (count >= num_pages) { |
| 309 | self.setBits(j, num_pages, 0); | 308 | self.setBits(j, num_pages, used); |
| 310 | return j; | 309 | return j; |
| 311 | } | 310 | } |
| 312 | } | 311 | } |
| ... | @@ -317,7 +316,7 @@ const WasmPageAllocator = struct { | ... | @@ -317,7 +316,7 @@ const WasmPageAllocator = struct { |
| 317 | } | 316 | } |
| 318 | | 317 | |
| 319 | fn recycle(self: *FreeBlock, start_idx: usize, len: usize) void { | 318 | fn recycle(self: *FreeBlock, start_idx: usize, len: usize) void { |
| 320 | self.setBits(start_idx, len, 1); | 319 | self.setBits(start_idx, len, free); |
| 321 | } | 320 | } |
| 322 | }; | 321 | }; |
| 323 | | 322 | |
| ... | @@ -375,8 +374,8 @@ const WasmPageAllocator = struct { | ... | @@ -375,8 +374,8 @@ const WasmPageAllocator = struct { |
| 375 | | 374 | |
| 376 | if (free_end > free_start) { | 375 | if (free_end > free_start) { |
| 377 | if (conventional.totalPages() == 0) { | 376 | if (conventional.totalPages() == 0) { |
| 378 | //conventional.initData(__heap_base[0..@intCast(usize, @"llvm.wasm.memory.size.i32"(0) * std.mem.page_size)]); | 377 | //conventional.bytes = __heap_base[0..@intCast(usize, @"llvm.wasm.memory.size.i32"(0) * std.mem.page_size)]; |
| 379 | conventional.initData(heap_base_wannabe[0..]); | 378 | conventional.bytes = heap_base_wannabe[0..]; |
| 380 | } | 379 | } |
| 381 | | 380 | |
| 382 | if (free_start < extendedOffset()) { | 381 | if (free_start < extendedOffset()) { |
| ... | @@ -384,8 +383,12 @@ const WasmPageAllocator = struct { | ... | @@ -384,8 +383,12 @@ const WasmPageAllocator = struct { |
| 384 | } else { | 383 | } else { |
| 385 | if (extended.totalPages() == 0) { | 384 | if (extended.totalPages() == 0) { |
| 386 | // Steal the last page from the memory currently being recycled | 385 | // Steal the last page from the memory currently being recycled |
| | 386 | // TODO: would it be better if we use the first page instead? |
| 387 | free_end -= 1; | 387 | free_end -= 1; |
| 388 | extended.initData(@intToPtr([*]align(16) u8, free_end * std.mem.page_size)[0..std.mem.page_size]); | 388 | |
| | 389 | extended.bytes = @intToPtr([*]align(16) u8, free_end * std.mem.page_size)[0..std.mem.page_size]; |
| | 390 | // Since this is the first page being freed and we consume it, assume *nothing* is free. |
| | 391 | std.mem.set(u8, extended.bytes, FreeBlock.used); |
| 389 | } | 392 | } |
| 390 | extended.recycle(free_start - extendedOffset(), free_end - free_start); | 393 | extended.recycle(free_start - extendedOffset(), free_end - free_start); |
| 391 | } | 394 | } |