Commit ddc3672d authored by evih's avatar evih Committed by Commit Bot

[wasm] Add GC support to generic js-to-wasm wrapper

GC support works for the current 0 and 1 param version
of the wrapper.

Bug: v8:10701
Change-Id: I9e3822b1481223c44050d23ddee7293936f1e6d4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2351673Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Eva Herencsárová <evih@google.com>
Cr-Commit-Position: refs/heads/master@{#69447}
parent f7d169c6
...@@ -3280,14 +3280,16 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3280,14 +3280,16 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
jump_table_offset = no_reg; jump_table_offset = no_reg;
jump_table_start = no_reg; jump_table_start = no_reg;
__ pushq(wasm_instance); // The order of pushes is important. We want the heap objects, that should be
// scanned by GC, to be on the top of the stack.
__ pushq(signature_type); __ pushq(signature_type);
__ pushq(wasm_instance);
__ call(function_entry); __ call(function_entry);
function_entry = no_reg; function_entry = no_reg;
__ popq(signature_type);
__ popq(wasm_instance); __ popq(wasm_instance);
__ popq(signature_type);
// Unset thread_in_wasm_flag. // Unset thread_in_wasm_flag.
thread_in_wasm_flag_addr = r8; thread_in_wasm_flag_addr = r8;
...@@ -3315,9 +3317,11 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3315,9 +3317,11 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
// Handle the conversion to int32 when the param is not a smi. // Handle the conversion to int32 when the param is not a smi.
__ bind(&not_smi); __ bind(&not_smi);
// The order of pushes is important. We want the heap objects, that should be
// scanned by GC, to be on the top of the stack.
__ pushq(signature_type);
__ pushq(wasm_instance); __ pushq(wasm_instance);
__ pushq(function_data); __ pushq(function_data);
__ pushq(signature_type);
__ LoadAnyTaggedField( __ LoadAnyTaggedField(
rsi, rsi,
MemOperand(wasm_instance, wasm::ObjectAccess::ToTagged( MemOperand(wasm_instance, wasm::ObjectAccess::ToTagged(
...@@ -3327,9 +3331,9 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) { ...@@ -3327,9 +3331,9 @@ void Builtins::Generate_GenericJSToWasmWrapper(MacroAssembler* masm) {
__ Call(BUILTIN_CODE(masm->isolate(), WasmTaggedNonSmiToInt32), __ Call(BUILTIN_CODE(masm->isolate(), WasmTaggedNonSmiToInt32),
RelocInfo::CODE_TARGET); RelocInfo::CODE_TARGET);
__ popq(signature_type);
__ popq(function_data); __ popq(function_data);
__ popq(wasm_instance); __ popq(wasm_instance);
__ popq(signature_type);
__ jmp(&params_done); __ jmp(&params_done);
} }
......
...@@ -623,8 +623,8 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, ...@@ -623,8 +623,8 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
case WASM_COMPILE_LAZY: case WASM_COMPILE_LAZY:
case WASM_EXIT: case WASM_EXIT:
case WASM_DEBUG_BREAK: case WASM_DEBUG_BREAK:
return candidate;
case JS_TO_WASM: case JS_TO_WASM:
return candidate;
case OPTIMIZED: case OPTIMIZED:
case INTERPRETED: case INTERPRETED:
default: default:
...@@ -1959,6 +1959,35 @@ Address WasmDebugBreakFrame::GetCallerStackPointer() const { ...@@ -1959,6 +1959,35 @@ Address WasmDebugBreakFrame::GetCallerStackPointer() const {
return fp() + WasmDebugBreakFrameConstants::kCallerSPOffset; return fp() + WasmDebugBreakFrameConstants::kCallerSPOffset;
} }
void JsToWasmFrame::Iterate(RootVisitor* v) const {
Code code = GetContainingCode(isolate(), pc());
// GenericJSToWasmWrapper stack layout
// ------+-----------------+----------------------
// | return addr |
// rbp |- - - - - - - - -| <-fp() -------------|
// | rbp | |
// rbp-p |- - - - - - - - -| |
// | frame marker | | no GC scan
// rbp-2p | - - - - - - - - | <- spill_slot_limit |
// | signature_type | |
// rbp-3p |- - - - - - - - -| -------------------|
// | .... | |
// | spill slots | | GC scan
// | .... |<- spill_slot_base |
// |- - - - - - - - -| -------------------|
if (code.is_null() || !code.is_builtin() ||
code.builtin_index() != Builtins::kGenericJSToWasmWrapper) {
// If it's not the GenericJSToWasmWrapper, then it's the TurboFan compiled
// specific wrapper. So we have to call IterateCompiledFrame.
IterateCompiledFrame(v);
return;
}
FullObjectSlot spill_slot_base(&Memory<Address>(sp()));
FullObjectSlot spill_slot_limit(
&Memory<Address>(fp() - 2 * kSystemPointerSize));
v->VisitRootPointers(Root::kTop, nullptr, spill_slot_base, spill_slot_limit);
}
Code WasmCompileLazyFrame::unchecked_code() const { return Code(); } Code WasmCompileLazyFrame::unchecked_code() const { return Code(); }
WasmInstanceObject WasmCompileLazyFrame::wasm_instance() const { WasmInstanceObject WasmCompileLazyFrame::wasm_instance() const {
......
...@@ -1000,6 +1000,8 @@ class JsToWasmFrame : public StubFrame { ...@@ -1000,6 +1000,8 @@ class JsToWasmFrame : public StubFrame {
public: public:
Type type() const override { return JS_TO_WASM; } Type type() const override { return JS_TO_WASM; }
void Iterate(RootVisitor* v) const override;
protected: protected:
inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator); inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --wasm-generic-wrapper // Flags: --wasm-generic-wrapper --expose-gc
load("test/mjsunit/wasm/wasm-module-builder.js"); load("test/mjsunit/wasm/wasm-module-builder.js");
...@@ -19,10 +19,12 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -19,10 +19,12 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
let x = 12; let x = 12;
function import_func() { function import_func() {
gc();
x = 20; x = 20;
} }
builder.instantiate({ mod: { func: import_func } }).exports.main(); let instance = builder.instantiate({ mod: { func: import_func } });
assertEquals(undefined, instance.exports.main());
assertEquals(x, 20); assertEquals(x, 20);
})(); })();
...@@ -67,6 +69,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -67,6 +69,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
let x = 12; let x = 12;
function import_func(param) { function import_func(param) {
gc();
x += param; x += param;
} }
...@@ -88,10 +91,11 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -88,10 +91,11 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
let x = 12; let x = 12;
function import_func(param) { function import_func(param) {
gc();
x += param; x += param;
} }
let y = {valueOf:() => {return 24;}}; let y = { valueOf: () => { print("Hello!"); gc(); return 24; } };
let instance = builder.instantiate({ mod: { func: import_func } }); let instance = builder.instantiate({ mod: { func: import_func } });
instance.exports.main(y); instance.exports.main(y);
assertEquals(36, x); assertEquals(36, x);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment