| 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 |