From 51975595db77acbd6e8965cb16af3838d9ad28de Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 29 Oct 2024 16:08:43 -0700 Subject: [PATCH] feat: performance builtin support (#150) --- CMakeLists.txt | 1 + Makefile | 2 +- embedding/embedding.cpp | 13 ++++++++++++- embedding/embedding.h | 2 ++ src/componentize.js | 1 + test/builtins/performance-disabled.js | 19 ++++++++++++++++++ test/builtins/performance.js | 28 +++++++++++++++++++++++++++ 7 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 test/builtins/performance-disabled.js create mode 100644 test/builtins/performance.js diff --git a/CMakeLists.txt b/CMakeLists.txt index d3123f5..ab0292c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,5 +3,6 @@ cmake_minimum_required(VERSION 3.27) include("StarlingMonkey/cmake/add_as_subproject.cmake") add_builtin(componentize::embedding SRC embedding/embedding.cpp) +include_directories("StarlingMonkey") project(ComponentizeJS) diff --git a/Makefile b/Makefile index 7cc9c0a..764905c 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ lib/starlingmonkey_embedding.wasm: StarlingMonkey/cmake/* embedding/* StarlingMo @cp build-release/starling-raw.wasm/starling-raw.wasm $@ lib/starlingmonkey_embedding_weval.wasm: StarlingMonkey/cmake/* embedding/* StarlingMonkey/runtime/* StarlingMonkey/builtins/* StarlingMonkey/builtins/*/* StarlingMonkey/builtins/*/*/* StarlingMonkey/include/* | lib - cmake -B build-release-weval -DCMAKE_BUILD_TYPE=Release -DWEVAL=ON + cmake -B build-release-weval -DCMAKE_BUILD_TYPE=Release -DUSE_WASM_OPT=OFF -DWEVAL=ON make -j16 -C build-release-weval @cp build-release-weval/starling-raw.wasm/starling-raw.wasm $@ diff --git a/embedding/embedding.cpp b/embedding/embedding.cpp index 428f121..f1a7566 100644 --- a/embedding/embedding.cpp +++ b/embedding/embedding.cpp @@ -1,4 +1,5 @@ #include "embedding.h" +#include "builtins/web/performance.h" namespace builtins::web::console { @@ -65,7 +66,8 @@ from_bigint64(JS::MutableHandleValue handle) { JS::BigInt *arg0 = handle.toBigInt(); uint64_t arg0_uint64; if (!JS::detail::BigIntIsUint64(arg0, &arg0_uint64)) { - Runtime.engine->abort("Internal bindgen error in coreabi_from_bigint64 validation"); + Runtime.engine->abort( + "Internal bindgen error in coreabi_from_bigint64 validation"); } return arg0_uint64; } @@ -148,6 +150,10 @@ __attribute__((export_name("call"))) uint32_t call(uint32_t fn_idx, if (Runtime.first_call) { js::ResetMathRandomSeed(Runtime.cx); Runtime.first_call = false; + if (Runtime.clocks) { + builtins::web::performance::Performance::timeOrigin.emplace( + std::chrono::high_resolution_clock::now()); + } } if (Runtime.cur_fn_idx != -1) { LOG("(call) unexpected call state, post_call was not called after last " @@ -350,6 +356,11 @@ componentize_initialize() { Runtime.debug = true; } + uint32_t feature_clocks = atoi(getenv("FEATURE_CLOCKS")); + if (feature_clocks) { + Runtime.clocks = true; + } + __wizer_initialize(); char env_name[100]; LOG("(wizer) retrieve and generate the export bindings"); diff --git a/embedding/embedding.h b/embedding/embedding.h index 2dd3ba6..11e95d5 100644 --- a/embedding/embedding.h +++ b/embedding/embedding.h @@ -46,6 +46,8 @@ namespace componentize::embedding bool debug = false; bool first_call = true; + bool clocks = false; + JSContext *cx; InitError init_err = InitError::OK; diff --git a/src/componentize.js b/src/componentize.js index 8a6c86d..d64d143 100644 --- a/src/componentize.js +++ b/src/componentize.js @@ -173,6 +173,7 @@ export async function componentize(jsSource, witWorld, opts) { SOURCE_NAME: sourceName, IMPORT_WRAPPER_CNT: Object.keys(importWrappers).length.toString(), EXPORT_CNT: exports.length.toString(), + FEATURE_CLOCKS: features.includes('clocks') ? '1' : '', }; for (const [idx, [export_name, expt]] of exports.entries()) { diff --git a/test/builtins/performance-disabled.js b/test/builtins/performance-disabled.js new file mode 100644 index 0000000..a6268b4 --- /dev/null +++ b/test/builtins/performance-disabled.js @@ -0,0 +1,19 @@ +import { ok, strictEqual } from 'node:assert'; + +export const source = ` + export function run () { + performance.now(); + }; +`; + +export const disableFeatures = ['clocks']; + +export async function test (run) { + try { + const { stdout, stderr } = await run(); + ok(false); + } catch { + // performance builtin just panics + // (yes we can and should do better...) + } +} diff --git a/test/builtins/performance.js b/test/builtins/performance.js new file mode 100644 index 0000000..2c68268 --- /dev/null +++ b/test/builtins/performance.js @@ -0,0 +1,28 @@ +import { ok, strictEqual } from 'node:assert'; + +export const source = ` + export function run () { + const start = performance.now(); + let previous = 0, cur = 1; + for (let i = 1; i < 1000; i++) { + const tmp = cur; + cur = previous + cur; + previous = tmp; + } + const end = performance.now(); + console.log('Calculated fib 1000: ' + cur); + console.error((end - start) + ' ms'); + }; +`; + +export async function test (run) { + const { stdout, stderr } = await run(); + strictEqual(stdout, 'Calculated fib 1000: 4.346655768693743e+208\n'); + + ok(stderr.includes(' ms')); + const time = Number(stderr.split(' ms')[0]); + // TODO: fix back to half a millisecond when Weval fix is added + if (time > 3) { + throw new Error('took more than half a millisecond - ' + time + ' ms'); + } +}