Repository navigation
Conversation
Replace the allocating UTF-8 fast call with a fast binding for sequential one-byte strings. Its slow fallback only returns a Smi sentinel. JavaScript sends rejected strings to a separate regular binding that can flatten strings and handle lazy deoptimization. Both native callbacks used by the fast API avoid JS-heap allocation. Add GC regression and string-representation coverage, including optimized fast acceptance and rejection checks. Fixes: nodejs#66870 Refs: nodejs#67134 Assisted-by: Codex Signed-off-by: Robert Nagy <ronagy@icloud.com>
There was a problem hiding this comment.
🔵 Needs a closer look
V8-aware maintainer review and supported-platform GC-stress CI are needed to validate the allocation-free callback/fallback contract and fast-call lazy-deoptimization behavior.
No open issues 🎉
What changed in this PR
This PR addresses the Buffer.byteLength() abort reported in #66870 while preserving a fast UTF-8 byte-length path for sequential one-byte strings. Rejected strings use a separate regular binding call so allocating string handling avoids the unsupported fast-call deoptimization path.
Changes:
- Restricts the native fast callback to one-byte strings and makes its fallback return
-1without inspecting the string. - Adds a JavaScript wrapper and binding type declaration for the separate fast path.
- Adds coverage for optimized acceptance and rejection, string representations, and garbage-collection-triggered deoptimization.
| File | Description |
|---|---|
typings/internalBinding/buffer.d.ts |
Declares the new fast byte-length binding. |
test/parallel/test-buffer-bytelength-strings.js |
Checks byte lengths across string representations before and after optimization. |
test/parallel/test-buffer-bytelength-safe-fast.js |
Tests fast-path acceptance, rejection, and public API results. |
test/parallel/test-buffer-bytelength-gc.js |
Adds regression coverage for deoptimization during string flattening. |
src/node_buffer.cc |
Implements the restricted fast callback and non-allocating sentinel fallback. |
lib/buffer.js |
Routes rejected fast calls to the regular UTF-8 binding. |
Review effort: Balanced
ronag
marked this pull request as ready for review
October 30, 2026 08:20
ronag
marked this pull request as draft
October 30, 2026 08:24
Keep the existing loop unrolling, variable names and scalar tail. Limit the fast-path changes to the safe input and fallback contract. Assisted-by: Codex Signed-off-by: Robert Nagy <ronagy@icloud.com>
ronag
marked this pull request as ready for review
October 30, 2026 08:38
Collaborator
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #67136 +/- ##
==========================================
+ Coverage 90.67% 90.69% +0.01%
==========================================
Files 797 797
Lines 278806 278803 -3
Branches 53621 53619 -2
==========================================
+ Hits 252813 252861 +48
+ Misses 16341 16305 -36
+ Partials 9652 9637 -15
🚀 New features to boost your workflow:
|
anonrig
approved these changes
Oct 30, 2026
addaleax
approved these changes
Oct 30, 2026
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.
Alternative to #67134. This is a
standalone change against
main; it does not depend on that PR.Keep a fast UTF-8 byte-length path for sequential one-byte strings.
The fast binding's slow fallback returns the Smi sentinel
-1withoutreading or flattening the string. JavaScript then calls the regular
binding separately. Both the fast callback and its fallback avoid JS-heap
allocation; allocating string handling uses an ordinary API continuation.
Validation on Linux x64, GCC 14.2.0, release builds of v28.0.0-pre:
44bd1bfa65f. The local regular-callback baseline35cf29a820ais main250037174eewith the removal fix from buffer: avoid fast API calls when computing UTF-8 byte length #67134,used only for the benchmark comparison.
fallback aborts both the direct and HTTP reproducers in 3/3 runs each.
show actual lazy deoptimization after weak objects are cleared, followed
by normal completion, including
end()andmaybePrepareFinalChunk().explicit optimized fast-acceptance and rejection checks.
string-representation corpus before and after optimization.
import, C++ formatting and whitespace checks pass.
Benchmark tradeoff versus the regular-callback baseline, ten alternating
runs per binary on one fixed logical CPU, two million calls per case:
Values are throughput changes with 95% confidence intervals in percentage
points. The repeated one-byte strings take the fallback. Eligible flat
inputs improve, while rejected inputs pay for the additional call.
Latin-1 and base64 encoding controls were also measured; raw results cover
27 configurations and 540 samples. Four comparisons remain significant
at 5% after the benchmark tool's Holm-Bonferroni adjustment.
Refs: #66870
AI assistance: Codex helped prepare the implementation and tests.