From bfe13285651fe09e3ec9cc742686b54409637bd7 Mon Sep 17 00:00:00 2001 From: Michael Starzinger Date: Fri, 8 Nov 2019 11:32:43 +0100 Subject: [PATCH] [wasm] Remove runtime call support from Liftoff. This removes the support to emit runtime calls in Liftoff code and uses WebAssembly runtime stubs instead. Calls to such stubs are smaller and more efficient. They also use embedded builtins directly instead of the on-heap {Code} object trampolines. This also removes the last use of a runtime call that passes a dynamically loaded CEntry builtin from the macro assembler. R=clemensb@chromium.org Change-Id: I9fa9f3b7a2b66cb76a677b70ce3cee49cb340f0f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1903443 Commit-Queue: Michael Starzinger Reviewed-by: Clemens Backes Cr-Commit-Position: refs/heads/master@{#64855} --- src/builtins/builtins-definitions.h | 2 + src/builtins/builtins-wasm-gen.cc | 7 +++ src/codegen/arm/macro-assembler-arm.cc | 13 ------ src/codegen/arm/macro-assembler-arm.h | 4 -- src/codegen/arm64/macro-assembler-arm64.cc | 13 ------ src/codegen/arm64/macro-assembler-arm64.h | 4 -- src/codegen/ia32/macro-assembler-ia32.cc | 14 ------ src/codegen/ia32/macro-assembler-ia32.h | 4 -- src/codegen/mips/macro-assembler-mips.cc | 13 ------ src/codegen/mips/macro-assembler-mips.h | 4 -- src/codegen/mips64/macro-assembler-mips64.cc | 14 ------ src/codegen/mips64/macro-assembler-mips64.h | 4 -- src/codegen/ppc/macro-assembler-ppc.cc | 13 ------ src/codegen/ppc/macro-assembler-ppc.h | 4 -- src/codegen/s390/macro-assembler-s390.cc | 9 ---- src/codegen/s390/macro-assembler-s390.h | 4 -- src/codegen/x64/macro-assembler-x64.cc | 14 ------ src/codegen/x64/macro-assembler-x64.h | 4 -- src/wasm/baseline/liftoff-compiler.cc | 49 +++++--------------- 19 files changed, 20 insertions(+), 173 deletions(-) diff --git a/src/builtins/builtins-definitions.h b/src/builtins/builtins-definitions.h index f4af77fec9..91633e4ad8 100644 --- a/src/builtins/builtins-definitions.h +++ b/src/builtins/builtins-definitions.h @@ -949,6 +949,7 @@ namespace internal { TFC(WasmStackOverflow, NoContext) \ TFC(WasmThrow, WasmThrow) \ TFC(WasmRethrow, WasmThrow) \ + TFS(WasmTraceMemory, kMemoryTracingInfo) \ TFS(ThrowWasmTrapUnreachable) \ TFS(ThrowWasmTrapMemOutOfBounds) \ TFS(ThrowWasmTrapUnalignedAccess) \ @@ -1263,6 +1264,7 @@ namespace internal { V(WasmStackOverflow) \ V(WasmThrow) \ V(WasmRethrow) \ + V(WasmTraceMemory) \ V(AllocateHeapNumber) \ V(ArgumentsAdaptorTrampoline) \ V(BigIntToI32Pair) \ diff --git a/src/builtins/builtins-wasm-gen.cc b/src/builtins/builtins-wasm-gen.cc index dbf20645cb..1d0cc1f7a3 100644 --- a/src/builtins/builtins-wasm-gen.cc +++ b/src/builtins/builtins-wasm-gen.cc @@ -61,6 +61,13 @@ TF_BUILTIN(WasmRethrow, WasmBuiltinsAssembler) { TailCallRuntime(Runtime::kReThrow, context, exception); } +TF_BUILTIN(WasmTraceMemory, WasmBuiltinsAssembler) { + TNode info = UncheckedParameter(Descriptor::kMemoryTracingInfo); + TNode instance = LoadInstanceFromFrame(); + TNode context = LoadContextFromInstance(instance); + TailCallRuntime(Runtime::kWasmTraceMemory, context, info); +} + TF_BUILTIN(WasmAtomicNotify, WasmBuiltinsAssembler) { TNode address = UncheckedCast(Parameter(Descriptor::kAddress)); diff --git a/src/codegen/arm/macro-assembler-arm.cc b/src/codegen/arm/macro-assembler-arm.cc index 94f5a43d0d..b749d80d81 100644 --- a/src/codegen/arm/macro-assembler-arm.cc +++ b/src/codegen/arm/macro-assembler-arm.cc @@ -1826,19 +1826,6 @@ void TurboAssembler::TruncateDoubleToI(Isolate* isolate, Zone* zone, bind(&done); } -void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid, - Register centry) { - const Runtime::Function* f = Runtime::FunctionForId(fid); - // TODO(1236192): Most runtime routines don't need the number of - // arguments passed in because it is constant. At some point we - // should remove this need and make the runtime routine entry code - // smarter. - mov(r0, Operand(f->nargs)); - Move(r1, ExternalReference::Create(f)); - DCHECK(!AreAliased(centry, r0, r1)); - CallCodeObject(centry); -} - void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, SaveFPRegsMode save_doubles) { // All parameters are on the stack. r0 has the return value after call. diff --git a/src/codegen/arm/macro-assembler-arm.h b/src/codegen/arm/macro-assembler-arm.h index d455a14bc7..d0d9b1c655 100644 --- a/src/codegen/arm/macro-assembler-arm.h +++ b/src/codegen/arm/macro-assembler-arm.h @@ -287,10 +287,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void LoadRootRegisterOffset(Register destination, intptr_t offset) override; void LoadRootRelative(Register destination, int32_t offset) override; - // Call a runtime routine. This expects {centry} to contain a fitting CEntry - // builtin for the target runtime function and uses an indirect call. - void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); - // Jump, Call, and Ret pseudo instructions implementing inter-working. void Call(Register target, Condition cond = al); void Call(Address target, RelocInfo::Mode rmode, Condition cond = al, diff --git a/src/codegen/arm64/macro-assembler-arm64.cc b/src/codegen/arm64/macro-assembler-arm64.cc index f366276f19..e5d09903f1 100644 --- a/src/codegen/arm64/macro-assembler-arm64.cc +++ b/src/codegen/arm64/macro-assembler-arm64.cc @@ -1618,19 +1618,6 @@ void TurboAssembler::AssertPositiveOrZero(Register value) { } } -void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid, - Register centry) { - const Runtime::Function* f = Runtime::FunctionForId(fid); - // TODO(1236192): Most runtime routines don't need the number of - // arguments passed in because it is constant. At some point we - // should remove this need and make the runtime routine entry code - // smarter. - Mov(x0, f->nargs); - Mov(x1, ExternalReference::Create(f)); - DCHECK(!AreAliased(centry, x0, x1)); - CallCodeObject(centry); -} - void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, SaveFPRegsMode save_doubles) { // All arguments must be on the stack before this function is called. diff --git a/src/codegen/arm64/macro-assembler-arm64.h b/src/codegen/arm64/macro-assembler-arm64.h index a25be3b925..14716ea037 100644 --- a/src/codegen/arm64/macro-assembler-arm64.h +++ b/src/codegen/arm64/macro-assembler-arm64.h @@ -560,10 +560,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { inline void Isb(); inline void Csdb(); - // Call a runtime routine. This expects {centry} to contain a fitting CEntry - // builtin for the target runtime function and uses an indirect call. - void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); - // Removes current frame and its arguments from the stack preserving // the arguments and a return address pushed to the stack for the next call. // Both |callee_args_count| and |caller_args_count| do not include diff --git a/src/codegen/ia32/macro-assembler-ia32.cc b/src/codegen/ia32/macro-assembler-ia32.cc index d1207fa601..dfb71aeb69 100644 --- a/src/codegen/ia32/macro-assembler-ia32.cc +++ b/src/codegen/ia32/macro-assembler-ia32.cc @@ -980,20 +980,6 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, Call(code, RelocInfo::CODE_TARGET); } -void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid, - Register centry) { - const Runtime::Function* f = Runtime::FunctionForId(fid); - // TODO(1236192): Most runtime routines don't need the number of - // arguments passed in because it is constant. At some point we - // should remove this need and make the runtime routine entry code - // smarter. - Move(kRuntimeCallArgCountRegister, Immediate(f->nargs)); - Move(kRuntimeCallFunctionRegister, Immediate(ExternalReference::Create(f))); - DCHECK(!AreAliased(centry, kRuntimeCallArgCountRegister, - kRuntimeCallFunctionRegister)); - CallCodeObject(centry); -} - void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) { // ----------- S t a t e ------------- // -- esp[0] : return address diff --git a/src/codegen/ia32/macro-assembler-ia32.h b/src/codegen/ia32/macro-assembler-ia32.h index 833f4e8ce3..4602ab217e 100644 --- a/src/codegen/ia32/macro-assembler-ia32.h +++ b/src/codegen/ia32/macro-assembler-ia32.h @@ -111,10 +111,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { void CallForDeoptimization(Address target, int deopt_id); - // Call a runtime routine. This expects {centry} to contain a fitting CEntry - // builtin for the target runtime function and uses an indirect call. - void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); - // Jump the register contains a smi. inline void JumpIfSmi(Register value, Label* smi_label, Label::Distance distance = Label::kFar) { diff --git a/src/codegen/mips/macro-assembler-mips.cc b/src/codegen/mips/macro-assembler-mips.cc index f89774a36d..3a7eed5676 100644 --- a/src/codegen/mips/macro-assembler-mips.cc +++ b/src/codegen/mips/macro-assembler-mips.cc @@ -4566,19 +4566,6 @@ void TurboAssembler::MulOverflow(Register dst, Register left, } } -void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid, - Register centry) { - const Runtime::Function* f = Runtime::FunctionForId(fid); - // TODO(1236192): Most runtime routines don't need the number of - // arguments passed in because it is constant. At some point we - // should remove this need and make the runtime routine entry code - // smarter. - PrepareCEntryArgs(f->nargs); - PrepareCEntryFunction(ExternalReference::Create(f)); - DCHECK(!AreAliased(centry, a0, a1)); - Call(centry, Code::kHeaderSize - kHeapObjectTag); -} - void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, SaveFPRegsMode save_doubles) { // All parameters are on the stack. v0 has the return value after call. diff --git a/src/codegen/mips/macro-assembler-mips.h b/src/codegen/mips/macro-assembler-mips.h index 3e207ef698..012b843609 100644 --- a/src/codegen/mips/macro-assembler-mips.h +++ b/src/codegen/mips/macro-assembler-mips.h @@ -504,10 +504,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { Label* condition_met); #undef COND_ARGS - // Call a runtime routine. This expects {centry} to contain a fitting CEntry - // builtin for the target runtime function and uses an indirect call. - void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); - // Performs a truncating conversion of a floating point number as used by // the JS bitwise operations. See ECMA-262 9.5: ToInt32. // Exits with 'result' holding the answer. diff --git a/src/codegen/mips64/macro-assembler-mips64.cc b/src/codegen/mips64/macro-assembler-mips64.cc index c0a13726bc..349a69788d 100644 --- a/src/codegen/mips64/macro-assembler-mips64.cc +++ b/src/codegen/mips64/macro-assembler-mips64.cc @@ -4881,20 +4881,6 @@ void TurboAssembler::MulOverflow(Register dst, Register left, xor_(overflow, overflow, scratch); } -void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid, - Register centry) { - const Runtime::Function* f = Runtime::FunctionForId(fid); - // TODO(1236192): Most runtime routines don't need the number of - // arguments passed in because it is constant. At some point we - // should remove this need and make the runtime routine entry code - // smarter. - PrepareCEntryArgs(f->nargs); - PrepareCEntryFunction(ExternalReference::Create(f)); - DCHECK(!AreAliased(centry, a0, a1)); - Daddu(centry, centry, Operand(Code::kHeaderSize - kHeapObjectTag)); - Call(centry); -} - void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, SaveFPRegsMode save_doubles) { // All parameters are on the stack. v0 has the return value after call. diff --git a/src/codegen/mips64/macro-assembler-mips64.h b/src/codegen/mips64/macro-assembler-mips64.h index bb8c543a9c..43a5d16c76 100644 --- a/src/codegen/mips64/macro-assembler-mips64.h +++ b/src/codegen/mips64/macro-assembler-mips64.h @@ -527,10 +527,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { Label* condition_met); #undef COND_ARGS - // Call a runtime routine. This expects {centry} to contain a fitting CEntry - // builtin for the target runtime function and uses an indirect call. - void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); - // Performs a truncating conversion of a floating point number as used by // the JS bitwise operations. See ECMA-262 9.5: ToInt32. // Exits with 'result' holding the answer. diff --git a/src/codegen/ppc/macro-assembler-ppc.cc b/src/codegen/ppc/macro-assembler-ppc.cc index 2fa7f52106..d34246639c 100644 --- a/src/codegen/ppc/macro-assembler-ppc.cc +++ b/src/codegen/ppc/macro-assembler-ppc.cc @@ -1573,19 +1573,6 @@ void TurboAssembler::TryInlineTruncateDoubleToI(Register result, beq(done); } -void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid, - Register centry) { - const Runtime::Function* f = Runtime::FunctionForId(fid); - // TODO(1236192): Most runtime routines don't need the number of - // arguments passed in because it is constant. At some point we - // should remove this need and make the runtime routine entry code - // smarter. - mov(r3, Operand(f->nargs)); - Move(r4, ExternalReference::Create(f)); - DCHECK(!AreAliased(centry, r3, r4)); - CallCodeObject(centry); -} - void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, SaveFPRegsMode save_doubles) { // All parameters are on the stack. r3 has the return value after call. diff --git a/src/codegen/ppc/macro-assembler-ppc.h b/src/codegen/ppc/macro-assembler-ppc.h index 2121a73db3..87de0a77c8 100644 --- a/src/codegen/ppc/macro-assembler-ppc.h +++ b/src/codegen/ppc/macro-assembler-ppc.h @@ -361,10 +361,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { int num_double_arguments, bool has_function_descriptor = true); - // Call a runtime routine. This expects {centry} to contain a fitting CEntry - // builtin for the target runtime function and uses an indirect call. - void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); - void MovFromFloatParameter(DoubleRegister dst); void MovFromFloatResult(DoubleRegister dst); diff --git a/src/codegen/s390/macro-assembler-s390.cc b/src/codegen/s390/macro-assembler-s390.cc index 8db12131d7..7a38e1ffb1 100644 --- a/src/codegen/s390/macro-assembler-s390.cc +++ b/src/codegen/s390/macro-assembler-s390.cc @@ -1518,15 +1518,6 @@ void TurboAssembler::TryInlineTruncateDoubleToI(Register result, beq(done); } -void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid, - Register centry) { - const Runtime::Function* f = Runtime::FunctionForId(fid); - mov(r2, Operand(f->nargs)); - Move(r3, ExternalReference::Create(f)); - DCHECK(!AreAliased(centry, r2, r3)); - CallCodeObject(centry); -} - void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, SaveFPRegsMode save_doubles) { // All parameters are on the stack. r2 has the return value after call. diff --git a/src/codegen/s390/macro-assembler-s390.h b/src/codegen/s390/macro-assembler-s390.h index ae2ca87e2e..d0d6ca6c06 100644 --- a/src/codegen/s390/macro-assembler-s390.h +++ b/src/codegen/s390/macro-assembler-s390.h @@ -811,10 +811,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { // --------------------------------------------------------------------------- // Runtime calls - // Call a runtime routine. This expects {centry} to contain a fitting CEntry - // builtin for the target runtime function and uses an indirect call. - void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); - // Before calling a C-function from generated code, align arguments on stack. // After aligning the frame, non-register arguments must be stored in // sp[0], sp[4], etc., not pushed. The argument count assumes all arguments diff --git a/src/codegen/x64/macro-assembler-x64.cc b/src/codegen/x64/macro-assembler-x64.cc index abfba4cafb..8f29ed9f71 100644 --- a/src/codegen/x64/macro-assembler-x64.cc +++ b/src/codegen/x64/macro-assembler-x64.cc @@ -590,20 +590,6 @@ void TurboAssembler::Abort(AbortReason reason) { int3(); } -void TurboAssembler::CallRuntimeWithCEntry(Runtime::FunctionId fid, - Register centry) { - const Runtime::Function* f = Runtime::FunctionForId(fid); - // TODO(1236192): Most runtime routines don't need the number of - // arguments passed in because it is constant. At some point we - // should remove this need and make the runtime routine entry code - // smarter. - Set(rax, f->nargs); - LoadAddress(rbx, ExternalReference::Create(f)); - DCHECK(!AreAliased(centry, rax, rbx)); - DCHECK(centry == rcx); - CallCodeObject(centry); -} - void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments, SaveFPRegsMode save_doubles) { // If the expected number of arguments of the runtime function is diff --git a/src/codegen/x64/macro-assembler-x64.h b/src/codegen/x64/macro-assembler-x64.h index 9615b7608e..18cd8897e8 100644 --- a/src/codegen/x64/macro-assembler-x64.h +++ b/src/codegen/x64/macro-assembler-x64.h @@ -494,10 +494,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { Register caller_args_count, Register scratch0, Register scratch1); - // Call a runtime routine. This expects {centry} to contain a fitting CEntry - // builtin for the target runtime function and uses an indirect call. - void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry); - void InitializeRootRegister() { ExternalReference isolate_root = ExternalReference::isolate_root(isolate()); Move(kRootRegister, isolate_root); diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index 0a7b45825f..938d6136c9 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -1669,47 +1669,20 @@ class LiftoffCompiler { __ Store(info.gp(), no_reg, offsetof(MemoryTracingInfo, mem_rep), address, StoreType::kI32Store8, pinned); + WasmTraceMemoryDescriptor descriptor; + DCHECK_EQ(0, descriptor.GetStackParameterCount()); + DCHECK_EQ(1, descriptor.GetRegisterParameterCount()); + Register param_reg = descriptor.GetRegisterParameter(0); + if (info.gp() != param_reg) { + __ Move(param_reg, info.gp(), LiftoffAssembler::kWasmIntPtr); + } + source_position_table_builder_.AddPosition(__ pc_offset(), SourcePosition(position), false); - - Register args[] = {info.gp()}; - GenerateRuntimeCall(Runtime::kWasmTraceMemory, arraysize(args), args); - __ DeallocateStackSlot(sizeof(MemoryTracingInfo)); - } - - void GenerateRuntimeCall(Runtime::FunctionId runtime_function, int num_args, - Register* args) { - // Currently, only one argument is supported. More arguments require some - // caution for the parallel register moves (reuse StackTransferRecipe). - DCHECK_EQ(1, num_args); -#ifdef DEBUG - auto call_descriptor = compiler::Linkage::GetRuntimeCallDescriptor( - compilation_zone_, runtime_function, num_args, - compiler::Operator::kNoProperties, compiler::CallDescriptor::kNoFlags); - constexpr size_t kInputShift = 1; // Input 0 is the call target. - compiler::LinkageLocation param_loc = - call_descriptor->GetInputLocation(kInputShift); - // Runtime calls take their arguments on the stack. - DCHECK(param_loc.IsCallerFrameSlot()); -#endif - LiftoffStackSlots stack_slots(&asm_); - stack_slots.Add(LiftoffAssembler::VarState(LiftoffAssembler::kWasmIntPtr, - LiftoffRegister(args[0]))); - stack_slots.Construct(); - - // Set context to "no context" for the runtime call. - __ TurboAssembler::Move(kContextRegister, - Smi::FromInt(Context::kNoContext)); - Register centry = kJavaScriptCallCodeStartRegister; - LOAD_INSTANCE_FIELD(centry, IsolateRoot, kSystemPointerSize); - // All cache registers are spilled and there are no register arguments. - LiftoffRegList pinned; - auto centry_id = - Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit; - __ LoadTaggedPointer(centry, centry, no_reg, - IsolateData::builtin_slot_offset(centry_id), pinned); - __ CallRuntimeWithCEntry(runtime_function, centry); + __ CallRuntimeStub(WasmCode::kWasmTraceMemory); safepoint_table_builder_.DefineSafepoint(&asm_, Safepoint::kNoLazyDeopt); + + __ DeallocateStackSlot(sizeof(MemoryTracingInfo)); } Register AddMemoryMasking(Register index, uint32_t* offset,