Commit 87fe4013 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Allow calling runtime stubs with stub linkage.

This allows WebAssembly runtime stubs implemented as {WasmCode} to be
called with regular stub linkage. So far we have only been able to call
such stubs with WebAssembly linkage.

Also switch two more on-heap builtins over to WebAssembly runtime stubs.

R=clemensh@chromium.org
BUG=v8:7424

Change-Id: Ifa553b5908ee27a1be780c325a114449d7fe7001
Reviewed-on: https://chromium-review.googlesource.com/1100882Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53734}
parent 8e2e1257
...@@ -1192,6 +1192,8 @@ namespace internal { ...@@ -1192,6 +1192,8 @@ namespace internal {
\ \
/* Wasm */ \ /* Wasm */ \
ASM(WasmCompileLazy) \ ASM(WasmCompileLazy) \
TFC(WasmArgumentsAdaptor, ArgumentAdaptor, 1) \
TFC(WasmCallJavaScript, CallTrampoline, 1) \
TFS(WasmStackGuard) \ TFS(WasmStackGuard) \
TFS(ThrowWasmTrapUnreachable) \ TFS(ThrowWasmTrapUnreachable) \
TFS(ThrowWasmTrapMemOutOfBounds) \ TFS(ThrowWasmTrapMemOutOfBounds) \
......
...@@ -12,6 +12,52 @@ namespace internal { ...@@ -12,6 +12,52 @@ namespace internal {
typedef compiler::Node Node; typedef compiler::Node Node;
TF_BUILTIN(WasmArgumentsAdaptor, CodeStubAssembler) {
TNode<Object> context =
UncheckedCast<Object>(Parameter(Descriptor::kContext));
TNode<Object> function =
UncheckedCast<Object>(Parameter(Descriptor::kFunction));
TNode<Object> new_target =
UncheckedCast<Object>(Parameter(Descriptor::kNewTarget));
TNode<Object> argc1 =
UncheckedCast<Object>(Parameter(Descriptor::kActualArgumentsCount));
TNode<Object> argc2 =
UncheckedCast<Object>(Parameter(Descriptor::kExpectedArgumentsCount));
TNode<Object> instance = UncheckedCast<Object>(
LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset));
TNode<IntPtrT> roots = UncheckedCast<IntPtrT>(
Load(MachineType::Pointer(), instance,
IntPtrConstant(WasmInstanceObject::kRootsArrayAddressOffset -
kHeapObjectTag)));
TNode<Code> target = UncheckedCast<Code>(Load(
MachineType::TaggedPointer(), roots,
IntPtrConstant(Heap::roots_to_builtins_offset() +
Builtins::kArgumentsAdaptorTrampoline * kPointerSize)));
TailCallStub(ArgumentAdaptorDescriptor(isolate()), target, context, function,
new_target, argc1, argc2);
}
TF_BUILTIN(WasmCallJavaScript, CodeStubAssembler) {
TNode<Object> context =
UncheckedCast<Object>(Parameter(Descriptor::kContext));
TNode<Object> function =
UncheckedCast<Object>(Parameter(Descriptor::kFunction));
TNode<Object> argc =
UncheckedCast<Object>(Parameter(Descriptor::kActualArgumentsCount));
TNode<Object> instance = UncheckedCast<Object>(
LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset));
TNode<IntPtrT> roots = UncheckedCast<IntPtrT>(
Load(MachineType::Pointer(), instance,
IntPtrConstant(WasmInstanceObject::kRootsArrayAddressOffset -
kHeapObjectTag)));
TNode<Code> target = UncheckedCast<Code>(
Load(MachineType::TaggedPointer(), roots,
IntPtrConstant(Heap::roots_to_builtins_offset() +
Builtins::kCall_ReceiverIsAny * kPointerSize)));
TailCallStub(CallTrampolineDescriptor(isolate()), target, context, function,
argc);
}
TF_BUILTIN(WasmStackGuard, CodeStubAssembler) { TF_BUILTIN(WasmStackGuard, CodeStubAssembler) {
TNode<Object> instance = UncheckedCast<Object>( TNode<Object> instance = UncheckedCast<Object>(
LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset)); LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset));
......
...@@ -614,7 +614,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -614,7 +614,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (HasImmediateInput(instr, 0)) { if (HasImmediateInput(instr, 0)) {
Constant constant = i.ToConstant(instr->InputAt(0)); Constant constant = i.ToConstant(instr->InputAt(0));
Address wasm_code = static_cast<Address>(constant.ToInt32()); Address wasm_code = static_cast<Address>(constant.ToInt32());
if (info()->IsWasm()) { if (DetermineStubCallMode() == StubCallMode::kCallWasmRuntimeStub) {
__ wasm_call(wasm_code, constant.rmode()); __ wasm_call(wasm_code, constant.rmode());
} else { } else {
if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) { if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) {
......
...@@ -347,7 +347,8 @@ CallDescriptor* Linkage::GetStubCallDescriptor( ...@@ -347,7 +347,8 @@ CallDescriptor* Linkage::GetStubCallDescriptor(
Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
int stack_parameter_count, CallDescriptor::Flags flags, int stack_parameter_count, CallDescriptor::Flags flags,
Operator::Properties properties, MachineType return_type, Operator::Properties properties, MachineType return_type,
size_t return_count, Linkage::ContextSpecification context_spec) { size_t return_count, Linkage::ContextSpecification context_spec,
StubCallMode stub_mode) {
const int register_parameter_count = descriptor.GetRegisterParameterCount(); const int register_parameter_count = descriptor.GetRegisterParameterCount();
const int js_parameter_count = const int js_parameter_count =
register_parameter_count + stack_parameter_count; register_parameter_count + stack_parameter_count;
...@@ -387,21 +388,25 @@ CallDescriptor* Linkage::GetStubCallDescriptor( ...@@ -387,21 +388,25 @@ CallDescriptor* Linkage::GetStubCallDescriptor(
locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged())); locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged()));
} }
// The target for stub calls is a code object. // The target for stub calls depends on the requested mode.
MachineType target_type = MachineType::AnyTagged(); CallDescriptor::Kind kind = stub_mode == StubCallMode::kCallWasmRuntimeStub
LinkageLocation target_loc = ? CallDescriptor::kCallWasmFunction
LinkageLocation::ForAnyRegister(MachineType::AnyTagged()); : CallDescriptor::kCallCodeObject;
return new (zone) CallDescriptor( // -- MachineType target_type = stub_mode == StubCallMode::kCallWasmRuntimeStub
CallDescriptor::kCallCodeObject, // kind ? MachineType::Pointer()
target_type, // target MachineType : MachineType::AnyTagged();
target_loc, // target location LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type);
locations.Build(), // location_sig return new (zone) CallDescriptor( // --
stack_parameter_count, // stack_parameter_count kind, // kind
properties, // properties target_type, // target MachineType
kNoCalleeSaved, // callee-saved registers target_loc, // target location
kNoCalleeSaved, // callee-saved fp locations.Build(), // location_sig
CallDescriptor::kCanUseRoots | // flags stack_parameter_count, // stack_parameter_count
flags, // flags properties, // properties
kNoCalleeSaved, // callee-saved registers
kNoCalleeSaved, // callee-saved fp
CallDescriptor::kCanUseRoots | // flags
flags, // flags
descriptor.DebugName(isolate), descriptor.allocatable_registers()); descriptor.DebugName(isolate), descriptor.allocatable_registers());
} }
......
...@@ -394,8 +394,8 @@ class V8_EXPORT_PRIVATE Linkage : public NON_EXPORTED_BASE(ZoneObject) { ...@@ -394,8 +394,8 @@ class V8_EXPORT_PRIVATE Linkage : public NON_EXPORTED_BASE(ZoneObject) {
int stack_parameter_count, CallDescriptor::Flags flags, int stack_parameter_count, CallDescriptor::Flags flags,
Operator::Properties properties = Operator::kNoProperties, Operator::Properties properties = Operator::kNoProperties,
MachineType return_type = MachineType::AnyTagged(), MachineType return_type = MachineType::AnyTagged(),
size_t return_count = 1, size_t return_count = 1, ContextSpecification context_spec = kPassContext,
ContextSpecification context_spec = kPassContext); StubCallMode stub_mode = StubCallMode::kCallOnHeapBuiltin);
static CallDescriptor* GetAllocateCallDescriptor(Isolate* isolate, static CallDescriptor* GetAllocateCallDescriptor(Isolate* isolate,
Zone* zone); Zone* zone);
......
...@@ -4479,9 +4479,9 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4479,9 +4479,9 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor), call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor),
pos, args); pos, args);
} else if (function->shared()->internal_formal_parameter_count() >= 0) { } else if (function->shared()->internal_formal_parameter_count() >= 0) {
Callable callable = CodeFactory::ArgumentAdaptor(isolate_);
int pos = 0; int pos = 0;
args[pos++] = jsgraph()->HeapConstant(callable.code()); args[pos++] = mcgraph()->RelocatableIntPtrConstant(
wasm::WasmCode::kWasmArgumentsAdaptor, RelocInfo::WASM_STUB_CALL);
args[pos++] = callable_node; // target callable args[pos++] = callable_node; // target callable
args[pos++] = undefined_node; // new target args[pos++] = undefined_node; // new target
args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count
...@@ -4497,16 +4497,19 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4497,16 +4497,19 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
args[pos++] = undefined_node; args[pos++] = undefined_node;
} }
call_descriptor = Linkage::GetStubCallDescriptor(
isolate_, mcgraph()->zone(), ArgumentAdaptorDescriptor(isolate_),
1 + wasm_count, CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), 1, Linkage::kPassContext,
StubCallMode::kCallWasmRuntimeStub);
// Convert wasm numbers to JS values. // Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_); pos = AddArgumentNodes(args, pos, wasm_count, sig_);
args[pos++] = function_context; args[pos++] = function_context;
args[pos++] = *effect_; args[pos++] = *effect_;
args[pos++] = *control_; args[pos++] = *control_;
call = graph()->NewNode( call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor),
mcgraph()->common()->Call(Linkage::GetStubCallDescriptor( pos, args);
isolate_, mcgraph()->zone(), callable.descriptor(),
1 + wasm_count, CallDescriptor::kNoFlags)),
pos, args);
} }
} }
} }
...@@ -4514,16 +4517,17 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4514,16 +4517,17 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
// We cannot call the target directly, we have to use the Call builtin. // We cannot call the target directly, we have to use the Call builtin.
if (!call) { if (!call) {
int pos = 0; int pos = 0;
// We cannot call the target directly, we have to use the Call builtin. args[pos++] = mcgraph()->RelocatableIntPtrConstant(
Callable callable = CodeFactory::Call(isolate_); wasm::WasmCode::kWasmCallJavaScript, RelocInfo::WASM_STUB_CALL);
args[pos++] = jsgraph()->HeapConstant(callable.code());
args[pos++] = callable_node; args[pos++] = callable_node;
args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count
args[pos++] = undefined_node; // receiver args[pos++] = undefined_node; // receiver
call_descriptor = Linkage::GetStubCallDescriptor( call_descriptor = Linkage::GetStubCallDescriptor(
isolate_, graph()->zone(), callable.descriptor(), wasm_count + 1, isolate_, graph()->zone(), CallTrampolineDescriptor(isolate_),
CallDescriptor::kNoFlags); wasm_count + 1, CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), 1, Linkage::kPassContext,
StubCallMode::kCallWasmRuntimeStub);
// Convert wasm numbers to JS values. // Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_); pos = AddArgumentNodes(args, pos, wasm_count, sig_);
......
...@@ -699,7 +699,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -699,7 +699,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (HasImmediateInput(instr, 0)) { if (HasImmediateInput(instr, 0)) {
Constant constant = i.ToConstant(instr->InputAt(0)); Constant constant = i.ToConstant(instr->InputAt(0));
Address wasm_code = static_cast<Address>(constant.ToInt64()); Address wasm_code = static_cast<Address>(constant.ToInt64());
if (info()->IsWasm()) { if (DetermineStubCallMode() == StubCallMode::kCallWasmRuntimeStub) {
__ near_call(wasm_code, constant.rmode()); __ near_call(wasm_code, constant.rmode());
} else { } else {
if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) { if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) {
...@@ -751,7 +751,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -751,7 +751,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
if (HasImmediateInput(instr, 0)) { if (HasImmediateInput(instr, 0)) {
Constant constant = i.ToConstant(instr->InputAt(0)); Constant constant = i.ToConstant(instr->InputAt(0));
Address wasm_code = static_cast<Address>(constant.ToInt64()); Address wasm_code = static_cast<Address>(constant.ToInt64());
if (info()->IsWasm()) { if (DetermineStubCallMode() == StubCallMode::kCallWasmRuntimeStub) {
__ near_jmp(wasm_code, constant.rmode()); __ near_jmp(wasm_code, constant.rmode());
} else { } else {
__ Move(kScratchRegister, wasm_code, constant.rmode()); __ Move(kScratchRegister, wasm_code, constant.rmode());
......
...@@ -202,8 +202,6 @@ void WasmCode::Validate() const { ...@@ -202,8 +202,6 @@ void WasmCode::Validate() const {
// of {RelocInfo::CODE_TARGET} relocation entries altogether. // of {RelocInfo::CODE_TARGET} relocation entries altogether.
int builtin_index = code->builtin_index(); int builtin_index = code->builtin_index();
CHECK(builtin_index == Builtins::kAllocateHeapNumber || CHECK(builtin_index == Builtins::kAllocateHeapNumber ||
builtin_index == Builtins::kArgumentsAdaptorTrampoline ||
builtin_index == Builtins::kCall_ReceiverIsAny ||
builtin_index == Builtins::kToNumber); builtin_index == Builtins::kToNumber);
break; break;
} }
......
...@@ -33,6 +33,8 @@ struct WasmModule; ...@@ -33,6 +33,8 @@ struct WasmModule;
// elements of the list coincide with {compiler::TrapId}, order matters. // elements of the list coincide with {compiler::TrapId}, order matters.
#define WASM_RUNTIME_STUB_LIST(V, VTRAP) \ #define WASM_RUNTIME_STUB_LIST(V, VTRAP) \
FOREACH_WASM_TRAPREASON(VTRAP) \ FOREACH_WASM_TRAPREASON(VTRAP) \
V(WasmArgumentsAdaptor) \
V(WasmCallJavaScript) \
V(WasmStackGuard) \ V(WasmStackGuard) \
V(DoubleToI) V(DoubleToI)
......
...@@ -124,6 +124,8 @@ PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_size, uint32_t, ...@@ -124,6 +124,8 @@ PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_size, uint32_t,
kMemorySizeOffset) kMemorySizeOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_mask, uint32_t, PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_mask, uint32_t,
kMemoryMaskOffset) kMemoryMaskOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, roots_array_address, Address,
kRootsArrayAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, stack_limit_address, Address, PRIMITIVE_ACCESSORS(WasmInstanceObject, stack_limit_address, Address,
kStackLimitAddressOffset) kStackLimitAddressOffset)
PRIMITIVE_ACCESSORS(WasmInstanceObject, imported_function_targets, Address*, PRIMITIVE_ACCESSORS(WasmInstanceObject, imported_function_targets, Address*,
......
...@@ -1327,6 +1327,8 @@ Handle<WasmInstanceObject> WasmInstanceObject::New( ...@@ -1327,6 +1327,8 @@ Handle<WasmInstanceObject> WasmInstanceObject::New(
instance->set_centry_stub(*centry_stub); instance->set_centry_stub(*centry_stub);
instance->SetRawMemory(nullptr, 0); instance->SetRawMemory(nullptr, 0);
instance->set_roots_array_address(
reinterpret_cast<Address>(isolate->heap()->roots_array_start()));
instance->set_stack_limit_address( instance->set_stack_limit_address(
isolate->stack_guard()->address_of_jslimit()); isolate->stack_guard()->address_of_jslimit());
instance->set_globals_start(nullptr); instance->set_globals_start(nullptr);
......
...@@ -394,7 +394,8 @@ class WasmInstanceObject : public JSObject { ...@@ -394,7 +394,8 @@ class WasmInstanceObject : public JSObject {
DECL_PRIMITIVE_ACCESSORS(memory_start, byte*) DECL_PRIMITIVE_ACCESSORS(memory_start, byte*)
DECL_PRIMITIVE_ACCESSORS(memory_size, uint32_t) DECL_PRIMITIVE_ACCESSORS(memory_size, uint32_t)
DECL_PRIMITIVE_ACCESSORS(memory_mask, uint32_t) DECL_PRIMITIVE_ACCESSORS(memory_mask, uint32_t)
DECL_PRIMITIVE_ACCESSORS(stack_limit_address, Address); DECL_PRIMITIVE_ACCESSORS(roots_array_address, Address)
DECL_PRIMITIVE_ACCESSORS(stack_limit_address, Address)
DECL_PRIMITIVE_ACCESSORS(imported_function_targets, Address*) DECL_PRIMITIVE_ACCESSORS(imported_function_targets, Address*)
DECL_PRIMITIVE_ACCESSORS(globals_start, byte*) DECL_PRIMITIVE_ACCESSORS(globals_start, byte*)
DECL_PRIMITIVE_ACCESSORS(imported_mutable_globals, Address*) DECL_PRIMITIVE_ACCESSORS(imported_mutable_globals, Address*)
...@@ -429,6 +430,7 @@ class WasmInstanceObject : public JSObject { ...@@ -429,6 +430,7 @@ class WasmInstanceObject : public JSObject {
V(kMemoryStartOffset, kPointerSize) /* untagged */ \ V(kMemoryStartOffset, kPointerSize) /* untagged */ \
V(kMemorySizeOffset, kUInt32Size) /* untagged */ \ V(kMemorySizeOffset, kUInt32Size) /* untagged */ \
V(kMemoryMaskOffset, kUInt32Size) /* untagged */ \ V(kMemoryMaskOffset, kUInt32Size) /* untagged */ \
V(kRootsArrayAddressOffset, kPointerSize) /* untagged */ \
V(kStackLimitAddressOffset, kPointerSize) /* untagged */ \ V(kStackLimitAddressOffset, kPointerSize) /* untagged */ \
V(kImportedFunctionTargetsOffset, kPointerSize) /* untagged */ \ V(kImportedFunctionTargetsOffset, kPointerSize) /* untagged */ \
V(kGlobalsStartOffset, kPointerSize) /* untagged */ \ V(kGlobalsStartOffset, kPointerSize) /* untagged */ \
......
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