OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 7 #if V8_TARGET_ARCH_PPC |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 2529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 // (9) Sliced string. Replace subject with parent. Go to (4). | 2540 // (9) Sliced string. Replace subject with parent. Go to (4). |
2541 // Load offset into r11 and replace subject string with parent. | 2541 // Load offset into r11 and replace subject string with parent. |
2542 __ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2542 __ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
2543 __ SmiUntag(r11); | 2543 __ SmiUntag(r11); |
2544 __ LoadP(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2544 __ LoadP(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
2545 __ b(&check_underlying); // Go to (4). | 2545 __ b(&check_underlying); // Go to (4). |
2546 #endif // V8_INTERPRETED_REGEXP | 2546 #endif // V8_INTERPRETED_REGEXP |
2547 } | 2547 } |
2548 | 2548 |
2549 | 2549 |
2550 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { | 2550 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, |
| 2551 bool is_super) { |
2551 // r3 : number of arguments to the construct function | 2552 // r3 : number of arguments to the construct function |
2552 // r5 : Feedback vector | 2553 // r4 : the function to call |
| 2554 // r5 : feedback vector |
2553 // r6 : slot in feedback vector (Smi) | 2555 // r6 : slot in feedback vector (Smi) |
2554 // r4 : the function to call | 2556 // r7 : original constructor (for IsSuperConstructorCall) |
2555 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2557 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
2556 | 2558 |
2557 // Number-of-arguments register must be smi-tagged to call out. | 2559 // Number-of-arguments register must be smi-tagged to call out. |
2558 __ SmiTag(r3); | 2560 __ SmiTag(r3); |
2559 __ Push(r6, r5, r4, r3); | 2561 if (is_super) { |
| 2562 __ Push(r6, r5, r4, r3, r7); |
| 2563 } else { |
| 2564 __ Push(r6, r5, r4, r3); |
| 2565 } |
2560 | 2566 |
2561 __ CallStub(stub); | 2567 __ CallStub(stub); |
2562 | 2568 |
2563 __ Pop(r6, r5, r4, r3); | 2569 if (is_super) { |
| 2570 __ Pop(r6, r5, r4, r3, r7); |
| 2571 } else { |
| 2572 __ Pop(r6, r5, r4, r3); |
| 2573 } |
2564 __ SmiUntag(r3); | 2574 __ SmiUntag(r3); |
2565 } | 2575 } |
2566 | 2576 |
2567 | 2577 |
2568 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2578 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { |
2569 // Cache the called function in a feedback vector slot. Cache states | 2579 // Cache the called function in a feedback vector slot. Cache states |
2570 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2580 // are uninitialized, monomorphic (indicated by a JSFunction), and |
2571 // megamorphic. | 2581 // megamorphic. |
2572 // r3 : number of arguments to the construct function | 2582 // r3 : number of arguments to the construct function |
2573 // r4 : the function to call | 2583 // r4 : the function to call |
2574 // r5 : Feedback vector | 2584 // r5 : feedback vector |
2575 // r6 : slot in feedback vector (Smi) | 2585 // r6 : slot in feedback vector (Smi) |
| 2586 // r7 : original constructor (for IsSuperConstructorCall) |
2576 Label initialize, done, miss, megamorphic, not_array_function; | 2587 Label initialize, done, miss, megamorphic, not_array_function; |
2577 | 2588 |
2578 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2589 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
2579 masm->isolate()->heap()->megamorphic_symbol()); | 2590 masm->isolate()->heap()->megamorphic_symbol()); |
2580 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2591 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
2581 masm->isolate()->heap()->uninitialized_symbol()); | 2592 masm->isolate()->heap()->uninitialized_symbol()); |
2582 | 2593 |
2583 // Load the cache state into r7. | 2594 // Load the cache state into r8. |
2584 __ SmiToPtrArrayOffset(r7, r6); | 2595 __ SmiToPtrArrayOffset(r8, r6); |
2585 __ add(r7, r5, r7); | 2596 __ add(r8, r5, r8); |
2586 __ LoadP(r7, FieldMemOperand(r7, FixedArray::kHeaderSize)); | 2597 __ LoadP(r8, FieldMemOperand(r8, FixedArray::kHeaderSize)); |
2587 | 2598 |
2588 // A monomorphic cache hit or an already megamorphic state: invoke the | 2599 // A monomorphic cache hit or an already megamorphic state: invoke the |
2589 // function without changing the state. | 2600 // function without changing the state. |
2590 // We don't know if r7 is a WeakCell or a Symbol, but it's harmless to read at | 2601 // We don't know if r8 is a WeakCell or a Symbol, but it's harmless to read at |
2591 // 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). |
2592 Label check_allocation_site; | 2603 Label check_allocation_site; |
2593 Register feedback_map = r8; | 2604 Register feedback_map = r9; |
2594 Register weak_value = r9; | 2605 Register weak_value = r10; |
2595 __ LoadP(weak_value, FieldMemOperand(r7, WeakCell::kValueOffset)); | 2606 __ LoadP(weak_value, FieldMemOperand(r8, WeakCell::kValueOffset)); |
2596 __ cmp(r4, weak_value); | 2607 __ cmp(r4, weak_value); |
2597 __ beq(&done); | 2608 __ beq(&done); |
2598 __ CompareRoot(r7, Heap::kmegamorphic_symbolRootIndex); | 2609 __ CompareRoot(r8, Heap::kmegamorphic_symbolRootIndex); |
2599 __ beq(&done); | 2610 __ beq(&done); |
2600 __ LoadP(feedback_map, FieldMemOperand(r7, HeapObject::kMapOffset)); | 2611 __ LoadP(feedback_map, FieldMemOperand(r8, HeapObject::kMapOffset)); |
2601 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | 2612 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); |
2602 __ bne(FLAG_pretenuring_call_new ? &miss : &check_allocation_site); | 2613 __ bne(FLAG_pretenuring_call_new ? &miss : &check_allocation_site); |
2603 | 2614 |
2604 // 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. |
2605 __ JumpIfSmi(weak_value, &initialize); | 2616 __ JumpIfSmi(weak_value, &initialize); |
2606 __ b(&megamorphic); | 2617 __ b(&megamorphic); |
2607 | 2618 |
2608 if (!FLAG_pretenuring_call_new) { | 2619 if (!FLAG_pretenuring_call_new) { |
2609 __ bind(&check_allocation_site); | 2620 __ bind(&check_allocation_site); |
2610 // 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. |
2611 // 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 |
2612 // 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 |
2613 // AllocationSite. | 2624 // AllocationSite. |
2614 __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex); | 2625 __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex); |
2615 __ bne(&miss); | 2626 __ bne(&miss); |
2616 | 2627 |
2617 // Make sure the function is the Array() function | 2628 // Make sure the function is the Array() function |
2618 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r7); | 2629 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r8); |
2619 __ cmp(r4, r7); | 2630 __ cmp(r4, r8); |
2620 __ bne(&megamorphic); | 2631 __ bne(&megamorphic); |
2621 __ b(&done); | 2632 __ b(&done); |
2622 } | 2633 } |
2623 | 2634 |
2624 __ bind(&miss); | 2635 __ bind(&miss); |
2625 | 2636 |
2626 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 2637 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
2627 // megamorphic. | 2638 // megamorphic. |
2628 __ CompareRoot(r7, Heap::kuninitialized_symbolRootIndex); | 2639 __ CompareRoot(r8, Heap::kuninitialized_symbolRootIndex); |
2629 __ beq(&initialize); | 2640 __ beq(&initialize); |
2630 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 2641 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
2631 // write-barrier is needed. | 2642 // write-barrier is needed. |
2632 __ bind(&megamorphic); | 2643 __ bind(&megamorphic); |
2633 __ SmiToPtrArrayOffset(r7, r6); | 2644 __ SmiToPtrArrayOffset(r8, r6); |
2634 __ add(r7, r5, r7); | 2645 __ add(r8, r5, r8); |
2635 __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex); | 2646 __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex); |
2636 __ StoreP(ip, FieldMemOperand(r7, FixedArray::kHeaderSize), r0); | 2647 __ StoreP(ip, FieldMemOperand(r8, FixedArray::kHeaderSize), r0); |
2637 __ jmp(&done); | 2648 __ jmp(&done); |
2638 | 2649 |
2639 // An uninitialized cache is patched with the function | 2650 // An uninitialized cache is patched with the function |
2640 __ bind(&initialize); | 2651 __ bind(&initialize); |
2641 | 2652 |
2642 if (!FLAG_pretenuring_call_new) { | 2653 if (!FLAG_pretenuring_call_new) { |
2643 // Make sure the function is the Array() function. | 2654 // Make sure the function is the Array() function. |
2644 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r7); | 2655 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r8); |
2645 __ cmp(r4, r7); | 2656 __ cmp(r4, r8); |
2646 __ bne(¬_array_function); | 2657 __ bne(¬_array_function); |
2647 | 2658 |
2648 // The target function is the Array constructor, | 2659 // The target function is the Array constructor, |
2649 // Create an AllocationSite if we don't already have it, store it in the | 2660 // Create an AllocationSite if we don't already have it, store it in the |
2650 // slot. | 2661 // slot. |
2651 CreateAllocationSiteStub create_stub(masm->isolate()); | 2662 CreateAllocationSiteStub create_stub(masm->isolate()); |
2652 CallStubInRecordCallTarget(masm, &create_stub); | 2663 CallStubInRecordCallTarget(masm, &create_stub, is_super); |
2653 __ b(&done); | 2664 __ b(&done); |
2654 | 2665 |
2655 __ bind(¬_array_function); | 2666 __ bind(¬_array_function); |
2656 } | 2667 } |
2657 | 2668 |
2658 CreateWeakCellStub create_stub(masm->isolate()); | 2669 CreateWeakCellStub create_stub(masm->isolate()); |
2659 CallStubInRecordCallTarget(masm, &create_stub); | 2670 CallStubInRecordCallTarget(masm, &create_stub, is_super); |
2660 __ bind(&done); | 2671 __ bind(&done); |
2661 } | 2672 } |
2662 | 2673 |
2663 | 2674 |
2664 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2675 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
2665 // Do not transform the receiver for strict mode functions and natives. | 2676 // Do not transform the receiver for strict mode functions and natives. |
2666 __ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 2677 __ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
2667 __ lwz(r7, FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset)); | 2678 __ lwz(r7, FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset)); |
2668 __ TestBit(r7, | 2679 __ TestBit(r7, |
2669 #if V8_TARGET_ARCH_PPC64 | 2680 #if V8_TARGET_ARCH_PPC64 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2792 // r7 : original constructor (for IsSuperConstructorCall) | 2803 // r7 : original constructor (for IsSuperConstructorCall) |
2793 Label slow, non_function_call; | 2804 Label slow, non_function_call; |
2794 | 2805 |
2795 // Check that the function is not a smi. | 2806 // Check that the function is not a smi. |
2796 __ JumpIfSmi(r4, &non_function_call); | 2807 __ JumpIfSmi(r4, &non_function_call); |
2797 // Check that the function is a JSFunction. | 2808 // Check that the function is a JSFunction. |
2798 __ CompareObjectType(r4, r8, r8, JS_FUNCTION_TYPE); | 2809 __ CompareObjectType(r4, r8, r8, JS_FUNCTION_TYPE); |
2799 __ bne(&slow); | 2810 __ bne(&slow); |
2800 | 2811 |
2801 if (RecordCallTarget()) { | 2812 if (RecordCallTarget()) { |
2802 if (IsSuperConstructorCall()) { | 2813 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); |
2803 __ push(r7); | |
2804 } | |
2805 // TODO(mstarzinger): Consider tweaking target recording to avoid push/pop. | |
2806 GenerateRecordCallTarget(masm); | |
2807 if (IsSuperConstructorCall()) { | |
2808 __ pop(r7); | |
2809 } | |
2810 | 2814 |
2811 __ SmiToPtrArrayOffset(r8, r6); | 2815 __ SmiToPtrArrayOffset(r8, r6); |
2812 __ add(r8, r5, r8); | 2816 __ add(r8, r5, r8); |
2813 if (FLAG_pretenuring_call_new) { | 2817 if (FLAG_pretenuring_call_new) { |
2814 // Put the AllocationSite from the feedback vector into r5. | 2818 // Put the AllocationSite from the feedback vector into r5. |
2815 // By adding kPointerSize we encode that we know the AllocationSite | 2819 // By adding kPointerSize we encode that we know the AllocationSite |
2816 // entry is at the feedback vector slot given by r6 + 1. | 2820 // entry is at the feedback vector slot given by r6 + 1. |
2817 __ LoadP(r5, FieldMemOperand(r8, FixedArray::kHeaderSize + kPointerSize)); | 2821 __ LoadP(r5, FieldMemOperand(r8, FixedArray::kHeaderSize + kPointerSize)); |
2818 } else { | 2822 } else { |
2819 // Put the AllocationSite from the feedback vector into r5, or undefined. | 2823 // Put the AllocationSite from the feedback vector into r5, or undefined. |
(...skipping 2853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5673 kStackUnwindSpace, NULL, | 5677 kStackUnwindSpace, NULL, |
5674 MemOperand(fp, 6 * kPointerSize), NULL); | 5678 MemOperand(fp, 6 * kPointerSize), NULL); |
5675 } | 5679 } |
5676 | 5680 |
5677 | 5681 |
5678 #undef __ | 5682 #undef __ |
5679 } // namespace internal | 5683 } // namespace internal |
5680 } // namespace v8 | 5684 } // namespace v8 |
5681 | 5685 |
5682 #endif // V8_TARGET_ARCH_PPC | 5686 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |