OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3523 | 3523 |
3524 void CEntryStub::Generate(MacroAssembler* masm) { | 3524 void CEntryStub::Generate(MacroAssembler* masm) { |
3525 // Called from JavaScript; parameters are on stack as if calling JS function | 3525 // Called from JavaScript; parameters are on stack as if calling JS function |
3526 // s0: number of arguments including receiver | 3526 // s0: number of arguments including receiver |
3527 // s1: size of arguments excluding receiver | 3527 // s1: size of arguments excluding receiver |
3528 // s2: pointer to builtin function | 3528 // s2: pointer to builtin function |
3529 // fp: frame pointer (restored after C call) | 3529 // fp: frame pointer (restored after C call) |
3530 // sp: stack pointer (restored as callee's sp after C call) | 3530 // sp: stack pointer (restored as callee's sp after C call) |
3531 // cp: current context (C callee-saved) | 3531 // cp: current context (C callee-saved) |
3532 | 3532 |
| 3533 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 3534 |
3533 // NOTE: Invocations of builtins may return failure objects | 3535 // NOTE: Invocations of builtins may return failure objects |
3534 // instead of a proper result. The builtin entry handles | 3536 // instead of a proper result. The builtin entry handles |
3535 // this by performing a garbage collection and retrying the | 3537 // this by performing a garbage collection and retrying the |
3536 // builtin once. | 3538 // builtin once. |
3537 | 3539 |
3538 // NOTE: s0-s2 hold the arguments of this function instead of a0-a2. | 3540 // NOTE: s0-s2 hold the arguments of this function instead of a0-a2. |
3539 // The reason for this is that these arguments would need to be saved anyway | 3541 // The reason for this is that these arguments would need to be saved anyway |
3540 // so it's faster to set them up directly. | 3542 // so it's faster to set them up directly. |
3541 // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction. | 3543 // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction. |
3542 | 3544 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3616 // Registers: | 3618 // Registers: |
3617 // a0: entry address | 3619 // a0: entry address |
3618 // a1: function | 3620 // a1: function |
3619 // a2: receiver | 3621 // a2: receiver |
3620 // a3: argc | 3622 // a3: argc |
3621 // | 3623 // |
3622 // Stack: | 3624 // Stack: |
3623 // 4 args slots | 3625 // 4 args slots |
3624 // args | 3626 // args |
3625 | 3627 |
| 3628 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
| 3629 |
3626 // Save callee saved registers on the stack. | 3630 // Save callee saved registers on the stack. |
3627 __ MultiPush(kCalleeSaved | ra.bit()); | 3631 __ MultiPush(kCalleeSaved | ra.bit()); |
3628 | 3632 |
3629 // Save callee-saved FPU registers. | 3633 // Save callee-saved FPU registers. |
3630 __ MultiPushFPU(kCalleeSavedFPU); | 3634 __ MultiPushFPU(kCalleeSavedFPU); |
3631 // Set up the reserved register for 0.0. | 3635 // Set up the reserved register for 0.0. |
3632 __ Move(kDoubleRegZero, 0.0); | 3636 __ Move(kDoubleRegZero, 0.0); |
3633 | 3637 |
3634 | 3638 |
3635 // Load argv in s0 register. | 3639 // Load argv in s0 register. |
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5038 | 5042 |
5039 // A monomorphic cache hit or an already megamorphic state: invoke the | 5043 // A monomorphic cache hit or an already megamorphic state: invoke the |
5040 // function without changing the state. | 5044 // function without changing the state. |
5041 __ Branch(&done, eq, a3, Operand(a1)); | 5045 __ Branch(&done, eq, a3, Operand(a1)); |
5042 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 5046 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
5043 __ Branch(&done, eq, a3, Operand(at)); | 5047 __ Branch(&done, eq, a3, Operand(at)); |
5044 | 5048 |
5045 // Special handling of the Array() function, which caches not only the | 5049 // Special handling of the Array() function, which caches not only the |
5046 // monomorphic Array function but the initial ElementsKind with special | 5050 // monomorphic Array function but the initial ElementsKind with special |
5047 // sentinels | 5051 // sentinels |
5048 Handle<Object> terminal_kind_sentinel = | |
5049 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), | |
5050 LAST_FAST_ELEMENTS_KIND); | |
5051 __ JumpIfNotSmi(a3, &miss); | 5052 __ JumpIfNotSmi(a3, &miss); |
5052 __ Branch(&miss, gt, a3, Operand(terminal_kind_sentinel)); | 5053 if (FLAG_debug_code) { |
| 5054 Handle<Object> terminal_kind_sentinel = |
| 5055 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), |
| 5056 LAST_FAST_ELEMENTS_KIND); |
| 5057 __ Assert(le, "Array function sentinel is not an ElementsKind", |
| 5058 a3, Operand(terminal_kind_sentinel)); |
| 5059 } |
| 5060 |
5053 // Make sure the function is the Array() function | 5061 // Make sure the function is the Array() function |
5054 __ LoadArrayFunction(a3); | 5062 __ LoadArrayFunction(a3); |
5055 __ Branch(&megamorphic, ne, a1, Operand(a3)); | 5063 __ Branch(&megamorphic, ne, a1, Operand(a3)); |
5056 __ jmp(&done); | 5064 __ jmp(&done); |
5057 | 5065 |
5058 __ bind(&miss); | 5066 __ bind(&miss); |
5059 | 5067 |
5060 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 5068 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
5061 // megamorphic. | 5069 // megamorphic. |
5062 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 5070 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
(...skipping 2436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7499 __ Addu(a1, a1, Operand(1)); | 7507 __ Addu(a1, a1, Operand(1)); |
7500 } | 7508 } |
7501 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); | 7509 masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE); |
7502 __ sll(a1, a1, kPointerSizeLog2); | 7510 __ sll(a1, a1, kPointerSizeLog2); |
7503 __ Ret(USE_DELAY_SLOT); | 7511 __ Ret(USE_DELAY_SLOT); |
7504 __ Addu(sp, sp, a1); | 7512 __ Addu(sp, sp, a1); |
7505 } | 7513 } |
7506 | 7514 |
7507 | 7515 |
7508 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { | 7516 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) { |
7509 if (entry_hook_ != NULL) { | 7517 if (masm->isolate()->function_entry_hook() != NULL) { |
| 7518 AllowStubCallsScope allow_stub_calls(masm, true); |
7510 ProfileEntryHookStub stub; | 7519 ProfileEntryHookStub stub; |
7511 __ push(ra); | 7520 __ push(ra); |
7512 __ CallStub(&stub); | 7521 __ CallStub(&stub); |
7513 __ pop(ra); | 7522 __ pop(ra); |
7514 } | 7523 } |
7515 } | 7524 } |
7516 | 7525 |
7517 | 7526 |
7518 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { | 7527 void ProfileEntryHookStub::Generate(MacroAssembler* masm) { |
7519 // The entry hook is a "push ra" instruction, followed by a call. | 7528 // The entry hook is a "push ra" instruction, followed by a call. |
7520 // Note: on MIPS "push" is 2 instruction | 7529 // Note: on MIPS "push" is 2 instruction |
7521 const int32_t kReturnAddressDistanceFromFunctionStart = | 7530 const int32_t kReturnAddressDistanceFromFunctionStart = |
7522 Assembler::kCallTargetAddressOffset + (2 * Assembler::kInstrSize); | 7531 Assembler::kCallTargetAddressOffset + (2 * Assembler::kInstrSize); |
7523 | 7532 |
7524 // Save live volatile registers. | 7533 // Save live volatile registers. |
7525 __ Push(ra, t1, a1); | 7534 // We also save ra, so the count here is one higher than the mask indicates. |
7526 const int32_t kNumSavedRegs = 3; | 7535 const int32_t kNumSavedRegs = kNumJSCallerSaved + 1; |
| 7536 |
| 7537 // Save all caller-save registers as this may be called from anywhere. |
| 7538 __ MultiPush(kJSCallerSaved | ra.bit()); |
7527 | 7539 |
7528 // Compute the function's address for the first argument. | 7540 // Compute the function's address for the first argument. |
7529 __ Subu(a0, ra, Operand(kReturnAddressDistanceFromFunctionStart)); | 7541 __ Subu(a0, ra, Operand(kReturnAddressDistanceFromFunctionStart)); |
7530 | 7542 |
7531 // The caller's return address is above the saved temporaries. | 7543 // The caller's return address is above the saved temporaries. |
7532 // Grab that for the second argument to the hook. | 7544 // Grab that for the second argument to the hook. |
7533 __ Addu(a1, sp, Operand(kNumSavedRegs * kPointerSize)); | 7545 __ Addu(a1, sp, Operand(kNumSavedRegs * kPointerSize)); |
7534 | 7546 |
7535 // Align the stack if necessary. | 7547 // Align the stack if necessary. |
7536 int frame_alignment = masm->ActivationFrameAlignment(); | 7548 int frame_alignment = masm->ActivationFrameAlignment(); |
7537 if (frame_alignment > kPointerSize) { | 7549 if (frame_alignment > kPointerSize) { |
7538 __ mov(t1, sp); | 7550 __ mov(t1, sp); |
7539 ASSERT(IsPowerOf2(frame_alignment)); | 7551 ASSERT(IsPowerOf2(frame_alignment)); |
7540 __ And(sp, sp, Operand(-frame_alignment)); | 7552 __ And(sp, sp, Operand(-frame_alignment)); |
7541 } | 7553 } |
7542 | 7554 |
7543 #if defined(V8_HOST_ARCH_MIPS) | 7555 #if defined(V8_HOST_ARCH_MIPS) |
7544 __ li(at, Operand(reinterpret_cast<int32_t>(&entry_hook_))); | 7556 int32_t entry_hook = |
7545 __ lw(at, MemOperand(at)); | 7557 reinterpret_cast<int32_t>(masm->isolate()->function_entry_hook()); |
| 7558 __ li(at, Operand(entry_hook)); |
7546 #else | 7559 #else |
7547 // Under the simulator we need to indirect the entry hook through a | 7560 // Under the simulator we need to indirect the entry hook through a |
7548 // trampoline function at a known address. | 7561 // trampoline function at a known address. |
7549 Address trampoline_address = reinterpret_cast<Address>( | 7562 ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline)); |
7550 reinterpret_cast<intptr_t>(EntryHookTrampoline)); | |
7551 ApiFunction dispatcher(trampoline_address); | |
7552 __ li(at, Operand(ExternalReference(&dispatcher, | 7563 __ li(at, Operand(ExternalReference(&dispatcher, |
7553 ExternalReference::BUILTIN_CALL, | 7564 ExternalReference::BUILTIN_CALL, |
7554 masm->isolate()))); | 7565 masm->isolate()))); |
7555 #endif | 7566 #endif |
7556 __ Call(at); | 7567 __ Call(at); |
7557 | 7568 |
7558 // Restore the stack pointer if needed. | 7569 // Restore the stack pointer if needed. |
7559 if (frame_alignment > kPointerSize) { | 7570 if (frame_alignment > kPointerSize) { |
7560 __ mov(sp, t1); | 7571 __ mov(sp, t1); |
7561 } | 7572 } |
7562 | 7573 |
7563 __ Pop(ra, t1, a1); | 7574 // Also pop ra to get Ret(0). |
| 7575 __ MultiPop(kJSCallerSaved | ra.bit()); |
7564 __ Ret(); | 7576 __ Ret(); |
7565 } | 7577 } |
7566 | 7578 |
7567 | 7579 |
7568 template<class T> | 7580 template<class T> |
7569 static void CreateArrayDispatch(MacroAssembler* masm) { | 7581 static void CreateArrayDispatch(MacroAssembler* masm) { |
7570 int last_index = GetSequenceIndexFromFastElementsKind( | 7582 int last_index = GetSequenceIndexFromFastElementsKind( |
7571 TERMINAL_FAST_ELEMENTS_KIND); | 7583 TERMINAL_FAST_ELEMENTS_KIND); |
7572 for (int i = 0; i <= last_index; ++i) { | 7584 for (int i = 0; i <= last_index; ++i) { |
7573 Label next; | 7585 Label next; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7607 | 7619 |
7608 // look at the first argument | 7620 // look at the first argument |
7609 __ lw(t1, MemOperand(sp, 0)); | 7621 __ lw(t1, MemOperand(sp, 0)); |
7610 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); | 7622 __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); |
7611 | 7623 |
7612 // We are going to create a holey array, but our kind is non-holey. | 7624 // We are going to create a holey array, but our kind is non-holey. |
7613 // Fix kind and retry | 7625 // Fix kind and retry |
7614 __ Addu(a3, a3, Operand(1)); | 7626 __ Addu(a3, a3, Operand(1)); |
7615 __ Branch(&normal_sequence, eq, a2, Operand(undefined_sentinel)); | 7627 __ Branch(&normal_sequence, eq, a2, Operand(undefined_sentinel)); |
7616 | 7628 |
| 7629 // The type cell may have gone megamorphic, don't overwrite if so. |
| 7630 __ lw(t1, FieldMemOperand(a2, kPointerSize)); |
| 7631 __ JumpIfNotSmi(t1, &normal_sequence); |
| 7632 |
7617 // Save the resulting elements kind in type info | 7633 // Save the resulting elements kind in type info |
7618 __ SmiTag(a3); | 7634 __ SmiTag(a3); |
7619 __ sw(a3, FieldMemOperand(a2, kPointerSize)); | 7635 __ sw(a3, FieldMemOperand(a2, kPointerSize)); |
7620 __ SmiUntag(a3); | 7636 __ SmiUntag(a3); |
7621 | 7637 |
7622 __ bind(&normal_sequence); | 7638 __ bind(&normal_sequence); |
7623 int last_index = GetSequenceIndexFromFastElementsKind( | 7639 int last_index = GetSequenceIndexFromFastElementsKind( |
7624 TERMINAL_FAST_ELEMENTS_KIND); | 7640 TERMINAL_FAST_ELEMENTS_KIND); |
7625 for (int i = 0; i <= last_index; ++i) { | 7641 for (int i = 0; i <= last_index; ++i) { |
7626 Label next; | 7642 Label next; |
(...skipping 11 matching lines...) Expand all Loading... |
7638 | 7654 |
7639 template<class T> | 7655 template<class T> |
7640 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { | 7656 static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { |
7641 int to_index = GetSequenceIndexFromFastElementsKind( | 7657 int to_index = GetSequenceIndexFromFastElementsKind( |
7642 TERMINAL_FAST_ELEMENTS_KIND); | 7658 TERMINAL_FAST_ELEMENTS_KIND); |
7643 for (int i = 0; i <= to_index; ++i) { | 7659 for (int i = 0; i <= to_index; ++i) { |
7644 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); | 7660 ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); |
7645 T stub(kind); | 7661 T stub(kind); |
7646 stub.GetCode(isolate)->set_is_pregenerated(true); | 7662 stub.GetCode(isolate)->set_is_pregenerated(true); |
7647 if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { | 7663 if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { |
7648 T stub1(kind, true); | 7664 T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); |
7649 stub1.GetCode(isolate)->set_is_pregenerated(true); | 7665 stub1.GetCode(isolate)->set_is_pregenerated(true); |
7650 } | 7666 } |
7651 } | 7667 } |
7652 } | 7668 } |
7653 | 7669 |
7654 | 7670 |
7655 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { | 7671 void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) { |
7656 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( | 7672 ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>( |
7657 isolate); | 7673 isolate); |
7658 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( | 7674 ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>( |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7829 __ bind(&fast_elements_case); | 7845 __ bind(&fast_elements_case); |
7830 GenerateCase(masm, FAST_ELEMENTS); | 7846 GenerateCase(masm, FAST_ELEMENTS); |
7831 } | 7847 } |
7832 | 7848 |
7833 | 7849 |
7834 #undef __ | 7850 #undef __ |
7835 | 7851 |
7836 } } // namespace v8::internal | 7852 } } // namespace v8::internal |
7837 | 7853 |
7838 #endif // V8_TARGET_ARCH_MIPS | 7854 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |