Repository navigation
ffi: cut the cost of crossing the ABI - #60
Merged
Merged
Conversation
The overlap check every call runs was a loop over a stack array: about
360 of the 520 instructions `encode_request` added on top of the core.
`disjoint!` now expands to the pairs themselves at compile time, each
written region against every region after it, never two reads, with no
loop or branch. The rule it checks is the same, and a test compares it
exhaustively with the rule written out plainly, over small addresses,
null, and lengths up to the top of the address space.
- `span_in` checks once that a span's end fits u32, which covers both
casts, instead of converting the offset and the length one by one. A
frame ends at most at PREFIX_LEN + COMLINE_MAX_FRAME_CEILING ==
u32::MAX, so the check never fails on a reachable state.
- `comline_handshake_check` checks `peer_out` for overlap only when it is
given: it's the only memory the call writes.
- `SliceBuf::{new, written, overflowed, clear}` are `#[inline]`, so other
crates (the ABI among them) don't call out for them.
- A `handshake-check-out` bench pair measures `handshake_check` with a
`peer_out`.
Instruction counts, against the base at the same paths: every ABI bench
is lower, none higher; the core benches are unchanged.
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.
Stacked on #59; it needs #59's benches as its base. Retarget it to
mainbefore #59 is merged with--delete-branch.Cuts what the C ABI costs on top of the core. Every ABI call is now cheaper and none costs more. No refusal changes, and the header doesn't change.
What changed
disjoint!) runs on every call. It was a loop over a stack array, about 360 of the 520 instructionsencode_requestadded on top of the core.disjoint_is_the_plain_rulecompares it exhaustively with the rule written out plainly:usize::MAX;<written as<=, and the reads dropped from the recursive arm) each fail that test.span_inchecks once that a span's end fitsu32, which covers both the offset and the length, instead of converting them one by one.PREFIX_LEN + COMLINE_MAX_FRAME_CEILING == u32::MAX.comline_handshake_checkcheckspeer_outfor overlap only when it's given, since it's the only memory the call writes.SliceBuf::{new, written, overflowed, clear}are#[inline], so the ABI and other crates no longer call out for them. The core's benches are unchanged.handshake-check-out:handshake_checkwith apeer_out.Instruction counts (base #59 → this, measured locally at the same paths)
encode-request/datagram@2/message/16encode-request/jsonrpc@1/message/16encode-request/*/65536feed/datagram@2/*feed/jsonrpc@1/message/16encode-reply/*name-hashhandshake-encodehandshake-checkhandshake-check-outAll 104 FFI benches: 0 regressed. All 58 core benches: no change.
Checked locally
cargo test --workspace, plus core with--no-default-features --features alloc,jsonrpc.cargo +nightly miri test -p comline-runtime-ffi --features test-hooks.ffi_feed: 5 min, 1.36M runs, no findings.ffi_vs_core: 5 min, 1.15M runs, no findings.Left alone: the about 87 instructions of UTF-8 validation of a request's name. The ABI promises to refuse an invalid name under every framing.