d89d185fad
Load current Memory start/size off of the wasm instance when entering fast calls, so they can use that info for whatever they need to do. Fast calls from JS set the memory to null, and the memory does not need to be piped from wasm to slow callbacks as wasm always calls the fast function. Change-Id: Ibfa33cdd7dba85300f95cbdacc9a56b3f7181663 Bug: chromium:1052746 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3719005 Reviewed-by: Maya Lekova <mslekova@chromium.org> Commit-Queue: snek <snek@chromium.org> Reviewed-by: Manos Koukoutos <manoskouk@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/main@{#81538}
208 lines
6.5 KiB
JavaScript
208 lines
6.5 KiB
JavaScript
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --turbo-fast-api-calls --expose-fast-api
|
|
|
|
load('test/mjsunit/wasm/wasm-module-builder.js');
|
|
|
|
assertThrows(() => d8.test.FastCAPI());
|
|
const fast_c_api = new d8.test.FastCAPI();
|
|
|
|
function buildWasm(name, sig, body) {
|
|
const builder = new WasmModuleBuilder();
|
|
const add_all_no_options = builder.addImport(
|
|
'fast_c_api',
|
|
'add_all_no_options',
|
|
makeSig(
|
|
[kWasmI32, kWasmI32, kWasmI32, kWasmI64, kWasmI64, kWasmF32, kWasmF64],
|
|
[kWasmF64],
|
|
),
|
|
);
|
|
const add_all_no_options_mismatch = builder.addImport(
|
|
'fast_c_api',
|
|
'add_all_no_options',
|
|
makeSig(
|
|
[kWasmI32, kWasmI32, kWasmI32, kWasmI64, kWasmF32, kWasmI64, kWasmF64],
|
|
[kWasmF64],
|
|
),
|
|
);
|
|
const add_all_nested_bound = builder.addImport(
|
|
'fast_c_api',
|
|
'add_all_nested_bound',
|
|
makeSig(
|
|
[kWasmI32, kWasmI32, kWasmI32, kWasmI64, kWasmI64, kWasmF32, kWasmF64],
|
|
[kWasmF64],
|
|
),
|
|
);
|
|
const overloaded_add_all_32bit_int = builder.addImport(
|
|
'fast_c_api',
|
|
'overloaded_add_all_32bit_int',
|
|
makeSig(
|
|
[kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32],
|
|
[kWasmI32],
|
|
),
|
|
);
|
|
const test_wasm_memory = builder.addImport(
|
|
'fast_c_api',
|
|
'test_wasm_memory',
|
|
makeSig([kWasmI32], [kWasmI32]),
|
|
);
|
|
builder
|
|
.addMemory(1, 1)
|
|
.addFunction(name, sig)
|
|
.addBody(body({
|
|
add_all_no_options,
|
|
add_all_no_options_mismatch,
|
|
add_all_nested_bound,
|
|
overloaded_add_all_32bit_int,
|
|
test_wasm_memory,
|
|
}))
|
|
.exportFunc();
|
|
const x = {};
|
|
const module = builder.instantiate({
|
|
fast_c_api: {
|
|
add_all_no_options: fast_c_api.add_all_no_options.bind(fast_c_api),
|
|
add_all_no_options_mismatch: fast_c_api.add_all_no_options.bind(fast_c_api),
|
|
add_all_nested_bound: fast_c_api.add_all_no_options
|
|
.bind(fast_c_api)
|
|
.bind(x),
|
|
overloaded_add_all_32bit_int: fast_c_api.overloaded_add_all_32bit_int_no_sig.bind(fast_c_api),
|
|
test_wasm_memory: fast_c_api.test_wasm_memory.bind(fast_c_api),
|
|
},
|
|
});
|
|
return module.exports[name];
|
|
}
|
|
|
|
// ----------- add_all -----------
|
|
// `add_all` has the following signature:
|
|
// double add_all(bool /*should_fallback*/, int32_t, uint32_t,
|
|
// int64_t, uint64_t, float, double)
|
|
|
|
const max_safe_float = 2**24 - 1;
|
|
const add_all_result = -42 + 45 + Number.MIN_SAFE_INTEGER + Number.MAX_SAFE_INTEGER +
|
|
max_safe_float * 0.5 + Math.PI;
|
|
|
|
const add_all_wasm = buildWasm(
|
|
'add_all_wasm', makeSig([], [kWasmF64]),
|
|
({ add_all_no_options }) => [
|
|
...wasmI32Const(0),
|
|
...wasmI32Const(-42),
|
|
...wasmI32Const(45),
|
|
kExprI64Const, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x70, // Number.MIN_SAFE_INTEGER
|
|
kExprI64Const, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, // Number.MAX_SAFE_INTEGER
|
|
...wasmF32Const(max_safe_float * 0.5),
|
|
...wasmF64Const(Math.PI),
|
|
kExprCallFunction, add_all_no_options,
|
|
kExprReturn,
|
|
],
|
|
);
|
|
|
|
if (fast_c_api.supports_fp_params) {
|
|
// Test wasm hits fast path.
|
|
fast_c_api.reset_counts();
|
|
assertEquals(add_all_result, add_all_wasm());
|
|
assertEquals(1, fast_c_api.fast_call_count());
|
|
assertEquals(0, fast_c_api.slow_call_count());
|
|
} else {
|
|
// Test wasm hits slow path.
|
|
fast_c_api.reset_counts();
|
|
assertEquals(add_all_result, add_all_wasm());
|
|
assertEquals(0, fast_c_api.fast_call_count());
|
|
assertEquals(1, fast_c_api.slow_call_count());
|
|
}
|
|
|
|
// ----------- Test add_all signature mismatch -----------
|
|
|
|
const add_all_mismatch_wasm = buildWasm(
|
|
'add_all_mismatch_wasm', makeSig([], [kWasmF64]),
|
|
({ add_all_no_options_mismatch }) => [
|
|
...wasmI32Const(0),
|
|
...wasmI32Const(45),
|
|
...wasmI32Const(-42),
|
|
kExprI64Const, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, // Number.MAX_SAFE_INTEGER
|
|
...wasmF32Const(max_safe_float * 0.5),
|
|
kExprI64Const, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x70, // Number.MIN_SAFE_INTEGER
|
|
...wasmF64Const(Math.PI),
|
|
kExprCallFunction, add_all_no_options_mismatch,
|
|
kExprReturn,
|
|
],
|
|
);
|
|
|
|
// Test that wasm takes slow path.
|
|
fast_c_api.reset_counts();
|
|
add_all_mismatch_wasm();
|
|
assertEquals(0, fast_c_api.fast_call_count());
|
|
assertEquals(1, fast_c_api.slow_call_count());
|
|
|
|
// ----------- Test add_all nested bound function -----------
|
|
|
|
const add_all_nested_bound_wasm = buildWasm(
|
|
'add_all_nested_bound_wasm', makeSig([], [kWasmF64]),
|
|
({ add_all_nested_bound }) => [
|
|
...wasmI32Const(0),
|
|
...wasmI32Const(-42),
|
|
...wasmI32Const(45),
|
|
kExprI64Const, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x70, // Number.MIN_SAFE_INTEGER
|
|
kExprI64Const, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, // Number.MAX_SAFE_INTEGER
|
|
...wasmF32Const(max_safe_float * 0.5),
|
|
...wasmF64Const(Math.PI),
|
|
kExprCallFunction, add_all_nested_bound,
|
|
kExprReturn,
|
|
],
|
|
);
|
|
|
|
// Test wasm hits slow path.
|
|
fast_c_api.reset_counts();
|
|
assertEquals(add_all_result, add_all_nested_bound_wasm());
|
|
assertEquals(0, fast_c_api.fast_call_count());
|
|
assertEquals(1, fast_c_api.slow_call_count());
|
|
|
|
// ----------- Test overloaded_add_all_32bit_int -----------
|
|
const overloaded_add_all_32bit_int_wasm = buildWasm(
|
|
'overloaded_add_all_32bit_int_wasm', makeSig([kWasmI32], [kWasmI32]),
|
|
({ overloaded_add_all_32bit_int }) => [
|
|
kExprLocalGet, 0,
|
|
...wasmI32Const(1),
|
|
...wasmI32Const(2),
|
|
...wasmI32Const(3),
|
|
...wasmI32Const(4),
|
|
...wasmI32Const(5),
|
|
...wasmI32Const(6),
|
|
kExprCallFunction, overloaded_add_all_32bit_int,
|
|
kExprReturn,
|
|
],
|
|
);
|
|
|
|
const overload_result = 1 + 2 + 3 + 4 + 5 + 6;
|
|
|
|
// Test wasm hits fast path.
|
|
fast_c_api.reset_counts();
|
|
assertEquals(overload_result, overloaded_add_all_32bit_int_wasm(false));
|
|
assertEquals(1, fast_c_api.fast_call_count());
|
|
assertEquals(0, fast_c_api.slow_call_count());
|
|
|
|
// Test wasm hits slow path.
|
|
fast_c_api.reset_counts();
|
|
assertEquals(overload_result, overloaded_add_all_32bit_int_wasm(true));
|
|
assertEquals(1, fast_c_api.fast_call_count());
|
|
assertEquals(1, fast_c_api.slow_call_count());
|
|
|
|
// ------------- Test test_wasm_memory ---------------
|
|
const test_wasm_memory_wasm = buildWasm(
|
|
'test_wasm_memory_wasm', makeSig([], [kWasmI32]),
|
|
({ test_wasm_memory }) => [
|
|
...wasmI32Const(12),
|
|
kExprCallFunction, test_wasm_memory,
|
|
kExprDrop,
|
|
...wasmI32Const(12),
|
|
kExprI32LoadMem8U, 0, 0,
|
|
],
|
|
);
|
|
|
|
// Test hits fast path.
|
|
fast_c_api.reset_counts();
|
|
assertEquals(42, test_wasm_memory_wasm())
|
|
assertEquals(1, fast_c_api.fast_call_count());
|
|
assertEquals(0, fast_c_api.slow_call_count());
|