| ... | @@ -347,23 +347,20 @@ pub const DepEntry = extern struct { | ... | @@ -347,23 +347,20 @@ pub const DepEntry = extern struct { |
| 347 | const Local = struct { | 347 | const Local = struct { |
| 348 | aligned: void align(std.atomic.cache_line) = {}, | 348 | aligned: void align(std.atomic.cache_line) = {}, |
| 349 | | 349 | |
| 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, |
| 355 | | 354 | |
| 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, |
| 360 | | 358 | |
| 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, |
| 365 | | 362 | |
| 366 | garbage: Garbage, | 363 | arena: std.heap.ArenaAllocator.State, |
| 367 | | 364 | |
| 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 | }; |
| 404 | | 394 | |
| 405 | const Shard = struct { | 395 | const 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 key | 418 | _ = @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) }; |
| 442 | | 431 | |
| | 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 | }); |
| 4665 | | 4657 | |
| 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); |
| 4741 | | 4733 | |
| 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); |
| 4751 | | 4737 | |
| 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) { |