| ... | ... | @@ -257,24 +257,28 @@ const WasmPageAllocator = struct { |
| 257 | 257 | var heap_base_wannabe: [256]u8 align(16) = undefined; |
| 258 | 258 | |
| 259 | 259 | const FreeBlock = struct { |
| 260 | | packed_data: std.PackedIntSlice(u1) = std.PackedIntSlice(u1).init(&[_]u8{}, 0), |
| 261 | | block_data: []u128 = &[_]u128{}, |
| 260 | const Io = std.packed_int_array.PackedIntIo(u1, .Little); |
| 262 | 261 | |
| 263 | | fn initData(self: *FreeBlock, data: []align(16) u8) void { |
| 262 | bytes: []align(16) u8, |
| 263 | |
| 264 | fn initData(self: *FreeBlock, bytes: []align(16) u8) void { |
| 264 | 265 | // 0 == used, 1 == free |
| 265 | | std.mem.set(u8, data, 0); |
| 266 | | self.packed_data = std.PackedIntSlice(u1).init(data, data.len * 8); |
| 267 | | self.block_data = @bytesToSlice(u128, data); |
| 266 | std.mem.set(u8, bytes, 0); |
| 267 | self.bytes = bytes; |
| 268 | 268 | } |
| 269 | 269 | |
| 270 | 270 | fn totalPages(self: FreeBlock) usize { |
| 271 | | return self.packed_data.int_count; |
| 271 | return self.bytes.len * 8; |
| 272 | } |
| 273 | |
| 274 | fn getBit(self: *FreeBlock, idx: usize) u1 { |
| 275 | return Io.get(self.bytes, idx, 0); |
| 272 | 276 | } |
| 273 | 277 | |
| 274 | 278 | fn setBits(self: *FreeBlock, start_idx: usize, len: usize, val: u1) void { |
| 275 | 279 | var i: usize = 0; |
| 276 | 280 | while (i < len) : (i += 1) { |
| 277 | | self.packed_data.set(i + start_idx, val); |
| 281 | Io.set(self.bytes, start_idx + i, 0, val); |
| 278 | 282 | } |
| 279 | 283 | } |
| 280 | 284 | |
| ... | ... | @@ -282,14 +286,15 @@ const WasmPageAllocator = struct { |
| 282 | 286 | // This saves ~50 bytes compared to returning a nullable |
| 283 | 287 | |
| 284 | 288 | // We can guarantee that conventional memory never gets this big, |
| 285 | | // and wasm32 would not be able to address this block (32 GB > usize). |
| 289 | // and wasm32 would not be able to address this memory (32 GB > usize). |
| 286 | 290 | |
| 287 | 291 | // Revisit if this is settled: https://github.com/ziglang/zig/issues/3806 |
| 288 | 292 | const not_found = std.math.maxInt(usize); |
| 289 | 293 | |
| 290 | 294 | fn useRecycled(self: *FreeBlock, num_pages: usize) usize { |
| 291 | 295 | @setCold(true); |
| 292 | | for (self.block_data) |segment, i| { |
| 296 | const segments = @bytesToSlice(u128, self.bytes); |
| 297 | for (segments) |segment, i| { |
| 293 | 298 | const spills_into_next = @bitCast(i128, segment) < 0; |
| 294 | 299 | const has_enough_bits = @popCount(u128, segment) >= num_pages; |
| 295 | 300 | |
| ... | ... | @@ -298,7 +303,7 @@ const WasmPageAllocator = struct { |
| 298 | 303 | var j: usize = i * 128; |
| 299 | 304 | while (j < (i + 1) * 128) : (j += 1) { |
| 300 | 305 | var count: usize = 0; |
| 301 | | while (j + count < self.packed_data.int_count and self.packed_data.get(j + count) == 1) { |
| 306 | while (j + count < self.totalPages() and self.getBit(j + count) == 1) { |
| 302 | 307 | count += 1; |
| 303 | 308 | if (count >= num_pages) { |
| 304 | 309 | self.setBits(j, num_pages, 0); |
| ... | ... | @@ -316,8 +321,8 @@ const WasmPageAllocator = struct { |
| 316 | 321 | } |
| 317 | 322 | }; |
| 318 | 323 | |
| 319 | | var conventional = FreeBlock{}; |
| 320 | | var extended = FreeBlock{}; |
| 324 | var conventional = FreeBlock{ .bytes = &[_]u8{} }; |
| 325 | var extended = FreeBlock{ .bytes = &[_]u8{} }; |
| 321 | 326 | |
| 322 | 327 | fn extendedOffset() usize { |
| 323 | 328 | return conventional.totalPages(); |