OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2542 // (9) Sliced string. Replace subject with parent. Go to (4). | 2542 // (9) Sliced string. Replace subject with parent. Go to (4). |
2543 // Load offset into t0 and replace subject string with parent. | 2543 // Load offset into t0 and replace subject string with parent. |
2544 __ ld(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2544 __ ld(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
2545 __ SmiUntag(t0); | 2545 __ SmiUntag(t0); |
2546 __ ld(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2546 __ ld(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
2547 __ jmp(&check_underlying); // Go to (4). | 2547 __ jmp(&check_underlying); // Go to (4). |
2548 #endif // V8_INTERPRETED_REGEXP | 2548 #endif // V8_INTERPRETED_REGEXP |
2549 } | 2549 } |
2550 | 2550 |
2551 | 2551 |
2552 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { | 2552 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, |
| 2553 bool is_super) { |
2553 // a0 : number of arguments to the construct function | 2554 // a0 : number of arguments to the construct function |
2554 // a2 : Feedback vector | 2555 // a2 : feedback vector |
2555 // a3 : slot in feedback vector (Smi) | 2556 // a3 : slot in feedback vector (Smi) |
2556 // a1 : the function to call | 2557 // a1 : the function to call |
| 2558 // a4 : original constructor (for IsSuperConstructorCall) |
2557 FrameScope scope(masm, StackFrame::INTERNAL); | 2559 FrameScope scope(masm, StackFrame::INTERNAL); |
2558 const RegList kSavedRegs = 1 << 4 | // a0 | 2560 const RegList kSavedRegs = 1 << 4 | // a0 |
2559 1 << 5 | // a1 | 2561 1 << 5 | // a1 |
2560 1 << 6 | // a2 | 2562 1 << 6 | // a2 |
2561 1 << 7; // a3 | 2563 1 << 7 | // a3 |
| 2564 BoolToInt(is_super) << 8; // a4 |
| 2565 |
2562 | 2566 |
2563 // Number-of-arguments register must be smi-tagged to call out. | 2567 // Number-of-arguments register must be smi-tagged to call out. |
2564 __ SmiTag(a0); | 2568 __ SmiTag(a0); |
2565 __ MultiPush(kSavedRegs); | 2569 __ MultiPush(kSavedRegs); |
2566 | 2570 |
2567 __ CallStub(stub); | 2571 __ CallStub(stub); |
2568 | 2572 |
2569 __ MultiPop(kSavedRegs); | 2573 __ MultiPop(kSavedRegs); |
2570 __ SmiUntag(a0); | 2574 __ SmiUntag(a0); |
2571 } | 2575 } |
2572 | 2576 |
2573 | 2577 |
2574 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2578 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { |
2575 // Cache the called function in a feedback vector slot. Cache states | 2579 // Cache the called function in a feedback vector slot. Cache states |
2576 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2580 // are uninitialized, monomorphic (indicated by a JSFunction), and |
2577 // megamorphic. | 2581 // megamorphic. |
2578 // a0 : number of arguments to the construct function | 2582 // a0 : number of arguments to the construct function |
2579 // a1 : the function to call | 2583 // a1 : the function to call |
2580 // a2 : Feedback vector | 2584 // a2 : feedback vector |
2581 // a3 : slot in feedback vector (Smi) | 2585 // a3 : slot in feedback vector (Smi) |
| 2586 // a4 : original constructor (for IsSuperConstructorCall) |
2582 Label initialize, done, miss, megamorphic, not_array_function; | 2587 Label initialize, done, miss, megamorphic, not_array_function; |
2583 | 2588 |
2584 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2589 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
2585 masm->isolate()->heap()->megamorphic_symbol()); | 2590 masm->isolate()->heap()->megamorphic_symbol()); |
2586 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2591 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
2587 masm->isolate()->heap()->uninitialized_symbol()); | 2592 masm->isolate()->heap()->uninitialized_symbol()); |
2588 | 2593 |
2589 // Load the cache state into a4. | 2594 // Load the cache state into a5. |
2590 __ dsrl(a4, a3, 32 - kPointerSizeLog2); | 2595 __ dsrl(a5, a3, 32 - kPointerSizeLog2); |
2591 __ Daddu(a4, a2, Operand(a4)); | 2596 __ Daddu(a5, a2, Operand(a5)); |
2592 __ ld(a4, FieldMemOperand(a4, FixedArray::kHeaderSize)); | 2597 __ ld(a5, FieldMemOperand(a5, FixedArray::kHeaderSize)); |
2593 | 2598 |
2594 // A monomorphic cache hit or an already megamorphic state: invoke the | 2599 // A monomorphic cache hit or an already megamorphic state: invoke the |
2595 // function without changing the state. | 2600 // function without changing the state. |
2596 // We don't know if a4 is a WeakCell or a Symbol, but it's harmless to read at | 2601 // We don't know if a5 is a WeakCell or a Symbol, but it's harmless to read at |
2597 // this position in a symbol (see static asserts in type-feedback-vector.h). | 2602 // this position in a symbol (see static asserts in type-feedback-vector.h). |
2598 Label check_allocation_site; | 2603 Label check_allocation_site; |
2599 Register feedback_map = a5; | 2604 Register feedback_map = a6; |
2600 Register weak_value = t0; | 2605 Register weak_value = t0; |
2601 __ ld(weak_value, FieldMemOperand(a4, WeakCell::kValueOffset)); | 2606 __ ld(weak_value, FieldMemOperand(a5, WeakCell::kValueOffset)); |
2602 __ Branch(&done, eq, a1, Operand(weak_value)); | 2607 __ Branch(&done, eq, a1, Operand(weak_value)); |
2603 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 2608 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
2604 __ Branch(&done, eq, a4, Operand(at)); | 2609 __ Branch(&done, eq, a5, Operand(at)); |
2605 __ ld(feedback_map, FieldMemOperand(a4, HeapObject::kMapOffset)); | 2610 __ ld(feedback_map, FieldMemOperand(a5, HeapObject::kMapOffset)); |
2606 __ LoadRoot(at, Heap::kWeakCellMapRootIndex); | 2611 __ LoadRoot(at, Heap::kWeakCellMapRootIndex); |
2607 __ Branch(FLAG_pretenuring_call_new ? &miss : &check_allocation_site, ne, | 2612 __ Branch(FLAG_pretenuring_call_new ? &miss : &check_allocation_site, ne, |
2608 feedback_map, Operand(at)); | 2613 feedback_map, Operand(at)); |
2609 | 2614 |
2610 // If the weak cell is cleared, we have a new chance to become monomorphic. | 2615 // If the weak cell is cleared, we have a new chance to become monomorphic. |
2611 __ JumpIfSmi(weak_value, &initialize); | 2616 __ JumpIfSmi(weak_value, &initialize); |
2612 __ jmp(&megamorphic); | 2617 __ jmp(&megamorphic); |
2613 | 2618 |
2614 if (!FLAG_pretenuring_call_new) { | 2619 if (!FLAG_pretenuring_call_new) { |
2615 __ bind(&check_allocation_site); | 2620 __ bind(&check_allocation_site); |
2616 // If we came here, we need to see if we are the array function. | 2621 // If we came here, we need to see if we are the array function. |
2617 // If we didn't have a matching function, and we didn't find the megamorph | 2622 // If we didn't have a matching function, and we didn't find the megamorph |
2618 // sentinel, then we have in the slot either some other function or an | 2623 // sentinel, then we have in the slot either some other function or an |
2619 // AllocationSite. | 2624 // AllocationSite. |
2620 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 2625 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
2621 __ Branch(&miss, ne, feedback_map, Operand(at)); | 2626 __ Branch(&miss, ne, feedback_map, Operand(at)); |
2622 | 2627 |
2623 // Make sure the function is the Array() function | 2628 // Make sure the function is the Array() function |
2624 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); | 2629 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a5); |
2625 __ Branch(&megamorphic, ne, a1, Operand(a4)); | 2630 __ Branch(&megamorphic, ne, a1, Operand(a5)); |
2626 __ jmp(&done); | 2631 __ jmp(&done); |
2627 } | 2632 } |
2628 | 2633 |
2629 __ bind(&miss); | 2634 __ bind(&miss); |
2630 | 2635 |
2631 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 2636 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
2632 // megamorphic. | 2637 // megamorphic. |
2633 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); | 2638 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); |
2634 __ Branch(&initialize, eq, a4, Operand(at)); | 2639 __ Branch(&initialize, eq, a5, Operand(at)); |
2635 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 2640 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
2636 // write-barrier is needed. | 2641 // write-barrier is needed. |
2637 __ bind(&megamorphic); | 2642 __ bind(&megamorphic); |
2638 __ dsrl(a4, a3, 32 - kPointerSizeLog2); | 2643 __ dsrl(a5, a3, 32 - kPointerSizeLog2); |
2639 __ Daddu(a4, a2, Operand(a4)); | 2644 __ Daddu(a5, a2, Operand(a5)); |
2640 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 2645 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
2641 __ sd(at, FieldMemOperand(a4, FixedArray::kHeaderSize)); | 2646 __ sd(at, FieldMemOperand(a5, FixedArray::kHeaderSize)); |
2642 __ jmp(&done); | 2647 __ jmp(&done); |
2643 | 2648 |
2644 // An uninitialized cache is patched with the function. | 2649 // An uninitialized cache is patched with the function. |
2645 __ bind(&initialize); | 2650 __ bind(&initialize); |
2646 if (!FLAG_pretenuring_call_new) { | 2651 if (!FLAG_pretenuring_call_new) { |
2647 // Make sure the function is the Array() function. | 2652 // Make sure the function is the Array() function. |
2648 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); | 2653 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a5); |
2649 __ Branch(¬_array_function, ne, a1, Operand(a4)); | 2654 __ Branch(¬_array_function, ne, a1, Operand(a5)); |
2650 | 2655 |
2651 // The target function is the Array constructor, | 2656 // The target function is the Array constructor, |
2652 // Create an AllocationSite if we don't already have it, store it in the | 2657 // Create an AllocationSite if we don't already have it, store it in the |
2653 // slot. | 2658 // slot. |
2654 CreateAllocationSiteStub create_stub(masm->isolate()); | 2659 CreateAllocationSiteStub create_stub(masm->isolate()); |
2655 CallStubInRecordCallTarget(masm, &create_stub); | 2660 CallStubInRecordCallTarget(masm, &create_stub, is_super); |
2656 __ Branch(&done); | 2661 __ Branch(&done); |
2657 | 2662 |
2658 __ bind(¬_array_function); | 2663 __ bind(¬_array_function); |
2659 } | 2664 } |
2660 | 2665 |
2661 CreateWeakCellStub create_stub(masm->isolate()); | 2666 CreateWeakCellStub create_stub(masm->isolate()); |
2662 CallStubInRecordCallTarget(masm, &create_stub); | 2667 CallStubInRecordCallTarget(masm, &create_stub, is_super); |
2663 __ bind(&done); | 2668 __ bind(&done); |
2664 } | 2669 } |
2665 | 2670 |
2666 | 2671 |
2667 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2672 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
2668 __ ld(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 2673 __ ld(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
2669 | 2674 |
2670 // Do not transform the receiver for strict mode functions. | 2675 // Do not transform the receiver for strict mode functions. |
2671 int32_t strict_mode_function_mask = | 2676 int32_t strict_mode_function_mask = |
2672 1 << SharedFunctionInfo::kStrictModeBitWithinByte ; | 2677 1 << SharedFunctionInfo::kStrictModeBitWithinByte ; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2787 // a3 : slot in feedback vector (Smi, for RecordCallTarget) | 2792 // a3 : slot in feedback vector (Smi, for RecordCallTarget) |
2788 // a4 : original constructor (for IsSuperConstructorCall) | 2793 // a4 : original constructor (for IsSuperConstructorCall) |
2789 Label slow, non_function_call; | 2794 Label slow, non_function_call; |
2790 // Check that the function is not a smi. | 2795 // Check that the function is not a smi. |
2791 __ JumpIfSmi(a1, &non_function_call); | 2796 __ JumpIfSmi(a1, &non_function_call); |
2792 // Check that the function is a JSFunction. | 2797 // Check that the function is a JSFunction. |
2793 __ GetObjectType(a1, a5, a5); | 2798 __ GetObjectType(a1, a5, a5); |
2794 __ Branch(&slow, ne, a5, Operand(JS_FUNCTION_TYPE)); | 2799 __ Branch(&slow, ne, a5, Operand(JS_FUNCTION_TYPE)); |
2795 | 2800 |
2796 if (RecordCallTarget()) { | 2801 if (RecordCallTarget()) { |
2797 if (IsSuperConstructorCall()) { | 2802 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); |
2798 __ push(a4); | |
2799 } | |
2800 GenerateRecordCallTarget(masm); | |
2801 if (IsSuperConstructorCall()) { | |
2802 __ pop(a4); | |
2803 } | |
2804 | 2803 |
2805 __ dsrl(at, a3, 32 - kPointerSizeLog2); | 2804 __ dsrl(at, a3, 32 - kPointerSizeLog2); |
2806 __ Daddu(a5, a2, at); | 2805 __ Daddu(a5, a2, at); |
2807 if (FLAG_pretenuring_call_new) { | 2806 if (FLAG_pretenuring_call_new) { |
2808 // Put the AllocationSite from the feedback vector into a2. | 2807 // Put the AllocationSite from the feedback vector into a2. |
2809 // By adding kPointerSize we encode that we know the AllocationSite | 2808 // By adding kPointerSize we encode that we know the AllocationSite |
2810 // entry is at the feedback vector slot given by a3 + 1. | 2809 // entry is at the feedback vector slot given by a3 + 1. |
2811 __ ld(a2, FieldMemOperand(a5, FixedArray::kHeaderSize + kPointerSize)); | 2810 __ ld(a2, FieldMemOperand(a5, FixedArray::kHeaderSize + kPointerSize)); |
2812 } else { | 2811 } else { |
2813 Label feedback_register_initialized; | 2812 Label feedback_register_initialized; |
(...skipping 2796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5610 MemOperand(fp, 6 * kPointerSize), NULL); | 5609 MemOperand(fp, 6 * kPointerSize), NULL); |
5611 } | 5610 } |
5612 | 5611 |
5613 | 5612 |
5614 #undef __ | 5613 #undef __ |
5615 | 5614 |
5616 } // namespace internal | 5615 } // namespace internal |
5617 } // namespace v8 | 5616 } // namespace v8 |
5618 | 5617 |
5619 #endif // V8_TARGET_ARCH_MIPS64 | 5618 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |