From 87fe40134a0a2b84f694f6b1796ef5f7ce71b44e Mon Sep 17 00:00:00 2001 From: Michael Starzinger Date: Thu, 14 Jun 2018 15:28:18 +0200 Subject: [PATCH] [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/1100882 Reviewed-by: Clemens Hammacher Commit-Queue: Michael Starzinger Cr-Commit-Position: refs/heads/master@{#53734} --- src/builtins/builtins-definitions.h | 2 ++ src/builtins/builtins-wasm-gen.cc | 46 ++++++++++++++++++++++++ src/compiler/ia32/code-generator-ia32.cc | 2 +- src/compiler/linkage.cc | 37 ++++++++++--------- src/compiler/linkage.h | 4 +-- src/compiler/wasm-compiler.cc | 28 ++++++++------- src/compiler/x64/code-generator-x64.cc | 4 +-- src/wasm/wasm-code-manager.cc | 2 -- src/wasm/wasm-code-manager.h | 2 ++ src/wasm/wasm-objects-inl.h | 2 ++ src/wasm/wasm-objects.cc | 2 ++ src/wasm/wasm-objects.h | 4 ++- 12 files changed, 99 insertions(+), 36 deletions(-) diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h index d2be0d05a4..873bb9f6f6 100644 --- a/src/builtins/builtins-definitions.h +++ b/src/builtins/builtins-definitions.h @@ -1192,6 +1192,8 @@ namespace internal { \ /* Wasm */ \ ASM(WasmCompileLazy) \ + TFC(WasmArgumentsAdaptor, ArgumentAdaptor, 1) \ + TFC(WasmCallJavaScript, CallTrampoline, 1) \ TFS(WasmStackGuard) \ TFS(ThrowWasmTrapUnreachable) \ TFS(ThrowWasmTrapMemOutOfBounds) \ diff --git a/src/builtins/builtins-wasm-gen.cc b/src/builtins/builtins-wasm-gen.cc index 0a7cd6115c..a890ebba62 100644 --- a/src/builtins/builtins-wasm-gen.cc +++ b/src/builtins/builtins-wasm-gen.cc @@ -12,6 +12,52 @@ namespace internal { typedef compiler::Node Node; +TF_BUILTIN(WasmArgumentsAdaptor, CodeStubAssembler) { + TNode context = + UncheckedCast(Parameter(Descriptor::kContext)); + TNode function = + UncheckedCast(Parameter(Descriptor::kFunction)); + TNode new_target = + UncheckedCast(Parameter(Descriptor::kNewTarget)); + TNode argc1 = + UncheckedCast(Parameter(Descriptor::kActualArgumentsCount)); + TNode argc2 = + UncheckedCast(Parameter(Descriptor::kExpectedArgumentsCount)); + TNode instance = UncheckedCast( + LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset)); + TNode roots = UncheckedCast( + Load(MachineType::Pointer(), instance, + IntPtrConstant(WasmInstanceObject::kRootsArrayAddressOffset - + kHeapObjectTag))); + TNode target = UncheckedCast(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 context = + UncheckedCast(Parameter(Descriptor::kContext)); + TNode function = + UncheckedCast(Parameter(Descriptor::kFunction)); + TNode argc = + UncheckedCast(Parameter(Descriptor::kActualArgumentsCount)); + TNode instance = UncheckedCast( + LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset)); + TNode roots = UncheckedCast( + Load(MachineType::Pointer(), instance, + IntPtrConstant(WasmInstanceObject::kRootsArrayAddressOffset - + kHeapObjectTag))); + TNode target = UncheckedCast( + 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) { TNode instance = UncheckedCast( LoadFromParentFrame(WasmCompiledFrameConstants::kWasmInstanceOffset)); diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc index 47e15d45ae..341c4fdb0d 100644 --- a/src/compiler/ia32/code-generator-ia32.cc +++ b/src/compiler/ia32/code-generator-ia32.cc @@ -614,7 +614,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( if (HasImmediateInput(instr, 0)) { Constant constant = i.ToConstant(instr->InputAt(0)); Address wasm_code = static_cast
(constant.ToInt32()); - if (info()->IsWasm()) { + if (DetermineStubCallMode() == StubCallMode::kCallWasmRuntimeStub) { __ wasm_call(wasm_code, constant.rmode()); } else { if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) { diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc index 70fd3d4079..a860841af5 100644 --- a/src/compiler/linkage.cc +++ b/src/compiler/linkage.cc @@ -347,7 +347,8 @@ CallDescriptor* Linkage::GetStubCallDescriptor( Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor, int stack_parameter_count, CallDescriptor::Flags flags, 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 js_parameter_count = register_parameter_count + stack_parameter_count; @@ -387,21 +388,25 @@ CallDescriptor* Linkage::GetStubCallDescriptor( locations.AddParam(regloc(kContextRegister, MachineType::AnyTagged())); } - // The target for stub calls is a code object. - MachineType target_type = MachineType::AnyTagged(); - LinkageLocation target_loc = - LinkageLocation::ForAnyRegister(MachineType::AnyTagged()); - return new (zone) CallDescriptor( // -- - CallDescriptor::kCallCodeObject, // kind - target_type, // target MachineType - target_loc, // target location - locations.Build(), // location_sig - stack_parameter_count, // stack_parameter_count - properties, // properties - kNoCalleeSaved, // callee-saved registers - kNoCalleeSaved, // callee-saved fp - CallDescriptor::kCanUseRoots | // flags - flags, // flags + // The target for stub calls depends on the requested mode. + CallDescriptor::Kind kind = stub_mode == StubCallMode::kCallWasmRuntimeStub + ? CallDescriptor::kCallWasmFunction + : CallDescriptor::kCallCodeObject; + MachineType target_type = stub_mode == StubCallMode::kCallWasmRuntimeStub + ? MachineType::Pointer() + : MachineType::AnyTagged(); + LinkageLocation target_loc = LinkageLocation::ForAnyRegister(target_type); + return new (zone) CallDescriptor( // -- + kind, // kind + target_type, // target MachineType + target_loc, // target location + locations.Build(), // location_sig + stack_parameter_count, // stack_parameter_count + properties, // properties + kNoCalleeSaved, // callee-saved registers + kNoCalleeSaved, // callee-saved fp + CallDescriptor::kCanUseRoots | // flags + flags, // flags descriptor.DebugName(isolate), descriptor.allocatable_registers()); } diff --git a/src/compiler/linkage.h b/src/compiler/linkage.h index 8b490e2f9a..01befb71db 100644 --- a/src/compiler/linkage.h +++ b/src/compiler/linkage.h @@ -394,8 +394,8 @@ class V8_EXPORT_PRIVATE Linkage : public NON_EXPORTED_BASE(ZoneObject) { int stack_parameter_count, CallDescriptor::Flags flags, Operator::Properties properties = Operator::kNoProperties, MachineType return_type = MachineType::AnyTagged(), - size_t return_count = 1, - ContextSpecification context_spec = kPassContext); + size_t return_count = 1, ContextSpecification context_spec = kPassContext, + StubCallMode stub_mode = StubCallMode::kCallOnHeapBuiltin); static CallDescriptor* GetAllocateCallDescriptor(Isolate* isolate, Zone* zone); diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index 4845d3b05c..d028b3ff55 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -4479,9 +4479,9 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor), pos, args); } else if (function->shared()->internal_formal_parameter_count() >= 0) { - Callable callable = CodeFactory::ArgumentAdaptor(isolate_); 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++] = undefined_node; // new target args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count @@ -4497,16 +4497,19 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { 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. pos = AddArgumentNodes(args, pos, wasm_count, sig_); args[pos++] = function_context; args[pos++] = *effect_; args[pos++] = *control_; - call = graph()->NewNode( - mcgraph()->common()->Call(Linkage::GetStubCallDescriptor( - isolate_, mcgraph()->zone(), callable.descriptor(), - 1 + wasm_count, CallDescriptor::kNoFlags)), - pos, args); + call = graph()->NewNode(mcgraph()->common()->Call(call_descriptor), + pos, args); } } } @@ -4514,16 +4517,17 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { // We cannot call the target directly, we have to use the Call builtin. if (!call) { int pos = 0; - // We cannot call the target directly, we have to use the Call builtin. - Callable callable = CodeFactory::Call(isolate_); - args[pos++] = jsgraph()->HeapConstant(callable.code()); + args[pos++] = mcgraph()->RelocatableIntPtrConstant( + wasm::WasmCode::kWasmCallJavaScript, RelocInfo::WASM_STUB_CALL); args[pos++] = callable_node; args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count args[pos++] = undefined_node; // receiver call_descriptor = Linkage::GetStubCallDescriptor( - isolate_, graph()->zone(), callable.descriptor(), wasm_count + 1, - CallDescriptor::kNoFlags); + isolate_, graph()->zone(), CallTrampolineDescriptor(isolate_), + wasm_count + 1, CallDescriptor::kNoFlags, Operator::kNoProperties, + MachineType::AnyTagged(), 1, Linkage::kPassContext, + StubCallMode::kCallWasmRuntimeStub); // Convert wasm numbers to JS values. pos = AddArgumentNodes(args, pos, wasm_count, sig_); diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc index 565581f218..9ee4813836 100644 --- a/src/compiler/x64/code-generator-x64.cc +++ b/src/compiler/x64/code-generator-x64.cc @@ -699,7 +699,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( if (HasImmediateInput(instr, 0)) { Constant constant = i.ToConstant(instr->InputAt(0)); Address wasm_code = static_cast
(constant.ToInt64()); - if (info()->IsWasm()) { + if (DetermineStubCallMode() == StubCallMode::kCallWasmRuntimeStub) { __ near_call(wasm_code, constant.rmode()); } else { if (HasCallDescriptorFlag(instr, CallDescriptor::kRetpoline)) { @@ -751,7 +751,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( if (HasImmediateInput(instr, 0)) { Constant constant = i.ToConstant(instr->InputAt(0)); Address wasm_code = static_cast
(constant.ToInt64()); - if (info()->IsWasm()) { + if (DetermineStubCallMode() == StubCallMode::kCallWasmRuntimeStub) { __ near_jmp(wasm_code, constant.rmode()); } else { __ Move(kScratchRegister, wasm_code, constant.rmode()); diff --git a/src/wasm/wasm-code-manager.cc b/src/wasm/wasm-code-manager.cc index 701ed57be8..9fe8566065 100644 --- a/src/wasm/wasm-code-manager.cc +++ b/src/wasm/wasm-code-manager.cc @@ -202,8 +202,6 @@ void WasmCode::Validate() const { // of {RelocInfo::CODE_TARGET} relocation entries altogether. int builtin_index = code->builtin_index(); CHECK(builtin_index == Builtins::kAllocateHeapNumber || - builtin_index == Builtins::kArgumentsAdaptorTrampoline || - builtin_index == Builtins::kCall_ReceiverIsAny || builtin_index == Builtins::kToNumber); break; } diff --git a/src/wasm/wasm-code-manager.h b/src/wasm/wasm-code-manager.h index 87db406ce3..5bb5430160 100644 --- a/src/wasm/wasm-code-manager.h +++ b/src/wasm/wasm-code-manager.h @@ -33,6 +33,8 @@ struct WasmModule; // elements of the list coincide with {compiler::TrapId}, order matters. #define WASM_RUNTIME_STUB_LIST(V, VTRAP) \ FOREACH_WASM_TRAPREASON(VTRAP) \ + V(WasmArgumentsAdaptor) \ + V(WasmCallJavaScript) \ V(WasmStackGuard) \ V(DoubleToI) diff --git a/src/wasm/wasm-objects-inl.h b/src/wasm/wasm-objects-inl.h index 48a6c89a62..64cfd551b8 100644 --- a/src/wasm/wasm-objects-inl.h +++ b/src/wasm/wasm-objects-inl.h @@ -124,6 +124,8 @@ PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_size, uint32_t, kMemorySizeOffset) PRIMITIVE_ACCESSORS(WasmInstanceObject, memory_mask, uint32_t, kMemoryMaskOffset) +PRIMITIVE_ACCESSORS(WasmInstanceObject, roots_array_address, Address, + kRootsArrayAddressOffset) PRIMITIVE_ACCESSORS(WasmInstanceObject, stack_limit_address, Address, kStackLimitAddressOffset) PRIMITIVE_ACCESSORS(WasmInstanceObject, imported_function_targets, Address*, diff --git a/src/wasm/wasm-objects.cc b/src/wasm/wasm-objects.cc index b7f6d7c998..e0c3873f5a 100644 --- a/src/wasm/wasm-objects.cc +++ b/src/wasm/wasm-objects.cc @@ -1327,6 +1327,8 @@ Handle WasmInstanceObject::New( instance->set_centry_stub(*centry_stub); instance->SetRawMemory(nullptr, 0); + instance->set_roots_array_address( + reinterpret_cast
(isolate->heap()->roots_array_start())); instance->set_stack_limit_address( isolate->stack_guard()->address_of_jslimit()); instance->set_globals_start(nullptr); diff --git a/src/wasm/wasm-objects.h b/src/wasm/wasm-objects.h index 1cc467d425..3c2e7f5ee0 100644 --- a/src/wasm/wasm-objects.h +++ b/src/wasm/wasm-objects.h @@ -394,7 +394,8 @@ class WasmInstanceObject : public JSObject { DECL_PRIMITIVE_ACCESSORS(memory_start, byte*) DECL_PRIMITIVE_ACCESSORS(memory_size, 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(globals_start, byte*) DECL_PRIMITIVE_ACCESSORS(imported_mutable_globals, Address*) @@ -429,6 +430,7 @@ class WasmInstanceObject : public JSObject { V(kMemoryStartOffset, kPointerSize) /* untagged */ \ V(kMemorySizeOffset, kUInt32Size) /* untagged */ \ V(kMemoryMaskOffset, kUInt32Size) /* untagged */ \ + V(kRootsArrayAddressOffset, kPointerSize) /* untagged */ \ V(kStackLimitAddressOffset, kPointerSize) /* untagged */ \ V(kImportedFunctionTargetsOffset, kPointerSize) /* untagged */ \ V(kGlobalsStartOffset, kPointerSize) /* untagged */ \