Skip to content

ffi: reuse libffi call plans - #64958

Open
umuoy1 wants to merge 2 commits into
nodejs:mainfrom
umuoy1:ffi-reuse-call-plans
Open

ffi: reuse libffi call plans#64958
umuoy1 wants to merge 2 commits into
nodejs:mainfrom
umuoy1:ffi-reuse-call-plans

Conversation

@umuoy1

@umuoy1 umuoy1 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Fixes: #64562
Refs: libffi/libffi@3cc6beb

libffi 3.7 introduced reusable call plans that precompute argument placement. Node.js FFI functions have fixed signatures, so this change creates a plan during function preparation and reuses it for generic and SharedBuffer calls on x86-64 System V.

Other platforms, older libffi versions, and allocation failures continue to use ffi_call(). An invocation benchmark is included: it measures the call path for signatures that bypass the V8 Fast API and reach FFIFunction::Invoke(), covering a register-only and a stack-spilled call plan.

Before (ffi_call):

signature ns/call
call_int_callback — (function, i32) → i32 29.2
sum_8_i32 — (i32 × 8) → i32 73.5

After (ffi_call_plan_invoke, plan reused):

signature ns/call
call_int_callback — (function, i32) → i32 10.5
sum_8_i32 — (i32 × 8) → i32 27.1

Precompute a libffi call plan for each fixed signature on x86-64
System V and reuse it from the generic and SharedBuffer invokers. This
avoids repeating argument-placement work for every call.

Continue to use ffi_call() with libffi older than 3.7, on other ABIs,
and when plan allocation fails.

Signed-off-by: umuoy1 <burningdian@gmail.com>
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/ffi
  • @nodejs/performance

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Aug 2, 2026
@codecov

codecov Bot commented Aug 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.42857% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 90.28%. Comparing base (276fe2b) to head (249d729).
⚠️ Report is 32 commits behind head on main.

Files with missing lines Patch % Lines
src/ffi/fast.cc 91.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #64958      +/-   ##
==========================================
- Coverage   90.28%   90.28%   -0.01%     
==========================================
  Files         760      762       +2     
  Lines      247076   247536     +460     
  Branches    46594    46680      +86     
==========================================
+ Hits       223081   223484     +403     
- Misses      15458    15495      +37     
- Partials     8537     8557      +20     
Files with missing lines Coverage Δ
src/node_ffi.cc 70.71% <100.00%> (+0.07%) ⬆️
src/node_ffi.h 72.22% <100.00%> (+10.68%) ⬆️
src/ffi/fast.cc 69.75% <91.66%> (+1.99%) ⬆️

... and 55 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Measure the call path for signatures that bypass the V8 Fast API and
reach FFIFunction::Invoke(), covering a register-only and a
stack-spilled libffi call plan on x86-64 System V. The per-call delta
is the decision-relevant metric for reusable call plans: plan
allocation is a one-time cost that amortizes within a few calls.

Signed-off-by: umuoy1 <burningdian@gmail.com>
@umuoy1
umuoy1 force-pushed the ffi-reuse-call-plans branch from 6d678be to 249d729 Compare August 3, 2026 09:51
@mcollina
mcollina requested review from ShogunPanda and trivikr and removed request for ShogunPanda August 3, 2026 10:31

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 3, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 3, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@trivikr trivikr added the ffi Issues and PRs related to experimental Foreign Function Interface support. label Aug 3, 2026
@trivikr trivikr added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Aug 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++. commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. ffi Issues and PRs related to experimental Foreign Function Interface support. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

libffi reusable call plans

6 participants