authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-03 16:35:39-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-07-07 22:59:52-04:00
log3e1b190fe6955ba051d961494433b8346af2af38
tree8660b2cd8098f40582612e7d72fe29bead39d102
parentc8b9364b30adfdd1716b20428a3d934eac75cc87

InternPool: replace garbage with an arena

This was just a badly implemented arena anyway.

1 files changed, 20 insertions(+), 46 deletions(-)

src/InternPool.zig+20-46
...@@ -347,23 +347,20 @@ pub const DepEntry = extern struct {...@@ -347,23 +347,20 @@ pub const DepEntry = extern struct {
347const Local = struct {347const Local = struct {
348 aligned: void align(std.atomic.cache_line) = {},348 aligned: void align(std.atomic.cache_line) = {},
349349
350 /// node: Garbage.Node,
351 /// header: List.Header,350 /// header: List.Header,
352 /// data: [capacity]u32,351 /// data: [capacity]u32,
353 /// tag: [header.capacity]Tag,352 /// tag: [header.capacity]Tag,
354 items: List,353 items: List,
355354
356 /// node: Garbage.Node,
357 /// header: List.Header,355 /// header: List.Header,
358 /// extra: [header.capacity]u32,356 /// extra: [header.capacity]u32,
359 extra: List,357 extra: List,
360358
361 /// node: Garbage.Node,
362 /// header: List.Header,359 /// header: List.Header,
363 /// bytes: [header.capacity]u8,360 /// bytes: [header.capacity]u8,
364 strings: List,361 strings: List,
365362
366 garbage: Garbage,363 arena: std.heap.ArenaAllocator.State,
367364
368 const List = struct {365 const List = struct {
369 entries: [*]u32,366 entries: [*]u32,
...@@ -393,13 +390,6 @@ const Local = struct {...@@ -393,13 +390,6 @@ const Local = struct {
393 return @ptrCast(list.entries - Header.fields_len);390 return @ptrCast(list.entries - Header.fields_len);
394 }391 }
395 };392 };
396
397 const Garbage = std.SinglyLinkedList(struct { buf_len: usize });
398 const garbage_align = @max(@alignOf(Garbage.Node), @alignOf(u32));
399
400 fn freeGarbage(garbage: *const Garbage.Node, gpa: Allocator) void {
401 gpa.free(@as([*]align(Local.garbage_align) const u8, @ptrCast(garbage))[0..garbage.data.buf_len]);
402 }
403};393};
404394
405const Shard = struct {395const Shard = struct {
...@@ -427,7 +417,6 @@ const Shard = struct {...@@ -427,7 +417,6 @@ const Shard = struct {
427 comptime assert(@typeInfo(Value).Enum.tag_type == u32);417 comptime assert(@typeInfo(Value).Enum.tag_type == u32);
428 _ = @as(Value, .none); // expected .none key418 _ = @as(Value, .none); // expected .none key
429 return struct {419 return struct {
430 /// node: Local.Garbage.Node,
431 /// header: Header,420 /// header: Header,
432 /// entries: [header.capacity]Entry,421 /// entries: [header.capacity]Entry,
433 entries: [*]Entry,422 entries: [*]Entry,
...@@ -440,6 +429,9 @@ const Shard = struct {...@@ -440,6 +429,9 @@ const Shard = struct {
440 .entries = .{.{ .value = .none, .hash = undefined }},429 .entries = .{.{ .value = .none, .hash = undefined }},
441 }).entries) };430 }).entries) };
442431
432 const alignment = @max(@alignOf(Header), @alignOf(Entry));
433 const entries_offset = std.mem.alignForward(usize, @sizeOf(Header), @alignOf(Entry));
434
443 fn acquire(map: *const @This()) @This() {435 fn acquire(map: *const @This()) @This() {
444 return .{ .entries = @atomicLoad([*]Entry, &map.entries, .acquire) };436 return .{ .entries = @atomicLoad([*]Entry, &map.entries, .acquire) };
445 }437 }
...@@ -4660,7 +4652,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, total_threads: usize) !void {...@@ -4660,7 +4652,7 @@ pub fn init(ip: *InternPool, gpa: Allocator, total_threads: usize) !void {
4660 .items = Local.List.empty,4652 .items = Local.List.empty,
4661 .extra = Local.List.empty,4653 .extra = Local.List.empty,
4662 .strings = Local.List.empty,4654 .strings = Local.List.empty,
4663 .garbage = .{},4655 .arena = .{},
4664 });4656 });
46654657
4666 ip.shard_shift = @intCast(std.math.log2_int_ceil(usize, total_threads));4658 ip.shard_shift = @intCast(std.math.log2_int_ceil(usize, total_threads));
...@@ -4740,13 +4732,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -4740,13 +4732,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
4740 ip.files.deinit(gpa);4732 ip.files.deinit(gpa);
47414733
4742 gpa.free(ip.shards);4734 gpa.free(ip.shards);
4743 for (ip.local) |*local| {4735 for (ip.local) |*local| local.arena.promote(gpa).deinit();
4744 var next = local.garbage.first;
4745 while (next) |cur| {
4746 next = cur.next;
4747 Local.freeGarbage(cur, gpa);
4748 }
4749 }
4750 gpa.free(ip.local);4736 gpa.free(ip.local);
47514737
4752 ip.* = undefined;4738 ip.* = undefined;
...@@ -5451,23 +5437,17 @@ fn getOrPutKey(...@@ -5451,23 +5437,17 @@ fn getOrPutKey(
5451 }5437 }
5452 const map_header = map.header().*;5438 const map_header = map.header().*;
5453 if (shard.mutate.map.len >= map_header.capacity * 3 / 5) {5439 if (shard.mutate.map.len >= map_header.capacity * 3 / 5) {
5440 var arena = ip.local[@intFromEnum(tid)].arena.promote(gpa);
5441 defer ip.local[@intFromEnum(tid)].arena = arena.state;
5454 const new_map_capacity = map_header.capacity * 2;5442 const new_map_capacity = map_header.capacity * 2;
5455 const new_map_buf = try gpa.alignedAlloc(5443 const new_map_buf = try arena.allocator().alignedAlloc(
5456 u8,5444 u8,
5457 Local.garbage_align,5445 Map.alignment,
5458 @sizeOf(Local.Garbage.Node) + @sizeOf(Map.Header) +5446 Map.entries_offset + new_map_capacity * @sizeOf(Map.Entry),
5459 new_map_capacity * @sizeOf(Map.Entry),
5460 );5447 );
5461 const new_node: *Local.Garbage.Node = @ptrCast(new_map_buf.ptr);5448 const new_map: Map = .{ .entries = @ptrCast(new_map_buf[Map.entries_offset..].ptr) };
5462 new_node.* = .{ .data = .{ .buf_len = new_map_buf.len } };
5463 ip.local[@intFromEnum(tid)].garbage.prepend(new_node);
5464 const new_map_entries = std.mem.bytesAsSlice(
5465 Map.Entry,
5466 new_map_buf[@sizeOf(Local.Garbage.Node) + @sizeOf(Map.Header) ..],
5467 );
5468 const new_map: Map = .{ .entries = new_map_entries.ptr };
5469 new_map.header().* = .{ .capacity = new_map_capacity };5449 new_map.header().* = .{ .capacity = new_map_capacity };
5470 @memset(new_map_entries, .{ .value = .none, .hash = undefined });5450 @memset(new_map.entries[0..new_map_capacity], .{ .value = .none, .hash = undefined });
5471 const new_map_mask = new_map.header().mask();5451 const new_map_mask = new_map.header().mask();
5472 map_index = 0;5452 map_index = 0;
5473 while (map_index < map_header.capacity) : (map_index += 1) {5453 while (map_index < map_header.capacity) : (map_index += 1) {
...@@ -9181,23 +9161,17 @@ fn getOrPutStringValue(...@@ -9181,23 +9161,17 @@ fn getOrPutStringValue(
9181 entry.release(value.toOptional());9161 entry.release(value.toOptional());
9182 return .none;9162 return .none;
9183 }9163 }
9164 var arena = ip.local[@intFromEnum(tid)].arena.promote(gpa);
9165 defer ip.local[@intFromEnum(tid)].arena = arena.state;
9184 const new_map_capacity = map_header.capacity * 2;9166 const new_map_capacity = map_header.capacity * 2;
9185 const new_map_buf = try gpa.alignedAlloc(9167 const new_map_buf = try arena.allocator().alignedAlloc(
9186 u8,9168 u8,
9187 Local.garbage_align,9169 Map.alignment,
9188 @sizeOf(Local.Garbage.Node) + @sizeOf(Map.Header) +9170 Map.entries_offset + new_map_capacity * @sizeOf(Map.Entry),
9189 new_map_capacity * @sizeOf(Map.Entry),
9190 );
9191 const new_node: *Local.Garbage.Node = @ptrCast(new_map_buf.ptr);
9192 new_node.* = .{ .data = .{ .buf_len = new_map_buf.len } };
9193 ip.local[@intFromEnum(tid)].garbage.prepend(new_node);
9194 const new_map_entries = std.mem.bytesAsSlice(
9195 Map.Entry,
9196 new_map_buf[@sizeOf(Local.Garbage.Node) + @sizeOf(Map.Header) ..],
9197 );9171 );
9198 const new_map: Map = .{ .entries = new_map_entries.ptr };9172 const new_map: Map = .{ .entries = @ptrCast(new_map_buf[Map.entries_offset..].ptr) };
9199 new_map.header().* = .{ .capacity = new_map_capacity };9173 new_map.header().* = .{ .capacity = new_map_capacity };
9200 @memset(new_map_entries, .{ .value = .none, .hash = undefined });9174 @memset(new_map.entries[0..new_map_capacity], .{ .value = .none, .hash = undefined });
9201 const new_map_mask = new_map.header().mask();9175 const new_map_mask = new_map.header().mask();
9202 map_index = 0;9176 map_index = 0;
9203 while (map_index < map_header.capacity) : (map_index += 1) {9177 while (map_index < map_header.capacity) : (map_index += 1) {