From 23cf68ac2c28e9b95b20a4ee1c58f26a4f491941 Mon Sep 17 00:00:00 2001 From: Jakob Gruber Date: Wed, 19 Sep 2018 13:25:48 +0200 Subject: [PATCH] [ia32,root] Port all CallFunction variants As part of this, we also update all InvokeFunctionCode callers to pass ecx as the expected-argc register. Drive-by: Inline InvokeFunction overload into its single use. Bug: v8:6666 Change-Id: I67590ecc3f4981d014642c9e18d3ed6db9831e54 Reviewed-on: https://chromium-review.googlesource.com/1233653 Commit-Queue: Jakob Gruber Reviewed-by: Sigurd Schneider Cr-Commit-Position: refs/heads/master@{#56040} --- src/builtins/builtins-call-gen.cc | 9 ++++++++ src/builtins/ia32/builtins-ia32.cc | 10 ++++++--- src/debug/ia32/debug-ia32.cc | 8 ++++--- src/ia32/macro-assembler-ia32.cc | 35 ++++++++++-------------------- src/ia32/macro-assembler-ia32.h | 3 --- 5 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/builtins/builtins-call-gen.cc b/src/builtins/builtins-call-gen.cc index d3df3731b6..cb2b345b1d 100644 --- a/src/builtins/builtins-call-gen.cc +++ b/src/builtins/builtins-call-gen.cc @@ -17,15 +17,24 @@ namespace internal { void Builtins::Generate_CallFunction_ReceiverIsNullOrUndefined( MacroAssembler* masm) { +#ifdef V8_TARGET_ARCH_IA32 + Assembler::SupportsRootRegisterScope supports_root_register(masm); +#endif Generate_CallFunction(masm, ConvertReceiverMode::kNullOrUndefined); } void Builtins::Generate_CallFunction_ReceiverIsNotNullOrUndefined( MacroAssembler* masm) { +#ifdef V8_TARGET_ARCH_IA32 + Assembler::SupportsRootRegisterScope supports_root_register(masm); +#endif Generate_CallFunction(masm, ConvertReceiverMode::kNotNullOrUndefined); } void Builtins::Generate_CallFunction_ReceiverIsAny(MacroAssembler* masm) { +#ifdef V8_TARGET_ARCH_IA32 + Assembler::SupportsRootRegisterScope supports_root_register(masm); +#endif Generate_CallFunction(masm, ConvertReceiverMode::kAny); } diff --git a/src/builtins/ia32/builtins-ia32.cc b/src/builtins/ia32/builtins-ia32.cc index ecc25fc090..6e08eec864 100644 --- a/src/builtins/ia32/builtins-ia32.cc +++ b/src/builtins/ia32/builtins-ia32.cc @@ -1866,6 +1866,8 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm, // static void Builtins::Generate_CallFunction(MacroAssembler* masm, ConvertReceiverMode mode) { + Assembler::SupportsRootRegisterScope supports_root_register(masm); + // ----------- S t a t e ------------- // -- eax : the number of arguments (not including the receiver) // -- edi : the function to call (checked to be a JSFunction) @@ -1906,8 +1908,10 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, __ mov(ecx, Operand(esp, eax, times_pointer_size, kPointerSize)); __ JumpIfSmi(ecx, &convert_to_object, Label::kNear); STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); - __ CmpObjectType(ecx, FIRST_JS_RECEIVER_TYPE, ebx); + __ CmpObjectType(ecx, FIRST_JS_RECEIVER_TYPE, ecx); // Clobbers ecx. __ j(above_equal, &done_convert); + // Reload the receiver (it was clobbered by CmpObjectType). + __ mov(ecx, Operand(esp, eax, times_pointer_size, kPointerSize)); if (mode != ConvertReceiverMode::kNotNullOrUndefined) { Label convert_global_proxy; __ JumpIfRoot(ecx, Heap::kUndefinedValueRootIndex, @@ -1955,9 +1959,9 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, // ----------------------------------- __ movzx_w( - ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); + ecx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); ParameterCount actual(eax); - ParameterCount expected(ebx); + ParameterCount expected(ecx); __ InvokeFunctionCode(edi, no_reg, expected, actual, JUMP_FUNCTION); // The function is a "classConstructor", need to raise an exception. __ bind(&class_constructor); diff --git a/src/debug/ia32/debug-ia32.cc b/src/debug/ia32/debug-ia32.cc index cee8e3d4bc..a4466ee9eb 100644 --- a/src/debug/ia32/debug-ia32.cc +++ b/src/debug/ia32/debug-ia32.cc @@ -40,11 +40,13 @@ void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { __ movzx_w( eax, FieldOperand(eax, SharedFunctionInfo::kFormalParameterCountOffset)); - ParameterCount dummy(eax); - __ InvokeFunction(edi, dummy, dummy, JUMP_FUNCTION); + // The expected and actual argument counts don't matter as long as they match + // and we don't enter the ArgumentsAdaptorTrampoline. + ParameterCount dummy(0); + __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); + __ InvokeFunctionCode(edi, no_reg, dummy, dummy, JUMP_FUNCTION); } - const bool LiveEdit::kFrameDropperSupported = true; #undef __ diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index 991bdcb322..f445851982 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -1037,6 +1037,9 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, bool* definitely_mismatches, InvokeFlag flag, Label::Distance done_near) { + DCHECK_IMPLIES(expected.is_reg(), expected.reg() == ecx); + DCHECK_IMPLIES(actual.is_reg(), actual.reg() == eax); + bool definitely_matches = false; *definitely_mismatches = false; Label invoke; @@ -1055,7 +1058,7 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, definitely_matches = true; } else { *definitely_mismatches = true; - mov(ebx, expected.immediate()); + mov(ecx, expected.immediate()); } } } else { @@ -1066,14 +1069,14 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, mov(eax, actual.immediate()); cmp(expected.reg(), actual.immediate()); j(equal, &invoke); - DCHECK(expected.reg() == ebx); + DCHECK(expected.reg() == ecx); } else if (expected.reg() != actual.reg()) { // Both expected and actual are in (different) registers. This // is the case when we invoke functions using call and apply. cmp(expected.reg(), actual.reg()); j(equal, &invoke); DCHECK(actual.reg() == eax); - DCHECK(expected.reg() == ebx); + DCHECK(expected.reg() == ecx); } else { definitely_matches = true; Move(eax, actual.reg()); @@ -1081,9 +1084,6 @@ void MacroAssembler::InvokePrologue(const ParameterCount& expected, } if (!definitely_matches) { - // TODO(v8:6666): All call-sites should be updated to pass in ecx as the - // expected register to avoid this useless move. - MoveForRootRegisterRefactoring(ecx, ebx); Handle adaptor = BUILTIN_CODE(isolate(), ArgumentsAdaptorTrampoline); if (flag == CALL_FUNCTION) { Call(adaptor, RelocInfo::CODE_TARGET); @@ -1155,6 +1155,8 @@ void MacroAssembler::InvokeFunctionCode(Register function, Register new_target, DCHECK(flag == JUMP_FUNCTION || has_frame()); DCHECK(function == edi); DCHECK_IMPLIES(new_target.is_valid(), new_target == edx); + DCHECK_IMPLIES(expected.is_reg(), expected.reg() == ecx); + DCHECK_IMPLIES(actual.is_reg(), actual.reg() == eax); // On function call, call into the debugger if necessary. CheckDebugHook(function, new_target, expected, actual); @@ -1192,28 +1194,15 @@ void MacroAssembler::InvokeFunction(Register fun, Register new_target, DCHECK(flag == JUMP_FUNCTION || has_frame()); DCHECK(fun == edi); - mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); + mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); - movzx_w(ebx, - FieldOperand(ebx, SharedFunctionInfo::kFormalParameterCountOffset)); + movzx_w(ecx, + FieldOperand(ecx, SharedFunctionInfo::kFormalParameterCountOffset)); - ParameterCount expected(ebx); + ParameterCount expected(ecx); InvokeFunctionCode(edi, new_target, expected, actual, flag); } -void MacroAssembler::InvokeFunction(Register fun, - const ParameterCount& expected, - const ParameterCount& actual, - InvokeFlag flag) { - // You can't call a function without a valid frame. - DCHECK(flag == JUMP_FUNCTION || has_frame()); - - DCHECK(fun == edi); - mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); - - InvokeFunctionCode(edi, no_reg, expected, actual, flag); -} - void MacroAssembler::LoadGlobalProxy(Register dst) { mov(dst, NativeContextOperand()); mov(dst, ContextOperand(dst, Context::GLOBAL_PROXY_INDEX)); diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h index a0c91735d1..b104788a09 100644 --- a/src/ia32/macro-assembler-ia32.h +++ b/src/ia32/macro-assembler-ia32.h @@ -608,9 +608,6 @@ class MacroAssembler : public TurboAssembler { void InvokeFunction(Register function, Register new_target, const ParameterCount& actual, InvokeFlag flag); - void InvokeFunction(Register function, const ParameterCount& expected, - const ParameterCount& actual, InvokeFlag flag); - // Compare object type for heap object. // Incoming register is heap_object and outgoing register is map. void CmpObjectType(Register heap_object, InstanceType type, Register map);