diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig index bba16dfb3f..0912e7d5f1 100644 --- a/src-self-hosted/main.zig +++ b/src-self-hosted/main.zig @@ -66,9 +66,11 @@ pub fn main2() -> %void { } +var fixed_buffer_mem: [100 * 1024]u8 = undefined; + fn testCanonical(source: []const u8) { - const allocator = std.debug.global_allocator; - std.debug.global_allocator_index = 0; + var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); + const allocator = &fixed_allocator.allocator; var tokenizer = Tokenizer.init(source); var parser = Parser.init(&tokenizer, allocator, "(memory buffer)"); diff --git a/std/debug.zig b/std/debug.zig index 3e7a38d043..25d6c84e0b 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -965,41 +965,6 @@ fn readILeb128(in_stream: &io.InStream) -> %i64 { } } -pub const global_allocator = &global_allocator_state; - -var global_allocator_state = mem.Allocator { - .allocFn = globalAlloc, - .reallocFn = globalRealloc, - .freeFn = globalFree, -}; - -pub var global_allocator_mem: [100 * 1024]u8 = undefined; -pub var global_allocator_index: usize = 0; - -error OutOfMemory; - -fn globalAlloc(self: &mem.Allocator, n: usize, alignment: u29) -> %[]u8 { - const addr = @ptrToInt(&global_allocator_mem[global_allocator_index]); - const rem = @rem(addr, alignment); - const march_forward_bytes = if (rem == 0) 0 else (alignment - rem); - const adjusted_index = global_allocator_index + march_forward_bytes; - const end_index = adjusted_index + n; - if (end_index > global_allocator_mem.len) { - return error.OutOfMemory; - } - const result = global_allocator_mem[adjusted_index .. end_index]; - global_allocator_index = end_index; - return result; -} - -fn globalRealloc(self: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 { - if (new_size <= old_mem.len) { - return old_mem[0..new_size]; - } else { - const result = %return globalAlloc(self, new_size, alignment); - @memcpy(result.ptr, old_mem.ptr, old_mem.len); - return result; - } -} - -fn globalFree(self: &mem.Allocator, memory: []u8) { } +pub const global_allocator = &global_fixed_allocator.allocator; +var global_fixed_allocator = mem.FixedBufferAllocator.init(global_allocator_mem[0..]); +var global_allocator_mem: [100 * 1024]u8 = undefined; diff --git a/std/mem.zig b/std/mem.zig index eec29e9caf..4f7609dd94 100644 --- a/std/mem.zig +++ b/std/mem.zig @@ -105,6 +105,51 @@ pub const Allocator = struct { } }; +pub const FixedBufferAllocator = struct { + allocator: Allocator, + end_index: usize, + buffer: []u8, + + pub fn init(buffer: []u8) -> FixedBufferAllocator { + return FixedBufferAllocator { + .allocator = Allocator { + .allocFn = alloc, + .reallocFn = realloc, + .freeFn = free, + }, + .buffer = buffer, + .end_index = 0, + }; + } + + fn alloc(allocator: &Allocator, n: usize, alignment: u29) -> %[]u8 { + const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator); + const addr = @ptrToInt(&self.buffer[self.end_index]); + const rem = @rem(addr, alignment); + const march_forward_bytes = if (rem == 0) 0 else (alignment - rem); + const adjusted_index = self.end_index + march_forward_bytes; + const new_end_index = adjusted_index + n; + if (new_end_index > self.buffer.len) { + return error.OutOfMemory; + } + const result = self.buffer[adjusted_index .. new_end_index]; + self.end_index = new_end_index; + return result; + } + + fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 { + if (new_size <= old_mem.len) { + return old_mem[0..new_size]; + } else { + const result = %return alloc(allocator, new_size, alignment); + copy(u8, result, old_mem); + return result; + } + } + + fn free(allocator: &Allocator, bytes: []u8) { } +}; + /// Copy all of source into dest at position 0. /// dest.len must be >= source.len.