OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_ARM | 5 #if V8_TARGET_ARCH_ARM |
6 | 6 |
| 7 #include "src/api-arguments.h" |
7 #include "src/assembler-inl.h" | 8 #include "src/assembler-inl.h" |
8 #include "src/codegen.h" | 9 #include "src/codegen.h" |
9 #include "src/counters.h" | 10 #include "src/counters.h" |
10 #include "src/debug/debug.h" | 11 #include "src/debug/debug.h" |
11 #include "src/deoptimizer.h" | 12 #include "src/deoptimizer.h" |
12 #include "src/full-codegen/full-codegen.h" | 13 #include "src/full-codegen/full-codegen.h" |
13 #include "src/objects-inl.h" | 14 #include "src/objects-inl.h" |
14 #include "src/runtime/runtime.h" | 15 #include "src/runtime/runtime.h" |
15 | 16 |
16 namespace v8 { | 17 namespace v8 { |
(...skipping 2686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2703 | 2704 |
2704 // CheckSpreadAndPushToStack will push r3 to save it. | 2705 // CheckSpreadAndPushToStack will push r3 to save it. |
2705 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); | 2706 __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); |
2706 CheckSpreadAndPushToStack(masm); | 2707 CheckSpreadAndPushToStack(masm); |
2707 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2708 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2708 TailCallMode::kDisallow), | 2709 TailCallMode::kDisallow), |
2709 RelocInfo::CODE_TARGET); | 2710 RelocInfo::CODE_TARGET); |
2710 } | 2711 } |
2711 | 2712 |
2712 // static | 2713 // static |
| 2714 void Builtins::Generate_CallFunctionCallback(MacroAssembler* masm) { |
| 2715 // ----------- S t a t e ------------- |
| 2716 // -- r0 : the number of arguments (not incl. the receiver) |
| 2717 // -- r1 : api function address |
| 2718 // -- sp[0] : holder |
| 2719 // -- sp[4] : isolate |
| 2720 // -- sp[8] : return value default |
| 2721 // -- sp[12] : return value |
| 2722 // -- sp[16] : call data |
| 2723 // -- sp[20] : target |
| 2724 // -- sp[24] : context save |
| 2725 // -- sp[28] : new.target |
| 2726 // -- sp[32] : last argument |
| 2727 // -- sp[28 + argc * 4] : first argument |
| 2728 // -- sp[32 + argc * 4] : receiver |
| 2729 // ----------------------------------- |
| 2730 typedef FunctionCallbackArguments FCA; |
| 2731 |
| 2732 STATIC_ASSERT(FCA::kNewTargetIndex == 7); |
| 2733 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
| 2734 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
| 2735 STATIC_ASSERT(FCA::kDataIndex == 4); |
| 2736 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
| 2737 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
| 2738 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
| 2739 STATIC_ASSERT(FCA::kHolderIndex == 0); |
| 2740 STATIC_ASSERT(FCA::kArgsLength == 8); |
| 2741 |
| 2742 // Compute the pointer to the implicit args on the stack. |
| 2743 __ mov(r2, sp); |
| 2744 |
| 2745 // Allocate the v8::FunctionCallbackInfo structure in the arguments' space |
| 2746 // since it's not controlled by the GC. |
| 2747 const int kApiStackSpace = 3; |
| 2748 FrameScope frame_scope(masm, StackFrame::MANUAL); |
| 2749 __ EnterExitFrame(false, kApiStackSpace); |
| 2750 // r3 = FunctionCallbackInfo& |
| 2751 // Arguments is after the return address. |
| 2752 __ add(r3, sp, Operand(1 * kPointerSize)); |
| 2753 // Initialize FunctionCallbackInfo::implicit_args_. |
| 2754 __ str(r2, MemOperand(r3, 0 * kPointerSize)); |
| 2755 // Initialize FunctionCallbackInfo::values_. |
| 2756 __ add(r2, r2, Operand(r0, LSL, kPointerSizeLog2)); |
| 2757 __ add(r2, r2, Operand((FCA::kArgsLength - 1) * kPointerSize)); |
| 2758 __ str(r2, MemOperand(r3, 1 * kPointerSize)); |
| 2759 // Initialize FunctionCallbackInfo::length_. |
| 2760 __ str(r0, MemOperand(r3, 2 * kPointerSize)); |
| 2761 |
| 2762 // Load first argument with pointer to FunctionCallbackInfo. |
| 2763 __ mov(r0, r3); |
| 2764 |
| 2765 // TODO(bmeurer): Do we need this? |
| 2766 AllowExternalCallThatCantCauseGC scope(masm); |
| 2767 |
| 2768 const int kNextOffset = 0; |
| 2769 const int kLimitOffset = AddressOffset( |
| 2770 ExternalReference::handle_scope_limit_address(masm->isolate()), |
| 2771 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2772 const int kLevelOffset = AddressOffset( |
| 2773 ExternalReference::handle_scope_level_address(masm->isolate()), |
| 2774 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2775 |
| 2776 // Allocate HandleScope in callee-save registers. |
| 2777 __ mov( |
| 2778 r9, |
| 2779 Operand(ExternalReference::handle_scope_next_address(masm->isolate()))); |
| 2780 __ ldr(r4, MemOperand(r9, kNextOffset)); |
| 2781 __ ldr(r5, MemOperand(r9, kLimitOffset)); |
| 2782 __ ldr(r6, MemOperand(r9, kLevelOffset)); |
| 2783 __ add(r6, r6, Operand(1)); |
| 2784 __ str(r6, MemOperand(r9, kLevelOffset)); |
| 2785 |
| 2786 // Check if profiling is active, and if so call the function indirectly |
| 2787 // via the invoke_function_callback helper. |
| 2788 Label call_indirect, done_call; |
| 2789 __ mov(ip, Operand(ExternalReference::is_profiling_address(masm->isolate()))); |
| 2790 __ ldrb(ip, MemOperand(ip, 0)); |
| 2791 __ cmp(ip, Operand(0)); |
| 2792 __ b(ne, &call_indirect); |
| 2793 { |
| 2794 // Call the API function directly. |
| 2795 // TODO(all): Deprecate DirectCEntryStub usage here, since this builtin |
| 2796 // is part of the snapshot and thus isn't relocated by the GC ever. |
| 2797 DirectCEntryStub stub(masm->isolate()); |
| 2798 stub.GenerateCall(masm, r1); |
| 2799 } |
| 2800 __ b(&done_call); |
| 2801 __ bind(&call_indirect); |
| 2802 { |
| 2803 // Call the API function indirectly when profiling is on. |
| 2804 // TODO(all): Deprecate DirectCEntryStub usage here, since this builtin |
| 2805 // is part of the snapshot and thus isn't relocated by the GC ever. |
| 2806 DirectCEntryStub stub(masm->isolate()); |
| 2807 __ mov( |
| 2808 r3, |
| 2809 Operand(ExternalReference::invoke_function_callback(masm->isolate()))); |
| 2810 stub.GenerateCall(masm, r3); |
| 2811 } |
| 2812 __ bind(&done_call); |
| 2813 |
| 2814 // No more valid handles (the result handle was the last one). Restore |
| 2815 // previous handle scope. |
| 2816 Label delete_allocated_handles; |
| 2817 __ str(r4, MemOperand(r9, kNextOffset)); |
| 2818 __ sub(r6, r6, Operand(1)); |
| 2819 __ str(r6, MemOperand(r9, kLevelOffset)); |
| 2820 __ ldr(ip, MemOperand(r9, kLimitOffset)); |
| 2821 __ cmp(r5, ip); |
| 2822 __ b(ne, &delete_allocated_handles); |
| 2823 |
| 2824 // Leave the API exit frame. |
| 2825 Label leave_exit_frame; |
| 2826 __ bind(&leave_exit_frame); |
| 2827 __ ldr(r0, MemOperand(fp, (2 + FCA::kReturnValueOffset) * kPointerSize)); |
| 2828 __ ldr(cp, MemOperand(fp, (2 + FCA::kContextSaveIndex) * kPointerSize)); |
| 2829 __ ldr(r4, MemOperand(sp, 3 * kPointerSize)); |
| 2830 __ LeaveExitFrame(false, no_reg, false); |
| 2831 |
| 2832 // Check if the function scheduled an exception. |
| 2833 Label promote_scheduled_exception; |
| 2834 __ mov( |
| 2835 ip, |
| 2836 Operand(ExternalReference::scheduled_exception_address(masm->isolate()))); |
| 2837 __ ldr(r5, MemOperand(ip)); |
| 2838 __ JumpIfNotRoot(r5, Heap::kTheHoleValueRootIndex, |
| 2839 &promote_scheduled_exception); |
| 2840 |
| 2841 // Check if the function returned a valid JavaScript value. |
| 2842 __ AssertApiCallResult(r0); |
| 2843 |
| 2844 // Drop the arguments and return. |
| 2845 __ add(sp, sp, Operand((FCA::kArgsLength + 1) * kPointerSize)); |
| 2846 __ add(sp, sp, Operand(r4, LSL, kPointerSizeLog2)); |
| 2847 __ Ret(); |
| 2848 |
| 2849 // Re-throw by promoting a scheduled exception. |
| 2850 __ bind(&promote_scheduled_exception); |
| 2851 __ TailCallRuntime(Runtime::kPromoteScheduledException); |
| 2852 |
| 2853 // HandleScope limit has changed. Delete allocated extensions. |
| 2854 __ bind(&delete_allocated_handles); |
| 2855 { |
| 2856 __ str(r5, MemOperand(r9, kLimitOffset)); |
| 2857 __ PrepareCallCFunction(1, r5); |
| 2858 __ mov(r0, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 2859 __ CallCFunction( |
| 2860 ExternalReference::delete_handle_scope_extensions(masm->isolate()), 1); |
| 2861 } |
| 2862 __ b(&leave_exit_frame); |
| 2863 } |
| 2864 |
| 2865 // static |
2713 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2866 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
2714 // ----------- S t a t e ------------- | 2867 // ----------- S t a t e ------------- |
2715 // -- r0 : the number of arguments (not including the receiver) | 2868 // -- r0 : the number of arguments (not including the receiver) |
2716 // -- r1 : the constructor to call (checked to be a JSFunction) | 2869 // -- r1 : the constructor to call (checked to be a JSFunction) |
2717 // -- r3 : the new target (checked to be a constructor) | 2870 // -- r3 : the new target (checked to be a constructor) |
2718 // ----------------------------------- | 2871 // ----------------------------------- |
2719 __ AssertFunction(r1); | 2872 __ AssertFunction(r1); |
2720 | 2873 |
2721 // Calling convention for function specific ConstructStubs require | 2874 // Calling convention for function specific ConstructStubs require |
2722 // r2 to contain either an AllocationSite or undefined. | 2875 // r2 to contain either an AllocationSite or undefined. |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3022 } | 3175 } |
3023 // Now jump to the instructions of the returned code object. | 3176 // Now jump to the instructions of the returned code object. |
3024 __ Jump(r8); | 3177 __ Jump(r8); |
3025 } | 3178 } |
3026 #undef __ | 3179 #undef __ |
3027 | 3180 |
3028 } // namespace internal | 3181 } // namespace internal |
3029 } // namespace v8 | 3182 } // namespace v8 |
3030 | 3183 |
3031 #endif // V8_TARGET_ARCH_ARM | 3184 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |