gen4: implement a growable semantics.TableSet #8905
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This was requested by @systay on Slack. We need a
TableSet
data structure that can support more than 64 tables. We're doing this right here in the smallest possible space:TableSet
is now 16 bytes large and packs a small, single-word bitmap that is used when the set contains less than 64 tables, and a pointer to an implementation of an arbitrarily large set.This implementation is pretty straightforward -- I don't believe it can be optimized further like we'd do in C/C++/Rust. For completeness, these kind of implementations are usually done like this in non-GC'ed languages:
Instead of the 16-byte
struct
we have here withstruct TableSet{ small uint64; large *largeTableSet }
, we'd have a single-field struct with a single word in it:struct TableSet { set uintptr }
. When trying to read or write to this set, we'd checkif ts.set & 0x1 != 0
; if this is true, then we have a 63 bit tableset by doingts.set >> 1
. If it's false, then we'd have a large tableset by doing(*largeTableSet)(ts.set)
. This works in practice because memory allocators will never return pointers with a 1-off alignment (their minimal alignment is at the very least the system's word size, 4/8), so we can store a bitmap in the pointer as long as the last bit of the bitmap is always1
. 👌...Of course this doesn't work in a garbage collected language like Go because if you leave a
*largeTableSet
pointed at by anuintptr
, the GC won't find it and it'll be freed on a later GC pass. So we don't get to to pack pointers and we need to run with 16-byteTableSet
s.Good enough!
cc @systay @frouioui
Related Issue(s)
#7280
Checklist