authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-21 22:52:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-21 22:52:45-04:00
log19de25993654f3e089eaf46391612e8a7e406d7e
treec59768f81a84b306ee043457a849da78ef08f4c5
parent9377af934f5be92821f36b5d2255f086e5a84cda

stage2 parser: arrays and structs directly in memory after the node

Slightly reduced memory usage. Roughly the same API and perf.

3 files changed, 134 insertions(+), 26 deletions(-)

lib/std/zig/ast.zig+116-12
......@@ -2067,11 +2067,23 @@ pub const Node = struct {
20672067 }
20682068 };
20692069
2070 /// Elements occur directly in memory after ArrayInitializer.
20702071 pub const ArrayInitializer = struct {
20712072 base: Node = Node{ .id = .ArrayInitializer },
20722073 rtoken: TokenIndex,
2074 list_len: NodeIndex,
20732075 lhs: *Node,
2074 list: []*Node,
2076
2077 /// After this the caller must initialize the fields_and_decls list.
2078 pub fn alloc(allocator: *mem.Allocator, list_len: NodeIndex) !*ArrayInitializer {
2079 const bytes = try allocator.alignedAlloc(u8, @alignOf(ArrayInitializer), sizeInBytes(list_len));
2080 return @ptrCast(*ArrayInitializer, bytes.ptr);
2081 }
2082
2083 pub fn free(self: *ArrayInitializer, allocator: *mem.Allocator) void {
2084 const bytes = @ptrCast([*]u8, self)[0..sizeInBytes(self.list_len)];
2085 allocator.free(bytes);
2086 }
20752087
20762088 pub fn iterate(self: *const ArrayInitializer) Node.Iterator {
20772089 return .{ .parent_node = &self.base, .index = 0, .node = null };
......@@ -2084,8 +2096,8 @@ pub const Node = struct {
20842096 if (i < 1) return self.lhs;
20852097 i -= 1;
20862098
2087 if (i < self.list.len) return self.list[i];
2088 i -= self.list.len;
2099 if (i < self.list_len) return self.listConst()[i];
2100 i -= self.list_len;
20892101
20902102 return null;
20912103 }
......@@ -2097,13 +2109,39 @@ pub const Node = struct {
20972109 pub fn lastToken(self: *const ArrayInitializer) TokenIndex {
20982110 return self.rtoken;
20992111 }
2112
2113 pub fn list(self: *ArrayInitializer) []*Node {
2114 const decls_start = @ptrCast([*]u8, self) + @sizeOf(ArrayInitializer);
2115 return @ptrCast([*]*Node, decls_start)[0..self.list_len];
2116 }
2117
2118 pub fn listConst(self: *const ArrayInitializer) []const *Node {
2119 const decls_start = @ptrCast([*]const u8, self) + @sizeOf(ArrayInitializer);
2120 return @ptrCast([*]const *Node, decls_start)[0..self.list_len];
2121 }
2122
2123 fn sizeInBytes(list_len: NodeIndex) usize {
2124 return @sizeOf(ArrayInitializer) + @sizeOf(*Node) * @as(usize, list_len);
2125 }
21002126 };
21012127
2128 /// Elements occur directly in memory after ArrayInitializerDot.
21022129 pub const ArrayInitializerDot = struct {
21032130 base: Node = Node{ .id = .ArrayInitializerDot },
21042131 dot: TokenIndex,
21052132 rtoken: TokenIndex,
2106 list: []*Node,
2133 list_len: NodeIndex,
2134
2135 /// After this the caller must initialize the fields_and_decls list.
2136 pub fn alloc(allocator: *mem.Allocator, list_len: NodeIndex) !*ArrayInitializerDot {
2137 const bytes = try allocator.alignedAlloc(u8, @alignOf(ArrayInitializerDot), sizeInBytes(list_len));
2138 return @ptrCast(*ArrayInitializerDot, bytes.ptr);
2139 }
2140
2141 pub fn free(self: *ArrayInitializerDot, allocator: *mem.Allocator) void {
2142 const bytes = @ptrCast([*]u8, self)[0..sizeInBytes(self.list_len)];
2143 allocator.free(bytes);
2144 }
21072145
21082146 pub fn iterate(self: *const ArrayInitializerDot) Node.Iterator {
21092147 return .{ .parent_node = &self.base, .index = 0, .node = null };
......@@ -2113,8 +2151,8 @@ pub const Node = struct {
21132151 var i = it.index;
21142152 it.index += 1;
21152153
2116 if (i < self.list.len) return self.list[i];
2117 i -= self.list.len;
2154 if (i < self.list_len) return self.listConst()[i];
2155 i -= self.list_len;
21182156
21192157 return null;
21202158 }
......@@ -2126,13 +2164,39 @@ pub const Node = struct {
21262164 pub fn lastToken(self: *const ArrayInitializerDot) TokenIndex {
21272165 return self.rtoken;
21282166 }
2167
2168 pub fn list(self: *ArrayInitializerDot) []*Node {
2169 const decls_start = @ptrCast([*]u8, self) + @sizeOf(ArrayInitializerDot);
2170 return @ptrCast([*]*Node, decls_start)[0..self.list_len];
2171 }
2172
2173 pub fn listConst(self: *const ArrayInitializerDot) []const *Node {
2174 const decls_start = @ptrCast([*]const u8, self) + @sizeOf(ArrayInitializerDot);
2175 return @ptrCast([*]const *Node, decls_start)[0..self.list_len];
2176 }
2177
2178 fn sizeInBytes(list_len: NodeIndex) usize {
2179 return @sizeOf(ArrayInitializerDot) + @sizeOf(*Node) * @as(usize, list_len);
2180 }
21292181 };
21302182
2183 /// Elements occur directly in memory after StructInitializer.
21312184 pub const StructInitializer = struct {
21322185 base: Node = Node{ .id = .StructInitializer },
21332186 rtoken: TokenIndex,
2187 list_len: NodeIndex,
21342188 lhs: *Node,
2135 list: []*Node,
2189
2190 /// After this the caller must initialize the fields_and_decls list.
2191 pub fn alloc(allocator: *mem.Allocator, list_len: NodeIndex) !*StructInitializer {
2192 const bytes = try allocator.alignedAlloc(u8, @alignOf(StructInitializer), sizeInBytes(list_len));
2193 return @ptrCast(*StructInitializer, bytes.ptr);
2194 }
2195
2196 pub fn free(self: *StructInitializer, allocator: *mem.Allocator) void {
2197 const bytes = @ptrCast([*]u8, self)[0..sizeInBytes(self.list_len)];
2198 allocator.free(bytes);
2199 }
21362200
21372201 pub fn iterate(self: *const StructInitializer) Node.Iterator {
21382202 return .{ .parent_node = &self.base, .index = 0, .node = null };
......@@ -2145,8 +2209,8 @@ pub const Node = struct {
21452209 if (i < 1) return self.lhs;
21462210 i -= 1;
21472211
2148 if (i < self.list.len) return self.list[i];
2149 i -= self.list.len;
2212 if (i < self.list_len) return self.listConst()[i];
2213 i -= self.list_len;
21502214
21512215 return null;
21522216 }
......@@ -2158,13 +2222,39 @@ pub const Node = struct {
21582222 pub fn lastToken(self: *const StructInitializer) TokenIndex {
21592223 return self.rtoken;
21602224 }
2225
2226 pub fn list(self: *StructInitializer) []*Node {
2227 const decls_start = @ptrCast([*]u8, self) + @sizeOf(StructInitializer);
2228 return @ptrCast([*]*Node, decls_start)[0..self.list_len];
2229 }
2230
2231 pub fn listConst(self: *const StructInitializer) []const *Node {
2232 const decls_start = @ptrCast([*]const u8, self) + @sizeOf(StructInitializer);
2233 return @ptrCast([*]const *Node, decls_start)[0..self.list_len];
2234 }
2235
2236 fn sizeInBytes(list_len: NodeIndex) usize {
2237 return @sizeOf(StructInitializer) + @sizeOf(*Node) * @as(usize, list_len);
2238 }
21612239 };
21622240
2241 /// Elements occur directly in memory after StructInitializerDot.
21632242 pub const StructInitializerDot = struct {
21642243 base: Node = Node{ .id = .StructInitializerDot },
21652244 dot: TokenIndex,
21662245 rtoken: TokenIndex,
2167 list: []*Node,
2246 list_len: NodeIndex,
2247
2248 /// After this the caller must initialize the fields_and_decls list.
2249 pub fn alloc(allocator: *mem.Allocator, list_len: NodeIndex) !*StructInitializerDot {
2250 const bytes = try allocator.alignedAlloc(u8, @alignOf(StructInitializerDot), sizeInBytes(list_len));
2251 return @ptrCast(*StructInitializerDot, bytes.ptr);
2252 }
2253
2254 pub fn free(self: *StructInitializerDot, allocator: *mem.Allocator) void {
2255 const bytes = @ptrCast([*]u8, self)[0..sizeInBytes(self.list_len)];
2256 allocator.free(bytes);
2257 }
21682258
21692259 pub fn iterate(self: *const StructInitializerDot) Node.Iterator {
21702260 return .{ .parent_node = &self.base, .index = 0, .node = null };
......@@ -2174,8 +2264,8 @@ pub const Node = struct {
21742264 var i = it.index;
21752265 it.index += 1;
21762266
2177 if (i < self.list.len) return self.list[i];
2178 i -= self.list.len;
2267 if (i < self.list_len) return self.listConst()[i];
2268 i -= self.list_len;
21792269
21802270 return null;
21812271 }
......@@ -2187,6 +2277,20 @@ pub const Node = struct {
21872277 pub fn lastToken(self: *const StructInitializerDot) TokenIndex {
21882278 return self.rtoken;
21892279 }
2280
2281 pub fn list(self: *StructInitializerDot) []*Node {
2282 const decls_start = @ptrCast([*]u8, self) + @sizeOf(StructInitializerDot);
2283 return @ptrCast([*]*Node, decls_start)[0..self.list_len];
2284 }
2285
2286 pub fn listConst(self: *const StructInitializerDot) []const *Node {
2287 const decls_start = @ptrCast([*]const u8, self) + @sizeOf(StructInitializerDot);
2288 return @ptrCast([*]const *Node, decls_start)[0..self.list_len];
2289 }
2290
2291 fn sizeInBytes(list_len: NodeIndex) usize {
2292 return @sizeOf(StructInitializerDot) + @sizeOf(*Node) * @as(usize, list_len);
2293 }
21902294 };
21912295
21922296 /// Parameter nodes directly follow Call in memory.
lib/std/zig/parse.zig+14-10
......@@ -1318,12 +1318,13 @@ const Parser = struct {
13181318 const next = (try p.parseFieldInit()) orelse break;
13191319 try init_list.append(next);
13201320 }
1321 const node = try p.arena.allocator.create(Node.StructInitializer);
1321 const node = try Node.StructInitializer.alloc(&p.arena.allocator, init_list.items.len);
13221322 node.* = .{
13231323 .lhs = lhs,
13241324 .rtoken = try p.expectToken(.RBrace),
1325 .list = try p.arena.allocator.dupe(*Node, init_list.items),
1325 .list_len = init_list.items.len,
13261326 };
1327 std.mem.copy(*Node, node.list(), init_list.items);
13271328 return &node.base;
13281329 }
13291330
......@@ -1333,12 +1334,13 @@ const Parser = struct {
13331334 const next = (try p.parseExpr()) orelse break;
13341335 try init_list.append(next);
13351336 }
1336 const node = try p.arena.allocator.create(Node.ArrayInitializer);
1337 const node = try Node.ArrayInitializer.alloc(&p.arena.allocator, init_list.items.len);
13371338 node.* = .{
13381339 .lhs = lhs,
13391340 .rtoken = try p.expectToken(.RBrace),
1340 .list = try p.arena.allocator.dupe(*Node, init_list.items),
1341 .list_len = init_list.items.len,
13411342 };
1343 std.mem.copy(*Node, node.list(), init_list.items);
13421344 return &node.base;
13431345 }
13441346
......@@ -1346,7 +1348,7 @@ const Parser = struct {
13461348 node.* = .{
13471349 .lhs = lhs,
13481350 .rtoken = try p.expectToken(.RBrace),
1349 .list = &[0]*Node{},
1351 .list_len = 0,
13501352 };
13511353 return &node.base;
13521354 }
......@@ -1366,12 +1368,13 @@ const Parser = struct {
13661368 const next = (try p.parseFieldInit()) orelse break;
13671369 try init_list.append(next);
13681370 }
1369 const node = try p.arena.allocator.create(Node.StructInitializerDot);
1371 const node = try Node.StructInitializerDot.alloc(&p.arena.allocator, init_list.items.len);
13701372 node.* = .{
13711373 .dot = dot,
13721374 .rtoken = try p.expectToken(.RBrace),
1373 .list = try p.arena.allocator.dupe(*Node, init_list.items),
1375 .list_len = init_list.items.len,
13741376 };
1377 std.mem.copy(*Node, node.list(), init_list.items);
13751378 return &node.base;
13761379 }
13771380
......@@ -1381,12 +1384,13 @@ const Parser = struct {
13811384 const next = (try p.parseExpr()) orelse break;
13821385 try init_list.append(next);
13831386 }
1384 const node = try p.arena.allocator.create(Node.ArrayInitializerDot);
1387 const node = try Node.ArrayInitializerDot.alloc(&p.arena.allocator, init_list.items.len);
13851388 node.* = .{
13861389 .dot = dot,
13871390 .rtoken = try p.expectToken(.RBrace),
1388 .list = try p.arena.allocator.dupe(*Node, init_list.items),
1391 .list_len = init_list.items.len,
13891392 };
1393 std.mem.copy(*Node, node.list(), init_list.items);
13901394 return &node.base;
13911395 }
13921396
......@@ -1394,7 +1398,7 @@ const Parser = struct {
13941398 node.* = .{
13951399 .dot = dot,
13961400 .rtoken = try p.expectToken(.RBrace),
1397 .list = &[0]*Node{},
1401 .list_len = 0,
13981402 };
13991403 return &node.base;
14001404 }
lib/std/zig/render.zig+4-4
......@@ -620,13 +620,13 @@ fn renderExpression(
620620 .ArrayInitializerDot => blk: {
621621 const casted = @fieldParentPtr(ast.Node.ArrayInitializerDot, "base", base);
622622 rtoken = casted.rtoken;
623 exprs = casted.list;
623 exprs = casted.list();
624624 break :blk .{ .dot = casted.dot };
625625 },
626626 .ArrayInitializer => blk: {
627627 const casted = @fieldParentPtr(ast.Node.ArrayInitializer, "base", base);
628628 rtoken = casted.rtoken;
629 exprs = casted.list;
629 exprs = casted.list();
630630 break :blk .{ .node = casted.lhs };
631631 },
632632 else => unreachable,
......@@ -784,13 +784,13 @@ fn renderExpression(
784784 .StructInitializerDot => blk: {
785785 const casted = @fieldParentPtr(ast.Node.StructInitializerDot, "base", base);
786786 rtoken = casted.rtoken;
787 field_inits = casted.list;
787 field_inits = casted.list();
788788 break :blk .{ .dot = casted.dot };
789789 },
790790 .StructInitializer => blk: {
791791 const casted = @fieldParentPtr(ast.Node.StructInitializer, "base", base);
792792 rtoken = casted.rtoken;
793 field_inits = casted.list;
793 field_inits = casted.list();
794794 break :blk .{ .node = casted.lhs };
795795 },
796796 else => unreachable,