| ... | ... | @@ -254,43 +254,54 @@ extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32; |
| 254 | 254 | |
| 255 | 255 | const WasmPageAllocator = struct { |
| 256 | 256 | // 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; |
| 258 | 258 | |
| 259 | 259 | const FreeBlock = struct { |
| 260 | 260 | offset: usize = 0, |
| 261 | 261 | packed_data: std.PackedIntSlice(u1) = std.PackedIntSlice(u1).init(&[_]u8{}, 0), |
| 262 | block_data: []u128 = &[_]u128{}, |
| 262 | 263 | |
| 263 | | fn initData(self: *FreeBlock, data: []u8) void { |
| 264 | fn initData(self: *FreeBlock, data: []align(16) u8) void { |
| 264 | 265 | // 0 == used, 1 == free |
| 265 | 266 | std.mem.set(u8, data, 0); |
| 266 | 267 | self.packed_data = std.PackedIntSlice(u1).init(data, data.len * 8); |
| 268 | self.block_data = @bytesToSlice(u128, data); |
| 267 | 269 | } |
| 268 | 270 | |
| 269 | 271 | fn totalPages(self: FreeBlock) usize { |
| 270 | 272 | return self.packed_data.int_count; |
| 271 | 273 | } |
| 272 | 274 | |
| 273 | | // TODO: optimize this terribleness |
| 274 | 275 | fn useRecycled(self: *FreeBlock, num_pages: usize) ?[*]u8 { |
| 275 | 276 | var found_idx: usize = 0; |
| 276 | 277 | var found_size: usize = 0; |
| 277 | 278 | |
| 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; |
| 287 | 284 | |
| 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); |
| 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 | 376 | |
| 366 | 377 | // Steal the last page from the memory currently being recycled |
| 367 | 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 | 381 | extended.recycle(free_start, free_end); |
| 371 | 382 | } |