Commit e6f874a
Ralph Küpper
gc: close the strhandle, derived-mask and new.target unrooted hazards (#7664)
`gc-root-dominance-statepoints`' `--max-unrooted` ratchet goes 21 -> 7.
#7663 pointed the root-dominance rule at the NATIVE root lowering -- the one
that ships since #7370 -- and reported 21 `unrooted` hazards. Fourteen were
shapes `root_reload.rs` looked straight through, because its rule is stated
over the load's own register and in both shapes the value at risk lives
somewhere else.
1. The root is a GLOBAL, not an alloca (10 hits). A string literal lowers to
`load double, ptr @<mod>_.str.N.handle`; the handle global is a registered
root, so the string is never swept, and an evacuating cycle REWRITES the
global while a register loaded beforehand keeps the pre-move address.
#7240's shape, whose fix covered call operands only.
2. The stale register is DERIVED from the load (3 of 7 unmasked receivers).
`this.count++` holds the unmasked receiver across the property GET; the
load's only use is the bitcast ABOVE the collecting call, so the window
was empty and the function took zero reloads.
3. `new.target`'s saved previous value (1 hit). `new.rs` saved
`js_new_target_get()` in a bare register across the whole constructor
body; the cell is a registered mutable root, so the restore publishes a
pre-move address back INTO a root the collector scans. #7226's
`prev_this` bug for `new.target`.
The reload rule is restated over the value's derivation rather than its
register: for a value read out of a collector-rewritten location -- a shadow
slot or a string-handle global -- and any value derived from it by pure bit
ops, every use a collection point can reach re-materialises the whole
derivation. A recipe is extended only through ops that are pure functions of
their operands and whose every register operand is already in the same single
root's recipe, which makes it self-contained and materialisable anywhere. Each
value's window is anchored at its own defining instruction, not at the root
load.
`new.target` gets `new_target_save`/`new_target_restore` in `crate::rooting`,
structurally `implicit_this_save`/`implicit_this_restore`. Re-reading the cell
would be the wrong repair: `js_new_target_set` has already overwritten it.
Measured on `Counter__increment`: before, all three statepoints carried an
EMPTY live set, so the receiver was marked by nothing; after, each carries a
"gc-live" bundle and a `gc.relocate`, and the SET reads a mask re-derived from
the relocated pointer plus a fresh load of the handle global.
Remaining 7, each its own slice: 4 unmasked are phi-mediated (the reload has to
go in the predecessor, on the edge); 2 `@perry_global_*` are module-level
variables the program assigns, so they need rooting rather than reloading
(pinned by `a_module_global_is_not_a_reload_source`); 1 capture read. #7664
stays open as the budget's referent.
Claude-Session: https://claude.ai/code/session_01Y1QZ5wUP9gRSwpiweT4Wix1 parent 7bde3de commit e6f874a
6 files changed
Lines changed: 770 additions & 96 deletions
File tree
- .github/workflows
- changelog.d
- crates/perry-codegen/src
- lower_call
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
464 | 464 | | |
465 | 465 | | |
466 | 466 | | |
467 | | - | |
468 | | - | |
469 | | - | |
470 | | - | |
471 | | - | |
472 | | - | |
473 | | - | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
474 | 474 | | |
475 | | - | |
476 | | - | |
477 | | - | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
478 | 496 | | |
479 | 497 | | |
480 | 498 | | |
| |||
494 | 512 | | |
495 | 513 | | |
496 | 514 | | |
497 | | - | |
| 515 | + | |
498 | 516 | | |
499 | 517 | | |
500 | 518 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
24 | 25 | | |
25 | 26 | | |
26 | 27 | | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
27 | 33 | | |
28 | 34 | | |
29 | 35 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1014 | 1014 | | |
1015 | 1015 | | |
1016 | 1016 | | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
1017 | 1020 | | |
1018 | | - | |
1019 | | - | |
| 1021 | + | |
1020 | 1022 | | |
1021 | 1023 | | |
1022 | 1024 | | |
1023 | | - | |
1024 | | - | |
1025 | | - | |
| 1025 | + | |
1026 | 1026 | | |
1027 | 1027 | | |
1028 | 1028 | | |
| |||
1034 | 1034 | | |
1035 | 1035 | | |
1036 | 1036 | | |
1037 | | - | |
1038 | | - | |
1039 | | - | |
| 1037 | + | |
| 1038 | + | |
1040 | 1039 | | |
1041 | 1040 | | |
1042 | 1041 | | |
| |||
1081 | 1080 | | |
1082 | 1081 | | |
1083 | 1082 | | |
1084 | | - | |
1085 | | - | |
1086 | | - | |
| 1083 | + | |
| 1084 | + | |
1087 | 1085 | | |
1088 | 1086 | | |
1089 | 1087 | | |
| |||
1760 | 1758 | | |
1761 | 1759 | | |
1762 | 1760 | | |
1763 | | - | |
1764 | 1761 | | |
1765 | | - | |
1766 | | - | |
| 1762 | + | |
1767 | 1763 | | |
1768 | | - | |
1769 | | - | |
| 1764 | + | |
1770 | 1765 | | |
1771 | 1766 | | |
1772 | 1767 | | |
| |||
1798 | 1793 | | |
1799 | 1794 | | |
1800 | 1795 | | |
1801 | | - | |
1802 | 1796 | | |
1803 | | - | |
1804 | | - | |
| 1797 | + | |
1805 | 1798 | | |
1806 | | - | |
1807 | | - | |
| 1799 | + | |
1808 | 1800 | | |
1809 | 1801 | | |
1810 | 1802 | | |
| |||
0 commit comments