Skip to content

Commit 654f1af

Browse files
committed
jit: admit a call-bearing LIST_APPEND body in a FOR_ITER loop
`for_iter_body_is_jit_safe_at` admitted an inlined comprehension's `LIST_APPEND` only when a preceding scan found no CALL anywhere in the body. The scan's premise was that a compiled loop's live-at-exit values stay reachable from the exit state, so a per-element call leaves a freshly constructed object rooted past the `STORE_FAST` that unbinds the comprehension slot, and `extra_tests/parity_tests/weakref_gc_lifeline.py` would see the last element outlive the collection that should have run its weakref callback. `SET_ADD` and `MAP_ADD` -- the set and dict comprehension accumulators, which fill the same fresh container from the same per-element expression -- never carried the scan. `{Target(i) for i in range(2000)}` and `{i: Target(i) for i in range(2000)}` therefore already compiled, and each reports 2000 of 2000 weakref callbacks with nothing left alive. The shape the scan declined was reachable through two sibling opcodes all along and does not retain, so the term was asymmetric rather than protective. Removing it makes the scan dead, and it goes with it. Direct measurement agrees. `PYRE_FOR_ITER_GATE_DIAG` names the two comprehensions `weakref_gc_lifeline.py` builds -- `[Target() ...]` and `[weakref.ref(target, callback) ...]`, 2000 elements each -- as that file's only declines; with the term gone both compile and the file still passes, every referent's callback running in the collection that drops it. All 127 parity scripts pass on dynasm and on cranelift under `--gc-poison`, which fills reclaimed nursery bytes so a dangling read aborts instead of decoding as a plausible object. Four fixtures' baselines move, identically on dynasm and cranelift: `list_to_tuple_star` compiles its loop at all (`loops_compiled 0 -> 1`), `mapdict_frozen_unboxing_fold` reaches `guard_failures 2 -> 11`, `list_append_virtual_payload` `bridges_compiled 4 -> 7` and `guard_failures 1001 -> 1403`, and `surrogate_class_kwargs` `bridges_compiled 0 -> 1`, `loops_aborted 0 -> 1`, `guard_failures 0 -> 2658`. The last one's abort is `abrt_bridge`, one aborted bridge attempt: pypy3 on the same fixture compiles 14 loops and 9 bridges and aborts 4 times, against pyre's 3, 1 and 1, so the movement is toward the oracle with a wide margin left. `list_to_tuple_star`'s header gave `loops_compiled=0` as its reason for carrying no `max-pypy-ratio`, which no longer holds; it now gives the reason that does. Assisted-by: Claude
1 parent 388d7e8 commit 654f1af

14 files changed

Lines changed: 52 additions & 81 deletions

‎pyre/bench/synth/list_append_virtual_payload.cranelift.jitstats‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bridges_compiled=4
1+
bridges_compiled=7
22
descr_set_absent=0
33
descr_set_ambiguous=0
44
descr_set_stale_absent=0
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=1001
11+
guard_failures=1403
1212
internal_compile_panics=0
1313
loops_aborted=0
1414
loops_compiled=2

‎pyre/bench/synth/list_append_virtual_payload.dynasm.jitstats‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bridges_compiled=4
1+
bridges_compiled=7
22
descr_set_absent=0
33
descr_set_ambiguous=0
44
descr_set_stale_absent=0
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=1001
11+
guard_failures=1403
1212
internal_compile_panics=0
1313
loops_aborted=0
1414
loops_compiled=2

‎pyre/bench/synth/list_append_virtual_payload.wasm.jitstats‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
bridges_compiled=4
1+
bridges_compiled=7
22
descr_set_absent=0
33
descr_set_ambiguous=0
44
descr_set_stale_absent=0
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=1001
11+
guard_failures=1403
1212
internal_compile_panics=0
1313
loops_aborted=0
1414
loops_compiled=2

‎pyre/bench/synth/list_to_tuple_star.cranelift.jitstats‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=0
11+
guard_failures=1
1212
internal_compile_panics=0
1313
loops_aborted=0
14-
loops_compiled=0
14+
loops_compiled=1

‎pyre/bench/synth/list_to_tuple_star.dynasm.jitstats‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=0
11+
guard_failures=1
1212
internal_compile_panics=0
1313
loops_aborted=0
14-
loops_compiled=0
14+
loops_compiled=1

‎pyre/bench/synth/list_to_tuple_star.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
# No `max-pypy-ratio`: this fixture compiles no loop -- its jitstats record
2-
# `loops_compiled=0` -- so a pypy ratio compares two interpreters' startup
3-
# rather than any generated code, and reads whatever the host's process
4-
# spawn cost happens to be that run. The jitstats baselines gate it.
1+
# No `max-pypy-ratio`: the star-unpack construct this fixture measures pulls in
2+
# unported ops, so the loop it now compiles carries no demonstrable speedup and
3+
# a pypy ratio would read mostly the two interpreters' startup plus whatever the
4+
# host's process spawn cost happens to be that run. The jitstats baselines gate
5+
# it.
56
N = 50000
67

78

‎pyre/bench/synth/list_to_tuple_star.wasm.jitstats‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=0
11+
guard_failures=1
1212
internal_compile_panics=0
1313
loops_aborted=0
14-
loops_compiled=0
14+
loops_compiled=1

‎pyre/bench/synth/mapdict_frozen_unboxing_fold.cranelift.jitstats‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=2
11+
guard_failures=11
1212
internal_compile_panics=0
1313
loops_aborted=0
1414
loops_compiled=3

‎pyre/bench/synth/mapdict_frozen_unboxing_fold.dynasm.jitstats‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=2
11+
guard_failures=11
1212
internal_compile_panics=0
1313
loops_aborted=0
1414
loops_compiled=3

‎pyre/bench/synth/mapdict_frozen_unboxing_fold.wasm.jitstats‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fbw_rolled_back_with_effects=0
88
fbw_store_journal_rollback_failed=0
99
field_pos_attached_misplaced=0
1010
field_pos_spec_misplaced=0
11-
guard_failures=2
11+
guard_failures=11
1212
internal_compile_panics=0
1313
loops_aborted=0
1414
loops_compiled=3

0 commit comments

Comments
 (0)