Repository navigation
accel/tcg, target/arm: inline jump-cache probe for A64 indirect branches - #62
Merged
Merged
Conversation
…(-accel tcg,x-inline-lookup) A64 indirect branches (BR/BLR/RET and the PAC forms) and cross-page direct branches now do the jump-cache hit in the generated code: hash the pc, load the cache entry, check its pc and the TB's cs_base, flags and cflags against those of the TB being translated (the CPU state at those exits), check for breakpoints, and jump to its code. A miss or any mismatch calls helper_arm_lookup_tb_ptr as before. Not used where the TB state may differ at the exit (DISAS_UPDATE_NOCHAIN, BTI's BTYPE), with exec logging, or when the TB's cflags are not the vCPU's current ones. -accel tcg,x-inline-lookup=off keeps the helper for every lookup. Android emulator, a13-test microbenchmarks, x-inline-lookup off -> on, median of 5: w1/u1 (hot BL/RET) -46%, w2/u2 (BLR/RET over 4096 targets) -27/-28%, w2s (16384 targets, mostly jump-cache misses) +6%, w4 control +1%. Tests: native_int_check.S test 9 calls a function first at EL1 (its EL1 TB goes into the jump cache) and then at EL0, where its MRS TPIDR_EL1 must trap: removing the probe's state checks makes it fail. native_int_gen.py adds BR and BLR/RET to the random programs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nd the second jump-cache probe On a miss, the generated code calls the new helper_lookup_tb_ptr_miss() with the pc and the TB state it already has, which goes straight to the slow lookup (breakpoints, hash table, jump-cache fill) instead of helper_arm_lookup_tb_ptr(), which recomputed the state from the CPU and probed the jump cache again. This takes back what the inline probe added to lookups that miss (w2s, 16384 targets: +6% before). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dylanneve1
force-pushed
the
perf/inline-lookup
branch
from
October 23, 2026 11:34
21825f8 to
2b0d4a4
Compare
dylanneve1
marked this pull request as ready for review
October 23, 2026 11:34
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A64 indirect branches (BR/BLR/RET and the PAC forms) and cross-page direct branches now do the jump-cache hit inline in the generated code:
A hit costs about 33 host instructions with no call. Through
helper_arm_lookup_tb_ptrit was about 69 plus a call.Misses: the generated code calls a new
helper_lookup_tb_ptr_miss()with the pc and the TB state it already has. That goes straight to the slow lookup, without recomputing the state or probing the jump cache a second time, so lookups that miss don't get slower.Where it doesn't apply:
DISAS_UPDATE_NOCHAIN, or BTI's BTYPE);It's on by default;
-accel tcg,x-inline-lookup=offkeeps the helper for every lookup.Numbers
Android emulator
emulator-5554, a13-test microbenchmarks, the same binary with x-inline-lookup off → on, median of 5:Restore boot (iOS 14 restore, -smp 4, 8 interleaved runs per variant): median
waiting_hostwent from 9.70 s to 9.45 s (−2.6%) and host CPU from 7.30 s to 7.25 s. All boots reachedwaiting_hostwith no panic.Tests
run-a13-tests.pypasses 41/41 on an M1 macOS build.native_int_check.Stest 9 calls a function at EL1 first, so its EL1 TB is in the jump cache, and then from EL0, where its MRS TPIDR_EL1 must trap. With the probe's state checks removed, the test fails as intended.native_int_gen.pynow also emits BR and BLR/RET. Soaks with 0 mismatches against TCG and the host CPU: 300 seeds on this change alone, then 100 seeds after rebasing onto native-int: SIMD&FP loads/stores and literal loads stay inside regions #61.#55 (32768-entry jump cache) on top
waiting_host(8 runs)The cost is 512 KiB of jump cache per vCPU instead of 256 KiB. The emulator runs on M1, so the open question from #55 (the Pixel's smaller L2) still needs a phone A/B.
🤖 Generated with Claude Code