diff options
| author | Benjamin Feng <benjamin.feng@glassdoor.com> | 2019-12-05 21:54:57 -0600 |
|---|---|---|
| committer | Benjamin Feng <benjamin.feng@glassdoor.com> | 2019-12-05 21:54:57 -0600 |
| commit | eb495d934b266cc9083f5caf093ec2c437f19788 (patch) | |
| tree | e7093c7e0c249fa8e51bd6d6d88134e52872dc67 /lib/std | |
| parent | f2b0dbea748ecc927a9c2482dbb1dad8843cf9f8 (diff) | |
| download | zig-eb495d934b266cc9083f5caf093ec2c437f19788.tar.gz zig-eb495d934b266cc9083f5caf093ec2c437f19788.zip | |
Add WasmPageAllocator tests
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/heap.zig | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/lib/std/heap.zig b/lib/std/heap.zig index e7fab637c0..9ff8b9f7b9 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -256,7 +256,7 @@ const WasmPageAllocator = struct { used = 0, free = 1, - pub const all_used: u8 = 0; + pub const none_free: u8 = 0; }; const FreeBlock = struct { @@ -265,7 +265,11 @@ const WasmPageAllocator = struct { const Io = std.packed_int_array.PackedIntIo(u1, .Little); fn totalPages(self: FreeBlock) usize { - return self.data.len * 8; + return self.data.len * 128; + } + + fn isInitialized(self: FreeBlock) bool { + return self.data.len > 0; } fn getBit(self: FreeBlock, idx: usize) PageStatus { @@ -319,7 +323,9 @@ const WasmPageAllocator = struct { } }; - const conventional = FreeBlock{ .data = &[_]u128{ 0, 0 } }; + var _conventional_data = [_]u128{0} ** 16; + // Marking `conventional` as const saves ~40 bytes + var conventional = FreeBlock{ .data = &_conventional_data }; var extended = FreeBlock{ .data = &[_]u128{} }; fn extendedOffset() usize { @@ -379,14 +385,14 @@ const WasmPageAllocator = struct { } if (free_end > extendedOffset()) { - if (extended.totalPages() == 0) { + if (!extended.isInitialized()) { // Steal the last page from the memory currently being recycled // TODO: would it be better if we use the first page instead? free_end -= 1; extended.data = @intToPtr([*]u128, free_end * std.mem.page_size)[0 .. std.mem.page_size / @sizeOf(u128)]; // Since this is the first page being freed and we consume it, assume *nothing* is free. - std.mem.set(u128, extended.data, PageStatus.all_used); + std.mem.set(u128, extended.data, PageStatus.none_free); } const clamped_start = std.math.max(extendedOffset(), free_start); extended.recycle(clamped_start - extendedOffset(), free_end - clamped_start); @@ -790,6 +796,38 @@ test "c_allocator" { } } +test "WasmPageAllocator internals" { + if (std.Target.current.isWasm()) { + const none_free = WasmPageAllocator.PageStatus.none_free; + std.debug.assert(none_free == WasmPageAllocator.conventional.data[0]); // Passes if this test runs first + std.debug.assert(!WasmPageAllocator.extended.isInitialized()); // Passes if this test runs first + + const tmp = try page_allocator.alloc(u8, 1); + testing.expect(none_free == WasmPageAllocator.conventional.data[0]); + page_allocator.free(tmp); + testing.expect(none_free < WasmPageAllocator.conventional.data[0]); + + const a_little_free = WasmPageAllocator.conventional.data[0]; + const tmp_large = try page_allocator.alloc(u8, std.mem.page_size + 1); + testing.expect(a_little_free == WasmPageAllocator.conventional.data[0]); + const tmp_small = try page_allocator.alloc(u8, 1); + testing.expect(none_free == WasmPageAllocator.conventional.data[0]); + + page_allocator.free(tmp_small); + testing.expect(a_little_free == WasmPageAllocator.conventional.data[0]); + page_allocator.free(tmp_large); + testing.expect(a_little_free < WasmPageAllocator.conventional.data[0]); + + const more_free = WasmPageAllocator.conventional.data[0]; + const supersize = try page_allocator.alloc(u8, std.mem.page_size * (WasmPageAllocator.conventional.totalPages() + 1)); + testing.expect(more_free == WasmPageAllocator.conventional.data[0]); + testing.expect(!WasmPageAllocator.extended.isInitialized()); + page_allocator.free(supersize); + testing.expect(WasmPageAllocator.extended.isInitialized()); + testing.expect(more_free < WasmPageAllocator.conventional.data[0]); + } +} + test "PageAllocator" { const allocator = page_allocator; try testAllocator(allocator); |
