Commit c408675
committed
ZJIT: Call megamorphic ISEQ targets without leaving JIT code
The send class table made the *lookup* at a megamorphic site cheap, but
the call itself still left JIT code: `rb_zjit_send_cached_without_block`,
`vm_call_iseq_setup`'s generic argument setup, an interpreter frame push,
the `setjmp` in `vm_exec`, and a trip through `jit_exec` and the entry
trampoline -- all to arrive at code ZJIT had already compiled. On lobsters
that is 4.4M calls a run, and instrumenting what they resolve to shows 45%
of them are the same small shape: an ISEQ method with fixed arity, no
locals beyond its parameters, and a compiled entry point sitting ready.
ISEQ 2,488,687 of which simple, no extra locals, compiled: 2,065,410
CFUNC 743,217
IVAR 639,155
MISSING 478,689
OPTIMIZED 269,758
So probe the table inline and, for that shape, push the frame and call the
callee from JIT code, the way SendDirect does for a statically known
target. The entry point it calls is the *interpreter* one,
`ISEQ_BODY(iseq)->jit_entry`: a JIT-to-JIT entry takes its arguments in C
registers and its address only exists inside the compiler's patching
machinery, while the interpreter entry reads its parameters back out of
the frame -- which is exactly where a simple callee's arguments already
are, because its local table is its parameter list and the caller's
operand stack holds them in order. The frame push is then the whole
calling convention, and the entry address is a field on the ISEQ.
Correctness rests on re-deriving everything per call rather than caching
it. The callcache validates itself against `CLASS_OF(recv)` and
`METHOD_ENTRY_INVALIDATED`, the two checks `vm_cc_hit_p` makes, which is
what covers redefinition, undef, aliasing, visibility changes,
include/prepend, refinements and object death. `body->jit_entry` is loaded
fresh, so an ISEQ whose code was reset -- by a TracePoint, a patch point,
a recompile -- reads as null and takes the slow path. And because the path
skips `vm_call_method`, the fill side only marks a target directly
callable when that function would have let the call straight through:
public, or private from an FCALL site, never protected.
The slot grows a second word for that decision, holding the method entry
rather than the ISEQ so JIT code can check it against the one the
callcache produced. That makes the pair self-validating: a reader that
catches another ractor's fill half-done sees a mismatch and searches,
so neither word needs a barrier or an atomic.
lobsters, 15 iterations:
ccall rb_zjit_send_cached_without_block 4,410,274 -> 2,423,746
send_megamorphic_direct 0 -> 1,986,528
send_megamorphic 4,187,398 -> 4,187,397
`--zjit-disable-megamorphic-direct` turns the new path off for A/B runs.
The wider slot doubles the tables' memory, 6.7MB to 13.3MB on lobsters;
they are 98% empty at 512 slots, so `--zjit-send-cache-entries=256` gets
that back with no measurable change in direct dispatches.
[zjit/min port note] Uses asm.new_block() directly: the FrameCaches-inheriting
JITState::new_block() wrapper the original called comes from an excluded commit
(66ff4fd) and master has no per-LIR-block frame caches. state.rs picks up only
gen_jit_entry_call_trampoline from the original's import list; the rest of that list
belongs to excluded commits.1 parent 8928b41 commit c408675
8 files changed
Lines changed: 1004 additions & 28 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6312 | 6312 | | |
6313 | 6313 | | |
6314 | 6314 | | |
| 6315 | + | |
| 6316 | + | |
| 6317 | + | |
| 6318 | + | |
| 6319 | + | |
| 6320 | + | |
| 6321 | + | |
| 6322 | + | |
| 6323 | + | |
| 6324 | + | |
| 6325 | + | |
| 6326 | + | |
| 6327 | + | |
| 6328 | + | |
| 6329 | + | |
| 6330 | + | |
| 6331 | + | |
| 6332 | + | |
| 6333 | + | |
| 6334 | + | |
| 6335 | + | |
| 6336 | + | |
| 6337 | + | |
| 6338 | + | |
| 6339 | + | |
| 6340 | + | |
| 6341 | + | |
| 6342 | + | |
| 6343 | + | |
| 6344 | + | |
| 6345 | + | |
| 6346 | + | |
| 6347 | + | |
| 6348 | + | |
| 6349 | + | |
| 6350 | + | |
| 6351 | + | |
| 6352 | + | |
| 6353 | + | |
| 6354 | + | |
| 6355 | + | |
| 6356 | + | |
| 6357 | + | |
| 6358 | + | |
| 6359 | + | |
| 6360 | + | |
| 6361 | + | |
| 6362 | + | |
| 6363 | + | |
| 6364 | + | |
| 6365 | + | |
| 6366 | + | |
| 6367 | + | |
| 6368 | + | |
| 6369 | + | |
| 6370 | + | |
| 6371 | + | |
| 6372 | + | |
| 6373 | + | |
| 6374 | + | |
| 6375 | + | |
| 6376 | + | |
| 6377 | + | |
| 6378 | + | |
6315 | 6379 | | |
6316 | 6380 | | |
6317 | 6381 | | |
| |||
6326 | 6390 | | |
6327 | 6391 | | |
6328 | 6392 | | |
6329 | | - | |
| 6393 | + | |
6330 | 6394 | | |
6331 | 6395 | | |
6332 | 6396 | | |
| |||
6340 | 6404 | | |
6341 | 6405 | | |
6342 | 6406 | | |
6343 | | - | |
| 6407 | + | |
6344 | 6408 | | |
6345 | 6409 | | |
6346 | | - | |
6347 | | - | |
| 6410 | + | |
| 6411 | + | |
| 6412 | + | |
| 6413 | + | |
| 6414 | + | |
| 6415 | + | |
| 6416 | + | |
| 6417 | + | |
6348 | 6418 | | |
6349 | 6419 | | |
6350 | 6420 | | |
| |||
6407 | 6477 | | |
6408 | 6478 | | |
6409 | 6479 | | |
| 6480 | + | |
| 6481 | + | |
| 6482 | + | |
| 6483 | + | |
| 6484 | + | |
| 6485 | + | |
| 6486 | + | |
| 6487 | + | |
| 6488 | + | |
| 6489 | + | |
| 6490 | + | |
| 6491 | + | |
| 6492 | + | |
| 6493 | + | |
6410 | 6494 | | |
6411 | 6495 | | |
6412 | 6496 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
111 | | - | |
| 111 | + | |
112 | 112 | | |
113 | 113 | | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
114 | 132 | | |
115 | 133 | | |
116 | 134 | | |
117 | 135 | | |
118 | 136 | | |
119 | | - | |
120 | | - | |
| 137 | + | |
| 138 | + | |
121 | 139 | | |
122 | 140 | | |
123 | 141 | | |
124 | 142 | | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
125 | 153 | | |
126 | 154 | | |
127 | 155 | | |
| |||
137 | 165 | | |
138 | 166 | | |
139 | 167 | | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
140 | 187 | | |
141 | 188 | | |
142 | 189 | | |
| |||
0 commit comments