Skip to content
Open
Show file tree
Hide file tree
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 Jul 24, 2026
4383835
[autofix.ci] apply automated fixes
autofix-ci[bot] Jul 24, 2026
9bc68f3
Report the coerced number in write* range errors; test and registrati…
Jarred-Sumner Jul 24, 2026
922d63b
Remove writeU_Int8 and the checkBounds export, now unused
Jarred-Sumner Jul 24, 2026
2800801
Move the variable-width read*/write* accessors to native functions too
Jarred-Sumner Jul 24, 2026
f289a67
Remove the now-unused dataView private name and dead var-width helper…
Jarred-Sumner Jul 24, 2026
77ba531
Build against the WebKit preview build for oven-sh/WebKit#330
Jarred-Sumner Jul 24, 2026
c404098
Bump the WebKit preview build (Windows JIT handler merge, write range…
Jarred-Sumner Jul 24, 2026
1fc5e56
Merge branch 'main' into claude/buffer-jit
Jarred-Sumner Jul 24, 2026
af34232
[autofix.ci] apply automated fixes
autofix-ci[bot] Jul 24, 2026
9bb5bd7
Pin the NaN / Infinity write semantics after tier-up
Jarred-Sumner Jul 24, 2026
c24eaa7
Run the buffer JIT tests concurrently; make the bad-receiver case rea…
Jarred-Sumner Jul 24, 2026
e702b53
Trigger the detached-receiver exit through the measured call site
Jarred-Sumner Jul 24, 2026
6382eeb
Bound the accessors by the receiver's element count, trim tier-up loops
Jarred-Sumner Jul 25, 2026
7957227
Bump the WebKit preview build (Int52 length path, review fixes)
Jarred-Sumner Jul 25, 2026
7d218bf
Buffer accessors: Node parity for DataView receivers, var-width offse…
Jarred-Sumner Jul 25, 2026
28491a1
[autofix.ci] apply automated fixes
autofix-ci[bot] Jul 25, 2026
357582d
Bump the WebKit preview build (differential fuzzer, restored Overflow…
Jarred-Sumner Jul 25, 2026
d807f2d
Guard the BigInt writers against DataView receivers as well
Jarred-Sumner Jul 25, 2026
c56e904
Check the offset before the value for one-byte var-width writes
Jarred-Sumner Jul 25, 2026
50bab58
Validate the BigInt value before reporting a DataView receiver
Jarred-Sumner Jul 25, 2026
f871414
Route the BigInt writers' DataView check through their offset validator
Jarred-Sumner Jul 25, 2026
4e3ea85
Port the JSC stress coverage into the Bun test suite
Jarred-Sumner Jul 26, 2026
9ce177c
[autofix.ci] apply automated fixes
autofix-ci[bot] Jul 26, 2026
ea0cf81
Check the offset type before the receiver in the var-width readers
Jarred-Sumner Jul 26, 2026
2a8c837
BigInt writers: validate the value before the receiver, default the o…
Jarred-Sumner Jul 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions bench/snippets/buffer-read-write.mjs
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();
2 changes: 1 addition & 1 deletion scripts/build/deps/webkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* for local mode. Override via `--webkit-version=<hash>` to test a branch.
* From https://github.com/oven-sh/WebKit releases.
*/
export const WEBKIT_VERSION = "549170099226f816a4b204ea1d8fa102fb79eefa";
export const WEBKIT_VERSION = "autobuild-preview-pr-330-8debd979";

/**
* WebKit (JavaScriptCore) — the JS engine.
Expand Down
3 changes: 0 additions & 3 deletions src/js/builtins.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ declare function $controller(): TODO;
declare function $createFIFO(): TODO;
declare function $createUninitializedArrayBuffer(size: number): ArrayBuffer;
declare function $data(): TODO;
declare function $dataView(): TODO;
declare function $decode(): TODO;
declare function $dirname(): TODO;
declare function $disturbed(): TODO;
Expand Down Expand Up @@ -692,8 +691,6 @@ declare function $toClass(fn: Function, name: string, base?: Function | undefine

declare function $min(a: number, b: number): number;

declare function $checkBufferRead(buf: Buffer, offset: number, byteLength: number): undefined;

/**
* Schedules a callback to be invoked as a microtask.
*/
Expand Down
2 changes: 0 additions & 2 deletions src/js/builtins/BunBuiltinNames.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ using namespace JSC;
macro(byobRequest) \
macro(bytes) \
macro(cancel) \
Comment thread
claude[bot] marked this conversation as resolved.
macro(checkBufferRead) \
macro(checks) \
macro(cloneArrayBuffer) \
macro(close) \
Expand All @@ -74,7 +73,6 @@ using namespace JSC;
macro(createUninitializedArrayBuffer) \
macro(ctimeMs) \
macro(data) \
macro(dataView) \
macro(decode) \
macro(dest) \
macro(dirname) \
Expand Down
Loading
Loading