diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index e1f099cd4d..bd353d98c8 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -5402,9 +5402,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); __ Branch(&call, ne, t0, Operand(at)); // Patch the receiver on the stack with the global receiver object. - __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); - __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); - __ sw(a2, MemOperand(sp, argc_ * kPointerSize)); + __ lw(a3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); + __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset)); + __ sw(a3, MemOperand(sp, argc_ * kPointerSize)); __ bind(&call); } @@ -5412,8 +5412,12 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // a1: pushed function (to be verified) __ JumpIfSmi(a1, &non_function); // Get the map of the function object. - __ GetObjectType(a1, a2, a2); - __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE)); + __ GetObjectType(a1, a3, a3); + __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); + + if (RecordCallTarget()) { + GenerateRecordCallTarget(masm); + } // Fast-case: Invoke the function now. // a1: pushed function @@ -5438,8 +5442,17 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Slow-case: Non-function called. __ bind(&slow); + if (RecordCallTarget()) { + // If there is a call target cache, mark it megamorphic in the + // non-function case. MegamorphicSentinel is an immortal immovable + // object (undefined) so no write barrier is needed. + ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), + masm->isolate()->heap()->undefined_value()); + __ LoadRoot(at, Heap::kUndefinedValueRootIndex); + __ sw(at, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); + } // Check for function proxy. - __ Branch(&non_function, ne, a2, Operand(JS_FUNCTION_PROXY_TYPE)); + __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); __ push(a1); // Put proxy as additional argument. __ li(a0, Operand(argc_ + 1, RelocInfo::NONE)); __ li(a2, Operand(0, RelocInfo::NONE)); diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc index bd6f9902aa..7456510584 100644 --- a/src/mips/full-codegen-mips.cc +++ b/src/mips/full-codegen-mips.cc @@ -2388,6 +2388,18 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { } // Record source position for debugger. SetSourcePosition(expr->position()); + + // Record call targets in unoptimized code, but not in the snapshot. + if (!Serializer::enabled()) { + flags = static_cast(flags | RECORD_CALL_TARGET); + Handle uninitialized = + TypeFeedbackCells::UninitializedSentinel(isolate()); + Handle cell = + isolate()->factory()->NewJSGlobalPropertyCell(uninitialized); + RecordTypeFeedbackCell(expr->id(), cell); + __ li(a2, Operand(cell)); + } + CallFunctionStub stub(arg_count, flags); __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize)); __ CallStub(&stub);