Index: src/mips/code-stubs-mips.cc |
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc |
index 0eea32cbc52985dabf9d4d838d2a3b2c86645b87..63e3b4454e4359dd7752a15b9159d9fed740e9b2 100644 |
--- a/src/mips/code-stubs-mips.cc |
+++ b/src/mips/code-stubs-mips.cc |
@@ -7766,6 +7766,66 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { |
} |
+void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
+ if (entry_hook_ != NULL) { |
+ ProfileEntryHookStub stub; |
+ __ push(ra); |
+ __ CallStub(&stub); |
+ __ pop(ra); |
+ } |
+} |
+ |
+ |
+void ProfileEntryHookStub::Generate(MacroAssembler* masm) { |
+ // The entry hook is a "push ra" instruction, followed by a call. |
+ // Note: on MIPS "push" is 2 instruction |
+ const int32_t kReturnAddressDistanceFromFunctionStart = |
+ Assembler::kCallTargetAddressOffset + (2 * Assembler::kInstrSize); |
+ |
+ // Save live volatile registers. |
+ __ Push(ra, t1, a1); |
+ const int32_t kNumSavedRegs = 3; |
+ |
+ // Compute the function's address for the first argument. |
+ __ Subu(a0, ra, Operand(kReturnAddressDistanceFromFunctionStart)); |
+ |
+ // The caller's return address is above the saved temporaries. |
+ // Grab that for the second argument to the hook. |
+ __ Addu(a1, sp, Operand(kNumSavedRegs * kPointerSize)); |
+ |
+ // Align the stack if necessary. |
+ int frame_alignment = masm->ActivationFrameAlignment(); |
+ if (frame_alignment > kPointerSize) { |
+ __ mov(t1, sp); |
+ ASSERT(IsPowerOf2(frame_alignment)); |
+ __ And(sp, sp, Operand(-frame_alignment)); |
+ } |
+ |
+#if defined(V8_HOST_ARCH_MIPS) |
+ __ li(at, Operand(reinterpret_cast<int32_t>(&entry_hook_))); |
+ __ lw(at, MemOperand(at)); |
+#else |
+ // Under the simulator we need to indirect the entry hook through a |
+ // trampoline function at a known address. |
+ Address trampoline_address = reinterpret_cast<Address>( |
+ reinterpret_cast<intptr_t>(EntryHookTrampoline)); |
+ ApiFunction dispatcher(trampoline_address); |
+ __ li(at, Operand(ExternalReference(&dispatcher, |
+ ExternalReference::BUILTIN_CALL, |
+ masm->isolate()))); |
+#endif |
+ __ Call(at); |
+ |
+ // Restore the stack pointer if needed. |
+ if (frame_alignment > kPointerSize) { |
+ __ mov(sp, t1); |
+ } |
+ |
+ __ Pop(ra, t1, a1); |
+ __ Ret(); |
+} |
+ |
+ |
#undef __ |
} } // namespace v8::internal |