| ... | @@ -259,22 +259,49 @@ test "" { | ... | @@ -259,22 +259,49 @@ test "" { |
| 259 | const WasmPageAllocator = struct { | 259 | const WasmPageAllocator = struct { |
| 260 | const FreeBlock = struct { | 260 | const FreeBlock = struct { |
| 261 | offset: usize = 0, | 261 | offset: usize = 0, |
| 262 | data: []u8 = &[_]u8{}, | 262 | packed_data: std.PackedIntSlice(u1) = std.PackedIntSlice(u1).init(&[_]u8{}, 0), |
| 263 | | 263 | |
| 264 | fn initData(self: *FreeBlock, data: []u8) void { | 264 | fn initData(self: *FreeBlock, data: []u8) void { |
| | 265 | // 0 == used, 1 == free |
| 265 | std.mem.set(u8, data, 0); | 266 | std.mem.set(u8, data, 0); |
| 266 | self.data = data; | 267 | self.packed_data = std.PackedIntSlice(u1).init(data, data.len * 8); |
| 267 | } | 268 | } |
| 268 | | 269 | |
| 269 | fn totalPages(self: FreeBlock) usize { | 270 | fn totalPages(self: FreeBlock) usize { |
| 270 | return self.data.len * @typeInfo(usize).Int.bits; | 271 | return self.packed_data.int_count; |
| 271 | } | 272 | } |
| 272 | | 273 | |
| | 274 | // TODO: optimize this terribleness |
| 273 | fn alloc(self: *FreeBlock, num_pages: usize) ?[]u8 { | 275 | fn alloc(self: *FreeBlock, num_pages: usize) ?[]u8 { |
| | 276 | var found_idx: usize = 0; |
| | 277 | var found_size: usize = 0; |
| | 278 | |
| | 279 | var i: usize = 0; |
| | 280 | while (i < self.packed_data.int_count) : (i += 1) { |
| | 281 | if (self.packed_data.get(i) == 0) { |
| | 282 | found_size = 0; |
| | 283 | } else { |
| | 284 | if (found_size == 0) { |
| | 285 | found_idx = i; |
| | 286 | } |
| | 287 | found_size += 1; |
| | 288 | |
| | 289 | if (found_size >= num_pages) { |
| | 290 | const page_ptr = @intToPtr([*]u8, (found_idx + self.offset) * std.mem.page_size); |
| | 291 | return page_ptr[0 .. found_size * std.mem.page_size]; |
| | 292 | } |
| | 293 | } |
| | 294 | } |
| 274 | return null; | 295 | return null; |
| 275 | } | 296 | } |
| 276 | | 297 | |
| 277 | fn reclaim(self: *FreeBlock, start_page: usize, end_page: usize) void {} | 298 | fn reclaim(self: *FreeBlock, start_index: usize, end_index: usize) void { |
| | 299 | var i = start_index - self.offset; |
| | 300 | while (i < end_index - self.offset) : (i += 1) { |
| | 301 | std.debug.assert(self.packed_data.get(i) == 0); |
| | 302 | self.packed_data.set(i, 1); |
| | 303 | } |
| | 304 | } |
| 278 | }; | 305 | }; |
| 279 | | 306 | |
| 280 | var conventional = FreeBlock{}; | 307 | var conventional = FreeBlock{}; |
| ... | @@ -321,14 +348,14 @@ const WasmPageAllocator = struct { | ... | @@ -321,14 +348,14 @@ const WasmPageAllocator = struct { |
| 321 | var free_end = nPages(@ptrToInt(old_mem.ptr) + old_mem.len); | 348 | var free_end = nPages(@ptrToInt(old_mem.ptr) + old_mem.len); |
| 322 | | 349 | |
| 323 | if (free_end > free_start) { | 350 | if (free_end > free_start) { |
| 324 | if (conventional.data.len == 0) { | 351 | if (conventional.totalPages() == 0) { |
| 325 | conventional.initData(__heap_base[0..@intCast(usize, @"llvm.wasm.memory.size.i32"(0) * std.mem.page_size)]); | 352 | conventional.initData(__heap_base[0..@intCast(usize, @"llvm.wasm.memory.size.i32"(0) * std.mem.page_size)]); |
| 326 | } | 353 | } |
| 327 | | 354 | |
| 328 | if (free_start < conventional.totalPages()) { | 355 | if (free_start < conventional.totalPages()) { |
| 329 | conventional.reclaim(free_start, free_end); | 356 | conventional.reclaim(free_start, free_end); |
| 330 | } else { | 357 | } else { |
| 331 | if (extended.data.len == 0) { | 358 | if (extended.totalPages() == 0) { |
| 332 | extended.offset = conventional.totalPages(); | 359 | extended.offset = conventional.totalPages(); |
| 333 | | 360 | |
| 334 | // Steal the last page from the memory currently being reclaimed | 361 | // Steal the last page from the memory currently being reclaimed |