authorgravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2019-12-05 18:28:32-06:00
committergravatar for benjamin.feng@glassdoor.comBenjamin Feng <benjamin.feng@glassdoor.com> 2019-12-05 18:43:51-06:00
log694616adb549fc0dc2d7416e120e17992087e75c
tree3df61ab7d9c62d7aa5de0c23d547d1aab9322a52
parent7d1c4fe4dcb6188d2af0f65bf713aca8d326ea46

Standardize around bigger slices


1 files changed, 14 insertions(+), 23 deletions(-)

lib/std/heap.zig+14-23
...@@ -246,16 +246,12 @@ const PageAllocator = struct {...@@ -246,16 +246,12 @@ const PageAllocator = struct {
246 }246 }
247};247};
248248
249extern const __heap_base: [*]u8;
250// TODO Exposed LLVM intrinsics is a bug249// TODO Exposed LLVM intrinsics is a bug
251// See: https://github.com/ziglang/zig/issues/2291250// See: https://github.com/ziglang/zig/issues/2291
252extern fn @"llvm.wasm.memory.size.i32"(u32) u32;251extern fn @"llvm.wasm.memory.size.i32"(u32) u32;
253extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32;252extern fn @"llvm.wasm.memory.grow.i32"(u32, u32) i32;
254253
255const WasmPageAllocator = struct {254const WasmPageAllocator = struct {
256 // TODO: figure out why __heap_base cannot be found
257 var heap_base_wannabe align(16) = [_]u8{0} ** 256;
258
259 const PageStatus = enum(u1) {255 const PageStatus = enum(u1) {
260 used = 0,256 used = 0,
261 free = 1,257 free = 1,
...@@ -264,24 +260,24 @@ const WasmPageAllocator = struct {...@@ -264,24 +260,24 @@ const WasmPageAllocator = struct {
264 };260 };
265261
266 const FreeBlock = struct {262 const FreeBlock = struct {
267 bytes: []align(16) u8,263 data: []u128,
268264
269 const Io = std.packed_int_array.PackedIntIo(u1, .Little);265 const Io = std.packed_int_array.PackedIntIo(u1, .Little);
270266
271 fn totalPages(self: FreeBlock) usize {267 fn totalPages(self: FreeBlock) usize {
272 return self.bytes.len * 8;268 return self.data.len * 8;
273 }269 }
274270
275 fn getBit(self: *FreeBlock, idx: usize) PageStatus {271 fn getBit(self: FreeBlock, idx: usize) PageStatus {
276 const bit_offset = 0;272 const bit_offset = 0;
277 return @intToEnum(PageStatus, Io.get(self.bytes, idx, bit_offset));273 return @intToEnum(PageStatus, Io.get(@sliceToBytes(self.data), idx, bit_offset));
278 }274 }
279275
280 fn setBits(self: *FreeBlock, start_idx: usize, len: usize, val: PageStatus) void {276 fn setBits(self: FreeBlock, start_idx: usize, len: usize, val: PageStatus) void {
281 const bit_offset = 0;277 const bit_offset = 0;
282 var i: usize = 0;278 var i: usize = 0;
283 while (i < len) : (i += 1) {279 while (i < len) : (i += 1) {
284 Io.set(self.bytes, start_idx + i, bit_offset, @enumToInt(val));280 Io.set(@sliceToBytes(self.data), start_idx + i, bit_offset, @enumToInt(val));
285 }281 }
286 }282 }
287283
...@@ -294,10 +290,9 @@ const WasmPageAllocator = struct {...@@ -294,10 +290,9 @@ const WasmPageAllocator = struct {
294 // Revisit if this is settled: https://github.com/ziglang/zig/issues/3806290 // Revisit if this is settled: https://github.com/ziglang/zig/issues/3806
295 const not_found = std.math.maxInt(usize);291 const not_found = std.math.maxInt(usize);
296292
297 fn useRecycled(self: *FreeBlock, num_pages: usize) usize {293 fn useRecycled(self: FreeBlock, num_pages: usize) usize {
298 @setCold(true);294 @setCold(true);
299 const segments = @bytesToSlice(u128, self.bytes);295 for (self.data) |segment, i| {
300 for (segments) |segment, i| {
301 const spills_into_next = @bitCast(i128, segment) < 0;296 const spills_into_next = @bitCast(i128, segment) < 0;
302 const has_enough_bits = @popCount(u128, segment) >= num_pages;297 const has_enough_bits = @popCount(u128, segment) >= num_pages;
303298
...@@ -319,13 +314,13 @@ const WasmPageAllocator = struct {...@@ -319,13 +314,13 @@ const WasmPageAllocator = struct {
319 return not_found;314 return not_found;
320 }315 }
321316
322 fn recycle(self: *FreeBlock, start_idx: usize, len: usize) void {317 fn recycle(self: FreeBlock, start_idx: usize, len: usize) void {
323 self.setBits(start_idx, len, .free);318 self.setBits(start_idx, len, .free);
324 }319 }
325 };320 };
326321
327 var conventional = FreeBlock{ .bytes = &[_]u8{} };322 const conventional = FreeBlock{ .data = &[_]u128{ 0, 0 } };
328 var extended = FreeBlock{ .bytes = &[_]u8{} };323 var extended = FreeBlock{ .data = &[_]u128{} };
329324
330 fn extendedOffset() usize {325 fn extendedOffset() usize {
331 return conventional.totalPages();326 return conventional.totalPages();
...@@ -373,15 +368,11 @@ const WasmPageAllocator = struct {...@@ -373,15 +368,11 @@ const WasmPageAllocator = struct {
373 }368 }
374369
375 pub fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {370 pub fn shrink(allocator: *Allocator, old_mem: []u8, old_align: u29, new_size: usize, new_align: u29) []u8 {
371 @setCold(true);
376 const free_start = nPages(@ptrToInt(old_mem.ptr) + new_size);372 const free_start = nPages(@ptrToInt(old_mem.ptr) + new_size);
377 var free_end = nPages(@ptrToInt(old_mem.ptr) + old_mem.len);373 var free_end = nPages(@ptrToInt(old_mem.ptr) + old_mem.len);
378374
379 if (free_end > free_start) {375 if (free_end > free_start) {
380 if (conventional.totalPages() == 0) {
381 //conventional.bytes = __heap_base[0..@intCast(usize, @"llvm.wasm.memory.size.i32"(0) * std.mem.page_size)];
382 conventional.bytes = heap_base_wannabe[0..];
383 }
384
385 if (free_start < extendedOffset()) {376 if (free_start < extendedOffset()) {
386 const clamped_end = std.math.min(extendedOffset(), free_end);377 const clamped_end = std.math.min(extendedOffset(), free_end);
387 conventional.recycle(free_start, clamped_end - free_start);378 conventional.recycle(free_start, clamped_end - free_start);
...@@ -393,9 +384,9 @@ const WasmPageAllocator = struct {...@@ -393,9 +384,9 @@ const WasmPageAllocator = struct {
393 // TODO: would it be better if we use the first page instead?384 // TODO: would it be better if we use the first page instead?
394 free_end -= 1;385 free_end -= 1;
395386
396 extended.bytes = @intToPtr([*]align(16) u8, free_end * std.mem.page_size)[0..std.mem.page_size];387 extended.data = @intToPtr([*]u128, free_end * std.mem.page_size)[0 .. std.mem.page_size / @sizeOf(u128)];
397 // Since this is the first page being freed and we consume it, assume *nothing* is free.388 // Since this is the first page being freed and we consume it, assume *nothing* is free.
398 std.mem.set(u8, extended.bytes, PageStatus.all_used);389 std.mem.set(u128, extended.data, PageStatus.all_used);
399 }390 }
400 const clamped_start = std.math.max(extendedOffset(), free_start);391 const clamped_start = std.math.max(extendedOffset(), free_start);
401 extended.recycle(clamped_start - extendedOffset(), free_end - clamped_start);392 extended.recycle(clamped_start - extendedOffset(), free_end - clamped_start);