| 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 #if V8_TARGET_ARCH_PPC | 5 #if V8_TARGET_ARCH_PPC |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 2549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2560 #if V8_TARGET_ARCH_PPC64 | 2560 #if V8_TARGET_ARCH_PPC64 |
| 2561 SharedFunctionInfo::kNative, | 2561 SharedFunctionInfo::kNative, |
| 2562 #else | 2562 #else |
| 2563 SharedFunctionInfo::kNative + kSmiTagSize, | 2563 SharedFunctionInfo::kNative + kSmiTagSize, |
| 2564 #endif | 2564 #endif |
| 2565 r0); | 2565 r0); |
| 2566 __ bne(cont, cr0); | 2566 __ bne(cont, cr0); |
| 2567 } | 2567 } |
| 2568 | 2568 |
| 2569 | 2569 |
| 2570 static void EmitSlowCase(MacroAssembler* masm, int argc, Label* non_function) { | 2570 static void EmitSlowCase(MacroAssembler* masm, int argc) { |
| 2571 // Check for function proxy. | 2571 __ mov(r3, Operand(argc)); |
| 2572 STATIC_ASSERT(JS_FUNCTION_PROXY_TYPE < 0xffffu); | 2572 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 2573 __ cmpi(r7, Operand(JS_FUNCTION_PROXY_TYPE)); | |
| 2574 __ bne(non_function); | |
| 2575 __ push(r4); // put proxy as additional argument | |
| 2576 __ li(r3, Operand(argc + 1)); | |
| 2577 __ li(r5, Operand::Zero()); | |
| 2578 __ GetBuiltinFunction(r4, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX); | |
| 2579 { | |
| 2580 Handle<Code> adaptor = | |
| 2581 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); | |
| 2582 __ Jump(adaptor, RelocInfo::CODE_TARGET); | |
| 2583 } | |
| 2584 | |
| 2585 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead | |
| 2586 // of the original receiver from the call site). | |
| 2587 __ bind(non_function); | |
| 2588 __ StoreP(r4, MemOperand(sp, argc * kPointerSize), r0); | |
| 2589 __ li(r3, Operand(argc)); // Set up the number of arguments. | |
| 2590 __ li(r5, Operand::Zero()); | |
| 2591 __ GetBuiltinFunction(r4, Context::CALL_NON_FUNCTION_BUILTIN_INDEX); | |
| 2592 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | |
| 2593 RelocInfo::CODE_TARGET); | |
| 2594 } | 2573 } |
| 2595 | 2574 |
| 2596 | 2575 |
| 2597 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { | 2576 static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) { |
| 2598 // Wrap the receiver and patch it back onto the stack. | 2577 // Wrap the receiver and patch it back onto the stack. |
| 2599 { | 2578 { |
| 2600 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); | 2579 FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL); |
| 2601 __ push(r4); | 2580 __ push(r4); |
| 2602 __ mr(r3, r6); | 2581 __ mr(r3, r6); |
| 2603 ToObjectStub stub(masm->isolate()); | 2582 ToObjectStub stub(masm->isolate()); |
| 2604 __ CallStub(&stub); | 2583 __ CallStub(&stub); |
| 2605 __ pop(r4); | 2584 __ pop(r4); |
| 2606 } | 2585 } |
| 2607 __ StoreP(r3, MemOperand(sp, argc * kPointerSize), r0); | 2586 __ StoreP(r3, MemOperand(sp, argc * kPointerSize), r0); |
| 2608 __ b(cont); | 2587 __ b(cont); |
| 2609 } | 2588 } |
| 2610 | 2589 |
| 2611 | 2590 |
| 2612 static void CallFunctionNoFeedback(MacroAssembler* masm, int argc, | 2591 static void CallFunctionNoFeedback(MacroAssembler* masm, int argc, |
| 2613 bool needs_checks, bool call_as_method) { | 2592 bool needs_checks, bool call_as_method) { |
| 2614 // r4 : the function to call | 2593 // r4 : the function to call |
| 2615 Label slow, non_function, wrap, cont; | 2594 Label slow, wrap, cont; |
| 2616 | 2595 |
| 2617 if (needs_checks) { | 2596 if (needs_checks) { |
| 2618 // Check that the function is really a JavaScript function. | 2597 // Check that the function is really a JavaScript function. |
| 2619 // r4: pushed function (to be verified) | 2598 // r4: pushed function (to be verified) |
| 2620 __ JumpIfSmi(r4, &non_function); | 2599 __ JumpIfSmi(r4, &slow); |
| 2621 | 2600 |
| 2622 // Goto slow case if we do not have a function. | 2601 // Goto slow case if we do not have a function. |
| 2623 __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE); | 2602 __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE); |
| 2624 __ bne(&slow); | 2603 __ bne(&slow); |
| 2625 } | 2604 } |
| 2626 | 2605 |
| 2627 // Fast-case: Invoke the function now. | 2606 // Fast-case: Invoke the function now. |
| 2628 // r4: pushed function | 2607 // r4: pushed function |
| 2629 ParameterCount actual(argc); | 2608 ParameterCount actual(argc); |
| 2630 | 2609 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2645 } | 2624 } |
| 2646 | 2625 |
| 2647 __ bind(&cont); | 2626 __ bind(&cont); |
| 2648 } | 2627 } |
| 2649 | 2628 |
| 2650 __ InvokeFunction(r4, actual, JUMP_FUNCTION, NullCallWrapper()); | 2629 __ InvokeFunction(r4, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 2651 | 2630 |
| 2652 if (needs_checks) { | 2631 if (needs_checks) { |
| 2653 // Slow-case: Non-function called. | 2632 // Slow-case: Non-function called. |
| 2654 __ bind(&slow); | 2633 __ bind(&slow); |
| 2655 EmitSlowCase(masm, argc, &non_function); | 2634 EmitSlowCase(masm, argc); |
| 2656 } | 2635 } |
| 2657 | 2636 |
| 2658 if (call_as_method) { | 2637 if (call_as_method) { |
| 2659 __ bind(&wrap); | 2638 __ bind(&wrap); |
| 2660 EmitWrapCase(masm, argc, &cont); | 2639 EmitWrapCase(masm, argc, &cont); |
| 2661 } | 2640 } |
| 2662 } | 2641 } |
| 2663 | 2642 |
| 2664 | 2643 |
| 2665 void CallFunctionStub::Generate(MacroAssembler* masm) { | 2644 void CallFunctionStub::Generate(MacroAssembler* masm) { |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2787 | 2766 |
| 2788 __ mr(r5, r7); | 2767 __ mr(r5, r7); |
| 2789 __ mr(r6, r4); | 2768 __ mr(r6, r4); |
| 2790 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2769 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 2791 __ TailCallStub(&stub); | 2770 __ TailCallStub(&stub); |
| 2792 | 2771 |
| 2793 __ bind(&miss); | 2772 __ bind(&miss); |
| 2794 GenerateMiss(masm); | 2773 GenerateMiss(masm); |
| 2795 | 2774 |
| 2796 // The slow case, we need this no matter what to complete a call after a miss. | 2775 // The slow case, we need this no matter what to complete a call after a miss. |
| 2797 CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod()); | 2776 __ mov(r3, Operand(arg_count())); |
| 2798 | 2777 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
| 2799 // Unreachable. | |
| 2800 __ stop("Unexpected code address"); | |
| 2801 } | 2778 } |
| 2802 | 2779 |
| 2803 | 2780 |
| 2804 void CallICStub::Generate(MacroAssembler* masm) { | 2781 void CallICStub::Generate(MacroAssembler* masm) { |
| 2805 // r4 - function | 2782 // r4 - function |
| 2806 // r6 - slot id (Smi) | 2783 // r6 - slot id (Smi) |
| 2807 // r5 - vector | 2784 // r5 - vector |
| 2808 const int with_types_offset = | 2785 const int with_types_offset = |
| 2809 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); | 2786 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); |
| 2810 const int generic_offset = | 2787 const int generic_offset = |
| 2811 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); | 2788 FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); |
| 2812 Label extra_checks_or_miss, slow_start; | 2789 Label extra_checks_or_miss, slow_start; |
| 2813 Label slow, non_function, wrap, cont; | 2790 Label slow, wrap, cont; |
| 2814 Label have_js_function; | 2791 Label have_js_function; |
| 2815 int argc = arg_count(); | 2792 int argc = arg_count(); |
| 2816 ParameterCount actual(argc); | 2793 ParameterCount actual(argc); |
| 2817 | 2794 |
| 2818 // The checks. First, does r4 match the recorded monomorphic target? | 2795 // The checks. First, does r4 match the recorded monomorphic target? |
| 2819 __ SmiToPtrArrayOffset(r9, r6); | 2796 __ SmiToPtrArrayOffset(r9, r6); |
| 2820 __ add(r9, r5, r9); | 2797 __ add(r9, r5, r9); |
| 2821 __ LoadP(r7, FieldMemOperand(r9, FixedArray::kHeaderSize)); | 2798 __ LoadP(r7, FieldMemOperand(r9, FixedArray::kHeaderSize)); |
| 2822 | 2799 |
| 2823 // We don't know that we have a weak cell. We might have a private symbol | 2800 // We don't know that we have a weak cell. We might have a private symbol |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2857 __ JumpIfSmi(r6, &wrap); | 2834 __ JumpIfSmi(r6, &wrap); |
| 2858 __ CompareObjectType(r6, r7, r7, FIRST_SPEC_OBJECT_TYPE); | 2835 __ CompareObjectType(r6, r7, r7, FIRST_SPEC_OBJECT_TYPE); |
| 2859 __ blt(&wrap); | 2836 __ blt(&wrap); |
| 2860 | 2837 |
| 2861 __ bind(&cont); | 2838 __ bind(&cont); |
| 2862 } | 2839 } |
| 2863 | 2840 |
| 2864 __ InvokeFunction(r4, actual, JUMP_FUNCTION, NullCallWrapper()); | 2841 __ InvokeFunction(r4, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 2865 | 2842 |
| 2866 __ bind(&slow); | 2843 __ bind(&slow); |
| 2867 EmitSlowCase(masm, argc, &non_function); | 2844 EmitSlowCase(masm, argc); |
| 2868 | 2845 |
| 2869 if (CallAsMethod()) { | 2846 if (CallAsMethod()) { |
| 2870 __ bind(&wrap); | 2847 __ bind(&wrap); |
| 2871 EmitWrapCase(masm, argc, &cont); | 2848 EmitWrapCase(masm, argc, &cont); |
| 2872 } | 2849 } |
| 2873 | 2850 |
| 2874 __ bind(&extra_checks_or_miss); | 2851 __ bind(&extra_checks_or_miss); |
| 2875 Label uninitialized, miss; | 2852 Label uninitialized, miss; |
| 2876 | 2853 |
| 2877 __ CompareRoot(r7, Heap::kmegamorphic_symbolRootIndex); | 2854 __ CompareRoot(r7, Heap::kmegamorphic_symbolRootIndex); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2942 | 2919 |
| 2943 // We are here because tracing is on or we encountered a MISS case we can't | 2920 // We are here because tracing is on or we encountered a MISS case we can't |
| 2944 // handle here. | 2921 // handle here. |
| 2945 __ bind(&miss); | 2922 __ bind(&miss); |
| 2946 GenerateMiss(masm); | 2923 GenerateMiss(masm); |
| 2947 | 2924 |
| 2948 // the slow case | 2925 // the slow case |
| 2949 __ bind(&slow_start); | 2926 __ bind(&slow_start); |
| 2950 // Check that the function is really a JavaScript function. | 2927 // Check that the function is really a JavaScript function. |
| 2951 // r4: pushed function (to be verified) | 2928 // r4: pushed function (to be verified) |
| 2952 __ JumpIfSmi(r4, &non_function); | 2929 __ JumpIfSmi(r4, &slow); |
| 2953 | 2930 |
| 2954 // Goto slow case if we do not have a function. | 2931 // Goto slow case if we do not have a function. |
| 2955 __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE); | 2932 __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE); |
| 2956 __ bne(&slow); | 2933 __ bne(&slow); |
| 2957 __ b(&have_js_function); | 2934 __ b(&have_js_function); |
| 2958 } | 2935 } |
| 2959 | 2936 |
| 2960 | 2937 |
| 2961 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 2938 void CallICStub::GenerateMiss(MacroAssembler* masm) { |
| 2962 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2939 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| (...skipping 2760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5723 kStackUnwindSpace, NULL, | 5700 kStackUnwindSpace, NULL, |
| 5724 MemOperand(fp, 6 * kPointerSize), NULL); | 5701 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5725 } | 5702 } |
| 5726 | 5703 |
| 5727 | 5704 |
| 5728 #undef __ | 5705 #undef __ |
| 5729 } // namespace internal | 5706 } // namespace internal |
| 5730 } // namespace v8 | 5707 } // namespace v8 |
| 5731 | 5708 |
| 5732 #endif // V8_TARGET_ARCH_PPC | 5709 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |