Skip to content

perf(codegen): a store emits the class-setter arm only for a name a compiled class declares as a setter - #11859

Merged
proggeramlug merged 2 commits into
mainfrom
regfix-accessor-arm-names
Oct 4, 2026
Merged

proggeramlug merged 2 commits into
mainfrom
regfix-accessor-arm-names

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Part of the key-add creep and binary growth that #11784 introduced.

Cause

#11784 (#10498) emits a class-setter arm (put.pic.acc) at every static-key store site, on the shape-miss edge ahead of the key-add memo and the ways. Every store that misses its word (a key-add, an overflow store) runs the arm's loads and tag test, and every store site carries the code. The runtime admits a setter entry only for an accessor some compiled class declares (class_chain_has_instance_accessor). So a store whose name no class declares as a setter can never take the arm.

Fix

The driver collects the accessor names every compiled class declares, over all modules (ClassAccessorNames: getters and setters, instance and static, a superset). It hands them to codegen as CompileOptions::program_class_accessor_names, through the same whole-program path short_spread_method_candidates takes, and adds them to the object-cache key. A store site emits the setter arm only for a declared setter name. A compile that does not collect the names (None: standalone, tests) emits the arm everywhere, as before. A store without the arm misses to js_put_value_set_packed_miss, which asks the same entry first.

The read sites' getter arm is NOT gated here, although the same argument applies to it. Gating it cuts tsc's binary by another 7.8 MB and leaves no class-accessor entry primed either way (read_accessor_primes=0 in both arms). But that build moves tsc's collector into a different regime: 233 to 240 full GCs instead of 244 to 247, RSS +4 to +13% (338 to 371 MB against 326 MB), and two of six runs +4% instructions. The same allocation trace diverges later in the collector's pacing. That needs a GC-side look before the getter half lands. Data is in the lane report.

Results

row (instructions per op) morning main this PR
#11497 addkey lit/factory num 452 485 472
#11497 inherited ocreate 142 156 153

Real workloads (n=5, median instructions:u; main = 5b06d69)

workload main instr this PR delta full GCs main/PR RSS KB main/PR binary bytes main/PR
tsc (transpile x3) 185,061,848,135 184,969,752,226 -0.05% 247/247 323,232/322,548 182,782,336/181,687,904
zod x5000 19,830,425,976 19,824,701,278 -0.03% 0/0 59,088/58,944 24,440,056/24,263,928
qs parse_nested 32,987,388,575 32,983,874,952 -0.01% 0/0 60,064/59,908 27,301,072/27,206,864
commander parse_argv 8,912,043,876 8,911,717,658 -0.00% 0/0 57,240/56,628 34,203,080/34,186,008

Outputs are identical to main's in every run.

Verification

  • New codegen test class_setter_arms_are_emitted_only_for_declared_setter_names: with no names collected the store arm is present. A name declared only as a getter gets no store arm, and the read arm is still present. A declared setter keeps the arm.
  • perry-codegen (--lib) passed on this branch. perry object-cache unit tests passed. perry-runtime --lib (RUST_TEST_THREADS=1): 4845 passed, 0 failed.
  • Gap suite (1254 files) compared with main: 0 regressions. fmt: clean.

@coderabbitai

coderabbitai Bot commented Oct 4, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: fa722a01-ff79-4558-8745-3d9d50fe1cd7
📥 Commits

Reviewing files that changed from the base of the PR and between e9575d8 and 2330a30.

