Skip to content

Commit 510e017

Browse files
committed
Move the loading code to shared prerunCode helpers
There's now three helpers `getBinary`/`getString`/`dynamicImport` that help fetch resources from blobs/paths in the various `benchmark.js`'s `init` functions. All of the preloads in JetStream have been switched to using one of those, thus an AsyncBenchmark with the exception of WasmLegacyBenchmark (aka tfjs-wasm). Lastly, there's also no more special casing for the wasmBinary preload, instead it's set in each relevant `benchmark.js`'s `init` function.
1 parent bcfccc3 commit 510e017

File tree

14 files changed

+103
-100
lines changed

14 files changed

+103
-100
lines changed

8bitbench/benchmark.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,8 @@ class Benchmark {
3838
romBinary;
3939

4040
async init() {
41-
if (isInBrowser) {
42-
let response = await fetch(romBinary);
43-
this.romBinary = new Int8Array(await response.arrayBuffer());
44-
} else {
45-
this.romBinary = new Int8Array(read(romBinary, "binary"));
46-
}
41+
Module.wasmBinary = await getBinary(wasmBinary);
42+
this.romBinary = await getBinary(romBinary);
4743
}
4844

4945
async runIteration() {

ARES-6/Babylon/benchmark.js

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2025 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -26,8 +26,7 @@
2626
"use strict";
2727

2828
class Benchmark {
29-
constructor(verbose = 0)
30-
{
29+
async init(verbose = 0) {
3130
let sources = [];
3231

3332
const files = [
@@ -37,23 +36,8 @@ class Benchmark {
3736
, [babylonBlob, {sourceType: "module"}]
3837
];
3938

40-
for (let [file, options] of files) {
41-
function appendSource(s) {
42-
sources.push([file, s, options]);
43-
}
44-
45-
let s;
46-
if (isInBrowser) {
47-
let request = new XMLHttpRequest();
48-
request.open('GET', file, false);
49-
request.send(null);
50-
if (!request.responseText.length)
51-
throw new Error("Expect non-empty sources");
52-
appendSource(request.responseText);
53-
} else {
54-
appendSource(read(file));
55-
}
56-
}
39+
for (let [file, options] of files)
40+
sources.push([file, await getString(file), options]);
5741

5842
this.sources = sources;
5943
}

Dart/benchmark.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -261,20 +261,9 @@ class Benchmark {
261261
async init() {
262262
// The generated JavaScript code from dart2wasm is an ES module, which we
263263
// can only load with a dynamic import (since this file is not a module.)
264-
// TODO: Support ES6 modules in the driver instead of this one-off solution.
265-
// This probably requires a new `Benchmark` field called `modules` that
266-
// is a map from module variable name (which will hold the resulting module
267-
// namespace object) to relative module URL, which is resolved in the
268-
// `preRunnerCode`, similar to this code here.
269264

270-
try {
271-
this.dart2wasmJsModule = await import(jsModule);
272-
} catch {
273-
// In shells, relative imports require different paths, so try with and
274-
// without the "./" prefix (e.g., JSC requires it).
275-
if (!isInBrowser)
276-
this.dart2wasmJsModule = await import(jsModule.slice("./".length))
277-
}
265+
Module.wasmBinary = await getBinary(wasmBinary);
266+
this.dart2wasmJsModule = await dynamicImport(jsModule);
278267
}
279268

280269
async runIteration() {

JetStreamDriver.js

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,6 @@ class Benchmark {
994994
return this._resourcesPromise;
995995

996996
this.preloads = [];
997-
this.blobs = [];
998997

999998
if (isInBrowser) {
1000999
this._resourcesPromise = Promise.resolve();
@@ -1137,6 +1136,51 @@ class DefaultBenchmark extends Benchmark {
11371136
}
11381137

11391138
class AsyncBenchmark extends DefaultBenchmark {
1139+
get prerunCode() {
1140+
let str = "";
1141+
// FIXME: It would be nice if these were available to any benchmark not just async ones but since these functions
1142+
// are async they would only work in a context where the benchmark is async anyway. Long term, we should do away
1143+
// with this class and make all benchmarks async.
1144+
if (isInBrowser) {
1145+
str += `
1146+
async function getBinary(blobURL) {
1147+
const response = await fetch(blobURL);
1148+
return new Int8Array(await response.arrayBuffer());
1149+
}
1150+
1151+
async function getString(blobURL) {
1152+
const response = await fetch(blobURL);
1153+
return response.text();
1154+
}
1155+
1156+
async function dynamicImport(blobURL) {
1157+
return await import(blobURL);
1158+
}
1159+
`;
1160+
} else {
1161+
str += `
1162+
async function getBinary(path) {
1163+
return new Int8Array(read(path, "binary"));
1164+
}
1165+
1166+
async function getString(path) {
1167+
return read(path);
1168+
}
1169+
1170+
async function dynamicImport(path) {
1171+
try {
1172+
return await import(path);
1173+
} catch (e) {
1174+
// In shells, relative imports require different paths, so try with and
1175+
// without the "./" prefix (e.g., JSC requires it).
1176+
return await import(path.slice("./".length))
1177+
}
1178+
}
1179+
`;
1180+
}
1181+
return str;
1182+
}
1183+
11401184
get runnerCode() {
11411185
return `
11421186
async function doRun() {
@@ -1174,7 +1218,7 @@ class AsyncBenchmark extends DefaultBenchmark {
11741218
// part of a larger project's build system or a wasm benchmark compiled from a language that doesn't compile with emcc.
11751219
class WasmEMCCBenchmark extends AsyncBenchmark {
11761220
get prerunCode() {
1177-
return `
1221+
let str = `
11781222
let verbose = false;
11791223
11801224
let globalObject = this;
@@ -1204,43 +1248,20 @@ class WasmEMCCBenchmark extends AsyncBenchmark {
12041248
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
12051249
},
12061250
};
1251+
12071252
globalObject.Module = Module;
1253+
${super.prerunCode};
12081254
`;
1209-
}
12101255

1211-
// This is in runnerCode rather than prerunCode because prerunCode isn't currently structured to be async by default.
1212-
get runnerCode() {
1213-
let str = `(async function doRunWrapper() {`
1214-
if (isInBrowser) {
1215-
str += `
1216-
async function getBinary(key, blobURL) {
1217-
const response = await fetch(blobURL);
1218-
Module[key] = new Int8Array(await response.arrayBuffer());
1219-
}
1220-
`;
1221-
} else
1256+
if (isSpiderMonkey) {
12221257
str += `
12231258
// Needed because SpiderMonkey shell doesn't have a setTimeout.
12241259
Module.setStatus = null;
12251260
Module.monitorRunDependencies = null;
1226-
function getBinary(key, path) {
1227-
Module[key] = new Int8Array(read(path, "binary"));
1228-
}
12291261
`;
1230-
1231-
for (let [ preloadKey, blobURLOrPath ] of this.preloads) {
1232-
if (preloadKey == "wasmBinary") {
1233-
str += `await getBinary("${preloadKey}", "${blobURLOrPath}");\n`
1234-
break;
1235-
}
12361262
}
12371263

1238-
str += super.runnerCode;
1239-
1240-
str += "\n})().catch((error) => { top.currentReject(error); });"
1241-
12421264
return str;
1243-
12441265
}
12451266
};
12461267

@@ -1576,7 +1597,7 @@ let BENCHMARKS = [
15761597
iterations: 60,
15771598
tags: ["ARES"],
15781599
}),
1579-
new DefaultBenchmark({
1600+
new AsyncBenchmark({
15801601
name: "Babylon",
15811602
files: [
15821603
"./ARES-6/Babylon/index.js"
@@ -1612,7 +1633,7 @@ let BENCHMARKS = [
16121633
tags: ["CDJS"],
16131634
}),
16141635
// CodeLoad
1615-
new DefaultBenchmark({
1636+
new AsyncBenchmark({
16161637
name: "first-inspector-code-load",
16171638
files: [
16181639
"./code-load/code-first-load.js"
@@ -1622,7 +1643,7 @@ let BENCHMARKS = [
16221643
},
16231644
tags: ["CodeLoad"],
16241645
}),
1625-
new DefaultBenchmark({
1646+
new AsyncBenchmark({
16261647
name: "multi-inspector-code-load",
16271648
files: [
16281649
"./code-load/code-multi-load.js"

code-load/code-first-load.js

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,8 @@
2525

2626
let indirectEval = eval;
2727
class Benchmark {
28-
constructor(iterations) {
29-
30-
let inspectorText;
31-
if (isInBrowser) {
32-
let request = new XMLHttpRequest();
33-
request.open('GET', inspectorPayloadBlob, false);
34-
request.send(null);
35-
if (!request.responseText.length)
36-
throw new Error("Expect non-empty sources");
37-
38-
inspectorText = request.responseText;
39-
} else
40-
inspectorText = readFile(inspectorPayloadBlob);
41-
42-
this.inspectorText = `let _____top_level_____ = ${Math.random()}; ${inspectorText}`;
28+
async init() {
29+
this.inspectorText = `let _____top_level_____ = ${Math.random()}; ${await getString(inspectorPayloadBlob)}`;
4330

4431
this.index = 0;
4532
}

code-load/code-multi-load.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,8 @@
2525

2626
let indirectEval = eval;
2727
class Benchmark {
28-
constructor(iterations) {
29-
30-
let inspectorText;
31-
if (isInBrowser) {
32-
let request = new XMLHttpRequest();
33-
request.open('GET', inspectorPayloadBlob, false);
34-
request.send(null);
35-
if (!request.responseText.length)
36-
throw new Error("Expect non-empty sources");
37-
inspectorText = request.responseText;
38-
} else
39-
inspectorText = readFile(inspectorPayloadBlob);
40-
41-
this.inspectorText = `let _____top_level_____ = ${Math.random()}; ${inspectorText}`;
28+
async init() {
29+
this.inspectorText = `let _____top_level_____ = ${Math.random()}; ${await getString(inspectorPayloadBlob)}`;
4230
this.index = 0;
4331
}
4432

sqlite3/benchmark.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// Copyright 2024 the V8 project authors. All rights reserved.
2+
// Copyright 2025 Apple Inc. All rights reserved.
23
// Use of this source code is governed by a BSD-style license that can be
34
// found in the LICENSE file.
45

@@ -51,6 +52,10 @@ delete globalThis.FileSystemHandle;
5152
class Benchmark {
5253
sqlite3Module;
5354

55+
async init() {
56+
Module.wasmBinary = await getBinary(wasmBinary);
57+
}
58+
5459
async runIteration() {
5560
if (!this.sqlite3Module) {
5661
// Defined in the generated SQLite JavaScript code.

wasm/HashSet/benchmark.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
// Copyright 2025 the V8 project authors. All rights reserved.
2+
// Copyright 2025 Apple Inc. All rights reserved.
23
// Use of this source code is governed by a BSD-style license that can be
34
// found in the LICENSE file.
45

56
class Benchmark {
7+
async init() {
8+
Module.wasmBinary = await getBinary(wasmBinary);
9+
}
10+
611
async runIteration() {
712
if (!Module._main)
813
await setupModule(Module);

wasm/TSF/benchmark.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2024 Apple Inc. All rights reserved.
2+
* Copyright (C) 2024-2025 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -24,6 +24,10 @@
2424
*/
2525

2626
class Benchmark {
27+
async init() {
28+
Module.wasmBinary = await getBinary(wasmBinary);
29+
}
30+
2731
async runIteration() {
2832
if (!Module._runIteration)
2933
await setupModule(Module);

wasm/argon2/benchmark.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ const version = 0x13;
7676
const saltLength = 12;
7777

7878
class Benchmark {
79+
async init() {
80+
Module.wasmBinary = await getBinary(wasmBinary);
81+
}
82+
7983
async runIteration() {
8084
// Instantiate the Wasm module before the first run.
8185
if (!Module._argon2_hash) {

0 commit comments

Comments
 (0)