Skip to content

Commit

Permalink
Support weval-based ahead-of-time compilation of JavaScript.
Browse files Browse the repository at this point in the history
When the `WEVAL` option is turned on (`cmake -DWEVAL=ON`), this PR adds:

- Integration to the CMake machinery to fetch a PBL+weval-ified version
  of SpiderMonkey artifacts;
- Likewise, to fetch weval binaries;
- A rule to pre-build a compilation cache of IC bodies specific to the
  StarlingMonkey build, so weval can use this cache and spend time only
  on user-provided code on first run;
- Integration in `componentize.sh`.

When built with:

```
$ mkdir build/; cd build/
$ cmake .. -DCMAKE_BUILD_TYPE=Release -DUSE_WASM_OPT=OFF -DWEVAL=ON
$ make
```

We can then do:

```
$ build/componentize.sh file.js --aot -o file.wasm
$ wasmtime serve -S cli=y file.wasm
```

Using the Richards Octane benchmark adapted slightly with a `main()` for
the HTTP server world [1], I get the following results:

```
%  build/componentize.sh
richards.js --aot -o weval.wasm
Componentizing richards.js into weval.wasm
[ verbose weval progress output ]

% wasmtime serve -S cli=y weval.wasm
Serving HTTP on http://0.0.0.0:8080/
stdout [0] :: Log: Richards: 676
stdout [0] :: Log: ----
stdout [0] :: Log: Score (version 9): 676

% wasmtime serve -S cli=y base.wasm
Serving HTTP on http://0.0.0.0:8080/
stdout [0] :: Log: Richards: 189
stdout [0] :: Log: ----
stdout [0] :: Log: Score (version 9): 189
```

[1]: https://gist.github.com/cfallin/4b18da12413e93f7e88568a92d09e4b7
  • Loading branch information
cfallin committed Jul 29, 2024
1 parent e5fe814 commit 57c9b75
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 14 deletions.
43 changes: 35 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ include("init-corrosion")
include("wasm-tools")
include("binaryen")
include("wizer")
include("weval")
include("wasmtime")

include("fmt")
Expand Down Expand Up @@ -90,9 +91,25 @@ endif()

target_link_libraries(starling.wasm PRIVATE host_api extension_api builtins spidermonkey rust-url)

# build a compilation cache of ICs
if(WEVAL)
include("weval")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/null.js "function main() {}")
add_custom_target(
starling-ics.wevalcache
ALL
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND rm -f starling-ics.wevalcache
COMMAND echo ./null.js | ${WEVAL_BIN} weval --dir . --show-stats --cache starling-ics.wevalcache -w -i starling.wasm -o /dev/null
DEPENDS starling.wasm
VERBATIM
)
set(WEVAL_CACHE_FILE "starling-ics.wevalcache")
endif()

set(RUNTIME_FILE "starling.wasm")
set(ADAPTER_FILE "preview1-adapter.wasm")
configure_file("componentize.sh" "${CMAKE_CURRENT_BINARY_DIR}/componentize.sh" COPYONLY)
configure_file("componentize.sh" "${CMAKE_CURRENT_BINARY_DIR}/componentize.sh" @ONLY)
configure_file(${ADAPTER} "${CMAKE_CURRENT_BINARY_DIR}/${ADAPTER_FILE}" COPYONLY)
configure_file(spin.toml spin.toml COPYONLY)

Expand All @@ -105,13 +122,23 @@ function(componentize OUTPUT)
list(JOIN ARG_SOURCES " " SOURCES)
get_target_property(RUNTIME_DIR starling.wasm BINARY_DIR)

add_custom_command(
OUTPUT ${OUTPUT}.wasm
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E env "PATH=${WASM_TOOLS_DIR};${WIZER_DIR};$ENV{PATH}" ${RUNTIME_DIR}/componentize.sh ${SOURCES} -o ${OUTPUT}.wasm
DEPENDS ${ARG_SOURCES} ${RUNTIME_DIR}/componentize.sh starling.wasm
VERBATIM
)
if(WEVAL)
add_custom_command(
OUTPUT ${OUTPUT}.wasm
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E env "PATH=${WASM_TOOLS_DIR};${WEVAL_DIR};$ENV{PATH}" ${RUNTIME_DIR}/componentize.sh ${SOURCES} --aot -o ${OUTPUT}.wasm
DEPENDS ${ARG_SOURCES} ${RUNTIME_DIR}/componentize.sh starling.wasm starling-ics.wevalcache
VERBATIM
)
else()
add_custom_command(
OUTPUT ${OUTPUT}.wasm
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E env "PATH=${WASM_TOOLS_DIR};${WIZER_DIR};$ENV{PATH}" ${RUNTIME_DIR}/componentize.sh ${SOURCES} -o ${OUTPUT}.wasm
DEPENDS ${ARG_SOURCES} ${RUNTIME_DIR}/componentize.sh starling.wasm
VERBATIM
)
endif()
add_custom_target(${OUTPUT} DEPENDS ${OUTPUT}.wasm)
endfunction()

