| ... | @@ -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; |
| 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 = undefined; | 257 | var heap_base_wannabe: [256]u8 align(16) = undefined; |
| 258 | | 258 | |
| 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{}, |
| 262 | | 263 | |
| 263 | fn initData(self: *FreeBlock, data: []u8) void { | 264 | fn initData(self: *FreeBlock, data: []align(16) u8) void { |
| 264 | // 0 == used, 1 == free | 265 | // 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 | } |
| 268 | | 270 | |
| 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 | } |
| 272 | | 274 | |
| 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; |
| 277 | | 278 | |
| 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; | | |
| 287 | | 284 | |
| 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 { |
| 365 | | 376 | |
| 366 | // Steal the last page from the memory currently being recycled | 377 | // 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 | } |