| Index: src/x64/stub-cache-x64.cc
|
| diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
|
| index 78998fa3b0225ecbff6e0e9d7eaf32d08fbed2ed..91d13ba4198fef064792103b1bd754fa2f4a0f63 100644
|
| --- a/src/x64/stub-cache-x64.cc
|
| +++ b/src/x64/stub-cache-x64.cc
|
| @@ -2188,11 +2188,11 @@ Handle<Code> CallStubCompiler::CompileFastApiCall(
|
| }
|
|
|
|
|
| -Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object,
|
| - Handle<JSObject> holder,
|
| - Handle<JSFunction> function,
|
| - Handle<String> name,
|
| - CheckType check) {
|
| +void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<String> name,
|
| + CheckType check,
|
| + Label* success) {
|
| // ----------- S t a t e -------------
|
| // rcx : function name
|
| // rsp[0] : return address
|
| @@ -2202,15 +2202,6 @@ Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object,
|
| // rsp[argc * 8] : argument 1
|
| // rsp[(argc + 1) * 8] : argument 0 = receiver
|
| // -----------------------------------
|
| -
|
| - if (HasCustomCallGenerator(function)) {
|
| - Handle<Code> code = CompileCustomCall(object, holder,
|
| - Handle<JSGlobalPropertyCell>::null(),
|
| - function, name);
|
| - // A null handle means bail out to the regular compiler code below.
|
| - if (!code.is_null()) return code;
|
| - }
|
| -
|
| Label miss;
|
| GenerateNameCheck(name, &miss);
|
|
|
| @@ -2245,76 +2236,86 @@ Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object,
|
| break;
|
|
|
| case STRING_CHECK:
|
| - if (function->IsBuiltin() || !function->shared()->is_classic_mode()) {
|
| - // Check that the object is a two-byte string or a symbol.
|
| - __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
|
| - __ j(above_equal, &miss);
|
| - // Check that the maps starting from the prototype haven't changed.
|
| - GenerateDirectLoadGlobalFunctionPrototype(
|
| - masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
|
| - CheckPrototypes(
|
| - Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| - rax, holder, rbx, rdx, rdi, name, &miss);
|
| - } else {
|
| - // Calling non-strict non-builtins with a value as the receiver
|
| - // requires boxing.
|
| - __ jmp(&miss);
|
| - }
|
| + // Check that the object is a two-byte string or a symbol.
|
| + __ CmpObjectType(rdx, FIRST_NONSTRING_TYPE, rax);
|
| + __ j(above_equal, &miss);
|
| + // Check that the maps starting from the prototype haven't changed.
|
| + GenerateDirectLoadGlobalFunctionPrototype(
|
| + masm(), Context::STRING_FUNCTION_INDEX, rax, &miss);
|
| + CheckPrototypes(
|
| + Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| + rax, holder, rbx, rdx, rdi, name, &miss);
|
| break;
|
|
|
| - case NUMBER_CHECK:
|
| - if (function->IsBuiltin() || !function->shared()->is_classic_mode()) {
|
| - Label fast;
|
| - // Check that the object is a smi or a heap number.
|
| - __ JumpIfSmi(rdx, &fast);
|
| - __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
|
| - __ j(not_equal, &miss);
|
| - __ bind(&fast);
|
| - // Check that the maps starting from the prototype haven't changed.
|
| - GenerateDirectLoadGlobalFunctionPrototype(
|
| - masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
|
| - CheckPrototypes(
|
| - Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| - rax, holder, rbx, rdx, rdi, name, &miss);
|
| - } else {
|
| - // Calling non-strict non-builtins with a value as the receiver
|
| - // requires boxing.
|
| - __ jmp(&miss);
|
| - }
|
| + case NUMBER_CHECK: {
|
| + Label fast;
|
| + // Check that the object is a smi or a heap number.
|
| + __ JumpIfSmi(rdx, &fast);
|
| + __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rax);
|
| + __ j(not_equal, &miss);
|
| + __ bind(&fast);
|
| + // Check that the maps starting from the prototype haven't changed.
|
| + GenerateDirectLoadGlobalFunctionPrototype(
|
| + masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
|
| + CheckPrototypes(
|
| + Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| + rax, holder, rbx, rdx, rdi, name, &miss);
|
| break;
|
| -
|
| - case BOOLEAN_CHECK:
|
| - if (function->IsBuiltin() || !function->shared()->is_classic_mode()) {
|
| - Label fast;
|
| - // Check that the object is a boolean.
|
| - __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
|
| - __ j(equal, &fast);
|
| - __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
|
| - __ j(not_equal, &miss);
|
| - __ bind(&fast);
|
| - // Check that the maps starting from the prototype haven't changed.
|
| - GenerateDirectLoadGlobalFunctionPrototype(
|
| - masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss);
|
| - CheckPrototypes(
|
| - Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| - rax, holder, rbx, rdx, rdi, name, &miss);
|
| - } else {
|
| - // Calling non-strict non-builtins with a value as the receiver
|
| - // requires boxing.
|
| - __ jmp(&miss);
|
| - }
|
| + }
|
| + case BOOLEAN_CHECK: {
|
| + Label fast;
|
| + // Check that the object is a boolean.
|
| + __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
|
| + __ j(equal, &fast);
|
| + __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
|
| + __ j(not_equal, &miss);
|
| + __ bind(&fast);
|
| + // Check that the maps starting from the prototype haven't changed.
|
| + GenerateDirectLoadGlobalFunctionPrototype(
|
| + masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss);
|
| + CheckPrototypes(
|
| + Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| + rax, holder, rbx, rdx, rdi, name, &miss);
|
| break;
|
| + }
|
| }
|
|
|
| + __ jmp(success);
|
| +
|
| + // Handle call cache miss.
|
| + __ bind(&miss);
|
| + GenerateMissBranch();
|
| +}
|
| +
|
| +
|
| +void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
|
| CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
|
| ? CALL_AS_FUNCTION
|
| : CALL_AS_METHOD;
|
| __ InvokeFunction(function, arguments(), JUMP_FUNCTION,
|
| NullCallWrapper(), call_kind);
|
| +}
|
|
|
| - // Handle call cache miss.
|
| - __ bind(&miss);
|
| - GenerateMissBranch();
|
| +
|
| +Handle<Code> CallStubCompiler::CompileCallConstant(
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<String> name,
|
| + CheckType check,
|
| + Handle<JSFunction> function) {
|
| + if (HasCustomCallGenerator(function)) {
|
| + Handle<Code> code = CompileCustomCall(object, holder,
|
| + Handle<JSGlobalPropertyCell>::null(),
|
| + function, name);
|
| + // A null handle means bail out to the regular compiler code below.
|
| + if (!code.is_null()) return code;
|
| + }
|
| +
|
| + Label success;
|
| +
|
| + CompileHandlerFrontend(object, holder, name, check, &success);
|
| + __ bind(&success);
|
| + CompileHandlerBackend(function);
|
|
|
| // Return the generated code.
|
| return GetCode(function);
|
|
|