Expand Down
10 changes: 9 additions & 1 deletion cmake/spidermonkey.cmake
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
set(SM_REV ffbf1c4641440e74174199def6558c710b3ac323)
set(SM_REV bbaee9532ff88b38c31c7f38d0aba1204a6aa9d6)

if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(SM_BUILD_TYPE debug)
else()
set(SM_BUILD_TYPE release)
endif()
set(SM_BUILD_TYPE_DASH ${SM_BUILD_TYPE})

option(WEVAL "Build with a SpiderMonkey variant that supports weval-based AOT compilation" OFF)

if (WEVAL)
set(SM_BUILD_TYPE_DASH "${SM_BUILD_TYPE}-weval")
set(SM_BUILD_TYPE "${SM_BUILD_TYPE}_weval")
endif()

# If the developer has specified an alternate local set of SpiderMonkey
# artifacts, use them. This allows for local/in-tree development without
Expand Down
6 changes: 6 additions & 0 deletions cmake/weval.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(WEVAL_VERSION v0.2.6)

set(WEVAL_URL https://github.com/cfallin/weval/releases/download/${WEVAL_VERSION}/weval-${WEVAL_VERSION}-${HOST_ARCH}-${HOST_OS}.tar.xz)
CPMAddPackage(NAME weval URL ${WEVAL_URL} DOWNLOAD_ONLY TRUE)
set(WEVAL_DIR ${CPM_PACKAGE_weval_SOURCE_DIR})
set(WEVAL_BIN ${WEVAL_DIR}/weval)
23 changes: 18 additions & 5 deletions componentize.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

wizer="${WIZER:-wizer}"
wasm_tools="${WASM_TOOLS:-wasm-tools}"
weval="${WEVAL:-@WEVAL_BIN@}"

usage() {
echo "Usage: $(basename "$0") [input.js] [-o output.wasm]"
echo "Usage: $(basename "$0") [input.js] [--aot] [-o output.wasm]"
echo " Providing an input file but no output uses the input base name with a .wasm extension"
echo " Providing an output file but no input creates a component without running any top-level script"
exit 1
Expand All @@ -19,6 +20,7 @@ fi

IN_FILE=""
OUT_FILE=""
AOT=0

while [ $# -gt 0 ]
do
Expand All @@ -27,6 +29,10 @@ do
OUT_FILE="$2"
shift 2
;;
--aot)
AOT=1
shift
;;
*)
if [ -n "$IN_FILE" ] && [ -z "$OUT_FILE" ] && [ $# -eq 1 ]
then
Expand Down Expand Up @@ -62,8 +68,15 @@ else
echo "Creating runtime-script component $OUT_FILE"
fi


echo "$IN_FILE" | WASMTIME_BACKTRACE_DETAILS=1 $wizer --allow-wasi --wasm-bulk-memory true \
--inherit-stdio true --inherit-env true $PREOPEN_DIR -o "$OUT_FILE" \
-- "$(dirname "$0")/starling.wasm"
if [[ $AOT -ne 0 ]]; then
echo "$IN_FILE" | WASMTIME_BACKTRACE_DETAILS=1 $weval weval -w $PREOPEN_DIR \
--cache-ro "$(dirname "$0")/starling-ics.wevalcache" \
--show-stats \
-o "$OUT_FILE" \
-i "$(dirname "$0")/starling.wasm"
else
echo "$IN_FILE" | WASMTIME_BACKTRACE_DETAILS=1 $wizer --allow-wasi --wasm-bulk-memory true \
--inherit-stdio true --inherit-env true $PREOPEN_DIR -o "$OUT_FILE" \
-- "$(dirname "$0")/starling.wasm"
fi
$wasm_tools component new -v --adapt "wasi_snapshot_preview1=$(dirname "$0")/preview1-adapter.wasm" --output "$OUT_FILE" "$OUT_FILE"

0 comments on commit 57c9b75

Please sign in to comment.