Skip to content
forked from v8/v8

Commit

Permalink
[wasm-gc] JS interop: Test for deopt loops
Browse files Browse the repository at this point in the history
Ensure that no deopt-loops happen for wasm objects used in JS on all
operations excluding a few corner cases that have not yet been adapted.

Bug: v8:7748
Change-Id: I43226115a65acacc6cf78d057513ac03a48ce786
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4615032
Commit-Queue: Matthias Liedtke <[email protected]>
Reviewed-by: Jakob Kummerow <[email protected]>
Cr-Commit-Position: refs/heads/main@{#88340}
  • Loading branch information
Liedtke authored and V8 LUCI CQ committed Jun 19, 2023
1 parent 4f096d4 commit 95cbef2
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 21 deletions.
1 change: 1 addition & 0 deletions test/mjsunit/wasm/gc-js-interop-async-debugger.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --allow-natives-syntax
// Flags: --turbofan --no-always-turbofan

// The implementation of Promises currently takes a different path (a C++
// runtime function instead of a Torque builtin) when the debugger is
Expand Down
1 change: 1 addition & 0 deletions test/mjsunit/wasm/gc-js-interop-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --allow-natives-syntax
// Flags: --turbofan --no-always-turbofan

d8.file.execute('test/mjsunit/wasm/gc-js-interop-helpers.js');

Expand Down
1 change: 1 addition & 0 deletions test/mjsunit/wasm/gc-js-interop-collections.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --allow-natives-syntax
// Flags: --turbofan --no-always-turbofan

d8.file.execute('test/mjsunit/wasm/gc-js-interop-helpers.js');

Expand Down
1 change: 1 addition & 0 deletions test/mjsunit/wasm/gc-js-interop-global-constructors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --allow-natives-syntax
// Flags: --turbofan --no-always-turbofan

d8.file.execute('test/mjsunit/wasm/gc-js-interop-helpers.js');

Expand Down
40 changes: 24 additions & 16 deletions test/mjsunit/wasm/gc-js-interop-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

// Helpers to test interoperability of Wasm objects in JavaScript.

// The following flags are required:
// Flags: --turbofan --no-always-turbofan --experimental-wasm-gc
// Flags: --allow-natives-syntax

d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');

function CreateWasmObjects() {
Expand Down Expand Up @@ -32,22 +36,26 @@ function CreateWasmObjects() {
};
}

function testThrowsRepeated(fn, ErrorType) {
%PrepareFunctionForOptimization(fn);
for (let i = 0; i < 5; i++) assertThrows(fn, ErrorType);
%OptimizeFunctionOnNextCall(fn);
assertThrows(fn, ErrorType);
// TODO(7748): This assertion doesn't hold true, as some cases run into
// deopt loops.
// assertTrue(%ActiveTierIsTurbofan(fn));
function testThrowsRepeated(fn, ErrorType, ignoreDeopts = false) {
const maxRuns = 2;
for (let run = 0; run < maxRuns; ++run) {
%PrepareFunctionForOptimization(fn);
for (let i = 0; i < 5; i++) assertThrows(fn, ErrorType);
%OptimizeFunctionOnNextCall(fn);
assertThrows(fn, ErrorType);
if (isOptimized(fn) || ignoreDeopts) return;
}
assertOptimized(fn);
}

function repeated(fn) {
%PrepareFunctionForOptimization(fn);
for (let i = 0; i < 5; i++) fn();
%OptimizeFunctionOnNextCall(fn);
fn();
// TODO(7748): This assertion doesn't hold true, as some cases run into
// deopt loops.
// assertTrue(%ActiveTierIsTurbofan(fn));
function repeated(fn, ignoreDeopts = false) {
const maxRuns = 2;
for (let run = 0; run < maxRuns; ++run) {
%PrepareFunctionForOptimization(fn);
for (let i = 0; i < 5; i++) fn();
%OptimizeFunctionOnNextCall(fn);
fn();
if (isOptimized(fn) || ignoreDeopts) return;
}
assertOptimized(fn);
}
1 change: 1 addition & 0 deletions test/mjsunit/wasm/gc-js-interop-import.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --allow-natives-syntax
// Flags: --turbofan --no-always-turbofan

import {struct, array} from 'gc-js-interop-export.mjs';

Expand Down
1 change: 1 addition & 0 deletions test/mjsunit/wasm/gc-js-interop-numeric.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --allow-natives-syntax
// Flags: --turbofan --no-always-turbofan

d8.file.execute('test/mjsunit/wasm/gc-js-interop-helpers.js');

Expand Down
1 change: 1 addition & 0 deletions test/mjsunit/wasm/gc-js-interop-objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --allow-natives-syntax
// Flags: --turbofan --no-always-turbofan

d8.file.execute('test/mjsunit/wasm/gc-js-interop-helpers.js');

Expand Down
2 changes: 1 addition & 1 deletion test/mjsunit/wasm/gc-js-interop-wasm.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --wasm-test-streaming
// Flags: --allow-natives-syntax
// Flags: --allow-natives-syntax --turbofan --no-always-turbofan

d8.file.execute('test/mjsunit/wasm/gc-js-interop-helpers.js');

Expand Down
16 changes: 12 additions & 4 deletions test/mjsunit/wasm/gc-js-interop.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
// found in the LICENSE file.

// Flags: --experimental-wasm-gc --allow-natives-syntax
// Flags: --turbofan --no-always-turbofan

d8.file.execute('test/mjsunit/wasm/gc-js-interop-helpers.js');

// TODO(14034): Some operations can still trigger a deopt loop.
const ignoreDeopts = true;

let {struct, array} = CreateWasmObjects();
for (const wasm_obj of [struct, array]) {
repeated(() => assertSame(undefined, wasm_obj.foo));
Expand Down Expand Up @@ -54,7 +58,9 @@ for (const wasm_obj of [struct, array]) {
repeated(() => assertSame(undefined, wasm_obj?.property));

repeated(() => assertEquals(undefined, void wasm_obj));
testThrowsRepeated(() => 2 == wasm_obj, TypeError);
// These deopt loops can also be triggered with JS only code, e.g.
// `2 == {valueOf: () => +2n}`.
testThrowsRepeated(() => 2 == wasm_obj, TypeError, ignoreDeopts);
repeated(() => assertFalse(2 === wasm_obj));
repeated(() => assertFalse({} === wasm_obj));
repeated(() => assertTrue(wasm_obj == wasm_obj));
Expand All @@ -63,9 +69,11 @@ for (const wasm_obj of [struct, array]) {
repeated(() => assertFalse(wasm_obj !== wasm_obj));
repeated(() => assertFalse(struct == array));
repeated(() => assertTrue(struct != array));
testThrowsRepeated(() => wasm_obj < wasm_obj, TypeError);
testThrowsRepeated(() => wasm_obj <= wasm_obj, TypeError);
testThrowsRepeated(() => wasm_obj >= wasm_obj, TypeError);
// JS Symbols also have the issue of triggering deopt loops on relational
// comparisons, e.g. `2 < Symbol("test")`.
testThrowsRepeated(() => wasm_obj < wasm_obj, TypeError, ignoreDeopts);
testThrowsRepeated(() => wasm_obj <= wasm_obj, TypeError, ignoreDeopts);
testThrowsRepeated(() => wasm_obj >= wasm_obj, TypeError, ignoreDeopts);

testThrowsRepeated(() => { let [] = wasm_obj; }, TypeError);
testThrowsRepeated(() => { let [a, b] = wasm_obj; }, TypeError);
Expand Down

0 comments on commit 95cbef2

Please sign in to comment.