| 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/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 __ addi(r6, r3, Operand(1)); | 1177 __ addi(r6, r3, Operand(1)); |
| 1178 | 1178 |
| 1179 // Push the arguments. r5, r6, r7 will be modified. | 1179 // Push the arguments. r5, r6, r7 will be modified. |
| 1180 Generate_InterpreterPushArgs(masm, r6, r5, r6, r7, &stack_overflow); | 1180 Generate_InterpreterPushArgs(masm, r6, r5, r6, r7, &stack_overflow); |
| 1181 | 1181 |
| 1182 // Call the target. | 1182 // Call the target. |
| 1183 if (mode == InterpreterPushArgsMode::kJSFunction) { | 1183 if (mode == InterpreterPushArgsMode::kJSFunction) { |
| 1184 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, | 1184 __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny, |
| 1185 tail_call_mode), | 1185 tail_call_mode), |
| 1186 RelocInfo::CODE_TARGET); | 1186 RelocInfo::CODE_TARGET); |
| 1187 } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) { |
| 1188 __ Jump(masm->isolate()->builtins()->CallWithSpread(), |
| 1189 RelocInfo::CODE_TARGET); |
| 1187 } else { | 1190 } else { |
| 1188 DCHECK_EQ(mode, InterpreterPushArgsMode::kOther); | |
| 1189 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 1191 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
| 1190 tail_call_mode), | 1192 tail_call_mode), |
| 1191 RelocInfo::CODE_TARGET); | 1193 RelocInfo::CODE_TARGET); |
| 1192 } | 1194 } |
| 1193 | 1195 |
| 1194 __ bind(&stack_overflow); | 1196 __ bind(&stack_overflow); |
| 1195 { | 1197 { |
| 1196 __ TailCallRuntime(Runtime::kThrowStackOverflow); | 1198 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
| 1197 // Unreachable Code. | 1199 // Unreachable Code. |
| 1198 __ bkpt(0); | 1200 __ bkpt(0); |
| (...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2681 | 2683 |
| 2682 // 3. Call to something that is not callable. | 2684 // 3. Call to something that is not callable. |
| 2683 __ bind(&non_callable); | 2685 __ bind(&non_callable); |
| 2684 { | 2686 { |
| 2685 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2687 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 2686 __ Push(r4); | 2688 __ Push(r4); |
| 2687 __ CallRuntime(Runtime::kThrowCalledNonCallable); | 2689 __ CallRuntime(Runtime::kThrowCalledNonCallable); |
| 2688 } | 2690 } |
| 2689 } | 2691 } |
| 2690 | 2692 |
| 2693 static void CheckSpreadAndPushToStack(MacroAssembler* masm) { |
| 2694 Register argc = r3; |
| 2695 Register constructor = r4; |
| 2696 Register new_target = r6; |
| 2697 |
| 2698 Register scratch = r5; |
| 2699 Register scratch2 = r9; |
| 2700 |
| 2701 Register spread = r7; |
| 2702 Register spread_map = r8; |
| 2703 Register spread_len = r8; |
| 2704 Label runtime_call, push_args; |
| 2705 __ LoadP(spread, MemOperand(sp, 0)); |
| 2706 __ JumpIfSmi(spread, &runtime_call); |
| 2707 __ LoadP(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset)); |
| 2708 |
| 2709 // Check that the spread is an array. |
| 2710 __ CompareInstanceType(spread_map, scratch, JS_ARRAY_TYPE); |
| 2711 __ bne(&runtime_call); |
| 2712 |
| 2713 // Check that we have the original ArrayPrototype. |
| 2714 __ LoadP(scratch, FieldMemOperand(spread_map, Map::kPrototypeOffset)); |
| 2715 __ LoadP(scratch2, NativeContextMemOperand()); |
| 2716 __ LoadP(scratch2, |
| 2717 ContextMemOperand(scratch2, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); |
| 2718 __ cmp(scratch, scratch2); |
| 2719 __ bne(&runtime_call); |
| 2720 |
| 2721 // Check that the ArrayPrototype hasn't been modified in a way that would |
| 2722 // affect iteration. |
| 2723 __ LoadRoot(scratch, Heap::kArrayIteratorProtectorRootIndex); |
| 2724 __ LoadP(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); |
| 2725 __ CmpSmiLiteral(scratch, Smi::FromInt(Isolate::kProtectorValid), r0); |
| 2726 __ bne(&runtime_call); |
| 2727 |
| 2728 // Check that the map of the initial array iterator hasn't changed. |
| 2729 __ LoadP(scratch2, NativeContextMemOperand()); |
| 2730 __ LoadP(scratch, |
| 2731 ContextMemOperand(scratch2, |
| 2732 Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX)); |
| 2733 __ LoadP(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset)); |
| 2734 __ LoadP(scratch2, |
| 2735 ContextMemOperand( |
| 2736 scratch2, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_MAP_INDEX)); |
| 2737 __ cmp(scratch, scratch2); |
| 2738 __ bne(&runtime_call); |
| 2739 |
| 2740 // For FastPacked kinds, iteration will have the same effect as simply |
| 2741 // accessing each property in order. |
| 2742 Label no_protector_check; |
| 2743 __ LoadP(scratch, FieldMemOperand(spread_map, Map::kBitField2Offset)); |
| 2744 __ DecodeField<Map::ElementsKindBits>(scratch); |
| 2745 __ cmpi(scratch, Operand(FAST_HOLEY_ELEMENTS)); |
| 2746 __ bgt(&runtime_call); |
| 2747 // For non-FastHoley kinds, we can skip the protector check. |
| 2748 __ cmpi(scratch, Operand(FAST_SMI_ELEMENTS)); |
| 2749 __ beq(&no_protector_check); |
| 2750 __ cmpi(scratch, Operand(FAST_ELEMENTS)); |
| 2751 __ beq(&no_protector_check); |
| 2752 // Check the ArrayProtector cell. |
| 2753 __ LoadRoot(scratch, Heap::kArrayProtectorRootIndex); |
| 2754 __ LoadP(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); |
| 2755 __ CmpSmiLiteral(scratch, Smi::FromInt(Isolate::kProtectorValid), r0); |
| 2756 __ bne(&runtime_call); |
| 2757 |
| 2758 __ bind(&no_protector_check); |
| 2759 // Load the FixedArray backing store, but use the length from the array. |
| 2760 __ LoadP(spread_len, FieldMemOperand(spread, JSArray::kLengthOffset)); |
| 2761 __ SmiUntag(spread_len); |
| 2762 __ LoadP(spread, FieldMemOperand(spread, JSArray::kElementsOffset)); |
| 2763 __ b(&push_args); |
| 2764 |
| 2765 __ bind(&runtime_call); |
| 2766 { |
| 2767 // Call the builtin for the result of the spread. |
| 2768 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 2769 __ SmiTag(argc); |
| 2770 __ Push(constructor, new_target, argc, spread); |
| 2771 __ CallRuntime(Runtime::kSpreadIterableFixed); |
| 2772 __ mr(spread, r3); |
| 2773 __ Pop(constructor, new_target, argc); |
| 2774 __ SmiUntag(argc); |
| 2775 } |
| 2776 |
| 2777 { |
| 2778 // Calculate the new nargs including the result of the spread. |
| 2779 __ LoadP(spread_len, FieldMemOperand(spread, FixedArray::kLengthOffset)); |
| 2780 __ SmiUntag(spread_len); |
| 2781 |
| 2782 __ bind(&push_args); |
| 2783 // argc += spread_len - 1. Subtract 1 for the spread itself. |
| 2784 __ add(argc, argc, spread_len); |
| 2785 __ subi(argc, argc, Operand(1)); |
| 2786 |
| 2787 // Pop the spread argument off the stack. |
| 2788 __ Pop(scratch); |
| 2789 } |
| 2790 |
| 2791 // Check for stack overflow. |
| 2792 { |
| 2793 // Check the stack for overflow. We are not trying to catch interruptions |
| 2794 // (i.e. debug break and preemption) here, so check the "real stack limit". |
| 2795 Label done; |
| 2796 __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex); |
| 2797 // Make scratch the space we have left. The stack might already be |
| 2798 // overflowed here which will cause scratch to become negative. |
| 2799 __ sub(scratch, sp, scratch); |
| 2800 // Check if the arguments will overflow the stack. |
| 2801 __ ShiftLeftImm(r0, spread_len, Operand(kPointerSizeLog2)); |
| 2802 __ cmp(scratch, r0); |
| 2803 __ bgt(&done); // Signed comparison. |
| 2804 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
| 2805 __ bind(&done); |
| 2806 } |
| 2807 |
| 2808 // Put the evaluated spread onto the stack as additional arguments. |
| 2809 { |
| 2810 __ li(scratch, Operand::Zero()); |
| 2811 Label done, loop; |
| 2812 __ bind(&loop); |
| 2813 __ cmp(scratch, spread_len); |
| 2814 __ beq(&done); |
| 2815 __ ShiftLeftImm(r0, scratch, Operand(kPointerSizeLog2)); |
| 2816 __ add(scratch2, spread, r0); |
| 2817 __ LoadP(scratch2, FieldMemOperand(scratch2, FixedArray::kHeaderSize)); |
| 2818 __ Push(scratch2); |
| 2819 __ addi(scratch, scratch, Operand(1)); |
| 2820 __ b(&loop); |
| 2821 __ bind(&done); |
| 2822 } |
| 2823 } |
| 2824 |
| 2825 // static |
| 2826 void Builtins::Generate_CallWithSpread(MacroAssembler* masm) { |
| 2827 // ----------- S t a t e ------------- |
| 2828 // -- r3 : the number of arguments (not including the receiver) |
| 2829 // -- r4 : the constructor to call (can be any Object) |
| 2830 // ----------------------------------- |
| 2831 |
| 2832 // CheckSpreadAndPushToStack will push r6 to save it. |
| 2833 __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); |
| 2834 CheckSpreadAndPushToStack(masm); |
| 2835 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
| 2836 TailCallMode::kDisallow), |
| 2837 RelocInfo::CODE_TARGET); |
| 2838 } |
| 2839 |
| 2691 // static | 2840 // static |
| 2692 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2841 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
| 2693 // ----------- S t a t e ------------- | 2842 // ----------- S t a t e ------------- |
| 2694 // -- r3 : the number of arguments (not including the receiver) | 2843 // -- r3 : the number of arguments (not including the receiver) |
| 2695 // -- r4 : the constructor to call (checked to be a JSFunction) | 2844 // -- r4 : the constructor to call (checked to be a JSFunction) |
| 2696 // -- r6 : the new target (checked to be a constructor) | 2845 // -- r6 : the new target (checked to be a constructor) |
| 2697 // ----------------------------------- | 2846 // ----------------------------------- |
| 2698 __ AssertFunction(r4); | 2847 __ AssertFunction(r4); |
| 2699 | 2848 |
| 2700 // Calling convention for function specific ConstructStubs require | 2849 // Calling convention for function specific ConstructStubs require |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2809 } | 2958 } |
| 2810 | 2959 |
| 2811 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) { | 2960 void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) { |
| 2812 // ----------- S t a t e ------------- | 2961 // ----------- S t a t e ------------- |
| 2813 // -- r3 : the number of arguments (not including the receiver) | 2962 // -- r3 : the number of arguments (not including the receiver) |
| 2814 // -- r4 : the constructor to call (can be any Object) | 2963 // -- r4 : the constructor to call (can be any Object) |
| 2815 // -- r6 : the new target (either the same as the constructor or | 2964 // -- r6 : the new target (either the same as the constructor or |
| 2816 // the JSFunction on which new was invoked initially) | 2965 // the JSFunction on which new was invoked initially) |
| 2817 // ----------------------------------- | 2966 // ----------------------------------- |
| 2818 | 2967 |
| 2819 Register argc = r3; | 2968 CheckSpreadAndPushToStack(masm); |
| 2820 Register constructor = r4; | |
| 2821 Register new_target = r6; | |
| 2822 | |
| 2823 Register scratch = r5; | |
| 2824 Register scratch2 = r9; | |
| 2825 | |
| 2826 Register spread = r7; | |
| 2827 Register spread_map = r8; | |
| 2828 __ LoadP(spread, MemOperand(sp, 0)); | |
| 2829 __ LoadP(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset)); | |
| 2830 | |
| 2831 Label runtime_call, push_args; | |
| 2832 // Check that the spread is an array. | |
| 2833 __ CompareInstanceType(spread_map, scratch, JS_ARRAY_TYPE); | |
| 2834 __ bne(&runtime_call); | |
| 2835 | |
| 2836 // Check that we have the original ArrayPrototype. | |
| 2837 __ LoadP(scratch, FieldMemOperand(spread_map, Map::kPrototypeOffset)); | |
| 2838 __ LoadP(scratch2, NativeContextMemOperand()); | |
| 2839 __ LoadP(scratch2, | |
| 2840 ContextMemOperand(scratch2, Context::INITIAL_ARRAY_PROTOTYPE_INDEX)); | |
| 2841 __ cmp(scratch, scratch2); | |
| 2842 __ bne(&runtime_call); | |
| 2843 | |
| 2844 // Check that the ArrayPrototype hasn't been modified in a way that would | |
| 2845 // affect iteration. | |
| 2846 __ LoadRoot(scratch, Heap::kArrayIteratorProtectorRootIndex); | |
| 2847 __ LoadP(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); | |
| 2848 __ CmpSmiLiteral(scratch, Smi::FromInt(Isolate::kProtectorValid), r0); | |
| 2849 __ bne(&runtime_call); | |
| 2850 | |
| 2851 // Check that the map of the initial array iterator hasn't changed. | |
| 2852 __ LoadP(scratch2, NativeContextMemOperand()); | |
| 2853 __ LoadP(scratch, | |
| 2854 ContextMemOperand(scratch2, | |
| 2855 Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX)); | |
| 2856 __ LoadP(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset)); | |
| 2857 __ LoadP(scratch2, | |
| 2858 ContextMemOperand( | |
| 2859 scratch2, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_MAP_INDEX)); | |
| 2860 __ cmp(scratch, scratch2); | |
| 2861 __ bne(&runtime_call); | |
| 2862 | |
| 2863 // For FastPacked kinds, iteration will have the same effect as simply | |
| 2864 // accessing each property in order. | |
| 2865 Label no_protector_check; | |
| 2866 __ LoadP(scratch, FieldMemOperand(spread_map, Map::kBitField2Offset)); | |
| 2867 __ DecodeField<Map::ElementsKindBits>(scratch); | |
| 2868 __ cmpi(scratch, Operand(FAST_HOLEY_ELEMENTS)); | |
| 2869 __ bgt(&runtime_call); | |
| 2870 // For non-FastHoley kinds, we can skip the protector check. | |
| 2871 __ cmpi(scratch, Operand(FAST_SMI_ELEMENTS)); | |
| 2872 __ beq(&no_protector_check); | |
| 2873 __ cmpi(scratch, Operand(FAST_ELEMENTS)); | |
| 2874 __ beq(&no_protector_check); | |
| 2875 // Check the ArrayProtector cell. | |
| 2876 __ LoadRoot(scratch, Heap::kArrayProtectorRootIndex); | |
| 2877 __ LoadP(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); | |
| 2878 __ CmpSmiLiteral(scratch, Smi::FromInt(Isolate::kProtectorValid), r0); | |
| 2879 __ bne(&runtime_call); | |
| 2880 | |
| 2881 __ bind(&no_protector_check); | |
| 2882 // Load the FixedArray backing store. | |
| 2883 __ LoadP(spread, FieldMemOperand(spread, JSArray::kElementsOffset)); | |
| 2884 __ b(&push_args); | |
| 2885 | |
| 2886 __ bind(&runtime_call); | |
| 2887 { | |
| 2888 // Call the builtin for the result of the spread. | |
| 2889 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
| 2890 __ SmiTag(argc); | |
| 2891 __ Push(constructor, new_target, argc, spread); | |
| 2892 __ CallRuntime(Runtime::kSpreadIterableFixed); | |
| 2893 __ mr(spread, r3); | |
| 2894 __ Pop(constructor, new_target, argc); | |
| 2895 __ SmiUntag(argc); | |
| 2896 } | |
| 2897 | |
| 2898 Register spread_len = r8; | |
| 2899 __ bind(&push_args); | |
| 2900 { | |
| 2901 // Pop the spread argument off the stack. | |
| 2902 __ Pop(scratch); | |
| 2903 // Calculate the new nargs including the result of the spread. | |
| 2904 __ LoadP(spread_len, FieldMemOperand(spread, FixedArray::kLengthOffset)); | |
| 2905 __ SmiUntag(spread_len); | |
| 2906 // argc += spread_len - 1. Subtract 1 for the spread itself. | |
| 2907 __ add(argc, argc, spread_len); | |
| 2908 __ subi(argc, argc, Operand(1)); | |
| 2909 } | |
| 2910 | |
| 2911 // Check for stack overflow. | |
| 2912 { | |
| 2913 // Check the stack for overflow. We are not trying to catch interruptions | |
| 2914 // (i.e. debug break and preemption) here, so check the "real stack limit". | |
| 2915 Label done; | |
| 2916 __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex); | |
| 2917 // Make scratch the space we have left. The stack might already be | |
| 2918 // overflowed here which will cause scratch to become negative. | |
| 2919 __ sub(scratch, sp, scratch); | |
| 2920 // Check if the arguments will overflow the stack. | |
| 2921 __ ShiftLeftImm(r0, spread_len, Operand(kPointerSizeLog2)); | |
| 2922 __ cmp(scratch, r0); | |
| 2923 __ bgt(&done); // Signed comparison. | |
| 2924 __ TailCallRuntime(Runtime::kThrowStackOverflow); | |
| 2925 __ bind(&done); | |
| 2926 } | |
| 2927 | |
| 2928 // Put the evaluated spread onto the stack as additional arguments. | |
| 2929 { | |
| 2930 __ li(scratch, Operand::Zero()); | |
| 2931 Label done, loop; | |
| 2932 __ bind(&loop); | |
| 2933 __ cmp(scratch, spread_len); | |
| 2934 __ beq(&done); | |
| 2935 __ ShiftLeftImm(r0, scratch, Operand(kPointerSizeLog2)); | |
| 2936 __ add(scratch2, spread, r0); | |
| 2937 __ LoadP(scratch2, FieldMemOperand(scratch2, FixedArray::kHeaderSize)); | |
| 2938 __ Push(scratch2); | |
| 2939 __ addi(scratch, scratch, Operand(1)); | |
| 2940 __ b(&loop); | |
| 2941 __ bind(&done); | |
| 2942 } | |
| 2943 | |
| 2944 // Dispatch. | |
| 2945 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2969 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
| 2946 } | 2970 } |
| 2947 | 2971 |
| 2948 // static | 2972 // static |
| 2949 void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) { | 2973 void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) { |
| 2950 // ----------- S t a t e ------------- | 2974 // ----------- S t a t e ------------- |
| 2951 // -- r4 : requested object size (untagged) | 2975 // -- r4 : requested object size (untagged) |
| 2952 // -- lr : return address | 2976 // -- lr : return address |
| 2953 // ----------------------------------- | 2977 // ----------------------------------- |
| 2954 __ SmiTag(r4); | 2978 __ SmiTag(r4); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3111 __ CallRuntime(Runtime::kThrowStackOverflow); | 3135 __ CallRuntime(Runtime::kThrowStackOverflow); |
| 3112 __ bkpt(0); | 3136 __ bkpt(0); |
| 3113 } | 3137 } |
| 3114 } | 3138 } |
| 3115 | 3139 |
| 3116 #undef __ | 3140 #undef __ |
| 3117 } // namespace internal | 3141 } // namespace internal |
| 3118 } // namespace v8 | 3142 } // namespace v8 |
| 3119 | 3143 |
| 3120 #endif // V8_TARGET_ARCH_PPC | 3144 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |