Skip to content

Commit 06c754d

Browse files
authored
Experimental: add ahead-of-time compilation via weval and PBL. (#883)
1 parent 2be17c7 commit 06c754d

File tree

10 files changed

+556
-228
lines changed

10 files changed

+556
-228
lines changed

.github/workflows/main.yml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ jobs:
395395
runs-on: ubuntu-latest
396396
strategy:
397397
matrix:
398-
profile: [debug, release]
398+
profile: [debug, release, weval]
399399
steps:
400400
- uses: actions/checkout@v3
401401
with:
@@ -416,11 +416,19 @@ jobs:
416416
- name: Build
417417
if: ${{ matrix.profile == 'debug' }}
418418
run: npm run build:starlingmonkey:debug
419+
- name: Build
420+
if: ${{ matrix.profile == 'weval' }}
421+
run: npm run build:starlingmonkey:weval
419422
- uses: actions/upload-artifact@v3
420423
with:
421424
if-no-files-found: error
422425
name: starling-${{ matrix.profile }}
423-
path: starling${{ matrix.profile == 'debug' && '.debug.wasm' || '.wasm' }}
426+
path: starling${{ matrix.profile == 'debug' && '.debug.wasm' || (matrix.profile == 'weval' && '-weval.wasm' || '.wasm') }}
427+
- uses: actions/upload-artifact@v3
428+
if: ${{ matrix.profile == 'weval' }}
429+
with:
430+
name: starling-${{ matrix.profile }}-ic-cache
431+
path: starling-ics.wevalcache
424432

425433
starlingmonkey-run_wpt:
426434
concurrency:
@@ -487,10 +495,12 @@ jobs:
487495
strategy:
488496
matrix:
489497
platform: [viceroy, compute]
490-
profile: [debug, release]
498+
profile: [debug, release, weval]
491499
exclude:
492500
- platform: compute
493501
profile: release
502+
- platform: compute
503+
profile: weval
494504
needs: [starlingmonkey-build]
495505
steps:
496506
- name: Checkout fastly/js-compute-runtime
@@ -532,11 +542,17 @@ jobs:
532542
uses: actions/download-artifact@v3
533543
with:
534544
name: starling-${{ matrix.profile }}
545+
- name: Download Engine (AOT weval cache)
546+
uses: actions/download-artifact@v3
547+
if: ${{ matrix.profile == 'weval'}}
548+
with:
549+
name: starling-${{ matrix.profile }}-ic-cache
550+
535551
- run: yarn install --frozen-lockfile
536552

537553
- name: Yarn install
538554
run: yarn && cd ./integration-tests/js-compute && yarn
539555

540-
- run: SUFFIX_STRING=${{matrix.profile}} node integration-tests/js-compute/test.js ${{ matrix.platform == 'viceroy' && '--local' || '' }} ${{ matrix.profile == 'debug' && '--debug-build' || '' }}
556+
- run: SUFFIX_STRING=${{matrix.profile}} node integration-tests/js-compute/test.js ${{ matrix.platform == 'viceroy' && '--local' || '' }} ${{ matrix.profile == 'weval' && '--aot' || '' }} ${{ matrix.profile == 'debug' && '--debug-build' || '' }}
541557
env:
542558
FASTLY_API_TOKEN: ${{ secrets.FASTLY_API_TOKEN }}

.github/workflows/release-please.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ jobs:
151151

152152
- run: yarn build:starlingmonkey
153153

154+
- run: yarn build:starlingmonkey:weval
155+
154156
- run: npm publish
155157
env:
156158
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

integration-tests/js-compute/test.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ let args = argv.slice(2);
3636

3737
const local = args.includes('--local');
3838
const starlingmonkey = !args.includes('--disable-starlingmonkey');
39+
const aot = args.includes("--aot");
3940
const debugBuild = args.includes('--debug-build');
4041
const filter = args.filter(arg => !arg.startsWith('--'));
4142

@@ -59,7 +60,7 @@ zx.verbose = true;
5960
const branchName = (await zx`git branch --show-current`).stdout.trim().replace(/[^a-zA-Z0-9_-]/g, '_')
6061

6162
const fixture = 'app';
62-
const serviceName = `${fixture}--${branchName}${starlingmonkey ? '--sm' : ''}${process.env.SUFFIX_STRING || ''}`
63+
const serviceName = `${fixture}--${branchName}${starlingmonkey ? '--sm' : ''}${aot ? '--aot' : ''}${process.env.SUFFIX_STRING || ''}`
6364
let domain;
6465
const fixturePath = join(__dirname, 'fixtures', fixture)
6566
let localServer;
@@ -73,6 +74,11 @@ if (!starlingmonkey) {
7374
buildArgs.splice(-1, null, '--disable-starlingmonkey')
7475
config.scripts.build = buildArgs.join(' ')
7576
}
77+
if (aot) {
78+
const buildArgs = config.scripts.build.split(' ');
79+
buildArgs.splice(-1, null, '--enable-experimental-aot');
80+
config.scripts.build = buildArgs.join(' ');
81+
}
7682
if (debugBuild) {
7783
const buildArgs = config.scripts.build.split(' ')
7884
buildArgs.splice(-1, null, '--debug-build')

js-compute-runtime-cli.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { addSdkMetadataField } from "./src/addSdkMetadataField.js";
77

88
const {
99
enablePBL,
10+
enableAOT,
11+
aotCache,
1012
enableExperimentalHighResolutionTimeMethods,
1113
enableExperimentalTopLevelAwait,
1214
starlingMonkey,
@@ -38,7 +40,9 @@ if (version) {
3840
enableExperimentalHighResolutionTimeMethods,
3941
enablePBL,
4042
enableExperimentalTopLevelAwait,
41-
starlingMonkey
43+
starlingMonkey,
44+
enableAOT,
45+
aotCache,
4246
);
4347
await addSdkMetadataField(output, enablePBL, starlingMonkey);
4448
}

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
"types",
1818
"js-compute-runtime-cli.js",
1919
"starling.wasm",
20+
"starling-weval.wasm",
2021
"js-compute-runtime.wasm",
22+
"starling-ics.wevalcache",
2123
"src",
2224
"index.d.ts",
2325
"package.json",
@@ -37,6 +39,7 @@
3739
"build:debug": "DEBUG=true make -j8 -C runtime/js-compute-runtime && cp runtime/js-compute-runtime/js-compute-runtime.wasm .",
3840
"build:starlingmonkey": "./runtime/fastly/build-release.sh",
3941
"build:starlingmonkey:debug": "./runtime/fastly/build-debug.sh",
42+
"build:starlingmonkey:weval": "./runtime/fastly/build-release-weval.sh",
4043
"build:starlingmonkey:debug:info": "./runtime/fastly/build-debug.sh --keep-debug-info",
4144
"format-changelog": "node ci/format-changelog.js CHANGELOG.md"
4245
},
@@ -54,6 +57,7 @@
5457
"dependencies": {
5558
"@bytecodealliance/jco": "^1.3.1",
5659
"@bytecodealliance/wizer": "^3.0.1",
60+
"@cfallin/weval": "^0.2.9",
5761
"acorn": "^8.12.1",
5862
"acorn-walk": "^8.3.3",
5963
"esbuild": "^0.23.0",

runtime/fastly/build-release-weval.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
cd "$(dirname "$0")" || exit 1
3+
RUNTIME_VERSION=$(npm pkg get version --json --prefix=../../ | jq -r)
4+
HOST_API=$(realpath host-api) cmake -B build-release-weval -DCMAKE_BUILD_TYPE=Release -DENABLE_BUILTIN_WEB_FETCH=0 -DENABLE_BUILTIN_WEB_FETCH_FETCH_EVENT=0 -DRUNTIME_VERSION="\"$RUNTIME_VERSION\"" -DWEVAL=ON
5+
cmake --build build-release-weval --parallel 8
6+
mv build-release-weval/starling.wasm/starling.wasm ../../starling-weval.wasm
7+
mv build-release-weval/starling.wasm/starling-ics.wevalcache ../../

src/compileApplicationToWasm.js

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { rmSync } from "node:fs";
66
import { isFile } from "./isFile.js";
77
import { isFileOrDoesNotExist } from "./isFileOrDoesNotExist.js";
88
import wizer from "@bytecodealliance/wizer";
9+
import weval from "@cfallin/weval";
910
import { precompile } from "./precompile.js";
1011
import { enableTopLevelAwait } from "./enableTopLevelAwait.js";
1112
import { bundle } from "./bundle.js";
@@ -21,7 +22,9 @@ export async function compileApplicationToWasm(
2122
enableExperimentalHighResolutionTimeMethods = false,
2223
enablePBL = false,
2324
enableExperimentalTopLevelAwait = false,
24-
starlingMonkey = false
25+
starlingMonkey = false,
26+
enableAOT = false,
27+
aotCache = '',
2528
) {
2629
try {
2730
if (!(await isFile(input))) {
@@ -121,35 +124,68 @@ export async function compileApplicationToWasm(
121124
}
122125

123126
try {
124-
let wizerProcess = spawnSync(
125-
`"${wizer}"`,
126-
[
127-
"--inherit-env=true",
128-
"--allow-wasi",
129-
"--dir=.",
130-
...starlingMonkey ? [`--dir=${dirname(wizerInput)}`] : [],
131-
`--wasm-bulk-memory=true`,
132-
"-r _start=wizer.resume",
133-
`-o="${output}"`,
134-
`"${wasmEngine}"`,
135-
],
136-
{
137-
stdio: [null, process.stdout, process.stderr],
138-
input: wizerInput,
139-
shell: true,
140-
encoding: "utf-8",
141-
env: {
142-
ENABLE_EXPERIMENTAL_HIGH_RESOLUTION_TIME_METHODS:
143-
enableExperimentalHighResolutionTimeMethods ? "1" : "0",
144-
ENABLE_PBL: enablePBL ? "1" : "0",
145-
...process.env,
146-
},
127+
if (enableAOT) {
128+
const wevalBin = await weval();
129+
130+
let wevalProcess = spawnSync(
131+
`"${wevalBin}"`,
132+
[
133+
"weval",
134+
...aotCache ? [`--cache-ro ${aotCache}`] : [],
135+
"--dir .",
136+
...starlingMonkey ? [`--dir ${dirname(wizerInput)}`] : [],
137+
"-w",
138+
`-i "${wasmEngine}"`,
139+
`-o "${output}"`,
140+
],
141+
{
142+
stdio: [null, process.stdout, process.stderr],
143+
input: wizerInput,
144+
shell: true,
145+
encoding: "utf-8",
146+
env: {
147+
ENABLE_EXPERIMENTAL_HIGH_RESOLUTION_TIME_METHODS:
148+
enableExperimentalHighResolutionTimeMethods ? "1" : "0",
149+
ENABLE_PBL: enablePBL ? "1" : "0",
150+
...process.env,
151+
},
152+
}
153+
);
154+
if (wevalProcess.status !== 0) {
155+
throw new Error(`Weval initialization failure`);
147156
}
148-
);
149-
if (wizerProcess.status !== 0) {
150-
throw new Error(`Wizer initialization failure`);
157+
process.exitCode = wevalProcess.status;
158+
} else {
159+
let wizerProcess = spawnSync(
160+
`"${wizer}"`,
161+
[
162+
"--inherit-env=true",
163+
"--allow-wasi",
164+
"--dir=.",
165+
...starlingMonkey ? [`--dir=${dirname(wizerInput)}`] : [],
166+
`--wasm-bulk-memory=true`,
167+
"-r _start=wizer.resume",
168+
`-o="${output}"`,
169+
`"${wasmEngine}"`,
170+
],
171+
{
172+
stdio: [null, process.stdout, process.stderr],
173+
input: wizerInput,
174+
shell: true,
175+
encoding: "utf-8",
176+
env: {
177+
ENABLE_EXPERIMENTAL_HIGH_RESOLUTION_TIME_METHODS:
178+
enableExperimentalHighResolutionTimeMethods ? "1" : "0",
179+
ENABLE_PBL: enablePBL ? "1" : "0",
180+
...process.env,
181+
},
182+
}
183+
);
184+
if (wizerProcess.status !== 0) {
185+
throw new Error(`Wizer initialization failure`);
186+
}
187+
process.exitCode = wizerProcess.status;
151188
}
152-
process.exitCode = wizerProcess.status;
153189
} catch (error) {
154190
console.error(
155191
`Error: Failed to compile JavaScript to Wasm: `,

src/parseInputs.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ export async function parseInputs(cliInputs) {
1111
let enableExperimentalTopLevelAwait = false;
1212
let starlingMonkey = true;
1313
let enablePBL = false;
14+
let enableAOT = false;
1415
let customEngineSet = false;
1516
let wasmEngine = join(__dirname, "../starling.wasm");
17+
let aotCache = join(__dirname, "../starling-ics.wevalcache");
1618
let customInputSet = false;
1719
let input = join(process.cwd(), "bin/index.js");
1820
let customOutputSet = false;
@@ -37,6 +39,10 @@ export async function parseInputs(cliInputs) {
3739
enablePBL = true;
3840
break;
3941
}
42+
case "--enable-experimental-aot": {
43+
enableAOT = true;
44+
break;
45+
}
4046
case "-V":
4147
case "--version": {
4248
return { version: true };
@@ -77,6 +83,14 @@ export async function parseInputs(cliInputs) {
7783
}
7884
break;
7985
}
86+
case "--aot-cache": {
87+
if (isAbsolute(value)) {
88+
aotCache = value;
89+
} else {
90+
aotCache = join(process.cwd(), value);
91+
}
92+
break;
93+
}
8094
default: {
8195
// The reason this is not another `case` and is an `if` using `startsWith`
8296
// is because previous versions of the CLI allowed an arbitrary amount of
@@ -119,10 +133,22 @@ export async function parseInputs(cliInputs) {
119133
}
120134
}
121135
}
136+
137+
if (!starlingMonkey && enableAOT) {
138+
// enableAOT requires StarlingMonkey.
139+
console.log("AOT option is not compatible with pre-StarlingMonkey engine; please use StarlingMonkey.");
140+
process.exit(1);
141+
}
142+
if (!customEngineSet && enableAOT) {
143+
wasmEngine = join(__dirname, "../starling-weval.wasm");
144+
}
145+
122146
return {
123147
enableExperimentalHighResolutionTimeMethods,
124148
enableExperimentalTopLevelAwait,
125149
enablePBL,
150+
enableAOT,
151+
aotCache,
126152
input,
127153
output,
128154
starlingMonkey,

0 commit comments

Comments
 (0)