📒 Files selected for processing (58)
  • changelog.d/PENDING-regfix-accessor-arm-names.md
  • crates/perry-codegen/src/codegen/closure.rs
  • crates/perry-codegen/src/codegen/emission_order_tests.rs
  • crates/perry-codegen/src/codegen/entry.rs
  • crates/perry-codegen/src/codegen/entry/tests.rs
  • crates/perry-codegen/src/codegen/function.rs
  • crates/perry-codegen/src/codegen/imported_global_order_tests.rs
  • crates/perry-codegen/src/codegen/method.rs
  • crates/perry-codegen/src/codegen/method_static.rs
  • crates/perry-codegen/src/codegen/mod.rs
  • crates/perry-codegen/src/codegen/number_exactness_tests.rs
  • crates/perry-codegen/src/codegen/opts.rs
  • crates/perry-codegen/src/collectors/proven_this_routing_tests.rs
  • crates/perry-codegen/src/expr/array_push_guard_tests.rs
  • crates/perry-codegen/src/expr/call_spread_short_tests.rs
  • crates/perry-codegen/src/expr/class_field_barrier_tests.rs
  • crates/perry-codegen/src/expr/class_method_arguments_object_tests.rs
  • crates/perry-codegen/src/expr/conforming_layout_note_tests.rs
  • crates/perry-codegen/src/expr/mod.rs
  • crates/perry-codegen/src/expr/property_get/tests.rs
  • crates/perry-codegen/src/expr/put_value_store_ic.rs
  • crates/perry-codegen/src/lib.rs
  • crates/perry-codegen/src/lower_call/alloc_hot_tests.rs
  • crates/perry-codegen/src/lower_call/typed_shape_bake_tests.rs
  • crates/perry-codegen/src/native_root_coverage/mod.rs
  • crates/perry-codegen/src/stmt/boxed_slot_no_root_tests.rs
  • crates/perry-codegen/src/stmt/class_field_loop_tests.rs
  • crates/perry-codegen/src/stmt/element_shape_loop_tests.rs
  • crates/perry-codegen/src/stmt/prealloc_module_global_tests.rs
  • crates/perry-codegen/src/temp_root_coverage/mod.rs
  • crates/perry-codegen/src/type_analysis/numeric/tests.rs
  • crates/perry-codegen/tests/app_window_config_options.rs
  • crates/perry-codegen/tests/argless_builtin_extra_args.rs
  • crates/perry-codegen/tests/class_field_store_pointer_test.rs
  • crates/perry-codegen/tests/class_keys_gc_root.rs
  • crates/perry-codegen/tests/constructor_recursion.rs
  • crates/perry-codegen/tests/crypto_hash_chain_lowering.rs
  • crates/perry-codegen/tests/destructure_call_location.rs
  • crates/perry-codegen/tests/i64_spec_ternary_recursion.rs
  • crates/perry-codegen/tests/ios_platform_api_lowering.rs
  • crates/perry-codegen/tests/large_object_barriers.rs
  • crates/perry-codegen/tests/loop_safepoint_purity.rs
  • crates/perry-codegen/tests/macos_bundle_chdir_gate.rs
  • crates/perry-codegen/tests/native_proof_buffer_views.rs
  • crates/perry-codegen/tests/native_proof_regressions.rs
  • crates/perry-codegen/tests/node_test_mock_property_presence.rs
  • crates/perry-codegen/tests/perry_builtin_name_collision.rs
  • crates/perry-codegen/tests/release_boxes_lowering.rs
  • crates/perry-codegen/tests/scalar_replaced_slot_roots.rs
  • crates/perry-codegen/tests/shadow_slot_hygiene.rs
  • crates/perry-codegen/tests/static_symbol_hygiene.rs
  • crates/perry-codegen/tests/temp_root_operand_temporaries.rs
  • crates/perry-codegen/tests/typed_feedback.rs
  • crates/perry-codegen/tests/typed_shape_descriptor.rs
  • crates/perry-codegen/tests/typed_shape_descriptors.rs
  • crates/perry/src/commands/compile/object_cache.rs
  • crates/perry/src/commands/compile/object_cache/object_cache_tests.rs
  • crates/perry/src/commands/compile/run_pipeline.rs
 __________________________________
< Jazz Jackrabbit is my alter ego. >
 ----------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug
proggeramlug merged commit 729b5da into main Oct 4, 2026
31 of 35 checks passed
@proggeramlug
proggeramlug deleted the regfix-accessor-arm-names branch October 4, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant