| ... | ... | @@ -939,8 +939,12 @@ const Shard = struct { |
| 939 | 939 | return @atomicLoad(Value, &entry.value, .acquire); |
| 940 | 940 | } |
| 941 | 941 | fn release(entry: *Entry, value: Value) void { |
| 942 | assert(value != .none); |
| 942 | 943 | @atomicStore(Value, &entry.value, value, .release); |
| 943 | 944 | } |
| 945 | fn resetUnordered(entry: *Entry) void { |
| 946 | @atomicStore(Value, &entry.value, .none, .unordered); |
| 947 | } |
| 944 | 948 | }; |
| 945 | 949 | }; |
| 946 | 950 | } |
| ... | ... | @@ -6583,35 +6587,55 @@ const GetOrPutKey = union(enum) { |
| 6583 | 6587 | }, |
| 6584 | 6588 | |
| 6585 | 6589 | fn put(gop: *GetOrPutKey) Index { |
| 6586 | | return gop.putAt(0); |
| 6587 | | } |
| 6588 | | fn putAt(gop: *GetOrPutKey, offset: u32) Index { |
| 6589 | 6590 | switch (gop.*) { |
| 6590 | 6591 | .existing => unreachable, |
| 6591 | | .new => |info| { |
| 6592 | .new => |*info| { |
| 6592 | 6593 | const index = Index.Unwrapped.wrap(.{ |
| 6593 | 6594 | .tid = info.tid, |
| 6594 | | .index = info.ip.getLocal(info.tid).mutate.items.len - 1 - offset, |
| 6595 | .index = info.ip.getLocal(info.tid).mutate.items.len - 1, |
| 6595 | 6596 | }, info.ip); |
| 6596 | | info.shard.shared.map.entries[info.map_index].release(index); |
| 6597 | gop.putTentative(index); |
| 6598 | gop.putFinal(index); |
| 6599 | return index; |
| 6600 | }, |
| 6601 | } |
| 6602 | } |
| 6603 | |
| 6604 | fn putTentative(gop: *GetOrPutKey, index: Index) void { |
| 6605 | assert(index != .none); |
| 6606 | switch (gop.*) { |
| 6607 | .existing => unreachable, |
| 6608 | .new => |*info| gop.new.shard.shared.map.entries[info.map_index].release(index), |
| 6609 | } |
| 6610 | } |
| 6611 | |
| 6612 | fn putFinal(gop: *GetOrPutKey, index: Index) void { |
| 6613 | assert(index != .none); |
| 6614 | switch (gop.*) { |
| 6615 | .existing => unreachable, |
| 6616 | .new => |info| { |
| 6617 | assert(info.shard.shared.map.entries[info.map_index].value == index); |
| 6597 | 6618 | info.shard.mutate.map.len += 1; |
| 6598 | 6619 | info.shard.mutate.map.mutex.unlock(); |
| 6599 | 6620 | gop.* = .{ .existing = index }; |
| 6600 | | return index; |
| 6601 | 6621 | }, |
| 6602 | 6622 | } |
| 6603 | 6623 | } |
| 6604 | 6624 | |
| 6605 | | fn assign(gop: *GetOrPutKey, new_gop: GetOrPutKey) void { |
| 6606 | | gop.deinit(); |
| 6607 | | gop.* = new_gop; |
| 6625 | fn cancel(gop: *GetOrPutKey) void { |
| 6626 | switch (gop.*) { |
| 6627 | .existing => {}, |
| 6628 | .new => |info| info.shard.mutate.map.mutex.unlock(), |
| 6629 | } |
| 6630 | gop.* = .{ .existing = undefined }; |
| 6608 | 6631 | } |
| 6609 | 6632 | |
| 6610 | 6633 | fn deinit(gop: *GetOrPutKey) void { |
| 6611 | 6634 | switch (gop.*) { |
| 6612 | 6635 | .existing => {}, |
| 6613 | | .new => |info| info.shard.mutate.map.mutex.unlock(), |
| 6636 | .new => |info| info.shard.shared.map.entries[info.map_index].resetUnordered(), |
| 6614 | 6637 | } |
| 6638 | gop.cancel(); |
| 6615 | 6639 | gop.* = undefined; |
| 6616 | 6640 | } |
| 6617 | 6641 | }; |
| ... | ... | @@ -6620,6 +6644,15 @@ fn getOrPutKey( |
| 6620 | 6644 | gpa: Allocator, |
| 6621 | 6645 | tid: Zcu.PerThread.Id, |
| 6622 | 6646 | key: Key, |
| 6647 | ) Allocator.Error!GetOrPutKey { |
| 6648 | return ip.getOrPutKeyEnsuringAdditionalCapacity(gpa, tid, key, 0); |
| 6649 | } |
| 6650 | fn getOrPutKeyEnsuringAdditionalCapacity( |
| 6651 | ip: *InternPool, |
| 6652 | gpa: Allocator, |
| 6653 | tid: Zcu.PerThread.Id, |
| 6654 | key: Key, |
| 6655 | additional_capacity: u32, |
| 6623 | 6656 | ) Allocator.Error!GetOrPutKey { |
| 6624 | 6657 | const full_hash = key.hash64(ip); |
| 6625 | 6658 | const hash: u32 = @truncate(full_hash >> 32); |
| ... | ... | @@ -6655,11 +6688,16 @@ fn getOrPutKey( |
| 6655 | 6688 | } |
| 6656 | 6689 | } |
| 6657 | 6690 | const map_header = map.header().*; |
| 6658 | | if (shard.mutate.map.len >= map_header.capacity * 3 / 5) { |
| 6691 | const required = shard.mutate.map.len + additional_capacity; |
| 6692 | if (required >= map_header.capacity * 3 / 5) { |
| 6659 | 6693 | const arena_state = &ip.getLocal(tid).mutate.arena; |
| 6660 | 6694 | var arena = arena_state.promote(gpa); |
| 6661 | 6695 | defer arena_state.* = arena.state; |
| 6662 | | const new_map_capacity = map_header.capacity * 2; |
| 6696 | var new_map_capacity = map_header.capacity; |
| 6697 | while (true) { |
| 6698 | new_map_capacity *= 2; |
| 6699 | if (required < new_map_capacity * 3 / 5) break; |
| 6700 | } |
| 6663 | 6701 | const new_map_buf = try arena.allocator().alignedAlloc( |
| 6664 | 6702 | u8, |
| 6665 | 6703 | Map.alignment, |
| ... | ... | @@ -6728,10 +6766,11 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 6728 | 6766 | assert(ptr_type.sentinel == .none or ip.typeOf(ptr_type.sentinel) == ptr_type.child); |
| 6729 | 6767 | |
| 6730 | 6768 | if (ptr_type.flags.size == .Slice) { |
| 6769 | gop.cancel(); |
| 6731 | 6770 | var new_key = key; |
| 6732 | 6771 | new_key.ptr_type.flags.size = .Many; |
| 6733 | 6772 | const ptr_type_index = try ip.get(gpa, tid, new_key); |
| 6734 | | gop.assign(try ip.getOrPutKey(gpa, tid, key)); |
| 6773 | gop = try ip.getOrPutKey(gpa, tid, key); |
| 6735 | 6774 | |
| 6736 | 6775 | try items.ensureUnusedCapacity(1); |
| 6737 | 6776 | items.appendAssumeCapacity(.{ |
| ... | ... | @@ -6911,9 +6950,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 6911 | 6950 | }, |
| 6912 | 6951 | .anon_decl => |anon_decl| if (ptrsHaveSameAlignment(ip, ptr.ty, ptr_type, anon_decl.orig_ty)) item: { |
| 6913 | 6952 | if (ptr.ty != anon_decl.orig_ty) { |
| 6953 | gop.cancel(); |
| 6914 | 6954 | var new_key = key; |
| 6915 | 6955 | new_key.ptr.base_addr.anon_decl.orig_ty = ptr.ty; |
| 6916 | | gop.assign(try ip.getOrPutKey(gpa, tid, new_key)); |
| 6956 | gop = try ip.getOrPutKey(gpa, tid, new_key); |
| 6917 | 6957 | if (gop == .existing) return gop.existing; |
| 6918 | 6958 | } |
| 6919 | 6959 | break :item .{ |
| ... | ... | @@ -6984,11 +7024,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 6984 | 7024 | }, |
| 6985 | 7025 | else => unreachable, |
| 6986 | 7026 | } |
| 7027 | gop.cancel(); |
| 6987 | 7028 | const index_index = try ip.get(gpa, tid, .{ .int = .{ |
| 6988 | 7029 | .ty = .usize_type, |
| 6989 | 7030 | .storage = .{ .u64 = base_index.index }, |
| 6990 | 7031 | } }); |
| 6991 | | gop.assign(try ip.getOrPutKey(gpa, tid, key)); |
| 7032 | gop = try ip.getOrPutKey(gpa, tid, key); |
| 6992 | 7033 | try items.ensureUnusedCapacity(1); |
| 6993 | 7034 | items.appendAssumeCapacity(.{ |
| 6994 | 7035 | .tag = switch (ptr.base_addr) { |
| ... | ... | @@ -7397,11 +7438,12 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All |
| 7397 | 7438 | } |
| 7398 | 7439 | const elem = switch (aggregate.storage) { |
| 7399 | 7440 | .bytes => |bytes| elem: { |
| 7441 | gop.cancel(); |
| 7400 | 7442 | const elem = try ip.get(gpa, tid, .{ .int = .{ |
| 7401 | 7443 | .ty = .u8_type, |
| 7402 | 7444 | .storage = .{ .u64 = bytes.at(0, ip) }, |
| 7403 | 7445 | } }); |
| 7404 | | gop.assign(try ip.getOrPutKey(gpa, tid, key)); |
| 7446 | gop = try ip.getOrPutKey(gpa, tid, key); |
| 7405 | 7447 | try items.ensureUnusedCapacity(1); |
| 7406 | 7448 | break :elem elem; |
| 7407 | 7449 | }, |
| ... | ... | @@ -8219,9 +8261,9 @@ pub fn getFuncDeclIes( |
| 8219 | 8261 | extra.mutate.len = prev_extra_len; |
| 8220 | 8262 | } |
| 8221 | 8263 | |
| 8222 | | var func_gop = try ip.getOrPutKey(gpa, tid, .{ |
| 8264 | var func_gop = try ip.getOrPutKeyEnsuringAdditionalCapacity(gpa, tid, .{ |
| 8223 | 8265 | .func = extraFuncDecl(tid, extra.list.*, func_decl_extra_index), |
| 8224 | | }); |
| 8266 | }, 3); |
| 8225 | 8267 | defer func_gop.deinit(); |
| 8226 | 8268 | if (func_gop == .existing) { |
| 8227 | 8269 | // An existing function type was found; undo the additions to our two arrays. |
| ... | ... | @@ -8229,23 +8271,28 @@ pub fn getFuncDeclIes( |
| 8229 | 8271 | extra.mutate.len = prev_extra_len; |
| 8230 | 8272 | return func_gop.existing; |
| 8231 | 8273 | } |
| 8232 | | var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{ |
| 8274 | func_gop.putTentative(func_index); |
| 8275 | var error_union_type_gop = try ip.getOrPutKeyEnsuringAdditionalCapacity(gpa, tid, .{ .error_union_type = .{ |
| 8233 | 8276 | .error_set_type = error_set_type, |
| 8234 | 8277 | .payload_type = key.bare_return_type, |
| 8235 | | } }); |
| 8278 | } }, 2); |
| 8236 | 8279 | defer error_union_type_gop.deinit(); |
| 8237 | | var error_set_type_gop = try ip.getOrPutKey(gpa, tid, .{ |
| 8280 | error_union_type_gop.putTentative(error_union_type); |
| 8281 | var error_set_type_gop = try ip.getOrPutKeyEnsuringAdditionalCapacity(gpa, tid, .{ |
| 8238 | 8282 | .inferred_error_set_type = func_index, |
| 8239 | | }); |
| 8283 | }, 1); |
| 8240 | 8284 | defer error_set_type_gop.deinit(); |
| 8285 | error_set_type_gop.putTentative(error_set_type); |
| 8241 | 8286 | var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{ |
| 8242 | 8287 | .func_type = extraFuncType(tid, extra.list.*, func_type_extra_index), |
| 8243 | 8288 | }); |
| 8244 | 8289 | defer func_ty_gop.deinit(); |
| 8245 | | assert(func_gop.putAt(3) == func_index); |
| 8246 | | assert(error_union_type_gop.putAt(2) == error_union_type); |
| 8247 | | assert(error_set_type_gop.putAt(1) == error_set_type); |
| 8248 | | assert(func_ty_gop.putAt(0) == func_ty); |
| 8290 | func_ty_gop.putTentative(func_ty); |
| 8291 | |
| 8292 | func_gop.putFinal(func_index); |
| 8293 | error_union_type_gop.putFinal(error_union_type); |
| 8294 | error_set_type_gop.putFinal(error_set_type); |
| 8295 | func_ty_gop.putFinal(func_ty); |
| 8249 | 8296 | return func_index; |
| 8250 | 8297 | } |
| 8251 | 8298 | |
| ... | ... | @@ -8504,9 +8551,9 @@ pub fn getFuncInstanceIes( |
| 8504 | 8551 | extra.mutate.len = prev_extra_len; |
| 8505 | 8552 | } |
| 8506 | 8553 | |
| 8507 | | var func_gop = try ip.getOrPutKey(gpa, tid, .{ |
| 8554 | var func_gop = try ip.getOrPutKeyEnsuringAdditionalCapacity(gpa, tid, .{ |
| 8508 | 8555 | .func = ip.extraFuncInstance(tid, extra.list.*, func_extra_index), |
| 8509 | | }); |
| 8556 | }, 3); |
| 8510 | 8557 | defer func_gop.deinit(); |
| 8511 | 8558 | if (func_gop == .existing) { |
| 8512 | 8559 | // Hot path: undo the additions to our two arrays. |
| ... | ... | @@ -8514,19 +8561,23 @@ pub fn getFuncInstanceIes( |
| 8514 | 8561 | extra.mutate.len = prev_extra_len; |
| 8515 | 8562 | return func_gop.existing; |
| 8516 | 8563 | } |
| 8517 | | var error_union_type_gop = try ip.getOrPutKey(gpa, tid, .{ .error_union_type = .{ |
| 8564 | func_gop.putTentative(func_index); |
| 8565 | var error_union_type_gop = try ip.getOrPutKeyEnsuringAdditionalCapacity(gpa, tid, .{ .error_union_type = .{ |
| 8518 | 8566 | .error_set_type = error_set_type, |
| 8519 | 8567 | .payload_type = arg.bare_return_type, |
| 8520 | | } }); |
| 8568 | } }, 2); |
| 8521 | 8569 | defer error_union_type_gop.deinit(); |
| 8522 | | var error_set_type_gop = try ip.getOrPutKey(gpa, tid, .{ |
| 8570 | error_union_type_gop.putTentative(error_union_type); |
| 8571 | var error_set_type_gop = try ip.getOrPutKeyEnsuringAdditionalCapacity(gpa, tid, .{ |
| 8523 | 8572 | .inferred_error_set_type = func_index, |
| 8524 | | }); |
| 8573 | }, 1); |
| 8525 | 8574 | defer error_set_type_gop.deinit(); |
| 8575 | error_set_type_gop.putTentative(error_set_type); |
| 8526 | 8576 | var func_ty_gop = try ip.getOrPutKey(gpa, tid, .{ |
| 8527 | 8577 | .func_type = extraFuncType(tid, extra.list.*, func_type_extra_index), |
| 8528 | 8578 | }); |
| 8529 | 8579 | defer func_ty_gop.deinit(); |
| 8580 | func_ty_gop.putTentative(func_ty); |
| 8530 | 8581 | try finishFuncInstance( |
| 8531 | 8582 | ip, |
| 8532 | 8583 | gpa, |
| ... | ... | @@ -8538,10 +8589,11 @@ pub fn getFuncInstanceIes( |
| 8538 | 8589 | arg.alignment, |
| 8539 | 8590 | arg.section, |
| 8540 | 8591 | ); |
| 8541 | | assert(func_gop.putAt(3) == func_index); |
| 8542 | | assert(error_union_type_gop.putAt(2) == error_union_type); |
| 8543 | | assert(error_set_type_gop.putAt(1) == error_set_type); |
| 8544 | | assert(func_ty_gop.putAt(0) == func_ty); |
| 8592 | |
| 8593 | func_gop.putFinal(func_index); |
| 8594 | error_union_type_gop.putFinal(error_union_type); |
| 8595 | error_set_type_gop.putFinal(error_set_type); |
| 8596 | func_ty_gop.putFinal(func_ty); |
| 8545 | 8597 | return func_index; |
| 8546 | 8598 | } |
| 8547 | 8599 | |
| ... | ... | @@ -10837,19 +10889,18 @@ pub fn getBackingDecl(ip: *const InternPool, val: Index) OptionalDeclIndex { |
| 10837 | 10889 | while (true) { |
| 10838 | 10890 | const unwrapped_base = base.unwrap(ip); |
| 10839 | 10891 | const base_item = unwrapped_base.getItem(ip); |
| 10840 | | const base_extra_items = unwrapped_base.getExtra(ip).view().items(.@"0"); |
| 10841 | 10892 | switch (base_item.tag) { |
| 10842 | | .ptr_decl => return @enumFromInt(base_extra_items[ |
| 10893 | .ptr_decl => return @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[ |
| 10843 | 10894 | base_item.data + std.meta.fieldIndex(PtrDecl, "decl").? |
| 10844 | 10895 | ]), |
| 10845 | 10896 | inline .ptr_eu_payload, |
| 10846 | 10897 | .ptr_opt_payload, |
| 10847 | 10898 | .ptr_elem, |
| 10848 | 10899 | .ptr_field, |
| 10849 | | => |tag| base = @enumFromInt(base_extra_items[ |
| 10900 | => |tag| base = @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[ |
| 10850 | 10901 | base_item.data + std.meta.fieldIndex(tag.Payload(), "base").? |
| 10851 | 10902 | ]), |
| 10852 | | .ptr_slice => base = @enumFromInt(base_extra_items[ |
| 10903 | .ptr_slice => base = @enumFromInt(unwrapped_base.getExtra(ip).view().items(.@"0")[ |
| 10853 | 10904 | base_item.data + std.meta.fieldIndex(PtrSlice, "ptr").? |
| 10854 | 10905 | ]), |
| 10855 | 10906 | else => return .none, |