OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
| 7 #include "src/api-arguments.h" |
7 #include "src/arm64/frames-arm64.h" | 8 #include "src/arm64/frames-arm64.h" |
8 #include "src/arm64/macro-assembler-arm64-inl.h" | 9 #include "src/arm64/macro-assembler-arm64-inl.h" |
9 #include "src/codegen.h" | 10 #include "src/codegen.h" |
10 #include "src/counters.h" | 11 #include "src/counters.h" |
11 #include "src/debug/debug.h" | 12 #include "src/debug/debug.h" |
12 #include "src/deoptimizer.h" | 13 #include "src/deoptimizer.h" |
13 #include "src/full-codegen/full-codegen.h" | 14 #include "src/full-codegen/full-codegen.h" |
14 #include "src/objects-inl.h" | 15 #include "src/objects-inl.h" |
15 #include "src/runtime/runtime.h" | 16 #include "src/runtime/runtime.h" |
16 | 17 |
(...skipping 2766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2783 __ LoadRoot(scratch2, Heap::kUndefinedValueRootIndex); | 2784 __ LoadRoot(scratch2, Heap::kUndefinedValueRootIndex); |
2784 __ bind(&push); | 2785 __ bind(&push); |
2785 __ Push(scratch2); | 2786 __ Push(scratch2); |
2786 __ Add(scratch, scratch, Operand(1)); | 2787 __ Add(scratch, scratch, Operand(1)); |
2787 __ B(&loop); | 2788 __ B(&loop); |
2788 __ Bind(&done); | 2789 __ Bind(&done); |
2789 } | 2790 } |
2790 } | 2791 } |
2791 | 2792 |
2792 // static | 2793 // static |
| 2794 void Builtins::Generate_CallFunctionCallback(MacroAssembler* masm) { |
| 2795 ASM_LOCATION("Builtins::Generate_CallFunctionCallback"); |
| 2796 // ----------- S t a t e ------------- |
| 2797 // -- x0 : the number of arguments (not incl. the receiver) |
| 2798 // -- x1 : api function address |
| 2799 // -- sp[0] : holder |
| 2800 // -- sp[8] : isolate |
| 2801 // -- sp[16] : return value default |
| 2802 // -- sp[24] : return value |
| 2803 // -- sp[32] : call data |
| 2804 // -- sp[40] : target |
| 2805 // -- sp[48] : context save |
| 2806 // -- sp[56] : new.target |
| 2807 // -- sp[64] : last argument |
| 2808 // -- sp[56 + argc * 4] : first argument |
| 2809 // -- sp[64 + argc * 4] : receiver |
| 2810 // ----------------------------------- |
| 2811 typedef FunctionCallbackArguments FCA; |
| 2812 |
| 2813 STATIC_ASSERT(FCA::kNewTargetIndex == 7); |
| 2814 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
| 2815 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
| 2816 STATIC_ASSERT(FCA::kDataIndex == 4); |
| 2817 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
| 2818 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
| 2819 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
| 2820 STATIC_ASSERT(FCA::kHolderIndex == 0); |
| 2821 STATIC_ASSERT(FCA::kArgsLength == 8); |
| 2822 |
| 2823 // Compute the pointer to the implicit args on the stack. |
| 2824 __ Mov(x6, masm->StackPointer()); |
| 2825 |
| 2826 // Allocate space for CallApiFunctionAndReturn can store some scratch |
| 2827 // registeres on the stack. |
| 2828 const int kCallApiFunctionSpillSpace = 4; |
| 2829 |
| 2830 // Allocate the v8::FunctionCallbackInfo structure in the arguments' space |
| 2831 // since it's not controlled by the GC. |
| 2832 const int kApiStackSpace = 3; |
| 2833 FrameScope frame_scope(masm, StackFrame::MANUAL); |
| 2834 __ EnterExitFrame(false, x10, kApiStackSpace + kCallApiFunctionSpillSpace); |
| 2835 // x3 = FunctionCallbackInfo& |
| 2836 // Arguments is after the return address. |
| 2837 __ Add(x3, masm->StackPointer(), 1 * kPointerSize); |
| 2838 // Initialize FunctionCallbackInfo::implicit_args_ and |
| 2839 // FunctionCallbackInfo::values_. |
| 2840 __ Add(x10, x6, Operand(x0, LSL, kPointerSizeLog2)); |
| 2841 __ Add(x10, x10, Operand((FCA::kArgsLength - 1) * kPointerSize)); |
| 2842 __ Stp(x6, x10, MemOperand(x3, 0 * kPointerSize)); |
| 2843 // FunctionCallbackInfo::length_ = argc |
| 2844 __ Str(x0, MemOperand(x3, 2 * kPointerSize)); |
| 2845 |
| 2846 // Load first argument with pointer to FunctionCallbackInfo. |
| 2847 __ Mov(x0, x3); |
| 2848 |
| 2849 // TODO(bmeurer): Do we need this? |
| 2850 AllowExternalCallThatCantCauseGC scope(masm); |
| 2851 |
| 2852 const int kNextOffset = 0; |
| 2853 const int kLimitOffset = AddressOffset( |
| 2854 ExternalReference::handle_scope_limit_address(masm->isolate()), |
| 2855 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2856 const int kLevelOffset = AddressOffset( |
| 2857 ExternalReference::handle_scope_level_address(masm->isolate()), |
| 2858 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2859 |
| 2860 // Allocate HandleScope in callee-save registers. |
| 2861 // We will need to restore the HandleScope after the call to the API function, |
| 2862 // by allocating it in callee-save registers they will be preserved by C code. |
| 2863 Register handle_scope_base = x22; |
| 2864 Register next_address_reg = x19; |
| 2865 Register limit_reg = x20; |
| 2866 Register level_reg = w21; |
| 2867 __ Mov(handle_scope_base, |
| 2868 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2869 __ Ldr(next_address_reg, MemOperand(handle_scope_base, kNextOffset)); |
| 2870 __ Ldr(limit_reg, MemOperand(handle_scope_base, kLimitOffset)); |
| 2871 __ Ldr(level_reg, MemOperand(handle_scope_base, kLevelOffset)); |
| 2872 __ Add(level_reg, level_reg, 1); |
| 2873 __ Str(level_reg, MemOperand(handle_scope_base, kLevelOffset)); |
| 2874 |
| 2875 // Check if profiling is active, and if so call the function indirectly |
| 2876 // via the invoke_function_callback helper. |
| 2877 Label call_indirect, done_call; |
| 2878 __ Mov(x10, ExternalReference::is_profiling_address(masm->isolate())); |
| 2879 __ Ldrb(w10, MemOperand(x10)); |
| 2880 __ Cbnz(w10, &call_indirect); |
| 2881 { |
| 2882 // Call the API function directly. |
| 2883 // TODO(all): Deprecate DirectCEntryStub usage here, since this builtin |
| 2884 // is part of the snapshot and thus isn't relocated by the GC ever. |
| 2885 DirectCEntryStub stub(masm->isolate()); |
| 2886 stub.GenerateCall(masm, x1); |
| 2887 } |
| 2888 __ B(&done_call); |
| 2889 __ Bind(&call_indirect); |
| 2890 { |
| 2891 // Call the API function indirectly when profiling is on. |
| 2892 // TODO(all): Deprecate DirectCEntryStub usage here, since this builtin |
| 2893 // is part of the snapshot and thus isn't relocated by the GC ever. |
| 2894 DirectCEntryStub stub(masm->isolate()); |
| 2895 __ Mov(x3, ExternalReference::invoke_function_callback(masm->isolate())); |
| 2896 stub.GenerateCall(masm, x3); |
| 2897 } |
| 2898 __ Bind(&done_call); |
| 2899 |
| 2900 // No more valid handles (the result handle was the last one). Restore |
| 2901 // previous handle scope. |
| 2902 Label delete_allocated_handles; |
| 2903 __ Str(next_address_reg, MemOperand(handle_scope_base, kNextOffset)); |
| 2904 __ Sub(level_reg, level_reg, 1); |
| 2905 __ Str(level_reg, MemOperand(handle_scope_base, kLevelOffset)); |
| 2906 __ Ldr(x1, MemOperand(handle_scope_base, kLimitOffset)); |
| 2907 __ Cmp(limit_reg, x1); |
| 2908 __ B(ne, &delete_allocated_handles); |
| 2909 |
| 2910 // Leave the API exit frame. |
| 2911 Label leave_exit_frame; |
| 2912 __ Bind(&leave_exit_frame); |
| 2913 __ Ldr(x0, MemOperand(fp, (2 + FCA::kReturnValueOffset) * kPointerSize)); |
| 2914 __ Ldr(cp, MemOperand(fp, (2 + FCA::kContextSaveIndex) * kPointerSize)); |
| 2915 __ Ldr(w2, MemOperand(masm->StackPointer(), 3 * kPointerSize)); |
| 2916 __ LeaveExitFrame(false, x1, false); |
| 2917 |
| 2918 // Check if the function scheduled an exception. |
| 2919 Label promote_scheduled_exception; |
| 2920 __ Mov(x5, ExternalReference::scheduled_exception_address(masm->isolate())); |
| 2921 __ Ldr(x5, MemOperand(x5)); |
| 2922 __ JumpIfNotRoot(x5, Heap::kTheHoleValueRootIndex, |
| 2923 &promote_scheduled_exception); |
| 2924 |
| 2925 // Check if the function returned a valid JavaScript value. |
| 2926 __ AssertApiCallResult(x0); |
| 2927 |
| 2928 // Drop the arguments and return. |
| 2929 __ Drop(x2); |
| 2930 __ Drop((FCA::kArgsLength + 1)); |
| 2931 __ Ret(); |
| 2932 |
| 2933 // Re-throw by promoting a scheduled exception. |
| 2934 __ Bind(&promote_scheduled_exception); |
| 2935 __ TailCallRuntime(Runtime::kPromoteScheduledException); |
| 2936 |
| 2937 // HandleScope limit has changed. Delete allocated extensions. |
| 2938 __ Bind(&delete_allocated_handles); |
| 2939 { |
| 2940 __ Str(limit_reg, MemOperand(handle_scope_base, kLimitOffset)); |
| 2941 // Save the return value in a callee-save register. |
| 2942 __ Mov(x0, ExternalReference::isolate_address(masm->isolate())); |
| 2943 __ CallCFunction( |
| 2944 ExternalReference::delete_handle_scope_extensions(masm->isolate()), 1); |
| 2945 } |
| 2946 __ B(&leave_exit_frame); |
| 2947 } |
| 2948 |
| 2949 // static |
2793 void Builtins::Generate_CallWithSpread(MacroAssembler* masm) { | 2950 void Builtins::Generate_CallWithSpread(MacroAssembler* masm) { |
2794 // ----------- S t a t e ------------- | 2951 // ----------- S t a t e ------------- |
2795 // -- x0 : the number of arguments (not including the receiver) | 2952 // -- x0 : the number of arguments (not including the receiver) |
2796 // -- x1 : the constructor to call (can be any Object) | 2953 // -- x1 : the constructor to call (can be any Object) |
2797 // ----------------------------------- | 2954 // ----------------------------------- |
2798 | 2955 |
2799 // CheckSpreadAndPushToStack will push r3 to save it. | 2956 // CheckSpreadAndPushToStack will push r3 to save it. |
2800 __ LoadRoot(x3, Heap::kUndefinedValueRootIndex); | 2957 __ LoadRoot(x3, Heap::kUndefinedValueRootIndex); |
2801 CheckSpreadAndPushToStack(masm); | 2958 CheckSpreadAndPushToStack(masm); |
2802 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2959 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3157 // Now jump to the instructions of the returned code object. | 3314 // Now jump to the instructions of the returned code object. |
3158 __ Jump(x8); | 3315 __ Jump(x8); |
3159 } | 3316 } |
3160 | 3317 |
3161 #undef __ | 3318 #undef __ |
3162 | 3319 |
3163 } // namespace internal | 3320 } // namespace internal |
3164 } // namespace v8 | 3321 } // namespace v8 |
3165 | 3322 |
3166 #endif // V8_TARGET_ARCH_ARM | 3323 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |