Commit 65f3861e authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[wasm-c-api] New call descriptor and stackframe kind

So far, calls to Wasm C/C++ API functions reused the call descriptors
of WasmImportWrappers, and the stack frame type of regular Wasm
functions. This CL cleans that up by introducing separate implementations
for both. No change in functionality or performance is expected.

Change-Id: I79301fa81da52283cc776ddf19d4712372f3a58b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1632235
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61914}
parent f6e39938
...@@ -2402,7 +2402,8 @@ void TurboAssembler::EnterFrame(StackFrame::Type type) { ...@@ -2402,7 +2402,8 @@ void TurboAssembler::EnterFrame(StackFrame::Type type) {
// sp[1] : type // sp[1] : type
// sp[0] : for alignment // sp[0] : for alignment
} else if (type == StackFrame::WASM_COMPILED || } else if (type == StackFrame::WASM_COMPILED ||
type == StackFrame::WASM_COMPILE_LAZY) { type == StackFrame::WASM_COMPILE_LAZY ||
type == StackFrame::WASM_EXIT) {
Register type_reg = temps.AcquireX(); Register type_reg = temps.AcquireX();
Mov(type_reg, StackFrame::TypeToMarker(type)); Mov(type_reg, StackFrame::TypeToMarker(type));
Push(lr, fp); Push(lr, fp);
......
...@@ -168,8 +168,9 @@ StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const { ...@@ -168,8 +168,9 @@ StackFrame::Type OptimizedCompilationInfo::GetOutputStackFrameType() const {
case Code::BUILTIN: case Code::BUILTIN:
return StackFrame::STUB; return StackFrame::STUB;
case Code::WASM_FUNCTION: case Code::WASM_FUNCTION:
case Code::WASM_TO_CAPI_FUNCTION:
return StackFrame::WASM_COMPILED; return StackFrame::WASM_COMPILED;
case Code::WASM_TO_CAPI_FUNCTION:
return StackFrame::WASM_EXIT;
case Code::JS_TO_WASM_FUNCTION: case Code::JS_TO_WASM_FUNCTION:
return StackFrame::JS_TO_WASM; return StackFrame::JS_TO_WASM;
case Code::WASM_TO_JS_FUNCTION: case Code::WASM_TO_JS_FUNCTION:
......
...@@ -833,12 +833,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -833,12 +833,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break; break;
case kArchCallCFunction: { case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode()); int const num_parameters = MiscField::decode(instr->opcode());
// Put the return address in a stack slot. if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
if (linkage()->GetIncomingDescriptor()->kind() == // Put the return address in a stack slot.
CallDescriptor::kCallWasmImportWrapper) {
// WasmCapiFunctionWrappers, which are reusing the WasmImportWrapper
// call descriptor, also need access to the PC.
// TODO(jkummerow): Separate the call descriptors for clarity.
__ str(pc, MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset)); __ str(pc, MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset));
} }
if (instr->InputAt(0)->IsImmediate()) { if (instr->InputAt(0)->IsImmediate()) {
...@@ -3008,7 +3004,8 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -3008,7 +3004,8 @@ void CodeGenerator::AssembleConstructFrame() {
__ StubPrologue(info()->GetOutputStackFrameType()); __ StubPrologue(info()->GetOutputStackFrameType());
if (call_descriptor->IsWasmFunctionCall()) { if (call_descriptor->IsWasmFunctionCall()) {
__ Push(kWasmInstanceRegister); __ Push(kWasmInstanceRegister);
} else if (call_descriptor->IsWasmImportWrapper()) { } else if (call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
// WASM import wrappers are passed a tuple in the place of the instance. // WASM import wrappers are passed a tuple in the place of the instance.
// Unpack the tuple into the instance and the target callable. // Unpack the tuple into the instance and the target callable.
// This must be done here in the codegen because it cannot be expressed // This must be done here in the codegen because it cannot be expressed
...@@ -3018,9 +3015,10 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -3018,9 +3015,10 @@ void CodeGenerator::AssembleConstructFrame() {
__ ldr(kWasmInstanceRegister, __ ldr(kWasmInstanceRegister,
FieldMemOperand(kWasmInstanceRegister, Tuple2::kValue1Offset)); FieldMemOperand(kWasmInstanceRegister, Tuple2::kValue1Offset));
__ Push(kWasmInstanceRegister); __ Push(kWasmInstanceRegister);
// Reserve PC slot space for WasmCapiFunction wrappers. if (call_descriptor->IsWasmCapiFunction()) {
// TODO(jkummerow): Separate the call descriptors for clarity. // Reserve space for saving the PC later.
__ AllocateStackSpace(kSystemPointerSize); __ AllocateStackSpace(kSystemPointerSize);
}
} }
} }
......
...@@ -744,14 +744,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -744,14 +744,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break; break;
case kArchCallCFunction: { case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode()); int const num_parameters = MiscField::decode(instr->opcode());
// Put the return address in a stack slot.
Register scratch = x8;
Label return_location; Label return_location;
if (linkage()->GetIncomingDescriptor()->kind() == if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
CallDescriptor::kCallWasmImportWrapper) { // Put the return address in a stack slot.
// WasmCapiFunctionWrappers, which are reusing the WasmImportWrapper Register scratch = x8;
// call descriptor, need access to the calling PC.
// TODO(jkummerow): Separate the call descriptors for clarity.
__ Adr(scratch, &return_location); __ Adr(scratch, &return_location);
__ Str(scratch, __ Str(scratch,
MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset)); MemOperand(fp, WasmExitFrameConstants::kCallingPCOffset));
...@@ -2559,7 +2555,8 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -2559,7 +2555,8 @@ void CodeGenerator::AssembleConstructFrame() {
__ Str(kWasmInstanceRegister, __ Str(kWasmInstanceRegister,
MemOperand(fp, WasmCompiledFrameConstants::kWasmInstanceOffset)); MemOperand(fp, WasmCompiledFrameConstants::kWasmInstanceOffset));
} break; } break;
case CallDescriptor::kCallWasmImportWrapper: { case CallDescriptor::kCallWasmImportWrapper:
case CallDescriptor::kCallWasmCapiFunction: {
UseScratchRegisterScope temps(tasm()); UseScratchRegisterScope temps(tasm());
__ LoadTaggedPointerField( __ LoadTaggedPointerField(
kJSFunctionRegister, kJSFunctionRegister,
...@@ -2567,8 +2564,11 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -2567,8 +2564,11 @@ void CodeGenerator::AssembleConstructFrame() {
__ LoadTaggedPointerField( __ LoadTaggedPointerField(
kWasmInstanceRegister, kWasmInstanceRegister,
FieldMemOperand(kWasmInstanceRegister, Tuple2::kValue1Offset)); FieldMemOperand(kWasmInstanceRegister, Tuple2::kValue1Offset));
__ Claim(required_slots + int extra_slots =
3); // Claim extra slots for marker + instance + pc. call_descriptor->kind() == CallDescriptor::kCallWasmImportWrapper
? 2 // Import wrapper: marker + instance.
: 3; // C-API function: marker + instance + PC.
__ Claim(required_slots + extra_slots);
Register scratch = temps.AcquireX(); Register scratch = temps.AcquireX();
__ Mov(scratch, __ Mov(scratch,
StackFrame::TypeToMarker(info()->GetOutputStackFrameType())); StackFrame::TypeToMarker(info()->GetOutputStackFrameType()));
......
...@@ -814,11 +814,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -814,11 +814,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchCallCFunction: { case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode()); int const num_parameters = MiscField::decode(instr->opcode());
Label return_location; Label return_location;
if (linkage()->GetIncomingDescriptor()->kind() == if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
CallDescriptor::kCallWasmImportWrapper) { // Put the return address in a stack slot.
// WasmCapiFunctionWrappers, which are reusing the WasmImportWrapper
// call descriptor, also need access to the PC.
// TODO(jkummerow): Separate the call descriptors for clarity.
Register scratch = eax; Register scratch = eax;
__ push(scratch); __ push(scratch);
__ PushPC(); __ PushPC();
...@@ -4236,7 +4233,8 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -4236,7 +4233,8 @@ void CodeGenerator::AssembleConstructFrame() {
__ StubPrologue(info()->GetOutputStackFrameType()); __ StubPrologue(info()->GetOutputStackFrameType());
if (call_descriptor->IsWasmFunctionCall()) { if (call_descriptor->IsWasmFunctionCall()) {
__ push(kWasmInstanceRegister); __ push(kWasmInstanceRegister);
} else if (call_descriptor->IsWasmImportWrapper()) { } else if (call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
// WASM import wrappers are passed a tuple in the place of the instance. // WASM import wrappers are passed a tuple in the place of the instance.
// Unpack the tuple into the instance and the target callable. // Unpack the tuple into the instance and the target callable.
// This must be done here in the codegen because it cannot be expressed // This must be done here in the codegen because it cannot be expressed
...@@ -4248,9 +4246,10 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -4248,9 +4246,10 @@ void CodeGenerator::AssembleConstructFrame() {
Operand(kWasmInstanceRegister, Operand(kWasmInstanceRegister,
Tuple2::kValue1Offset - kHeapObjectTag)); Tuple2::kValue1Offset - kHeapObjectTag));
__ push(kWasmInstanceRegister); __ push(kWasmInstanceRegister);
// Reserve PC slot space for WasmCapiFunction wrappers. if (call_descriptor->IsWasmCapiFunction()) {
// TODO(jkummerow): Separate the call descriptors for clarity. // Reserve space for saving the PC later.
__ AllocateStackSpace(kSystemPointerSize); __ AllocateStackSpace(kSystemPointerSize);
}
} }
} }
} }
......
...@@ -907,6 +907,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, ...@@ -907,6 +907,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
? g.UseFixed(callee, kJavaScriptCallCodeStartRegister) ? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
: g.UseRegister(callee)); : g.UseRegister(callee));
break; break;
case CallDescriptor::kCallWasmCapiFunction:
case CallDescriptor::kCallWasmFunction: case CallDescriptor::kCallWasmFunction:
case CallDescriptor::kCallWasmImportWrapper: case CallDescriptor::kCallWasmImportWrapper:
buffer->instruction_args.push_back( buffer->instruction_args.push_back(
...@@ -2631,6 +2632,7 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { ...@@ -2631,6 +2632,7 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
case CallDescriptor::kCallJSFunction: case CallDescriptor::kCallJSFunction:
opcode = kArchCallJSFunction | MiscField::encode(flags); opcode = kArchCallJSFunction | MiscField::encode(flags);
break; break;
case CallDescriptor::kCallWasmCapiFunction:
case CallDescriptor::kCallWasmFunction: case CallDescriptor::kCallWasmFunction:
case CallDescriptor::kCallWasmImportWrapper: case CallDescriptor::kCallWasmImportWrapper:
opcode = kArchCallWasmFunction | MiscField::encode(flags); opcode = kArchCallWasmFunction | MiscField::encode(flags);
......
...@@ -902,11 +902,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -902,11 +902,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchCallCFunction: { case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode()); int const num_parameters = MiscField::decode(instr->opcode());
Label return_location; Label return_location;
if (linkage()->GetIncomingDescriptor()->kind() == if (linkage()->GetIncomingDescriptor()->IsWasmCapiFunction()) {
CallDescriptor::kCallWasmImportWrapper) { // Put the return address in a stack slot.
// WasmCapiFunctionWrappers, which are reusing the WasmImportWrapper
// call descriptor, also need access to the PC.
// TODO(jkummerow): Separate the call descriptors for clarity.
__ leaq(kScratchRegister, Operand(&return_location, 0)); __ leaq(kScratchRegister, Operand(&return_location, 0));
__ movq(MemOperand(rbp, WasmExitFrameConstants::kCallingPCOffset), __ movq(MemOperand(rbp, WasmExitFrameConstants::kCallingPCOffset),
kScratchRegister); kScratchRegister);
...@@ -3746,7 +3743,8 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -3746,7 +3743,8 @@ void CodeGenerator::AssembleConstructFrame() {
__ StubPrologue(info()->GetOutputStackFrameType()); __ StubPrologue(info()->GetOutputStackFrameType());
if (call_descriptor->IsWasmFunctionCall()) { if (call_descriptor->IsWasmFunctionCall()) {
__ pushq(kWasmInstanceRegister); __ pushq(kWasmInstanceRegister);
} else if (call_descriptor->IsWasmImportWrapper()) { } else if (call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
// WASM import wrappers are passed a tuple in the place of the instance. // WASM import wrappers are passed a tuple in the place of the instance.
// Unpack the tuple into the instance and the target callable. // Unpack the tuple into the instance and the target callable.
// This must be done here in the codegen because it cannot be expressed // This must be done here in the codegen because it cannot be expressed
...@@ -3758,9 +3756,10 @@ void CodeGenerator::AssembleConstructFrame() { ...@@ -3758,9 +3756,10 @@ void CodeGenerator::AssembleConstructFrame() {
kWasmInstanceRegister, kWasmInstanceRegister,
FieldOperand(kWasmInstanceRegister, Tuple2::kValue1Offset)); FieldOperand(kWasmInstanceRegister, Tuple2::kValue1Offset));
__ pushq(kWasmInstanceRegister); __ pushq(kWasmInstanceRegister);
// Reserve PC slot space for WasmCapiFunction wrappers. if (call_descriptor->IsWasmCapiFunction()) {
// TODO(jkummerow): Separate the call descriptors for clarity. // Reserve space for saving the PC later.
__ AllocateStackSpace(kSystemPointerSize); __ AllocateStackSpace(kSystemPointerSize);
}
} }
} }
......
...@@ -37,6 +37,9 @@ std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) { ...@@ -37,6 +37,9 @@ std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) {
case CallDescriptor::kCallAddress: case CallDescriptor::kCallAddress:
os << "Addr"; os << "Addr";
break; break;
case CallDescriptor::kCallWasmCapiFunction:
os << "WasmExit";
break;
case CallDescriptor::kCallWasmFunction: case CallDescriptor::kCallWasmFunction:
os << "WasmFunction"; os << "WasmFunction";
break; break;
...@@ -147,11 +150,9 @@ int CallDescriptor::CalculateFixedFrameSize() const { ...@@ -147,11 +150,9 @@ int CallDescriptor::CalculateFixedFrameSize() const {
case kCallBuiltinPointer: case kCallBuiltinPointer:
return TypedFrameConstants::kFixedSlotCount; return TypedFrameConstants::kFixedSlotCount;
case kCallWasmFunction: case kCallWasmFunction:
return WasmCompiledFrameConstants::kFixedSlotCount;
case kCallWasmImportWrapper: case kCallWasmImportWrapper:
// TODO(jkummerow): Introduce a separate "wasm-to-capi" frame type, return WasmCompiledFrameConstants::kFixedSlotCount;
// and let other CallWasmImportWrapper frames go back to having the case kCallWasmCapiFunction:
// same size as CallWasmFunction frames.
return WasmExitFrameConstants::kFixedSlotCount; return WasmExitFrameConstants::kFixedSlotCount;
} }
UNREACHABLE(); UNREACHABLE();
......
...@@ -175,6 +175,7 @@ class V8_EXPORT_PRIVATE CallDescriptor final ...@@ -175,6 +175,7 @@ class V8_EXPORT_PRIVATE CallDescriptor final
kCallCodeObject, // target is a Code object kCallCodeObject, // target is a Code object
kCallJSFunction, // target is a JSFunction object kCallJSFunction, // target is a JSFunction object
kCallAddress, // target is a machine pointer kCallAddress, // target is a machine pointer
kCallWasmCapiFunction, // target is a Wasm C API function
kCallWasmFunction, // target is a wasm function kCallWasmFunction, // target is a wasm function
kCallWasmImportWrapper, // target is a wasm import wrapper kCallWasmImportWrapper, // target is a wasm import wrapper
kCallBuiltinPointer, // target is a builtin pointer kCallBuiltinPointer, // target is a builtin pointer
...@@ -236,6 +237,9 @@ class V8_EXPORT_PRIVATE CallDescriptor final ...@@ -236,6 +237,9 @@ class V8_EXPORT_PRIVATE CallDescriptor final
// Returns {true} if this descriptor is a call to a WebAssembly function. // Returns {true} if this descriptor is a call to a WebAssembly function.
bool IsWasmImportWrapper() const { return kind_ == kCallWasmImportWrapper; } bool IsWasmImportWrapper() const { return kind_ == kCallWasmImportWrapper; }
// Returns {true} if this descriptor is a call to a Wasm C API function.
bool IsWasmCapiFunction() const { return kind_ == kCallWasmCapiFunction; }
bool RequiresFrameAsIncoming() const { bool RequiresFrameAsIncoming() const {
return IsCFunctionCall() || IsJSFunctionCall() || IsWasmFunctionCall(); return IsCFunctionCall() || IsJSFunctionCall() || IsWasmFunctionCall();
} }
......
...@@ -6224,7 +6224,7 @@ wasm::WasmCode* CompileWasmImportCallWrapper(wasm::WasmEngine* wasm_engine, ...@@ -6224,7 +6224,7 @@ wasm::WasmCode* CompileWasmImportCallWrapper(wasm::WasmEngine* wasm_engine,
// Schedule and compile to machine code. // Schedule and compile to machine code.
CallDescriptor* incoming = CallDescriptor* incoming =
GetWasmCallDescriptor(&zone, sig, WasmGraphBuilder::kNoRetpoline, GetWasmCallDescriptor(&zone, sig, WasmGraphBuilder::kNoRetpoline,
WasmGraphBuilder::kExtraCallableParam); WasmCallKind::kWasmImportWrapper);
if (machine.Is32()) { if (machine.Is32()) {
incoming = GetI32WasmCallDescriptor(&zone, incoming); incoming = GetI32WasmCallDescriptor(&zone, incoming);
} }
...@@ -6279,7 +6279,7 @@ wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine, ...@@ -6279,7 +6279,7 @@ wasm::WasmCode* CompileWasmCapiCallWrapper(wasm::WasmEngine* wasm_engine,
// Run the compiler pipeline to generate machine code. // Run the compiler pipeline to generate machine code.
CallDescriptor* call_descriptor = CallDescriptor* call_descriptor =
GetWasmCallDescriptor(&zone, sig, WasmGraphBuilder::kNoRetpoline, GetWasmCallDescriptor(&zone, sig, WasmGraphBuilder::kNoRetpoline,
WasmGraphBuilder::kExtraCallableParam); WasmCallKind::kWasmCapiFunction);
if (mcgraph->machine()->Is32()) { if (mcgraph->machine()->Is32()) {
call_descriptor = GetI32WasmCallDescriptor(&zone, call_descriptor); call_descriptor = GetI32WasmCallDescriptor(&zone, call_descriptor);
} }
...@@ -6559,10 +6559,11 @@ class LinkageLocationAllocator { ...@@ -6559,10 +6559,11 @@ class LinkageLocationAllocator {
// General code uses the above configuration data. // General code uses the above configuration data.
CallDescriptor* GetWasmCallDescriptor( CallDescriptor* GetWasmCallDescriptor(
Zone* zone, wasm::FunctionSig* fsig, Zone* zone, wasm::FunctionSig* fsig,
WasmGraphBuilder::UseRetpoline use_retpoline, WasmGraphBuilder::UseRetpoline use_retpoline, WasmCallKind call_kind) {
WasmGraphBuilder::ExtraCallableParam extra_callable_param) {
// The extra here is to accomodate the instance object as first parameter // The extra here is to accomodate the instance object as first parameter
// and, when specified, the additional callable. // and, when specified, the additional callable.
bool extra_callable_param =
call_kind == kWasmImportWrapper || call_kind == kWasmCapiFunction;
int extra_params = extra_callable_param ? 2 : 1; int extra_params = extra_callable_param ? 2 : 1;
LocationSignature::Builder locations(zone, fsig->return_count(), LocationSignature::Builder locations(zone, fsig->return_count(),
fsig->parameter_count() + extra_params); fsig->parameter_count() + extra_params);
...@@ -6627,14 +6628,20 @@ CallDescriptor* GetWasmCallDescriptor( ...@@ -6627,14 +6628,20 @@ CallDescriptor* GetWasmCallDescriptor(
MachineType target_type = MachineType::Pointer(); MachineType target_type = MachineType::Pointer();
LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type); LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type);
CallDescriptor::Kind kind = extra_callable_param CallDescriptor::Kind descriptor_kind;
? CallDescriptor::kCallWasmImportWrapper if (call_kind == kWasmFunction) {
: CallDescriptor::kCallWasmFunction; descriptor_kind = CallDescriptor::kCallWasmFunction;
} else if (call_kind == kWasmImportWrapper) {
descriptor_kind = CallDescriptor::kCallWasmImportWrapper;
} else {
DCHECK_EQ(call_kind, kWasmCapiFunction);
descriptor_kind = CallDescriptor::kCallWasmCapiFunction;
}
CallDescriptor::Flags flags = CallDescriptor::Flags flags =
use_retpoline ? CallDescriptor::kRetpoline : CallDescriptor::kNoFlags; use_retpoline ? CallDescriptor::kRetpoline : CallDescriptor::kNoFlags;
return new (zone) CallDescriptor( // -- return new (zone) CallDescriptor( // --
kind, // kind descriptor_kind, // kind
target_type, // target MachineType target_type, // target MachineType
target_loc, // target location target_loc, // target location
locations.Build(), // location_sig locations.Build(), // location_sig
......
...@@ -164,10 +164,6 @@ class WasmGraphBuilder { ...@@ -164,10 +164,6 @@ class WasmGraphBuilder {
kRetpoline = true, kRetpoline = true,
kNoRetpoline = false kNoRetpoline = false
}; };
enum ExtraCallableParam : bool { // --
kExtraCallableParam = true,
kNoExtraCallableParam = false
};
V8_EXPORT_PRIVATE WasmGraphBuilder( V8_EXPORT_PRIVATE WasmGraphBuilder(
wasm::CompilationEnv* env, Zone* zone, MachineGraph* mcgraph, wasm::CompilationEnv* env, Zone* zone, MachineGraph* mcgraph,
...@@ -610,12 +606,13 @@ class WasmGraphBuilder { ...@@ -610,12 +606,13 @@ class WasmGraphBuilder {
TrapId GetTrapIdForTrap(wasm::TrapReason reason); TrapId GetTrapIdForTrap(wasm::TrapReason reason);
}; };
enum WasmCallKind { kWasmFunction, kWasmImportWrapper, kWasmCapiFunction };
V8_EXPORT_PRIVATE CallDescriptor* GetWasmCallDescriptor( V8_EXPORT_PRIVATE CallDescriptor* GetWasmCallDescriptor(
Zone* zone, wasm::FunctionSig* signature, Zone* zone, wasm::FunctionSig* signature,
WasmGraphBuilder::UseRetpoline use_retpoline = WasmGraphBuilder::UseRetpoline use_retpoline =
WasmGraphBuilder::kNoRetpoline, WasmGraphBuilder::kNoRetpoline,
WasmGraphBuilder::ExtraCallableParam callable_param = WasmCallKind kind = kWasmFunction);
WasmGraphBuilder::kNoExtraCallableParam);
V8_EXPORT_PRIVATE CallDescriptor* GetI32WasmCallDescriptor( V8_EXPORT_PRIVATE CallDescriptor* GetI32WasmCallDescriptor(
Zone* zone, CallDescriptor* call_descriptor); Zone* zone, CallDescriptor* call_descriptor);
......
...@@ -210,13 +210,13 @@ class TypedFrameConstants : public CommonFrameConstants { ...@@ -210,13 +210,13 @@ class TypedFrameConstants : public CommonFrameConstants {
(TypedFrameConstants::kFirstPushedFrameValueOffset - (x)*kSystemPointerSize) (TypedFrameConstants::kFirstPushedFrameValueOffset - (x)*kSystemPointerSize)
#define TYPED_FRAME_SIZE(count) \ #define TYPED_FRAME_SIZE(count) \
(TypedFrameConstants::kFixedFrameSize + (count)*kSystemPointerSize) (TypedFrameConstants::kFixedFrameSize + (count)*kSystemPointerSize)
#define TYPED_FRAME_SIZE_FROM_SP(count) \ #define TYPED_FRAME_SIZE_FROM_FP(count) \
(TypedFrameConstants::kFixedFrameSizeFromFp + (count)*kSystemPointerSize) (TypedFrameConstants::kFixedFrameSizeFromFp + (count)*kSystemPointerSize)
#define DEFINE_TYPED_FRAME_SIZES(count) \ #define DEFINE_TYPED_FRAME_SIZES(count) \
static constexpr int kFixedFrameSize = TYPED_FRAME_SIZE(count); \ static constexpr int kFixedFrameSize = TYPED_FRAME_SIZE(count); \
static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize; \ static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize; \
static constexpr int kFixedFrameSizeFromFp = \ static constexpr int kFixedFrameSizeFromFp = \
TYPED_FRAME_SIZE_FROM_SP(count); \ TYPED_FRAME_SIZE_FROM_FP(count); \
static constexpr int kFixedSlotCountFromFp = \ static constexpr int kFixedSlotCountFromFp = \
kFixedFrameSizeFromFp / kSystemPointerSize kFixedFrameSizeFromFp / kSystemPointerSize
......
...@@ -223,6 +223,9 @@ inline BuiltinFrame::BuiltinFrame(StackFrameIteratorBase* iterator) ...@@ -223,6 +223,9 @@ inline BuiltinFrame::BuiltinFrame(StackFrameIteratorBase* iterator)
inline WasmCompiledFrame::WasmCompiledFrame(StackFrameIteratorBase* iterator) inline WasmCompiledFrame::WasmCompiledFrame(StackFrameIteratorBase* iterator)
: StandardFrame(iterator) {} : StandardFrame(iterator) {}
inline WasmExitFrame::WasmExitFrame(StackFrameIteratorBase* iterator)
: WasmCompiledFrame(iterator) {}
inline WasmInterpreterEntryFrame::WasmInterpreterEntryFrame( inline WasmInterpreterEntryFrame::WasmInterpreterEntryFrame(
StackFrameIteratorBase* iterator) StackFrameIteratorBase* iterator)
: StandardFrame(iterator) {} : StandardFrame(iterator) {}
......
...@@ -163,16 +163,7 @@ bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const { ...@@ -163,16 +163,7 @@ bool StackTraceFrameIterator::IsValidFrame(StackFrame* frame) const {
if (!js_frame->function().IsJSFunction()) return false; if (!js_frame->function().IsJSFunction()) return false;
return js_frame->function().shared().IsSubjectToDebugging(); return js_frame->function().shared().IsSubjectToDebugging();
} }
// Apart from JavaScript frames, only Wasm frames are valid, with the // Apart from JavaScript frames, only Wasm frames are valid.
// exception of Wasm-to-Capi frames.
// TODO(jkummerow): Give Wasm-to-Capi frames their own marker.
if (frame->is_wasm_compiled()) {
wasm::WasmCodeRefScope scope;
if (static_cast<WasmCompiledFrame*>(frame)->wasm_code()->kind() ==
wasm::WasmCode::kWasmToCapiWrapper) {
return false;
}
}
return frame->is_wasm(); return frame->is_wasm();
} }
...@@ -520,8 +511,9 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, ...@@ -520,8 +511,9 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
if (wasm_code != nullptr) { if (wasm_code != nullptr) {
switch (wasm_code->kind()) { switch (wasm_code->kind()) {
case wasm::WasmCode::kFunction: case wasm::WasmCode::kFunction:
case wasm::WasmCode::kWasmToCapiWrapper:
return WASM_COMPILED; return WASM_COMPILED;
case wasm::WasmCode::kWasmToCapiWrapper:
return WASM_EXIT;
case wasm::WasmCode::kWasmToJsWrapper: case wasm::WasmCode::kWasmToJsWrapper:
return WASM_TO_JS; return WASM_TO_JS;
case wasm::WasmCode::kRuntimeStub: case wasm::WasmCode::kRuntimeStub:
...@@ -593,6 +585,7 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, ...@@ -593,6 +585,7 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
case WASM_TO_JS: case WASM_TO_JS:
case WASM_COMPILED: case WASM_COMPILED:
case WASM_COMPILE_LAZY: case WASM_COMPILE_LAZY:
case WASM_EXIT:
return candidate; return candidate;
case JS_TO_WASM: case JS_TO_WASM:
case OPTIMIZED: case OPTIMIZED:
...@@ -675,15 +668,9 @@ Address ExitFrame::GetCallerStackPointer() const { ...@@ -675,15 +668,9 @@ Address ExitFrame::GetCallerStackPointer() const {
StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) { StackFrame::Type ExitFrame::GetStateForFramePointer(Address fp, State* state) {
if (fp == 0) return NONE; if (fp == 0) return NONE;
Address sp = ComputeStackPointer(fp);
StackFrame::Type type = ComputeFrameType(fp); StackFrame::Type type = ComputeFrameType(fp);
if (type == StackFrame::WASM_COMPILED) { Address sp = (type == WASM_EXIT) ? WasmExitFrame::ComputeStackPointer(fp)
// {sp} is only needed for finding the PC slot, the rest is handled : ExitFrame::ComputeStackPointer(fp);
// via safepoint.
sp = fp + WasmExitFrameConstants::kWasmInstanceOffset;
DCHECK_EQ(sp - 1 * kPCOnStackSize,
fp + WasmExitFrameConstants::kCallingPCOffset);
}
FillState(fp, sp, state); FillState(fp, sp, state);
DCHECK_NE(*state->pc_address, kNullAddress); DCHECK_NE(*state->pc_address, kNullAddress);
return type; return type;
...@@ -703,7 +690,7 @@ StackFrame::Type ExitFrame::ComputeFrameType(Address fp) { ...@@ -703,7 +690,7 @@ StackFrame::Type ExitFrame::ComputeFrameType(Address fp) {
StackFrame::Type frame_type = static_cast<StackFrame::Type>(marker_int >> 1); StackFrame::Type frame_type = static_cast<StackFrame::Type>(marker_int >> 1);
if (frame_type == EXIT || frame_type == BUILTIN_EXIT || if (frame_type == EXIT || frame_type == BUILTIN_EXIT ||
frame_type == WASM_COMPILED) { frame_type == WASM_EXIT) {
return frame_type; return frame_type;
} }
...@@ -716,6 +703,15 @@ Address ExitFrame::ComputeStackPointer(Address fp) { ...@@ -716,6 +703,15 @@ Address ExitFrame::ComputeStackPointer(Address fp) {
return Memory<Address>(fp + ExitFrameConstants::kSPOffset); return Memory<Address>(fp + ExitFrameConstants::kSPOffset);
} }
Address WasmExitFrame::ComputeStackPointer(Address fp) {
// For WASM_EXIT frames, {sp} is only needed for finding the PC slot,
// everything else is handled via safepoint information.
Address sp = fp + WasmExitFrameConstants::kWasmInstanceOffset;
DCHECK_EQ(sp - 1 * kPCOnStackSize,
fp + WasmExitFrameConstants::kCallingPCOffset);
return sp;
}
void ExitFrame::FillState(Address fp, Address sp, State* state) { void ExitFrame::FillState(Address fp, Address sp, State* state) {
state->sp = sp; state->sp = sp;
state->fp = fp; state->fp = fp;
...@@ -938,6 +934,14 @@ void StandardFrame::IterateCompiledFrame(RootVisitor* v) const { ...@@ -938,6 +934,14 @@ void StandardFrame::IterateCompiledFrame(RootVisitor* v) const {
case WASM_COMPILE_LAZY: case WASM_COMPILE_LAZY:
frame_header_size = WasmCompiledFrameConstants::kFixedFrameSizeFromFp; frame_header_size = WasmCompiledFrameConstants::kFixedFrameSizeFromFp;
break; break;
case WASM_EXIT:
// The last value in the frame header is the calling PC, which should
// not be visited.
static_assert(WasmExitFrameConstants::kFixedSlotCountFromFp ==
WasmCompiledFrameConstants::kFixedSlotCountFromFp + 1,
"WasmExitFrame has one slot more than WasmCompiledFrame");
frame_header_size = WasmCompiledFrameConstants::kFixedFrameSizeFromFp;
break;
case OPTIMIZED: case OPTIMIZED:
case INTERPRETED: case INTERPRETED:
case BUILTIN: case BUILTIN:
......
...@@ -70,6 +70,7 @@ class StackHandler { ...@@ -70,6 +70,7 @@ class StackHandler {
V(JS_TO_WASM, JsToWasmFrame) \ V(JS_TO_WASM, JsToWasmFrame) \
V(WASM_INTERPRETER_ENTRY, WasmInterpreterEntryFrame) \ V(WASM_INTERPRETER_ENTRY, WasmInterpreterEntryFrame) \
V(C_WASM_ENTRY, CWasmEntryFrame) \ V(C_WASM_ENTRY, CWasmEntryFrame) \
V(WASM_EXIT, WasmExitFrame) \
V(WASM_COMPILE_LAZY, WasmCompileLazyFrame) \ V(WASM_COMPILE_LAZY, WasmCompileLazyFrame) \
V(INTERPRETED, InterpretedFrame) \ V(INTERPRETED, InterpretedFrame) \
V(STUB, StubFrame) \ V(STUB, StubFrame) \
...@@ -171,6 +172,7 @@ class StackFrame { ...@@ -171,6 +172,7 @@ class StackFrame {
bool is_optimized() const { return type() == OPTIMIZED; } bool is_optimized() const { return type() == OPTIMIZED; }
bool is_interpreted() const { return type() == INTERPRETED; } bool is_interpreted() const { return type() == INTERPRETED; }
bool is_wasm_compiled() const { return type() == WASM_COMPILED; } bool is_wasm_compiled() const { return type() == WASM_COMPILED; }
bool is_wasm_exit() const { return type() == WASM_EXIT; }
bool is_wasm_compile_lazy() const { return type() == WASM_COMPILE_LAZY; } bool is_wasm_compile_lazy() const { return type() == WASM_COMPILE_LAZY; }
bool is_wasm_to_js() const { return type() == WASM_TO_JS; } bool is_wasm_to_js() const { return type() == WASM_TO_JS; }
bool is_js_to_wasm() const { return type() == JS_TO_WASM; } bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
...@@ -925,7 +927,7 @@ class BuiltinFrame final : public JavaScriptFrame { ...@@ -925,7 +927,7 @@ class BuiltinFrame final : public JavaScriptFrame {
friend class StackFrameIteratorBase; friend class StackFrameIteratorBase;
}; };
class WasmCompiledFrame final : public StandardFrame { class WasmCompiledFrame : public StandardFrame {
public: public:
Type type() const override { return WASM_COMPILED; } Type type() const override { return WASM_COMPILED; }
...@@ -968,6 +970,18 @@ class WasmCompiledFrame final : public StandardFrame { ...@@ -968,6 +970,18 @@ class WasmCompiledFrame final : public StandardFrame {
WasmModuleObject module_object() const; WasmModuleObject module_object() const;
}; };
class WasmExitFrame : public WasmCompiledFrame {
public:
Type type() const override { return WASM_EXIT; }
static Address ComputeStackPointer(Address fp);
protected:
inline explicit WasmExitFrame(StackFrameIteratorBase* iterator);
private:
friend class StackFrameIteratorBase;
};
class WasmInterpreterEntryFrame final : public StandardFrame { class WasmInterpreterEntryFrame final : public StandardFrame {
public: public:
Type type() const override { return WASM_INTERPRETER_ENTRY; } Type type() const override { return WASM_INTERPRETER_ENTRY; }
......
...@@ -425,6 +425,7 @@ FRAME_MARKERS = ( ...@@ -425,6 +425,7 @@ FRAME_MARKERS = (
"JS_TO_WASM", "JS_TO_WASM",
"WASM_INTERPRETER_ENTRY", "WASM_INTERPRETER_ENTRY",
"C_WASM_ENTRY", "C_WASM_ENTRY",
"WASM_EXIT",
"WASM_COMPILE_LAZY", "WASM_COMPILE_LAZY",
"INTERPRETED", "INTERPRETED",
"STUB", "STUB",
......
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