Commit 8d7d9d9
authored
Use dict keys-version stamps and entry-index hints in LOAD_ATTR/STORE_ATTR specializations (#8350)
* Use dict keys-version stamps and entry-index hints in attr specializations
Add a keys-version stamp to Dict: a globally unique u32 assigned lazily
and reset on any key-set change (new key, deletion, clear). Value-only
updates keep the stamp.
- LoadAttrMethodWithValues / LoadAttrNondescriptorWithValues: cache the
instance dict's stamp in the pointer cache and skip the shadow probe
while the stamp matches.
- LoadAttrWithHint: cache the entry index at specialization time; a hit
is an identity check on the entry key instead of a hash probe, with
self-refresh on miss.
- StoreAttrWithHint / StoreAttrInstanceValue: replace values through the
cached entry index via set_item_with_hint.
Fixes youknowone#42
Assisted-by: Claude
* Share keys-version stamps between dicts with identical layouts
Derive the keys-version stamp from a shape — the ordered interned-key
sequence of a hole-free dict — instead of always allocating a unique
stamp. Dicts with identical layouts (instances of the same class built
by the same __init__) now carry equal stamps, so a LOAD_ATTR cache
entry populated by one instance skips the shadow probe for every
instance sharing the layout.
Shapes are held in a fixed-size lock-free table keyed by interned key
addresses; dicts with holes, non-interned keys, or more than 32 keys
fall back to dict-unique stamps.
Assisted-by: Claude
* Address clippy and review feedback for keys-version stamps
- Use BuildHasher::hash_one for shape hashing (clippy manual_hash_one)
- Fix set_item_with_hint doc: a refreshed hint is returned on any hint
miss, not only when the hinted slot was vacant
- Route both holey-dict instances through a single LOAD_ATTR cache site
in the snippet test
Assisted-by: Claude
* Restore try_read_cached_descriptor doc comment to its function
The doc block and #[inline] were left attached to store_attr_dict_hinted
when it was inserted above try_read_cached_descriptor.
Assisted-by: Claude
* Specialize LoadAttrWithHint even when the entry index exceeds u16
hint_for_key returns None both for an absent key and for a present key
whose entry index does not fit in u16, so very large instance dicts
stopped specializing entirely. Use get_item_opt_refresh_hint to decide
presence, degrading an unrepresentable hint to 0: the handler then
keeps taking its full-probe fallback path.
Assisted-by: Claude1 parent dd9bce5 commit 8d7d9d9
5 files changed
Lines changed: 550 additions & 40 deletions
File tree
- crates
- compiler-core/src
- vm/src
- builtins
- extra_tests/snippets
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
776 | 776 | | |
777 | 777 | | |
778 | 778 | | |
779 | | - | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
780 | 783 | | |
781 | 784 | | |
782 | 785 | | |
783 | | - | |
784 | | - | |
| 786 | + | |
| 787 | + | |
785 | 788 | | |
786 | 789 | | |
787 | 790 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
753 | 753 | | |
754 | 754 | | |
755 | 755 | | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
756 | 813 | | |
757 | 814 | | |
758 | 815 | | |
| |||
0 commit comments