-
Notifications
You must be signed in to change notification settings - Fork 5k
Make Buffer read*/write* native functions with a DFG/FTL intrinsic #35343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Jarred-Sumner
wants to merge
26
commits into
main
Choose a base branch
from
claude/buffer-jit
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,599
−829
Open
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
9bb8897
Make Buffer read*/write* native functions with a DFG/FTL intrinsic
Jarred-Sumner 4383835
[autofix.ci] apply automated fixes
autofix-ci[bot] 9bc68f3
Report the coerced number in write* range errors; test and registrati…
Jarred-Sumner 922d63b
Remove writeU_Int8 and the checkBounds export, now unused
Jarred-Sumner 2800801
Move the variable-width read*/write* accessors to native functions too
Jarred-Sumner f289a67
Remove the now-unused dataView private name and dead var-width helper…
Jarred-Sumner 77ba531
Build against the WebKit preview build for oven-sh/WebKit#330
Jarred-Sumner c404098
Bump the WebKit preview build (Windows JIT handler merge, write range…
Jarred-Sumner 1fc5e56
Merge branch 'main' into claude/buffer-jit
Jarred-Sumner af34232
[autofix.ci] apply automated fixes
autofix-ci[bot] 9bb5bd7
Pin the NaN / Infinity write semantics after tier-up
Jarred-Sumner c24eaa7
Run the buffer JIT tests concurrently; make the bad-receiver case rea…
Jarred-Sumner e702b53
Trigger the detached-receiver exit through the measured call site
Jarred-Sumner 6382eeb
Bound the accessors by the receiver's element count, trim tier-up loops
Jarred-Sumner 7957227
Bump the WebKit preview build (Int52 length path, review fixes)
Jarred-Sumner 7d218bf
Buffer accessors: Node parity for DataView receivers, var-width offse…
Jarred-Sumner 28491a1
[autofix.ci] apply automated fixes
autofix-ci[bot] 357582d
Bump the WebKit preview build (differential fuzzer, restored Overflow…
Jarred-Sumner d807f2d
Guard the BigInt writers against DataView receivers as well
Jarred-Sumner c56e904
Check the offset before the value for one-byte var-width writes
Jarred-Sumner 50bab58
Validate the BigInt value before reporting a DataView receiver
Jarred-Sumner f871414
Route the BigInt writers' DataView check through their offset validator
Jarred-Sumner 4e3ea85
Port the JSC stress coverage into the Bun test suite
Jarred-Sumner 9ce177c
[autofix.ci] apply automated fixes
autofix-ci[bot] ea0cf81
Check the offset type before the receiver in the var-width readers
Jarred-Sumner 2a8c837
BigInt writers: validate the value before the receiver, default the o…
Jarred-Sumner File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| // Buffer.prototype.read* / write* — the fixed-width accessors that JSC JIT-compiles into | ||
| // bounds-checked loads/stores (see JSBuffer.cpp / JavaScriptCore BufferAccessorRegistry). | ||
| // | ||
| // Three shapes: | ||
| // - a tight loop over one buffer (constant offset): mostly measures call/loop overhead | ||
| // - a loop over increasing offsets on one buffer: the load/store + bounds check per iteration | ||
| // - one access on each of many distinct buffers: previously paid a hidden DataView allocation | ||
| // plus a structure transition per buffer | ||
| import { bench, group, run } from "../runner.mjs"; | ||
|
|
||
| const size = 4096; | ||
| const buf = Buffer.alloc(size); | ||
| for (let i = 0; i < size; i++) buf[i] = (i * 37 + 11) & 0xff; | ||
|
|
||
| const many = Array.from({ length: 1024 }, () => Buffer.alloc(64)); | ||
|
|
||
| group("constant offset (10 accesses per iteration)", () => { | ||
| bench("readInt32LE(0)", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < 10; i++) s += buf.readInt32LE(0); | ||
| return s; | ||
| }); | ||
| bench("writeInt32LE(v, 0)", () => { | ||
| for (let i = 0; i < 10; i++) buf.writeInt32LE(i, 0); | ||
| }); | ||
| }); | ||
|
|
||
| group("varying offset over one buffer", () => { | ||
| bench("readInt8", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < size; i++) s += buf.readInt8(i); | ||
| return s; | ||
| }); | ||
| bench("readUInt8", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < size; i++) s += buf.readUInt8(i); | ||
| return s; | ||
| }); | ||
| bench("readInt16BE", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < size; i += 2) s += buf.readInt16BE(i); | ||
| return s; | ||
| }); | ||
| bench("readInt32LE", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < size; i += 4) s += buf.readInt32LE(i); | ||
| return s; | ||
| }); | ||
| bench("readUInt32BE", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < size; i += 4) s += buf.readUInt32BE(i); | ||
| return s; | ||
| }); | ||
| bench("readFloatLE", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < size; i += 4) s += buf.readFloatLE(i); | ||
| return s; | ||
| }); | ||
| bench("readDoubleLE", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < size; i += 8) s += buf.readDoubleLE(i); | ||
| return s; | ||
| }); | ||
| bench("readBigInt64LE", () => { | ||
| let s = 0n; | ||
| for (let i = 0; i < size; i += 8) s += buf.readBigInt64LE(i); | ||
| return s; | ||
| }); | ||
| bench("writeUInt8", () => { | ||
| for (let i = 0; i < size; i++) buf.writeUInt8(i & 0xff, i); | ||
| }); | ||
| bench("writeInt16BE", () => { | ||
| for (let i = 0; i < size; i += 2) buf.writeInt16BE(i, i); | ||
| }); | ||
| bench("writeInt32LE", () => { | ||
| for (let i = 0; i < size; i += 4) buf.writeInt32LE(i, i); | ||
| }); | ||
| bench("writeUInt32BE", () => { | ||
| for (let i = 0; i < size; i += 4) buf.writeUInt32BE(i, i); | ||
| }); | ||
| bench("writeFloatLE", () => { | ||
| for (let i = 0; i < size; i += 4) buf.writeFloatLE(i + 0.5, i); | ||
| }); | ||
| bench("writeDoubleLE", () => { | ||
| for (let i = 0; i < size; i += 8) buf.writeDoubleLE(i + 0.5, i); | ||
| }); | ||
| }); | ||
|
|
||
| group("one access on each of 1024 buffers", () => { | ||
| bench("readInt32LE", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < many.length; i++) s += many[i].readInt32LE(0); | ||
| return s; | ||
| }); | ||
| bench("writeInt32LE", () => { | ||
| for (let i = 0; i < many.length; i++) many[i].writeInt32LE(i, 0); | ||
| }); | ||
| bench("readDoubleLE", () => { | ||
| let s = 0; | ||
| for (let i = 0; i < many.length; i++) s += many[i].readDoubleLE(0); | ||
| return s; | ||
| }); | ||
| }); | ||
|
|
||
| await run(); |
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.