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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
6 | 6 |
| 7 #include "src/api-arguments.h" |
7 #include "src/codegen.h" | 8 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 11 #include "src/full-codegen/full-codegen.h" |
11 #include "src/runtime/runtime.h" | 12 #include "src/runtime/runtime.h" |
12 | 13 |
13 namespace v8 { | 14 namespace v8 { |
14 namespace internal { | 15 namespace internal { |
15 | 16 |
16 #define __ ACCESS_MASM(masm) | 17 #define __ ACCESS_MASM(masm) |
(...skipping 2702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2719 // ----------------------------------- | 2720 // ----------------------------------- |
2720 | 2721 |
2721 // CheckSpreadAndPushToStack will push a3 to save it. | 2722 // CheckSpreadAndPushToStack will push a3 to save it. |
2722 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex); | 2723 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex); |
2723 CheckSpreadAndPushToStack(masm); | 2724 CheckSpreadAndPushToStack(masm); |
2724 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2725 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2725 TailCallMode::kDisallow), | 2726 TailCallMode::kDisallow), |
2726 RelocInfo::CODE_TARGET); | 2727 RelocInfo::CODE_TARGET); |
2727 } | 2728 } |
2728 | 2729 |
| 2730 // static |
| 2731 void Builtins::Generate_CallFunctionCallback(MacroAssembler* masm) { |
| 2732 // ----------- S t a t e ------------- |
| 2733 // -- a0 : the number of arguments (not incl. the receiver) |
| 2734 // -- a1 : api function address |
| 2735 // -- sp[0] : holder |
| 2736 // -- sp[8] : isolate |
| 2737 // -- sp[16] : return value default |
| 2738 // -- sp[24] : return value |
| 2739 // -- sp[32] : call data |
| 2740 // -- sp[40] : target |
| 2741 // -- sp[48] : context save |
| 2742 // -- sp[56] : new.target |
| 2743 // -- sp[64] : last argument |
| 2744 // -- sp[56 + argc * 4] : first argument |
| 2745 // -- sp[64 + argc * 4] : receiver |
| 2746 // ----------------------------------- |
| 2747 typedef FunctionCallbackArguments FCA; |
| 2748 |
| 2749 STATIC_ASSERT(FCA::kNewTargetIndex == 7); |
| 2750 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
| 2751 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
| 2752 STATIC_ASSERT(FCA::kDataIndex == 4); |
| 2753 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
| 2754 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
| 2755 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
| 2756 STATIC_ASSERT(FCA::kHolderIndex == 0); |
| 2757 STATIC_ASSERT(FCA::kArgsLength == 8); |
| 2758 |
| 2759 // Compute the pointer to the implicit args on the stack. |
| 2760 __ mov(a2, sp); |
| 2761 |
| 2762 // Allocate the v8::FunctionCallbackInfo structure in the arguments' space |
| 2763 // since it's not controlled by the GC. |
| 2764 const int kApiStackSpace = 3; |
| 2765 FrameScope frame_scope(masm, StackFrame::MANUAL); |
| 2766 __ EnterExitFrame(false, kApiStackSpace); |
| 2767 // a3 = FunctionCallbackInfo& |
| 2768 // Arguments is after the return address. |
| 2769 __ Daddu(a3, sp, Operand(1 * kPointerSize)); |
| 2770 // Initialize FunctionCallbackInfo::implicit_args_. |
| 2771 __ Sd(a2, MemOperand(a3, 0 * kPointerSize)); |
| 2772 // Initialize FunctionCallbackInfo::values_. |
| 2773 __ Dlsa(at, a2, a0, kPointerSizeLog2); |
| 2774 __ Daddu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize)); |
| 2775 __ Sd(at, MemOperand(a3, 1 * kPointerSize)); |
| 2776 // Initialize FunctionCallbackInfo::length_. |
| 2777 __ Sw(a0, MemOperand(a3, 2 * kPointerSize)); |
| 2778 |
| 2779 // Load first argument with pointer to FunctionCallbackInfo. |
| 2780 __ mov(a0, a3); |
| 2781 |
| 2782 // TODO(bmeurer): Do we need this? |
| 2783 AllowExternalCallThatCantCauseGC scope(masm); |
| 2784 |
| 2785 const int kNextOffset = 0; |
| 2786 const int kLimitOffset = AddressOffset( |
| 2787 ExternalReference::handle_scope_limit_address(masm->isolate()), |
| 2788 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2789 const int kLevelOffset = AddressOffset( |
| 2790 ExternalReference::handle_scope_level_address(masm->isolate()), |
| 2791 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2792 |
| 2793 // Allocate HandleScope in callee-save registers. |
| 2794 __ li(s3, |
| 2795 Operand(ExternalReference::handle_scope_next_address(masm->isolate()))); |
| 2796 __ Ld(s0, MemOperand(s3, kNextOffset)); |
| 2797 __ Ld(s1, MemOperand(s3, kLimitOffset)); |
| 2798 __ Lw(s2, MemOperand(s3, kLevelOffset)); |
| 2799 __ Addu(s2, s2, Operand(1)); |
| 2800 __ Sw(s2, MemOperand(s3, kLevelOffset)); |
| 2801 |
| 2802 // Check if profiling is active, and if so call the function indirectly |
| 2803 // via the invoke_function_callback helper. |
| 2804 Label call_indirect, done_call; |
| 2805 __ li(t9, Operand(ExternalReference::is_profiling_address(masm->isolate()))); |
| 2806 __ lb(t9, MemOperand(t9, 0)); |
| 2807 __ Branch(&call_indirect, ne, t9, Operand(zero_reg)); |
| 2808 { |
| 2809 // Call the API function directly. |
| 2810 // TODO(all): Deprecate DirectCEntryStub usage here, since this builtin |
| 2811 // is part of the snapshot and thus isn't relocated by the GC ever. |
| 2812 DirectCEntryStub stub(masm->isolate()); |
| 2813 stub.GenerateCall(masm, a1); |
| 2814 } |
| 2815 __ b(&done_call); |
| 2816 __ bind(&call_indirect); |
| 2817 { |
| 2818 // Call the API function indirectly when profiling is on. |
| 2819 // TODO(all): Deprecate DirectCEntryStub usage here, since this builtin |
| 2820 // is part of the snapshot and thus isn't relocated by the GC ever. |
| 2821 DirectCEntryStub stub(masm->isolate()); |
| 2822 __ li( |
| 2823 a3, |
| 2824 Operand(ExternalReference::invoke_function_callback(masm->isolate()))); |
| 2825 stub.GenerateCall(masm, a3); |
| 2826 } |
| 2827 __ bind(&done_call); |
| 2828 |
| 2829 // No more valid handles (the result handle was the last one). Restore |
| 2830 // previous handle scope. |
| 2831 Label delete_allocated_handles; |
| 2832 __ Sd(s0, MemOperand(s3, kNextOffset)); |
| 2833 __ Subu(s2, s2, Operand(1)); |
| 2834 __ Sw(s2, MemOperand(s3, kLevelOffset)); |
| 2835 __ Ld(t1, MemOperand(s3, kLimitOffset)); |
| 2836 __ Branch(&delete_allocated_handles, ne, s1, Operand(t1)); |
| 2837 |
| 2838 // Leave the API exit frame. |
| 2839 Label leave_exit_frame; |
| 2840 __ bind(&leave_exit_frame); |
| 2841 __ Ld(v0, MemOperand(fp, (2 + FCA::kReturnValueOffset) * kPointerSize)); |
| 2842 __ Ld(cp, MemOperand(fp, (2 + FCA::kContextSaveIndex) * kPointerSize)); |
| 2843 __ Lw(s0, MemOperand(sp, 3 * kPointerSize)); |
| 2844 __ LeaveExitFrame(false, no_reg, false); |
| 2845 |
| 2846 // Check if the function scheduled an exception. |
| 2847 Label promote_scheduled_exception; |
| 2848 __ li( |
| 2849 t1, |
| 2850 Operand(ExternalReference::scheduled_exception_address(masm->isolate()))); |
| 2851 __ Ld(t1, MemOperand(t1)); |
| 2852 __ JumpIfNotRoot(t1, Heap::kTheHoleValueRootIndex, |
| 2853 &promote_scheduled_exception); |
| 2854 |
| 2855 // Check if the function returned a valid JavaScript value. |
| 2856 __ AssertApiCallResult(v0); |
| 2857 |
| 2858 // Drop the arguments and return. |
| 2859 __ Daddu(sp, sp, Operand((FCA::kArgsLength + 1) * kPointerSize)); |
| 2860 __ Dlsa(sp, sp, s0, kPointerSizeLog2); |
| 2861 __ Ret(); |
| 2862 |
| 2863 // Re-throw by promoting a scheduled exception. |
| 2864 __ bind(&promote_scheduled_exception); |
| 2865 __ TailCallRuntime(Runtime::kPromoteScheduledException); |
| 2866 |
| 2867 // HandleScope limit has changed. Delete allocated extensions. |
| 2868 __ bind(&delete_allocated_handles); |
| 2869 { |
| 2870 __ Sd(s1, MemOperand(s3, kLimitOffset)); |
| 2871 __ PrepareCallCFunction(1, s1); |
| 2872 __ li(a0, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 2873 __ CallCFunction( |
| 2874 ExternalReference::delete_handle_scope_extensions(masm->isolate()), 1); |
| 2875 } |
| 2876 __ b(&leave_exit_frame); |
| 2877 } |
| 2878 |
2729 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2879 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
2730 // ----------- S t a t e ------------- | 2880 // ----------- S t a t e ------------- |
2731 // -- a0 : the number of arguments (not including the receiver) | 2881 // -- a0 : the number of arguments (not including the receiver) |
2732 // -- a1 : the constructor to call (checked to be a JSFunction) | 2882 // -- a1 : the constructor to call (checked to be a JSFunction) |
2733 // -- a3 : the new target (checked to be a constructor) | 2883 // -- a3 : the new target (checked to be a constructor) |
2734 // ----------------------------------- | 2884 // ----------------------------------- |
2735 __ AssertFunction(a1); | 2885 __ AssertFunction(a1); |
2736 | 2886 |
2737 // Calling convention for function specific ConstructStubs require | 2887 // Calling convention for function specific ConstructStubs require |
2738 // a2 to contain either an AllocationSite or undefined. | 2888 // a2 to contain either an AllocationSite or undefined. |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3110 __ Daddu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 3260 __ Daddu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
3111 __ Jump(at); | 3261 __ Jump(at); |
3112 } | 3262 } |
3113 | 3263 |
3114 #undef __ | 3264 #undef __ |
3115 | 3265 |
3116 } // namespace internal | 3266 } // namespace internal |
3117 } // namespace v8 | 3267 } // namespace v8 |
3118 | 3268 |
3119 #endif // V8_TARGET_ARCH_MIPS64 | 3269 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |