authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-20 22:42:43-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-05-20 22:42:43-04:00
log688aa114e434e05b96f916c168f177aa0484baec
tree67eb9b79f73c08533ddae31afa90a316a18d457d
parent84df1d4f3d0312553f5a3857ed67042319c20846

Revert "stage2 parser: elide memcpy of large initialization lists"

This reverts commit 84df1d4f3d0312553f5a3857ed67042319c20846. Not worth the complexity! Always memcpy initialization lists into the arena.

2 files changed, 4 insertions(+), 56 deletions(-)

lib/std/zig/ast.zig-6
...@@ -18,8 +18,6 @@ pub const Tree = struct {...@@ -18,8 +18,6 @@ pub const Tree = struct {
1818
19 arena: std.heap.ArenaAllocator.State,19 arena: std.heap.ArenaAllocator.State,
20 gpa: *mem.Allocator,20 gpa: *mem.Allocator,
21 /// This keeps track of slices of memory that must be freed on deinit.
22 owned_memory: [][]u8,
2321
24 /// translate-c uses this to avoid having to emit correct newlines22 /// translate-c uses this to avoid having to emit correct newlines
25 /// TODO get rid of this hack23 /// TODO get rid of this hack
...@@ -28,10 +26,6 @@ pub const Tree = struct {...@@ -28,10 +26,6 @@ pub const Tree = struct {
28 pub fn deinit(self: *Tree) void {26 pub fn deinit(self: *Tree) void {
29 self.gpa.free(self.tokens);27 self.gpa.free(self.tokens);
30 self.gpa.free(self.errors);28 self.gpa.free(self.errors);
31 for (self.owned_memory) |list| {
32 self.gpa.free(list);
33 }
34 self.gpa.free(self.owned_memory);
35 self.arena.promote(self.gpa).deinit();29 self.arena.promote(self.gpa).deinit();
36 }30 }
3731
lib/std/zig/parse.zig+4-50
...@@ -10,13 +10,6 @@ const Token = std.zig.Token;...@@ -10,13 +10,6 @@ const Token = std.zig.Token;
1010
11pub const Error = error{ParseError} || Allocator.Error;11pub const Error = error{ParseError} || Allocator.Error;
1212
13/// This is the maximum length of a list that will be copied into the ast.Tree
14/// arena when parsing. If the list is longer than this, the ast.Tree will have
15/// a reference to the memory allocated in the general purpose allocator, and
16/// will free it separately. Simply put, lists longer than this will elide the
17/// memcpy().
18const large_list_len = 512;
19
20/// Result should be freed with tree.deinit() when there are13/// Result should be freed with tree.deinit() when there are
21/// no more references to any of the tokens or nodes.14/// no more references to any of the tokens or nodes.
22pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!*Tree {15pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!*Tree {
...@@ -39,11 +32,6 @@ pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!*Tree {...@@ -39,11 +32,6 @@ pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!*Tree {
39 .tokens = tokens.items,32 .tokens = tokens.items,
40 .errors = .{},33 .errors = .{},
41 .tok_i = 0,34 .tok_i = 0,
42 .owned_memory = .{},
43 };
44 defer parser.owned_memory.deinit(gpa);
45 errdefer for (parser.owned_memory.items) |list| {
46 gpa.free(list);
47 };35 };
48 defer parser.errors.deinit(gpa);36 defer parser.errors.deinit(gpa);
49 errdefer parser.arena.deinit();37 errdefer parser.arena.deinit();
...@@ -58,7 +46,6 @@ pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!*Tree {...@@ -58,7 +46,6 @@ pub fn parse(gpa: *Allocator, source: []const u8) Allocator.Error!*Tree {
58 .source = source,46 .source = source,
59 .tokens = tokens.toOwnedSlice(),47 .tokens = tokens.toOwnedSlice(),
60 .errors = parser.errors.toOwnedSlice(gpa),48 .errors = parser.errors.toOwnedSlice(gpa),
61 .owned_memory = parser.owned_memory.toOwnedSlice(gpa),
62 .root_node = root_node,49 .root_node = root_node,
63 .arena = parser.arena.state,50 .arena = parser.arena.state,
64 };51 };
...@@ -73,7 +60,6 @@ const Parser = struct {...@@ -73,7 +60,6 @@ const Parser = struct {
73 tokens: []const Token,60 tokens: []const Token,
74 tok_i: TokenIndex,61 tok_i: TokenIndex,
75 errors: std.ArrayListUnmanaged(AstError),62 errors: std.ArrayListUnmanaged(AstError),
76 owned_memory: std.ArrayListUnmanaged([]u8),
7763
78 /// Root <- skip ContainerMembers eof64 /// Root <- skip ContainerMembers eof
79 fn parseRoot(p: *Parser) Allocator.Error!*Node.Root {65 fn parseRoot(p: *Parser) Allocator.Error!*Node.Root {
...@@ -1321,19 +1307,11 @@ const Parser = struct {...@@ -1321,19 +1307,11 @@ const Parser = struct {
1321 const next = (try p.parseFieldInit()) orelse break;1307 const next = (try p.parseFieldInit()) orelse break;
1322 try init_list.append(next);1308 try init_list.append(next);
1323 }1309 }
1324
1325 const list = if (init_list.items.len > large_list_len) blk: {
1326 try p.owned_memory.ensureCapacity(p.gpa, p.owned_memory.items.len + 1);
1327 const list = init_list.toOwnedSlice();
1328 p.owned_memory.appendAssumeCapacity(std.mem.sliceAsBytes(list));
1329 break :blk list;
1330 } else try p.arena.allocator.dupe(*Node, init_list.items);
1331
1332 const node = try p.arena.allocator.create(Node.StructInitializer);1310 const node = try p.arena.allocator.create(Node.StructInitializer);
1333 node.* = .{1311 node.* = .{
1334 .lhs = lhs,1312 .lhs = lhs,
1335 .rtoken = try p.expectToken(.RBrace),1313 .rtoken = try p.expectToken(.RBrace),
1336 .list = list,1314 .list = try p.arena.allocator.dupe(*Node, init_list.items),
1337 };1315 };
1338 return &node.base;1316 return &node.base;
1339 }1317 }
...@@ -1344,19 +1322,11 @@ const Parser = struct {...@@ -1344,19 +1322,11 @@ const Parser = struct {
1344 const next = (try p.parseExpr()) orelse break;1322 const next = (try p.parseExpr()) orelse break;
1345 try init_list.append(next);1323 try init_list.append(next);
1346 }1324 }
1347
1348 const list = if (init_list.items.len > large_list_len) blk: {
1349 try p.owned_memory.ensureCapacity(p.gpa, p.owned_memory.items.len + 1);
1350 const list = init_list.toOwnedSlice();
1351 p.owned_memory.appendAssumeCapacity(std.mem.sliceAsBytes(list));
1352 break :blk list;
1353 } else try p.arena.allocator.dupe(*Node, init_list.items);
1354
1355 const node = try p.arena.allocator.create(Node.ArrayInitializer);1325 const node = try p.arena.allocator.create(Node.ArrayInitializer);
1356 node.* = .{1326 node.* = .{
1357 .lhs = lhs,1327 .lhs = lhs,
1358 .rtoken = try p.expectToken(.RBrace),1328 .rtoken = try p.expectToken(.RBrace),
1359 .list = list,1329 .list = try p.arena.allocator.dupe(*Node, init_list.items),
1360 };1330 };
1361 return &node.base;1331 return &node.base;
1362 }1332 }
...@@ -1385,19 +1355,11 @@ const Parser = struct {...@@ -1385,19 +1355,11 @@ const Parser = struct {
1385 const next = (try p.parseFieldInit()) orelse break;1355 const next = (try p.parseFieldInit()) orelse break;
1386 try init_list.append(next);1356 try init_list.append(next);
1387 }1357 }
1388
1389 const list = if (init_list.items.len > large_list_len) blk: {
1390 try p.owned_memory.ensureCapacity(p.gpa, p.owned_memory.items.len + 1);
1391 const list = init_list.toOwnedSlice();
1392 p.owned_memory.appendAssumeCapacity(std.mem.sliceAsBytes(list));
1393 break :blk list;
1394 } else try p.arena.allocator.dupe(*Node, init_list.items);
1395
1396 const node = try p.arena.allocator.create(Node.StructInitializerDot);1358 const node = try p.arena.allocator.create(Node.StructInitializerDot);
1397 node.* = .{1359 node.* = .{
1398 .dot = dot,1360 .dot = dot,
1399 .rtoken = try p.expectToken(.RBrace),1361 .rtoken = try p.expectToken(.RBrace),
1400 .list = list,1362 .list = try p.arena.allocator.dupe(*Node, init_list.items),
1401 };1363 };
1402 return &node.base;1364 return &node.base;
1403 }1365 }
...@@ -1408,19 +1370,11 @@ const Parser = struct {...@@ -1408,19 +1370,11 @@ const Parser = struct {
1408 const next = (try p.parseExpr()) orelse break;1370 const next = (try p.parseExpr()) orelse break;
1409 try init_list.append(next);1371 try init_list.append(next);
1410 }1372 }
1411
1412 const list = if (init_list.items.len > large_list_len) blk: {
1413 try p.owned_memory.ensureCapacity(p.gpa, p.owned_memory.items.len + 1);
1414 const list = init_list.toOwnedSlice();
1415 p.owned_memory.appendAssumeCapacity(std.mem.sliceAsBytes(list));
1416 break :blk list;
1417 } else try p.arena.allocator.dupe(*Node, init_list.items);
1418
1419 const node = try p.arena.allocator.create(Node.ArrayInitializerDot);1373 const node = try p.arena.allocator.create(Node.ArrayInitializerDot);
1420 node.* = .{1374 node.* = .{
1421 .dot = dot,1375 .dot = dot,
1422 .rtoken = try p.expectToken(.RBrace),1376 .rtoken = try p.expectToken(.RBrace),
1423 .list = list,1377 .list = try p.arena.allocator.dupe(*Node, init_list.items),
1424 };1378 };
1425 return &node.base;1379 return &node.base;
1426 }1380 }