authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-12 10:48:02-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-12 10:48:02-05:00
log491d818f17aa94b94998da51ebce6d153491744b
tree0bffe308c399b4ec9a4bae95349fea47f8387f94
parentef6260b3a7ed09e5dc5d8383ad20f229411bd9ff
parentec0846a00fd3d0ae0b7b94961f855b8ab6c938db

Merge remote-tracking branch 'origin/master' into llvm6


14 files changed, 373 insertions(+), 187 deletions(-)

doc/docgen.zig+7-4
......@@ -13,10 +13,13 @@ const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
1313const tmp_dir_name = "docgen_tmp";
1414
1515pub fn main() !void {
16 // TODO use a more general purpose allocator here
17 var inc_allocator = try std.heap.IncrementingAllocator.init(max_doc_file_size);
18 defer inc_allocator.deinit();
19 const allocator = &inc_allocator.allocator;
16 var direct_allocator = std.heap.DirectAllocator.init();
17 defer direct_allocator.deinit();
18
19 var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
20 defer arena.deinit();
21
22 const allocator = &arena.allocator;
2023
2124 var args_it = os.args();
2225
src-self-hosted/main.zig+1-1
......@@ -575,7 +575,7 @@ fn fmtMain(allocator: &mem.Allocator, file_paths: []const []const u8) !void {
575575 var parser = std.zig.Parser.init(&tokenizer, allocator, file_path);
576576 defer parser.deinit();
577577
578 const tree = try parser.parse();
578 var tree = try parser.parse();
579579 defer tree.deinit();
580580
581581 const baf = try io.BufferedAtomicFile.create(allocator, file_path);
src-self-hosted/module.zig+1-1
......@@ -241,7 +241,7 @@ pub const Module = struct {
241241 var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path);
242242 defer parser.deinit();
243243
244 const tree = try parser.parse();
244 var tree = try parser.parse();
245245 defer tree.deinit();
246246
247247 var stderr_file = try std.io.getStdErr();
std/c/index.zig+1
......@@ -45,6 +45,7 @@ pub extern "c" fn nanosleep(rqtp: &const timespec, rmtp: ?&timespec) c_int;
4545pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) c_int;
4646pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) c_int;
4747
48pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?&c_void;
4849pub extern "c" fn malloc(usize) ?&c_void;
4950pub extern "c" fn realloc(&c_void, usize) ?&c_void;
5051pub extern "c" fn free(&c_void) void;
std/debug/index.zig+1-1
......@@ -1078,5 +1078,5 @@ fn readILeb128(in_stream: var) !i64 {
10781078}
10791079
10801080pub const global_allocator = &global_fixed_allocator.allocator;
1081var global_fixed_allocator = mem.FixedBufferAllocator.init(global_allocator_mem[0..]);
1081var global_fixed_allocator = std.heap.FixedBufferAllocator.init(global_allocator_mem[0..]);
10821082var global_allocator_mem: [100 * 1024]u8 = undefined;
std/heap.zig+250-51
......@@ -17,7 +17,8 @@ var c_allocator_state = Allocator {
1717};
1818
1919fn cAlloc(self: &Allocator, n: usize, alignment: u29) ![]u8 {
20 return if (c.malloc(usize(n))) |buf|
20 assert(alignment <= @alignOf(c_longdouble));
21 return if (c.malloc(n)) |buf|
2122 @ptrCast(&u8, buf)[0..n]
2223 else
2324 error.OutOfMemory;
......@@ -39,82 +40,256 @@ fn cFree(self: &Allocator, old_mem: []u8) void {
3940 c.free(old_ptr);
4041}
4142
42pub const IncrementingAllocator = struct {
43/// This allocator makes a syscall directly for every allocation and free.
44pub const DirectAllocator = struct {
4345 allocator: Allocator,
44 bytes: []u8,
45 end_index: usize,
46 heap_handle: if (builtin.os == Os.windows) os.windows.HANDLE else void,
46 heap_handle: ?HeapHandle,
47
48 const HeapHandle = if (builtin.os == Os.windows) os.windows.HANDLE else void;
49
50 //pub const canary_bytes = []u8 {48, 239, 128, 46, 18, 49, 147, 9, 195, 59, 203, 3, 245, 54, 9, 122};
51 //pub const want_safety = switch (builtin.mode) {
52 // builtin.Mode.Debug => true,
53 // builtin.Mode.ReleaseSafe => true,
54 // else => false,
55 //};
56
57 pub fn init() DirectAllocator {
58 return DirectAllocator {
59 .allocator = Allocator {
60 .allocFn = alloc,
61 .reallocFn = realloc,
62 .freeFn = free,
63 },
64 .heap_handle = if (builtin.os == Os.windows) null else {},
65 };
66 }
67
68 pub fn deinit(self: &DirectAllocator) void {
69 switch (builtin.os) {
70 Os.windows => if (self.heap_handle) |heap_handle| {
71 _ = os.windows.HeapDestroy(heap_handle);
72 },
73 else => {},
74 }
75 }
76
77 fn alloc(allocator: &Allocator, n: usize, alignment: u29) ![]u8 {
78 const self = @fieldParentPtr(DirectAllocator, "allocator", allocator);
4779
48 fn init(capacity: usize) !IncrementingAllocator {
4980 switch (builtin.os) {
5081 Os.linux, Os.macosx, Os.ios => {
82 assert(alignment <= os.page_size);
5183 const p = os.posix;
52 const addr = p.mmap(null, capacity, p.PROT_READ|p.PROT_WRITE,
53 p.MAP_PRIVATE|p.MAP_ANONYMOUS|p.MAP_NORESERVE, -1, 0);
84 const addr = p.mmap(null, n, p.PROT_READ|p.PROT_WRITE,
85 p.MAP_PRIVATE|p.MAP_ANONYMOUS, -1, 0);
5486 if (addr == p.MAP_FAILED) {
5587 return error.OutOfMemory;
5688 }
57 return IncrementingAllocator {
58 .allocator = Allocator {
59 .allocFn = alloc,
60 .reallocFn = realloc,
61 .freeFn = free,
62 },
63 .bytes = @intToPtr(&u8, addr)[0..capacity],
64 .end_index = 0,
65 .heap_handle = {},
89 return @intToPtr(&u8, addr)[0..n];
90 },
91 Os.windows => {
92 const amt = n + alignment + @sizeOf(usize);
93 const heap_handle = self.heap_handle ?? blk: {
94 const hh = os.windows.HeapCreate(os.windows.HEAP_NO_SERIALIZE, amt, 0) ?? return error.OutOfMemory;
95 self.heap_handle = hh;
96 break :blk hh;
6697 };
98 const ptr = os.windows.HeapAlloc(heap_handle, 0, amt) ?? return error.OutOfMemory;
99 const root_addr = @ptrToInt(ptr);
100 const rem = @rem(root_addr, alignment);
101 const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
102 const adjusted_addr = root_addr + march_forward_bytes;
103 const record_addr = adjusted_addr + n;
104 *@intToPtr(&align(1) usize, record_addr) = root_addr;
105 return @intToPtr(&u8, adjusted_addr)[0..n];
106 },
107 else => @compileError("Unsupported OS"),
108 }
109 }
110
111 fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
112 const self = @fieldParentPtr(DirectAllocator, "allocator", allocator);
113
114 switch (builtin.os) {
115 Os.linux, Os.macosx, Os.ios => {
116 if (new_size <= old_mem.len) {
117 const base_addr = @ptrToInt(old_mem.ptr);
118 const old_addr_end = base_addr + old_mem.len;
119 const new_addr_end = base_addr + new_size;
120 const rem = @rem(new_addr_end, os.page_size);
121 const new_addr_end_rounded = new_addr_end + if (rem == 0) 0 else (os.page_size - rem);
122 if (old_addr_end > new_addr_end_rounded) {
123 _ = os.posix.munmap(@intToPtr(&u8, new_addr_end_rounded), old_addr_end - new_addr_end_rounded);
124 }
125 return old_mem[0..new_size];
126 }
127
128 const result = try alloc(allocator, new_size, alignment);
129 mem.copy(u8, result, old_mem);
130 return result;
67131 },
68132 Os.windows => {
69 const heap_handle = os.windows.GetProcessHeap() ?? return error.OutOfMemory;
70 const ptr = os.windows.HeapAlloc(heap_handle, 0, capacity) ?? return error.OutOfMemory;
71 return IncrementingAllocator {
72 .allocator = Allocator {
73 .allocFn = alloc,
74 .reallocFn = realloc,
75 .freeFn = free,
76 },
77 .bytes = @ptrCast(&u8, ptr)[0..capacity],
78 .end_index = 0,
79 .heap_handle = heap_handle,
133 const old_adjusted_addr = @ptrToInt(old_mem.ptr);
134 const old_record_addr = old_adjusted_addr + old_mem.len;
135 const root_addr = *@intToPtr(&align(1) usize, old_record_addr);
136 const old_ptr = @intToPtr(os.windows.LPVOID, root_addr);
137 const amt = new_size + alignment + @sizeOf(usize);
138 const new_ptr = os.windows.HeapReAlloc(??self.heap_handle, 0, old_ptr, amt) ?? blk: {
139 if (new_size > old_mem.len) return error.OutOfMemory;
140 const new_record_addr = old_record_addr - new_size + old_mem.len;
141 *@intToPtr(&align(1) usize, new_record_addr) = root_addr;
142 return old_mem[0..new_size];
80143 };
144 const offset = old_adjusted_addr - root_addr;
145 const new_root_addr = @ptrToInt(new_ptr);
146 const new_adjusted_addr = new_root_addr + offset;
147 assert(new_adjusted_addr % alignment == 0);
148 const new_record_addr = new_adjusted_addr + new_size;
149 *@intToPtr(&align(1) usize, new_record_addr) = new_root_addr;
150 return @intToPtr(&u8, new_adjusted_addr)[0..new_size];
81151 },
82152 else => @compileError("Unsupported OS"),
83153 }
84154 }
85155
86 fn deinit(self: &IncrementingAllocator) void {
156 fn free(allocator: &Allocator, bytes: []u8) void {
157 const self = @fieldParentPtr(DirectAllocator, "allocator", allocator);
158
87159 switch (builtin.os) {
88160 Os.linux, Os.macosx, Os.ios => {
89 _ = os.posix.munmap(self.bytes.ptr, self.bytes.len);
161 _ = os.posix.munmap(bytes.ptr, bytes.len);
90162 },
91163 Os.windows => {
92 _ = os.windows.HeapFree(self.heap_handle, 0, @ptrCast(os.windows.LPVOID, self.bytes.ptr));
164 const record_addr = @ptrToInt(bytes.ptr) + bytes.len;
165 const root_addr = *@intToPtr(&align(1) usize, record_addr);
166 const ptr = @intToPtr(os.windows.LPVOID, root_addr);
167 _ = os.windows.HeapFree(??self.heap_handle, 0, ptr);
93168 },
94169 else => @compileError("Unsupported OS"),
95170 }
96171 }
172};
173
174/// This allocator takes an existing allocator, wraps it, and provides an interface
175/// where you can allocate without freeing, and then free it all together.
176pub const ArenaAllocator = struct {
177 pub allocator: Allocator,
178
179 child_allocator: &Allocator,
180 buffer_list: std.LinkedList([]u8),
181 end_index: usize,
182
183 const BufNode = std.LinkedList([]u8).Node;
184
185 pub fn init(child_allocator: &Allocator) ArenaAllocator {
186 return ArenaAllocator {
187 .allocator = Allocator {
188 .allocFn = alloc,
189 .reallocFn = realloc,
190 .freeFn = free,
191 },
192 .child_allocator = child_allocator,
193 .buffer_list = std.LinkedList([]u8).init(),
194 .end_index = 0,
195 };
196 }
197
198 pub fn deinit(self: &ArenaAllocator) void {
199 var it = self.buffer_list.first;
200 while (it) |node| {
201 // this has to occur before the free because the free frees node
202 it = node.next;
203
204 self.child_allocator.free(node.data);
205 }
206 }
97207
98 fn reset(self: &IncrementingAllocator) void {
208 fn createNode(self: &ArenaAllocator, prev_len: usize, minimum_size: usize) !&BufNode {
209 const actual_min_size = minimum_size + @sizeOf(BufNode);
210 var len = prev_len;
211 while (true) {
212 len += len / 2;
213 len += os.page_size - @rem(len, os.page_size);
214 if (len >= actual_min_size) break;
215 }
216 const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);
217 const buf_node_slice = ([]BufNode)(buf[0..@sizeOf(BufNode)]);
218 const buf_node = &buf_node_slice[0];
219 *buf_node = BufNode {
220 .data = buf,
221 .prev = null,
222 .next = null,
223 };
224 self.buffer_list.append(buf_node);
99225 self.end_index = 0;
226 return buf_node;
227 }
228
229 fn alloc(allocator: &Allocator, n: usize, alignment: u29) ![]u8 {
230 const self = @fieldParentPtr(ArenaAllocator, "allocator", allocator);
231
232 var cur_node = if (self.buffer_list.last) |last_node| last_node else try self.createNode(0, n + alignment);
233 while (true) {
234 const cur_buf = cur_node.data[@sizeOf(BufNode)..];
235 const addr = @ptrToInt(cur_buf.ptr) + self.end_index;
236 const rem = @rem(addr, alignment);
237 const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
238 const adjusted_index = self.end_index + march_forward_bytes;
239 const new_end_index = adjusted_index + n;
240 if (new_end_index > cur_buf.len) {
241 cur_node = try self.createNode(cur_buf.len, n + alignment);
242 continue;
243 }
244 const result = cur_buf[adjusted_index .. new_end_index];
245 self.end_index = new_end_index;
246 return result;
247 }
100248 }
101249
102 fn bytesLeft(self: &const IncrementingAllocator) usize {
103 return self.bytes.len - self.end_index;
250 fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
251 if (new_size <= old_mem.len) {
252 return old_mem[0..new_size];
253 } else {
254 const result = try alloc(allocator, new_size, alignment);
255 mem.copy(u8, result, old_mem);
256 return result;
257 }
258 }
259
260 fn free(allocator: &Allocator, bytes: []u8) void { }
261};
262
263pub const FixedBufferAllocator = struct {
264 allocator: Allocator,
265 end_index: usize,
266 buffer: []u8,
267
268 pub fn init(buffer: []u8) FixedBufferAllocator {
269 return FixedBufferAllocator {
270 .allocator = Allocator {
271 .allocFn = alloc,
272 .reallocFn = realloc,
273 .freeFn = free,
274 },
275 .buffer = buffer,
276 .end_index = 0,
277 };
104278 }
105279
106280 fn alloc(allocator: &Allocator, n: usize, alignment: u29) ![]u8 {
107 const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
108 const addr = @ptrToInt(&self.bytes[self.end_index]);
281 const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
282 const addr = @ptrToInt(&self.buffer[self.end_index]);
109283 const rem = @rem(addr, alignment);
110284 const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
111285 const adjusted_index = self.end_index + march_forward_bytes;
112286 const new_end_index = adjusted_index + n;
113 if (new_end_index > self.bytes.len) {
287 if (new_end_index > self.buffer.len) {
114288 return error.OutOfMemory;
115289 }
116 const result = self.bytes[adjusted_index .. new_end_index];
290 const result = self.buffer[adjusted_index .. new_end_index];
117291 self.end_index = new_end_index;
292
118293 return result;
119294 }
120295
......@@ -128,11 +303,11 @@ pub const IncrementingAllocator = struct {
128303 }
129304 }
130305
131 fn free(allocator: &Allocator, bytes: []u8) void {
132 // Do nothing. That's the point of an incrementing allocator.
133 }
306 fn free(allocator: &Allocator, bytes: []u8) void { }
134307};
135308
309
310
136311test "c_allocator" {
137312 if (builtin.link_libc) {
138313 var slice = c_allocator.alloc(u8, 50) catch return;
......@@ -141,23 +316,47 @@ test "c_allocator" {
141316 }
142317}
143318
144test "IncrementingAllocator" {
145 const total_bytes = 100 * 1024 * 1024;
146 var inc_allocator = try IncrementingAllocator.init(total_bytes);
147 defer inc_allocator.deinit();
319test "DirectAllocator" {
320 var direct_allocator = DirectAllocator.init();
321 defer direct_allocator.deinit();
322
323 const allocator = &direct_allocator.allocator;
324 try testAllocator(allocator);
325}
148326
149 const allocator = &inc_allocator.allocator;
150 const slice = try allocator.alloc(&i32, 100);
327test "ArenaAllocator" {
328 var direct_allocator = DirectAllocator.init();
329 defer direct_allocator.deinit();
330
331 var arena_allocator = ArenaAllocator.init(&direct_allocator.allocator);
332 defer arena_allocator.deinit();
333
334 try testAllocator(&arena_allocator.allocator);
335}
336
337var test_fixed_buffer_allocator_memory: [30000 * @sizeOf(usize)]u8 = undefined;
338test "FixedBufferAllocator" {
339 var fixed_buffer_allocator = FixedBufferAllocator.init(test_fixed_buffer_allocator_memory[0..]);
340
341 try testAllocator(&fixed_buffer_allocator.allocator);
342}
343
344fn testAllocator(allocator: &mem.Allocator) !void {
345 var slice = try allocator.alloc(&i32, 100);
151346
152347 for (slice) |*item, i| {
153348 *item = try allocator.create(i32);
154349 **item = i32(i);
155350 }
156351
157 assert(inc_allocator.bytesLeft() == total_bytes - @sizeOf(i32) * 100 - @sizeOf(usize) * 100);
352 for (slice) |item, i| {
353 allocator.destroy(item);
354 }
158355
159 inc_allocator.reset();
356 slice = try allocator.realloc(&i32, slice, 20000);
357 slice = try allocator.realloc(&i32, slice, 50);
358 slice = try allocator.realloc(&i32, slice, 25);
359 slice = try allocator.realloc(&i32, slice, 10);
160360
161 assert(inc_allocator.bytesLeft() == total_bytes);
361 allocator.free(slice);
162362}
163
std/mem.zig+8-49
......@@ -44,6 +44,7 @@ pub const Allocator = struct {
4444 {
4545 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
4646 const byte_slice = try self.allocFn(self, byte_count, alignment);
47 assert(byte_slice.len == byte_count);
4748 // This loop should get optimized out in ReleaseFast mode
4849 for (byte_slice) |*byte| {
4950 *byte = undefined;
......@@ -65,9 +66,12 @@ pub const Allocator = struct {
6566 const old_byte_slice = ([]u8)(old_mem);
6667 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
6768 const byte_slice = try self.reallocFn(self, old_byte_slice, byte_count, alignment);
68 // This loop should get optimized out in ReleaseFast mode
69 for (byte_slice[old_byte_slice.len..]) |*byte| {
70 *byte = undefined;
69 assert(byte_slice.len == byte_count);
70 if (n > old_mem.len) {
71 // This loop should get optimized out in ReleaseFast mode
72 for (byte_slice[old_byte_slice.len..]) |*byte| {
73 *byte = undefined;
74 }
7175 }
7276 return ([]T)(@alignCast(alignment, byte_slice));
7377 }
......@@ -94,6 +98,7 @@ pub const Allocator = struct {
9498 const byte_count = @sizeOf(T) * n;
9599
96100 const byte_slice = self.reallocFn(self, ([]u8)(old_mem), byte_count, alignment) catch unreachable;
101 assert(byte_slice.len == byte_count);
97102 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
98103 }
99104
......@@ -106,52 +111,6 @@ pub const Allocator = struct {
106111 }
107112};
108113
109pub const FixedBufferAllocator = struct {
110 allocator: Allocator,
111 end_index: usize,
112 buffer: []u8,
113
114 pub fn init(buffer: []u8) FixedBufferAllocator {
115 return FixedBufferAllocator {
116 .allocator = Allocator {
117 .allocFn = alloc,
118 .reallocFn = realloc,
119 .freeFn = free,
120 },
121 .buffer = buffer,
122 .end_index = 0,
123 };
124 }
125
126 fn alloc(allocator: &Allocator, n: usize, alignment: u29) ![]u8 {
127 const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
128 const addr = @ptrToInt(&self.buffer[self.end_index]);
129 const rem = @rem(addr, alignment);
130 const march_forward_bytes = if (rem == 0) 0 else (alignment - rem);
131 const adjusted_index = self.end_index + march_forward_bytes;
132 const new_end_index = adjusted_index + n;
133 if (new_end_index > self.buffer.len) {
134 return error.OutOfMemory;
135 }
136 const result = self.buffer[adjusted_index .. new_end_index];
137 self.end_index = new_end_index;
138 return result;
139 }
140
141 fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
142 if (new_size <= old_mem.len) {
143 return old_mem[0..new_size];
144 } else {
145 const result = try alloc(allocator, new_size, alignment);
146 copy(u8, result, old_mem);
147 return result;
148 }
149 }
150
151 fn free(allocator: &Allocator, bytes: []u8) void { }
152};
153
154
155114/// Copy all of source into dest at position 0.
156115/// dest.len must be >= source.len.
157116pub fn copy(comptime T: type, dest: []T, source: []const T) void {
std/os/child_process.zig+2-2
......@@ -363,7 +363,7 @@ pub const ChildProcess = struct {
363363 const dev_null_fd = if (any_ignore) blk: {
364364 const dev_null_path = "/dev/null";
365365 var fixed_buffer_mem: [dev_null_path.len + 1]u8 = undefined;
366 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
366 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
367367 break :blk try os.posixOpen(&fixed_allocator.allocator, "/dev/null", posix.O_RDWR, 0);
368368 } else blk: {
369369 break :blk undefined;
......@@ -472,7 +472,7 @@ pub const ChildProcess = struct {
472472 const nul_handle = if (any_ignore) blk: {
473473 const nul_file_path = "NUL";
474474 var fixed_buffer_mem: [nul_file_path.len + 1]u8 = undefined;
475 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
475 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
476476 break :blk try os.windowsOpen(&fixed_allocator.allocator, "NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ,
477477 windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL);
478478 } else blk: {
std/os/index.zig+2-2
......@@ -1702,12 +1702,12 @@ pub fn openSelfExe() !os.File {
17021702 Os.linux => {
17031703 const proc_file_path = "/proc/self/exe";
17041704 var fixed_buffer_mem: [proc_file_path.len + 1]u8 = undefined;
1705 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1705 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
17061706 return os.File.openRead(&fixed_allocator.allocator, proc_file_path);
17071707 },
17081708 Os.macosx, Os.ios => {
17091709 var fixed_buffer_mem: [darwin.PATH_MAX * 2]u8 = undefined;
1710 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1710 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
17111711 const self_exe_path = try selfExePath(&fixed_allocator.allocator);
17121712 return os.File.openRead(&fixed_allocator.allocator, self_exe_path);
17131713 },
std/os/windows/index.zig+17-5
......@@ -22,7 +22,7 @@ pub extern "kernel32" stdcallcc fn CreatePipe(hReadPipe: &HANDLE, hWritePipe: &H
2222
2323pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lpCommandLine: LPSTR,
2424 lpProcessAttributes: ?&SECURITY_ATTRIBUTES, lpThreadAttributes: ?&SECURITY_ATTRIBUTES, bInheritHandles: BOOL,
25 dwCreationFlags: DWORD, lpEnvironment: ?LPVOID, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,
25 dwCreationFlags: DWORD, lpEnvironment: ?&c_void, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,
2626 lpProcessInformation: &PROCESS_INFORMATION) BOOL;
2727
2828pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(lpSymlinkFileName: LPCSTR, lpTargetFileName: LPCSTR,
......@@ -61,16 +61,24 @@ pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA(hFile: HANDLE, lpsz
6161
6262pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE;
6363
64pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE;
65pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL;
66pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: &c_void, dwBytes: SIZE_T) ?&c_void;
67pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: &const c_void) SIZE_T;
68pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: &const c_void) BOOL;
69pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T;
70pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL;
71
6472pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE;
6573
66pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?LPVOID;
74pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?&c_void;
6775
68pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) BOOL;
76pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: &c_void) BOOL;
6977
7078pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR,
7179 dwFlags: DWORD) BOOL;
7280
73pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: LPVOID,
81pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: &c_void,
7482 in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD,
7583 in_out_lpOverlapped: ?&OVERLAPPED) BOOL;
7684
......@@ -201,7 +209,7 @@ pub const VOLUME_NAME_NT = 0x2;
201209
202210pub const SECURITY_ATTRIBUTES = extern struct {
203211 nLength: DWORD,
204 lpSecurityDescriptor: ?LPVOID,
212 lpSecurityDescriptor: ?&c_void,
205213 bInheritHandle: BOOL,
206214};
207215pub const PSECURITY_ATTRIBUTES = &SECURITY_ATTRIBUTES;
......@@ -296,3 +304,7 @@ pub const MOVEFILE_WRITE_THROUGH = 8;
296304pub const FILE_BEGIN = 0;
297305pub const FILE_CURRENT = 1;
298306pub const FILE_END = 2;
307
308pub const HEAP_CREATE_ENABLE_EXECUTE = 0x00040000;
309pub const HEAP_GENERATE_EXCEPTIONS = 0x00000004;
310pub const HEAP_NO_SERIALIZE = 0x00000001;
std/sort.zig+1-1
......@@ -1094,7 +1094,7 @@ var fixed_buffer_mem: [100 * 1024]u8 = undefined;
10941094
10951095fn fuzzTest(rng: &std.rand.Rand) void {
10961096 const array_size = rng.range(usize, 0, 1000);
1097 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1097 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
10981098 var array = fixed_allocator.allocator.alloc(IdAndValue, array_size) catch unreachable;
10991099 // populate with random data
11001100 for (array) |*item, index| {
std/special/build_runner.zig+10-4
......@@ -12,11 +12,17 @@ const warn = std.debug.warn;
1212pub fn main() !void {
1313 var arg_it = os.args();
1414
15 // TODO use a more general purpose allocator here
16 var inc_allocator = try std.heap.IncrementingAllocator.init(40 * 1024 * 1024);
17 defer inc_allocator.deinit();
15 // Here we use an ArenaAllocator backed by a DirectAllocator because a build is a short-lived,
16 // one shot program. We don't need to waste time freeing memory and finding places to squish
17 // bytes into. So we free everything all at once at the very end.
1818
19 const allocator = &inc_allocator.allocator;
19 var direct_allocator = std.heap.DirectAllocator.init();
20 defer direct_allocator.deinit();
21
22 var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
23 defer arena.deinit();
24
25 const allocator = &arena.allocator;
2026
2127
2228 // skip my own exe name
std/zig/parser.zig+66-63
......@@ -13,7 +13,7 @@ const io = std.io;
1313const warn = std.debug.warn;
1414
1515pub const Parser = struct {
16 allocator: &mem.Allocator,
16 util_allocator: &mem.Allocator,
1717 tokenizer: &Tokenizer,
1818 put_back_tokens: [2]Token,
1919 put_back_count: usize,
......@@ -21,9 +21,10 @@ pub const Parser = struct {
2121
2222 pub const Tree = struct {
2323 root_node: &ast.NodeRoot,
24 arena_allocator: std.heap.ArenaAllocator,
2425
25 pub fn deinit(self: &const Tree) void {
26 // TODO free the whole arena
26 pub fn deinit(self: &Tree) void {
27 self.arena_allocator.deinit();
2728 }
2829 };
2930
......@@ -33,12 +34,10 @@ pub const Parser = struct {
3334 const utility_bytes_align = @alignOf( union { a: RenderAstFrame, b: State, c: RenderState } );
3435 utility_bytes: []align(utility_bytes_align) u8,
3536
36 /// `allocator` should be an arena allocator. Parser never calls free on anything. After you're
37 /// done with a Parser, free the arena. After the arena is freed, no member functions of Parser
38 /// may be called.
37 /// allocator must outlive the returned Parser and all the parse trees you create with it.
3938 pub fn init(tokenizer: &Tokenizer, allocator: &mem.Allocator, source_file_name: []const u8) Parser {
4039 return Parser {
41 .allocator = allocator,
40 .util_allocator = allocator,
4241 .tokenizer = tokenizer,
4342 .put_back_tokens = undefined,
4443 .put_back_count = 0,
......@@ -48,7 +47,7 @@ pub const Parser = struct {
4847 }
4948
5049 pub fn deinit(self: &Parser) void {
51 self.allocator.free(self.utility_bytes);
50 self.util_allocator.free(self.utility_bytes);
5251 }
5352
5453 const TopLevelDeclCtx = struct {
......@@ -101,8 +100,11 @@ pub const Parser = struct {
101100 var stack = self.initUtilityArrayList(State);
102101 defer self.deinitUtilityArrayList(stack);
103102
104 const root_node = try self.createRoot();
105 // TODO errdefer arena free root node
103 var arena_allocator = std.heap.ArenaAllocator.init(self.util_allocator);
104 errdefer arena_allocator.deinit();
105
106 const arena = &arena_allocator.allocator;
107 const root_node = try self.createRoot(arena);
106108
107109 try stack.append(State.TopLevel);
108110
......@@ -130,7 +132,7 @@ pub const Parser = struct {
130132 stack.append(State { .TopLevelExtern = token }) catch unreachable;
131133 continue;
132134 },
133 Token.Id.Eof => return Tree {.root_node = root_node},
135 Token.Id.Eof => return Tree {.root_node = root_node, .arena_allocator = arena_allocator},
134136 else => {
135137 self.putBackToken(token);
136138 stack.append(State { .TopLevelExtern = null }) catch unreachable;
......@@ -164,7 +166,7 @@ pub const Parser = struct {
164166 Token.Id.Keyword_var, Token.Id.Keyword_const => {
165167 stack.append(State.TopLevel) catch unreachable;
166168 // TODO shouldn't need these casts
167 const var_decl_node = try self.createAttachVarDecl(&root_node.decls, ctx.visib_token,
169 const var_decl_node = try self.createAttachVarDecl(arena, &root_node.decls, ctx.visib_token,
168170 token, (?Token)(null), ctx.extern_token);
169171 try stack.append(State { .VarDecl = var_decl_node });
170172 continue;
......@@ -172,7 +174,7 @@ pub const Parser = struct {
172174 Token.Id.Keyword_fn => {
173175 stack.append(State.TopLevel) catch unreachable;
174176 // TODO shouldn't need these casts
175 const fn_proto = try self.createAttachFnProto(&root_node.decls, token,
177 const fn_proto = try self.createAttachFnProto(arena, &root_node.decls, token,
176178 ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null));
177179 try stack.append(State { .FnDef = fn_proto });
178180 try stack.append(State { .FnProto = fn_proto });
......@@ -185,7 +187,7 @@ pub const Parser = struct {
185187 stack.append(State.TopLevel) catch unreachable;
186188 const fn_token = try self.eatToken(Token.Id.Keyword_fn);
187189 // TODO shouldn't need this cast
188 const fn_proto = try self.createAttachFnProto(&root_node.decls, fn_token,
190 const fn_proto = try self.createAttachFnProto(arena, &root_node.decls, fn_token,
189191 ctx.extern_token, (?Token)(token), (?Token)(null), (?Token)(null));
190192 try stack.append(State { .FnDef = fn_proto });
191193 try stack.append(State { .FnProto = fn_proto });
......@@ -253,13 +255,13 @@ pub const Parser = struct {
253255 const token = self.getNextToken();
254256 switch (token.id) {
255257 Token.Id.Keyword_return => {
256 try stack.append(State { .PrefixOp = try self.createPrefixOp(token,
258 try stack.append(State { .PrefixOp = try self.createPrefixOp(arena, token,
257259 ast.NodePrefixOp.PrefixOp.Return) });
258260 try stack.append(State.ExpectOperand);
259261 continue;
260262 },
261263 Token.Id.Ampersand => {
262 const prefix_op = try self.createPrefixOp(token, ast.NodePrefixOp.PrefixOp{
264 const prefix_op = try self.createPrefixOp(arena, token, ast.NodePrefixOp.PrefixOp{
263265 .AddrOf = ast.NodePrefixOp.AddrOfInfo {
264266 .align_expr = null,
265267 .bit_offset_start_token = null,
......@@ -275,21 +277,21 @@ pub const Parser = struct {
275277 },
276278 Token.Id.Identifier => {
277279 try stack.append(State {
278 .Operand = &(try self.createIdentifier(token)).base
280 .Operand = &(try self.createIdentifier(arena, token)).base
279281 });
280282 try stack.append(State.AfterOperand);
281283 continue;
282284 },
283285 Token.Id.IntegerLiteral => {
284286 try stack.append(State {
285 .Operand = &(try self.createIntegerLiteral(token)).base
287 .Operand = &(try self.createIntegerLiteral(arena, token)).base
286288 });
287289 try stack.append(State.AfterOperand);
288290 continue;
289291 },
290292 Token.Id.FloatLiteral => {
291293 try stack.append(State {
292 .Operand = &(try self.createFloatLiteral(token)).base
294 .Operand = &(try self.createFloatLiteral(arena, token)).base
293295 });
294296 try stack.append(State.AfterOperand);
295297 continue;
......@@ -306,14 +308,14 @@ pub const Parser = struct {
306308 switch (token.id) {
307309 Token.Id.EqualEqual => {
308310 try stack.append(State {
309 .InfixOp = try self.createInfixOp(token, ast.NodeInfixOp.InfixOp.EqualEqual)
311 .InfixOp = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.EqualEqual)
310312 });
311313 try stack.append(State.ExpectOperand);
312314 continue;
313315 },
314316 Token.Id.BangEqual => {
315317 try stack.append(State {
316 .InfixOp = try self.createInfixOp(token, ast.NodeInfixOp.InfixOp.BangEqual)
318 .InfixOp = try self.createInfixOp(arena, token, ast.NodeInfixOp.InfixOp.BangEqual)
317319 });
318320 try stack.append(State.ExpectOperand);
319321 continue;
......@@ -421,7 +423,7 @@ pub const Parser = struct {
421423 if (token.id == Token.Id.RParen) {
422424 continue;
423425 }
424 const param_decl = try self.createAttachParamDecl(&fn_proto.params);
426 const param_decl = try self.createAttachParamDecl(arena, &fn_proto.params);
425427 if (token.id == Token.Id.Keyword_comptime) {
426428 param_decl.comptime_token = token;
427429 token = self.getNextToken();
......@@ -470,7 +472,7 @@ pub const Parser = struct {
470472 const token = self.getNextToken();
471473 switch(token.id) {
472474 Token.Id.LBrace => {
473 const block = try self.createBlock(token);
475 const block = try self.createBlock(arena, token);
474476 fn_proto.body_node = &block.base;
475477 stack.append(State { .Block = block }) catch unreachable;
476478 continue;
......@@ -504,7 +506,7 @@ pub const Parser = struct {
504506 const mut_token = self.getNextToken();
505507 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
506508 // TODO shouldn't need these casts
507 const var_decl = try self.createAttachVarDecl(&block.statements, (?Token)(null),
509 const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null),
508510 mut_token, (?Token)(comptime_token), (?Token)(null));
509511 try stack.append(State { .VarDecl = var_decl });
510512 continue;
......@@ -518,7 +520,7 @@ pub const Parser = struct {
518520 const mut_token = self.getNextToken();
519521 if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
520522 // TODO shouldn't need these casts
521 const var_decl = try self.createAttachVarDecl(&block.statements, (?Token)(null),
523 const var_decl = try self.createAttachVarDecl(arena, &block.statements, (?Token)(null),
522524 mut_token, (?Token)(null), (?Token)(null));
523525 try stack.append(State { .VarDecl = var_decl });
524526 continue;
......@@ -541,20 +543,20 @@ pub const Parser = struct {
541543 }
542544 }
543545
544 fn createRoot(self: &Parser) !&ast.NodeRoot {
545 const node = try self.allocator.create(ast.NodeRoot);
546 fn createRoot(self: &Parser, arena: &mem.Allocator) !&ast.NodeRoot {
547 const node = try arena.create(ast.NodeRoot);
546548
547549 *node = ast.NodeRoot {
548550 .base = ast.Node {.id = ast.Node.Id.Root},
549 .decls = ArrayList(&ast.Node).init(self.allocator),
551 .decls = ArrayList(&ast.Node).init(arena),
550552 };
551553 return node;
552554 }
553555
554 fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,
555 extern_token: &const ?Token) !&ast.NodeVarDecl
556 fn createVarDecl(self: &Parser, arena: &mem.Allocator, visib_token: &const ?Token, mut_token: &const Token,
557 comptime_token: &const ?Token, extern_token: &const ?Token) !&ast.NodeVarDecl
556558 {
557 const node = try self.allocator.create(ast.NodeVarDecl);
559 const node = try arena.create(ast.NodeVarDecl);
558560
559561 *node = ast.NodeVarDecl {
560562 .base = ast.Node {.id = ast.Node.Id.VarDecl},
......@@ -573,17 +575,17 @@ pub const Parser = struct {
573575 return node;
574576 }
575577
576 fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token,
578 fn createFnProto(self: &Parser, arena: &mem.Allocator, fn_token: &const Token, extern_token: &const ?Token,
577579 cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) !&ast.NodeFnProto
578580 {
579 const node = try self.allocator.create(ast.NodeFnProto);
581 const node = try arena.create(ast.NodeFnProto);
580582
581583 *node = ast.NodeFnProto {
582584 .base = ast.Node {.id = ast.Node.Id.FnProto},
583585 .visib_token = *visib_token,
584586 .name_token = null,
585587 .fn_token = *fn_token,
586 .params = ArrayList(&ast.Node).init(self.allocator),
588 .params = ArrayList(&ast.Node).init(arena),
587589 .return_type = undefined,
588590 .var_args_token = null,
589591 .extern_token = *extern_token,
......@@ -596,8 +598,8 @@ pub const Parser = struct {
596598 return node;
597599 }
598600
599 fn createParamDecl(self: &Parser) !&ast.NodeParamDecl {
600 const node = try self.allocator.create(ast.NodeParamDecl);
601 fn createParamDecl(self: &Parser, arena: &mem.Allocator) !&ast.NodeParamDecl {
602 const node = try arena.create(ast.NodeParamDecl);
601603
602604 *node = ast.NodeParamDecl {
603605 .base = ast.Node {.id = ast.Node.Id.ParamDecl},
......@@ -610,20 +612,20 @@ pub const Parser = struct {
610612 return node;
611613 }
612614
613 fn createBlock(self: &Parser, begin_token: &const Token) !&ast.NodeBlock {
614 const node = try self.allocator.create(ast.NodeBlock);
615 fn createBlock(self: &Parser, arena: &mem.Allocator, begin_token: &const Token) !&ast.NodeBlock {
616 const node = try arena.create(ast.NodeBlock);
615617
616618 *node = ast.NodeBlock {
617619 .base = ast.Node {.id = ast.Node.Id.Block},
618620 .begin_token = *begin_token,
619621 .end_token = undefined,
620 .statements = ArrayList(&ast.Node).init(self.allocator),
622 .statements = ArrayList(&ast.Node).init(arena),
621623 };
622624 return node;
623625 }
624626
625 fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) !&ast.NodeInfixOp {
626 const node = try self.allocator.create(ast.NodeInfixOp);
627 fn createInfixOp(self: &Parser, arena: &mem.Allocator, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) !&ast.NodeInfixOp {
628 const node = try arena.create(ast.NodeInfixOp);
627629
628630 *node = ast.NodeInfixOp {
629631 .base = ast.Node {.id = ast.Node.Id.InfixOp},
......@@ -635,8 +637,8 @@ pub const Parser = struct {
635637 return node;
636638 }
637639
638 fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) !&ast.NodePrefixOp {
639 const node = try self.allocator.create(ast.NodePrefixOp);
640 fn createPrefixOp(self: &Parser, arena: &mem.Allocator, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) !&ast.NodePrefixOp {
641 const node = try arena.create(ast.NodePrefixOp);
640642
641643 *node = ast.NodePrefixOp {
642644 .base = ast.Node {.id = ast.Node.Id.PrefixOp},
......@@ -647,8 +649,8 @@ pub const Parser = struct {
647649 return node;
648650 }
649651
650 fn createIdentifier(self: &Parser, name_token: &const Token) !&ast.NodeIdentifier {
651 const node = try self.allocator.create(ast.NodeIdentifier);
652 fn createIdentifier(self: &Parser, arena: &mem.Allocator, name_token: &const Token) !&ast.NodeIdentifier {
653 const node = try arena.create(ast.NodeIdentifier);
652654
653655 *node = ast.NodeIdentifier {
654656 .base = ast.Node {.id = ast.Node.Id.Identifier},
......@@ -657,8 +659,8 @@ pub const Parser = struct {
657659 return node;
658660 }
659661
660 fn createIntegerLiteral(self: &Parser, token: &const Token) !&ast.NodeIntegerLiteral {
661 const node = try self.allocator.create(ast.NodeIntegerLiteral);
662 fn createIntegerLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !&ast.NodeIntegerLiteral {
663 const node = try arena.create(ast.NodeIntegerLiteral);
662664
663665 *node = ast.NodeIntegerLiteral {
664666 .base = ast.Node {.id = ast.Node.Id.IntegerLiteral},
......@@ -667,8 +669,8 @@ pub const Parser = struct {
667669 return node;
668670 }
669671
670 fn createFloatLiteral(self: &Parser, token: &const Token) !&ast.NodeFloatLiteral {
671 const node = try self.allocator.create(ast.NodeFloatLiteral);
672 fn createFloatLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !&ast.NodeFloatLiteral {
673 const node = try arena.create(ast.NodeFloatLiteral);
672674
673675 *node = ast.NodeFloatLiteral {
674676 .base = ast.Node {.id = ast.Node.Id.FloatLiteral},
......@@ -677,31 +679,32 @@ pub const Parser = struct {
677679 return node;
678680 }
679681
680 fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) !&ast.NodeIdentifier {
681 const node = try self.createIdentifier(name_token);
682 fn createAttachIdentifier(self: &Parser, arena: &mem.Allocator, dest_ptr: &const DestPtr, name_token: &const Token) !&ast.NodeIdentifier {
683 const node = try self.createIdentifier(arena, name_token);
682684 try dest_ptr.store(&node.base);
683685 return node;
684686 }
685687
686 fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) !&ast.NodeParamDecl {
687 const node = try self.createParamDecl();
688 fn createAttachParamDecl(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node)) !&ast.NodeParamDecl {
689 const node = try self.createParamDecl(arena);
688690 try list.append(&node.base);
689691 return node;
690692 }
691693
692 fn createAttachFnProto(self: &Parser, list: &ArrayList(&ast.Node), fn_token: &const Token,
694 fn createAttachFnProto(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node), fn_token: &const Token,
693695 extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token,
694696 inline_token: &const ?Token) !&ast.NodeFnProto
695697 {
696 const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token);
698 const node = try self.createFnProto(arena, fn_token, extern_token, cc_token, visib_token, inline_token);
697699 try list.append(&node.base);
698700 return node;
699701 }
700702
701 fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token,
702 mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) !&ast.NodeVarDecl
703 fn createAttachVarDecl(self: &Parser, arena: &mem.Allocator, list: &ArrayList(&ast.Node),
704 visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,
705 extern_token: &const ?Token) !&ast.NodeVarDecl
703706 {
704 const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token);
707 const node = try self.createVarDecl(arena, visib_token, mut_token, comptime_token, extern_token);
705708 try list.append(&node.base);
706709 return node;
707710 }
......@@ -1018,10 +1021,10 @@ pub const Parser = struct {
10181021
10191022 fn initUtilityArrayList(self: &Parser, comptime T: type) ArrayList(T) {
10201023 const new_byte_count = self.utility_bytes.len - self.utility_bytes.len % @sizeOf(T);
1021 self.utility_bytes = self.allocator.alignedShrink(u8, utility_bytes_align, self.utility_bytes, new_byte_count);
1024 self.utility_bytes = self.util_allocator.alignedShrink(u8, utility_bytes_align, self.utility_bytes, new_byte_count);
10221025 const typed_slice = ([]T)(self.utility_bytes);
10231026 return ArrayList(T) {
1024 .allocator = self.allocator,
1027 .allocator = self.util_allocator,
10251028 .items = typed_slice,
10261029 .len = 0,
10271030 };
......@@ -1043,7 +1046,7 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 {
10431046 var parser = Parser.init(&tokenizer, allocator, "(memory buffer)");
10441047 defer parser.deinit();
10451048
1046 const tree = try parser.parse();
1049 var tree = try parser.parse();
10471050 defer tree.deinit();
10481051
10491052 var buffer = try std.Buffer.initSize(allocator, 0);
......@@ -1057,7 +1060,7 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 {
10571060fn testCanonical(source: []const u8) !void {
10581061 const needed_alloc_count = x: {
10591062 // Try it once with unlimited memory, make sure it works
1060 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1063 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
10611064 var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize));
10621065 const result_source = try testParse(source, &failing_allocator.allocator);
10631066 if (!mem.eql(u8, result_source, source)) {
......@@ -1074,7 +1077,7 @@ fn testCanonical(source: []const u8) !void {
10741077
10751078 var fail_index: usize = 0;
10761079 while (fail_index < needed_alloc_count) : (fail_index += 1) {
1077 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1080 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
10781081 var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);
10791082 if (testParse(source, &failing_allocator.allocator)) |_| {
10801083 return error.NondeterministicMemoryUsage;
test/standalone/brace_expansion/main.zig+6-3
......@@ -182,10 +182,13 @@ pub fn main() !void {
182182 var stdin_file = try io.getStdIn();
183183 var stdout_file = try io.getStdOut();
184184
185 var inc_allocator = try std.heap.IncrementingAllocator.init(2 * 1024 * 1024);
186 defer inc_allocator.deinit();
185 var direct_allocator = std.heap.DirectAllocator.init();
186 defer direct_allocator.deinit();
187187
188 global_allocator = &inc_allocator.allocator;
188 var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator);
189 defer arena.deinit();
190
191 global_allocator = &arena.allocator;
189192
190193 var stdin_buf = try Buffer.initSize(global_allocator, 0);
191194 defer stdin_buf.deinit();