| ... | ... | @@ -259,22 +259,49 @@ test "" { |
| 259 | 259 | const WasmPageAllocator = struct { |
| 260 | 260 | const FreeBlock = struct { |
| 261 | 261 | offset: usize = 0, |
| 262 | | data: []u8 = &[_]u8{}, |
| 262 | packed_data: std.PackedIntSlice(u1) = std.PackedIntSlice(u1).init(&[_]u8{}, 0), |
| 263 | 263 | |
| 264 | 264 | fn initData(self: *FreeBlock, data: []u8) void { |
| 265 | // 0 == used, 1 == free |
| 265 | 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 | 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 | 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 | 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 | 307 | var conventional = FreeBlock{}; |
| ... | ... | @@ -321,14 +348,14 @@ const WasmPageAllocator = struct { |
| 321 | 348 | var free_end = nPages(@ptrToInt(old_mem.ptr) + old_mem.len); |
| 322 | 349 | |
| 323 | 350 | if (free_end > free_start) { |
| 324 | | if (conventional.data.len == 0) { |
| 351 | if (conventional.totalPages() == 0) { |
| 325 | 352 | conventional.initData(__heap_base[0..@intCast(usize, @"llvm.wasm.memory.size.i32"(0) * std.mem.page_size)]); |
| 326 | 353 | } |
| 327 | 354 | |
| 328 | 355 | if (free_start < conventional.totalPages()) { |
| 329 | 356 | conventional.reclaim(free_start, free_end); |
| 330 | 357 | } else { |
| 331 | | if (extended.data.len == 0) { |
| 358 | if (extended.totalPages() == 0) { |
| 332 | 359 | extended.offset = conventional.totalPages(); |
| 333 | 360 | |
| 334 | 361 | // Steal the last page from the memory currently being reclaimed |