From 6311105e00858076ac1d9a284b5c5c06de514a19 Mon Sep 17 00:00:00 2001 From: "antonm@chromium.org" Date: Thu, 17 Mar 2011 17:25:54 +0000 Subject: [PATCH] Refactor fast API call. Make it use custom call generator infrastructure. Review URL: http://codereview.chromium.org/6686003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7246 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/stub-cache-arm.cc | 106 +++++++++++++++++++------------- src/hydrogen.cc | 15 +---- src/ia32/stub-cache-ia32.cc | 118 +++++++++++++++++++++-------------- src/stub-cache.cc | 49 ++++++++++----- src/stub-cache.h | 15 ++++- src/x64/stub-cache-x64.cc | 119 +++++++++++++++++++++--------------- 6 files changed, 256 insertions(+), 166 deletions(-) diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc index 57fe596ac..61f7801af 100644 --- a/src/arm/stub-cache-arm.cc +++ b/src/arm/stub-cache-arm.cc @@ -2278,6 +2278,60 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, } +MaybeObject* CallStubCompiler::CompileFastApiCall( + const CallOptimization& optimization, + Object* object, + JSObject* holder, + JSGlobalPropertyCell* cell, + JSFunction* function, + String* name) { + ASSERT(optimization.is_simple_api_call()); + // Bail out if object is a global object as we don't want to + // repatch it to global receiver. + if (object->IsGlobalObject()) return Heap::undefined_value(); + if (cell != NULL) return Heap::undefined_value(); + int depth = optimization.GetPrototypeDepthOfExpectedType( + JSObject::cast(object), holder); + if (depth == kInvalidProtoDepth) return Heap::undefined_value(); + + Label miss, miss_before_stack_reserved; + + GenerateNameCheck(name, &miss_before_stack_reserved); + + // Get the receiver from the stack. + const int argc = arguments().immediate(); + __ ldr(r1, MemOperand(sp, argc * kPointerSize)); + + // Check that the receiver isn't a smi. + __ tst(r1, Operand(kSmiTagMask)); + __ b(eq, &miss_before_stack_reserved); + + __ IncrementCounter(&Counters::call_const, 1, r0, r3); + __ IncrementCounter(&Counters::call_const_fast_api, 1, r0, r3); + + ReserveSpaceForFastApiCall(masm(), r0); + + // Check that the maps haven't changed and find a Holder as a side effect. + CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, + depth, &miss); + + MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); + if (result->IsFailure()) return result; + + __ bind(&miss); + FreeSpaceForFastApiCall(masm()); + + __ bind(&miss_before_stack_reserved); + Object* obj; + { MaybeObject* maybe_obj = GenerateMissBranch(); + if (!maybe_obj->ToObject(&obj)) return maybe_obj; + } + + // Return the generated code. + return GetCode(function); +} + + MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, JSObject* holder, JSFunction* function, @@ -2287,22 +2341,18 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // -- r2 : name // -- lr : return address // ----------------------------------- - SharedFunctionInfo* function_info = function->shared(); - if (function_info->HasBuiltinFunctionId()) { - BuiltinFunctionId id = function_info->builtin_function_id(); + if (HasCustomCallGenerator(function)) { MaybeObject* maybe_result = CompileCustomCall( - id, object, holder, NULL, function, name); + object, holder, NULL, function, name); Object* result; if (!maybe_result->ToObject(&result)) return maybe_result; // undefined means bail out to regular compiler. - if (!result->IsUndefined()) { - return result; - } + if (!result->IsUndefined()) return result; } - Label miss_in_smi_check; + Label miss; - GenerateNameCheck(name, &miss_in_smi_check); + GenerateNameCheck(name, &miss); // Get the receiver from the stack const int argc = arguments().immediate(); @@ -2311,39 +2361,25 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // Check that the receiver isn't a smi. if (check != NUMBER_CHECK) { __ tst(r1, Operand(kSmiTagMask)); - __ b(eq, &miss_in_smi_check); + __ b(eq, &miss); } // Make sure that it's okay not to patch the on stack receiver // unless we're doing a receiver map check. ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); - CallOptimization optimization(function); - int depth = kInvalidProtoDepth; - Label miss; - + SharedFunctionInfo* function_info = function->shared(); switch (check) { case RECEIVER_MAP_CHECK: __ IncrementCounter(&Counters::call_const, 1, r0, r3); - if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { - depth = optimization.GetPrototypeDepthOfExpectedType( - JSObject::cast(object), holder); - } - - if (depth != kInvalidProtoDepth) { - __ IncrementCounter(&Counters::call_const_fast_api, 1, r0, r3); - ReserveSpaceForFastApiCall(masm(), r0); - } - // Check that the maps haven't changed. CheckPrototypes(JSObject::cast(object), r1, holder, r0, r3, r4, name, - depth, &miss); + &miss); // Patch the receiver on the stack with the global proxy if // necessary. if (object->IsGlobalObject()) { - ASSERT(depth == kInvalidProtoDepth); __ ldr(r3, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset)); __ str(r3, MemOperand(sp, argc * kPointerSize)); } @@ -2416,20 +2452,10 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, UNREACHABLE(); } - if (depth != kInvalidProtoDepth) { - MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); - if (result->IsFailure()) return result; - } else { - __ InvokeFunction(function, arguments(), JUMP_FUNCTION); - } + __ InvokeFunction(function, arguments(), JUMP_FUNCTION); // Handle call cache miss. __ bind(&miss); - if (depth != kInvalidProtoDepth) { - FreeSpaceForFastApiCall(masm()); - } - - __ bind(&miss_in_smi_check); Object* obj; { MaybeObject* maybe_obj = GenerateMissBranch(); if (!maybe_obj->ToObject(&obj)) return maybe_obj; @@ -2505,11 +2531,9 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, // -- lr : return address // ----------------------------------- - SharedFunctionInfo* function_info = function->shared(); - if (function_info->HasBuiltinFunctionId()) { - BuiltinFunctionId id = function_info->builtin_function_id(); + if (HasCustomCallGenerator(function)) { MaybeObject* maybe_result = CompileCustomCall( - id, object, holder, cell, function, name); + object, holder, cell, function, name); Object* result; if (!maybe_result->ToObject(&result)) return maybe_result; // undefined means bail out to regular compiler. diff --git a/src/hydrogen.cc b/src/hydrogen.cc index b5c08babf..b1c1cb148 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -4224,13 +4224,6 @@ bool HGraphBuilder::TryCallApply(Call* expr) { } -static bool HasCustomCallGenerator(Handle function) { - SharedFunctionInfo* info = function->shared(); - return info->HasBuiltinFunctionId() && - CallStubCompiler::HasCustomCallGenerator(info->builtin_function_id()); -} - - void HGraphBuilder::VisitCall(Call* expr) { Expression* callee = expr->expression(); int argument_count = expr->arguments()->length() + 1; // Plus receiver. @@ -4288,13 +4281,11 @@ void HGraphBuilder::VisitCall(Call* expr) { return; } - if (HasCustomCallGenerator(expr->target()) || - CallOptimization(*expr->target()).is_simple_api_call() || + if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || expr->check_type() != RECEIVER_MAP_CHECK) { // When the target has a custom call IC generator, use the IC, - // because it is likely to generate better code. Similarly, we - // generate better call stubs for some API functions. - // Also use the IC when a primitive receiver check is required. + // because it is likely to generate better code. Also use the IC + // when a primitive receiver check is required. HContext* context = new HContext; AddInstruction(context); call = PreProcessCall(new HCallNamed(context, name, argument_count)); diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 37688315d..7e86a887d 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -2127,6 +2127,68 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, } +MaybeObject* CallStubCompiler::CompileFastApiCall( + const CallOptimization& optimization, + Object* object, + JSObject* holder, + JSGlobalPropertyCell* cell, + JSFunction* function, + String* name) { + ASSERT(optimization.is_simple_api_call()); + // Bail out if object is a global object as we don't want to + // repatch it to global receiver. + if (object->IsGlobalObject()) return Heap::undefined_value(); + if (cell != NULL) return Heap::undefined_value(); + int depth = optimization.GetPrototypeDepthOfExpectedType( + JSObject::cast(object), holder); + if (depth == kInvalidProtoDepth) return Heap::undefined_value(); + + Label miss, miss_before_stack_reserved; + + GenerateNameCheck(name, &miss_before_stack_reserved); + + // Get the receiver from the stack. + const int argc = arguments().immediate(); + __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); + + // Check that the receiver isn't a smi. + __ test(edx, Immediate(kSmiTagMask)); + __ j(zero, &miss_before_stack_reserved, not_taken); + + __ IncrementCounter(&Counters::call_const, 1); + __ IncrementCounter(&Counters::call_const_fast_api, 1); + + // Allocate space for v8::Arguments implicit values. Must be initialized + // before calling any runtime function. + __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); + + // Check that the maps haven't changed and find a Holder as a side effect. + CheckPrototypes(JSObject::cast(object), edx, holder, + ebx, eax, edi, name, depth, &miss); + + // Move the return address on top of the stack. + __ mov(eax, Operand(esp, 3 * kPointerSize)); + __ mov(Operand(esp, 0 * kPointerSize), eax); + + // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains + // duplicate of return address and will be overwritten. + MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); + if (result->IsFailure()) return result; + + __ bind(&miss); + __ add(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); + + __ bind(&miss_before_stack_reserved); + Object* obj; + { MaybeObject* maybe_obj = GenerateMissBranch(); + if (!maybe_obj->ToObject(&obj)) return maybe_obj; + } + + // Return the generated code. + return GetCode(function); +} + + MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, JSObject* holder, JSFunction* function, @@ -2140,20 +2202,18 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // -- esp[(argc + 1) * 4] : receiver // ----------------------------------- - SharedFunctionInfo* function_info = function->shared(); - if (function_info->HasBuiltinFunctionId()) { - BuiltinFunctionId id = function_info->builtin_function_id(); + if (HasCustomCallGenerator(function)) { MaybeObject* maybe_result = CompileCustomCall( - id, object, holder, NULL, function, name); + object, holder, NULL, function, name); Object* result; if (!maybe_result->ToObject(&result)) return maybe_result; // undefined means bail out to regular compiler. if (!result->IsUndefined()) return result; } - Label miss_in_smi_check; + Label miss; - GenerateNameCheck(name, &miss_in_smi_check); + GenerateNameCheck(name, &miss); // Get the receiver from the stack. const int argc = arguments().immediate(); @@ -2162,42 +2222,25 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // Check that the receiver isn't a smi. if (check != NUMBER_CHECK) { __ test(edx, Immediate(kSmiTagMask)); - __ j(zero, &miss_in_smi_check, not_taken); + __ j(zero, &miss, not_taken); } // Make sure that it's okay not to patch the on stack receiver // unless we're doing a receiver map check. ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); - CallOptimization optimization(function); - int depth = kInvalidProtoDepth; - Label miss; - + SharedFunctionInfo* function_info = function->shared(); switch (check) { case RECEIVER_MAP_CHECK: __ IncrementCounter(&Counters::call_const, 1); - if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { - depth = optimization.GetPrototypeDepthOfExpectedType( - JSObject::cast(object), holder); - } - - if (depth != kInvalidProtoDepth) { - __ IncrementCounter(&Counters::call_const_fast_api, 1); - - // Allocate space for v8::Arguments implicit values. Must be initialized - // before to call any runtime function. - __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); - } - // Check that the maps haven't changed. CheckPrototypes(JSObject::cast(object), edx, holder, - ebx, eax, edi, name, depth, &miss); + ebx, eax, edi, name, &miss); // Patch the receiver on the stack with the global proxy if // necessary. if (object->IsGlobalObject()) { - ASSERT(depth == kInvalidProtoDepth); __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); } @@ -2268,25 +2311,10 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, UNREACHABLE(); } - if (depth != kInvalidProtoDepth) { - // Move the return address on top of the stack. - __ mov(eax, Operand(esp, 3 * kPointerSize)); - __ mov(Operand(esp, 0 * kPointerSize), eax); - - // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains - // duplicate of return address and will be overwritten. - MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); - if (result->IsFailure()) return result; - } else { - __ InvokeFunction(function, arguments(), JUMP_FUNCTION); - } + __ InvokeFunction(function, arguments(), JUMP_FUNCTION); // Handle call cache miss. __ bind(&miss); - if (depth != kInvalidProtoDepth) { - __ add(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); - } - __ bind(&miss_in_smi_check); Object* obj; { MaybeObject* maybe_obj = GenerateMissBranch(); if (!maybe_obj->ToObject(&obj)) return maybe_obj; @@ -2378,11 +2406,9 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, // -- esp[(argc + 1) * 4] : receiver // ----------------------------------- - SharedFunctionInfo* function_info = function->shared(); - if (function_info->HasBuiltinFunctionId()) { - BuiltinFunctionId id = function_info->builtin_function_id(); + if (HasCustomCallGenerator(function)) { MaybeObject* maybe_result = CompileCustomCall( - id, object, holder, cell, function, name); + object, holder, cell, function, name); Object* result; if (!maybe_result->ToObject(&result)) return maybe_result; // undefined means bail out to regular compiler. diff --git a/src/stub-cache.cc b/src/stub-cache.cc index 91d4c7075..789dafd89 100644 --- a/src/stub-cache.cc +++ b/src/stub-cache.cc @@ -1726,32 +1726,51 @@ CallStubCompiler::CallStubCompiler(int argc, } -bool CallStubCompiler::HasCustomCallGenerator(BuiltinFunctionId id) { +bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) { + SharedFunctionInfo* info = function->shared(); + if (info->HasBuiltinFunctionId()) { + BuiltinFunctionId id = info->builtin_function_id(); #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; - CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) + CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) #undef CALL_GENERATOR_CASE + } + CallOptimization optimization(function); + if (optimization.is_simple_api_call()) { + return true; + } return false; } -MaybeObject* CallStubCompiler::CompileCustomCall(BuiltinFunctionId id, - Object* object, +MaybeObject* CallStubCompiler::CompileCustomCall(Object* object, JSObject* holder, JSGlobalPropertyCell* cell, JSFunction* function, String* fname) { -#define CALL_GENERATOR_CASE(name) \ - if (id == k##name) { \ - return CallStubCompiler::Compile##name##Call(object, \ - holder, \ - cell, \ - function, \ - fname); \ - } - CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) + ASSERT(HasCustomCallGenerator(function)); + + SharedFunctionInfo* info = function->shared(); + if (info->HasBuiltinFunctionId()) { + BuiltinFunctionId id = info->builtin_function_id(); +#define CALL_GENERATOR_CASE(name) \ + if (id == k##name) { \ + return CallStubCompiler::Compile##name##Call(object, \ + holder, \ + cell, \ + function, \ + fname); \ + } + CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) #undef CALL_GENERATOR_CASE - ASSERT(!HasCustomCallGenerator(id)); - return Heap::undefined_value(); + } + CallOptimization optimization(function); + ASSERT(optimization.is_simple_api_call()); + return CompileFastApiCall(optimization, + object, + holder, + cell, + function, + fname); } diff --git a/src/stub-cache.h b/src/stub-cache.h index 33d3995ef..99c024211 100644 --- a/src/stub-cache.h +++ b/src/stub-cache.h @@ -680,6 +680,8 @@ class KeyedStoreStubCompiler: public StubCompiler { V(MathAbs) +class CallOptimization; + class CallStubCompiler: public StubCompiler { public: CallStubCompiler(int argc, @@ -706,14 +708,13 @@ class CallStubCompiler: public StubCompiler { JSFunction* function, String* name); - static bool HasCustomCallGenerator(BuiltinFunctionId id); + static bool HasCustomCallGenerator(JSFunction* function); private: // Compiles a custom call constant/global IC. For constant calls // cell is NULL. Returns undefined if there is no custom call code // for the given function or it can't be generated. - MUST_USE_RESULT MaybeObject* CompileCustomCall(BuiltinFunctionId id, - Object* object, + MUST_USE_RESULT MaybeObject* CompileCustomCall(Object* object, JSObject* holder, JSGlobalPropertyCell* cell, JSFunction* function, @@ -728,6 +729,14 @@ class CallStubCompiler: public StubCompiler { CUSTOM_CALL_IC_GENERATORS(DECLARE_CALL_GENERATOR) #undef DECLARE_CALL_GENERATOR + MUST_USE_RESULT MaybeObject* CompileFastApiCall( + const CallOptimization& optimization, + Object* object, + JSObject* holder, + JSGlobalPropertyCell* cell, + JSFunction* function, + String* name); + const ParameterCount arguments_; const InLoopFlag in_loop_; const Code::Kind kind_; diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc index e85f37e01..bc8effe6c 100644 --- a/src/x64/stub-cache-x64.cc +++ b/src/x64/stub-cache-x64.cc @@ -1982,6 +1982,65 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, } +MaybeObject* CallStubCompiler::CompileFastApiCall( + const CallOptimization& optimization, + Object* object, + JSObject* holder, + JSGlobalPropertyCell* cell, + JSFunction* function, + String* name) { + ASSERT(optimization.is_simple_api_call()); + // Bail out if object is a global object as we don't want to + // repatch it to global receiver. + if (object->IsGlobalObject()) return Heap::undefined_value(); + if (cell != NULL) return Heap::undefined_value(); + int depth = optimization.GetPrototypeDepthOfExpectedType( + JSObject::cast(object), holder); + if (depth == kInvalidProtoDepth) return Heap::undefined_value(); + + Label miss, miss_before_stack_reserved; + + GenerateNameCheck(name, &miss_before_stack_reserved); + + // Get the receiver from the stack. + const int argc = arguments().immediate(); + __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); + + // Check that the receiver isn't a smi. + __ JumpIfSmi(rdx, &miss_before_stack_reserved); + + __ IncrementCounter(&Counters::call_const, 1); + __ IncrementCounter(&Counters::call_const_fast_api, 1); + + // Allocate space for v8::Arguments implicit values. Must be initialized + // before calling any runtime function. + __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); + + // Check that the maps haven't changed and find a Holder as a side effect. + CheckPrototypes(JSObject::cast(object), rdx, holder, + rbx, rax, rdi, name, depth, &miss); + + // Move the return address on top of the stack. + __ movq(rax, Operand(rsp, 3 * kPointerSize)); + __ movq(Operand(rsp, 0 * kPointerSize), rax); + + MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); + if (result->IsFailure()) return result; + + __ bind(&miss); + __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); + + __ bind(&miss_before_stack_reserved); + Object* obj; + { MaybeObject* maybe_obj = GenerateMissBranch(); + if (!maybe_obj->ToObject(&obj)) return maybe_obj; + } + + // Return the generated code. + return GetCode(function); +} + + MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, JSObject* holder, JSFunction* function, @@ -1997,20 +2056,18 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // rsp[(argc + 1) * 8] : argument 0 = receiver // ----------------------------------- - SharedFunctionInfo* function_info = function->shared(); - if (function_info->HasBuiltinFunctionId()) { - BuiltinFunctionId id = function_info->builtin_function_id(); + if (HasCustomCallGenerator(function)) { MaybeObject* maybe_result = CompileCustomCall( - id, object, holder, NULL, function, name); + object, holder, NULL, function, name); Object* result; if (!maybe_result->ToObject(&result)) return maybe_result; // undefined means bail out to regular compiler. if (!result->IsUndefined()) return result; } - Label miss_in_smi_check; + Label miss; - GenerateNameCheck(name, &miss_in_smi_check); + GenerateNameCheck(name, &miss); // Get the receiver from the stack. const int argc = arguments().immediate(); @@ -2018,42 +2075,25 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // Check that the receiver isn't a smi. if (check != NUMBER_CHECK) { - __ JumpIfSmi(rdx, &miss_in_smi_check); + __ JumpIfSmi(rdx, &miss); } // Make sure that it's okay not to patch the on stack receiver // unless we're doing a receiver map check. ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); - CallOptimization optimization(function); - int depth = kInvalidProtoDepth; - Label miss; - + SharedFunctionInfo* function_info = function->shared(); switch (check) { case RECEIVER_MAP_CHECK: __ IncrementCounter(&Counters::call_const, 1); - if (optimization.is_simple_api_call() && !object->IsGlobalObject()) { - depth = optimization.GetPrototypeDepthOfExpectedType( - JSObject::cast(object), holder); - } - - if (depth != kInvalidProtoDepth) { - __ IncrementCounter(&Counters::call_const_fast_api, 1); - - // Allocate space for v8::Arguments implicit values. Must be initialized - // before to call any runtime function. - __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); - } - // Check that the maps haven't changed. CheckPrototypes(JSObject::cast(object), rdx, holder, - rbx, rax, rdi, name, depth, &miss); + rbx, rax, rdi, name, &miss); // Patch the receiver on the stack with the global proxy if // necessary. if (object->IsGlobalObject()) { - ASSERT(depth == kInvalidProtoDepth); __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); } @@ -2123,27 +2163,10 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, UNREACHABLE(); } - if (depth != kInvalidProtoDepth) { - // Move the return address on top of the stack. - __ movq(rax, Operand(rsp, 3 * kPointerSize)); - __ movq(Operand(rsp, 0 * kPointerSize), rax); - - // rsp[2 * kPointerSize] is uninitialized, rsp[3 * kPointerSize] contains - // duplicate of return address and will be overwritten. - MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc); - if (result->IsFailure()) return result; - } else { - __ InvokeFunction(function, arguments(), JUMP_FUNCTION); - } + __ InvokeFunction(function, arguments(), JUMP_FUNCTION); // Handle call cache miss. __ bind(&miss); - if (depth != kInvalidProtoDepth) { - __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); - } - - // Handle call cache miss. - __ bind(&miss_in_smi_check); Object* obj; { MaybeObject* maybe_obj = GenerateMissBranch(); if (!maybe_obj->ToObject(&obj)) return maybe_obj; @@ -2238,11 +2261,9 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, // rsp[(argc + 1) * 8] : argument 0 = receiver // ----------------------------------- - SharedFunctionInfo* function_info = function->shared(); - if (function_info->HasBuiltinFunctionId()) { - BuiltinFunctionId id = function_info->builtin_function_id(); + if (HasCustomCallGenerator(function)) { MaybeObject* maybe_result = CompileCustomCall( - id, object, holder, cell, function, name); + object, holder, cell, function, name); Object* result; if (!maybe_result->ToObject(&result)) return maybe_result; // undefined means bail out to regular compiler. @@ -2960,7 +2981,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadSpecialized(JSObject* receiver) { // ----------- S t a t e ------------- // -- rax : key // -- rdx : receiver - // -- esp[0] : return address + // -- rsp[0] : return address // ----------------------------------- Label miss; -- 2.34.1