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 |