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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
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 2672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2689 | 2690 |
2690 // CheckSpreadAndPushToStack will push a3 to save it. | 2691 // CheckSpreadAndPushToStack will push a3 to save it. |
2691 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex); | 2692 __ LoadRoot(a3, Heap::kUndefinedValueRootIndex); |
2692 CheckSpreadAndPushToStack(masm); | 2693 CheckSpreadAndPushToStack(masm); |
2693 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, | 2694 __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny, |
2694 TailCallMode::kDisallow), | 2695 TailCallMode::kDisallow), |
2695 RelocInfo::CODE_TARGET); | 2696 RelocInfo::CODE_TARGET); |
2696 } | 2697 } |
2697 | 2698 |
2698 // static | 2699 // static |
| 2700 void Builtins::Generate_CallFunctionCallback(MacroAssembler* masm) { |
| 2701 // ----------- S t a t e ------------- |
| 2702 // -- a0 : the number of arguments (not incl. the receiver) |
| 2703 // -- a1 : api function address |
| 2704 // -- sp[0] : holder |
| 2705 // -- sp[4] : isolate |
| 2706 // -- sp[8] : return value default |
| 2707 // -- sp[12] : return value |
| 2708 // -- sp[16] : call data |
| 2709 // -- sp[20] : target |
| 2710 // -- sp[24] : context save |
| 2711 // -- sp[28] : new.target |
| 2712 // -- sp[32] : last argument |
| 2713 // -- sp[28 + argc * 4] : first argument |
| 2714 // -- sp[32 + argc * 4] : receiver |
| 2715 // ----------------------------------- |
| 2716 typedef FunctionCallbackArguments FCA; |
| 2717 |
| 2718 STATIC_ASSERT(FCA::kNewTargetIndex == 7); |
| 2719 STATIC_ASSERT(FCA::kContextSaveIndex == 6); |
| 2720 STATIC_ASSERT(FCA::kCalleeIndex == 5); |
| 2721 STATIC_ASSERT(FCA::kDataIndex == 4); |
| 2722 STATIC_ASSERT(FCA::kReturnValueOffset == 3); |
| 2723 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); |
| 2724 STATIC_ASSERT(FCA::kIsolateIndex == 1); |
| 2725 STATIC_ASSERT(FCA::kHolderIndex == 0); |
| 2726 STATIC_ASSERT(FCA::kArgsLength == 8); |
| 2727 |
| 2728 // Compute the pointer to the implicit args on the stack. |
| 2729 __ mov(a2, sp); |
| 2730 |
| 2731 // Allocate the v8::FunctionCallbackInfo structure in the arguments' space |
| 2732 // since it's not controlled by the GC. |
| 2733 const int kApiStackSpace = 3; |
| 2734 FrameScope frame_scope(masm, StackFrame::MANUAL); |
| 2735 __ EnterExitFrame(false, kApiStackSpace); |
| 2736 // a3 = FunctionCallbackInfo& |
| 2737 // Arguments is after the return address. |
| 2738 __ Addu(a3, sp, Operand(1 * kPointerSize)); |
| 2739 // Initialize FunctionCallbackInfo::implicit_args_. |
| 2740 __ sw(a2, MemOperand(a3, 0 * kPointerSize)); |
| 2741 // Initialize FunctionCallbackInfo::values_. |
| 2742 __ Lsa(at, a2, a0, kPointerSizeLog2); |
| 2743 __ Addu(at, at, Operand((FCA::kArgsLength - 1) * kPointerSize)); |
| 2744 __ sw(at, MemOperand(a3, 1 * kPointerSize)); |
| 2745 // Initialize FunctionCallbackInfo::length_. |
| 2746 __ sw(a0, MemOperand(a3, 2 * kPointerSize)); |
| 2747 |
| 2748 // Load first argument with pointer to FunctionCallbackInfo. |
| 2749 __ mov(a0, a3); |
| 2750 |
| 2751 // TODO(bmeurer): Do we need this? |
| 2752 AllowExternalCallThatCantCauseGC scope(masm); |
| 2753 |
| 2754 const int kNextOffset = 0; |
| 2755 const int kLimitOffset = AddressOffset( |
| 2756 ExternalReference::handle_scope_limit_address(masm->isolate()), |
| 2757 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2758 const int kLevelOffset = AddressOffset( |
| 2759 ExternalReference::handle_scope_level_address(masm->isolate()), |
| 2760 ExternalReference::handle_scope_next_address(masm->isolate())); |
| 2761 |
| 2762 // Allocate HandleScope in callee-save registers. |
| 2763 __ li(s3, |
| 2764 Operand(ExternalReference::handle_scope_next_address(masm->isolate()))); |
| 2765 __ lw(s0, MemOperand(s3, kNextOffset)); |
| 2766 __ lw(s1, MemOperand(s3, kLimitOffset)); |
| 2767 __ lw(s2, MemOperand(s3, kLevelOffset)); |
| 2768 __ Addu(s2, s2, Operand(1)); |
| 2769 __ sw(s2, MemOperand(s3, kLevelOffset)); |
| 2770 |
| 2771 // Check if profiling is active, and if so call the function indirectly |
| 2772 // via the invoke_function_callback helper. |
| 2773 Label call_indirect, done_call; |
| 2774 __ li(t9, Operand(ExternalReference::is_profiling_address(masm->isolate()))); |
| 2775 __ lb(t9, MemOperand(t9, 0)); |
| 2776 __ Branch(&call_indirect, ne, t9, Operand(zero_reg)); |
| 2777 { |
| 2778 // Call the API function directly. |
| 2779 // TODO(all): Deprecate DirectCEntryStub usage here, since this builtin |
| 2780 // is part of the snapshot and thus isn't relocated by the GC ever. |
| 2781 DirectCEntryStub stub(masm->isolate()); |
| 2782 stub.GenerateCall(masm, a1); |
| 2783 } |
| 2784 __ b(&done_call); |
| 2785 __ bind(&call_indirect); |
| 2786 { |
| 2787 // Call the API function indirectly when profiling is on. |
| 2788 // TODO(all): Deprecate DirectCEntryStub usage here, since this builtin |
| 2789 // is part of the snapshot and thus isn't relocated by the GC ever. |
| 2790 DirectCEntryStub stub(masm->isolate()); |
| 2791 __ li( |
| 2792 a3, |
| 2793 Operand(ExternalReference::invoke_function_callback(masm->isolate()))); |
| 2794 stub.GenerateCall(masm, a3); |
| 2795 } |
| 2796 __ bind(&done_call); |
| 2797 |
| 2798 // No more valid handles (the result handle was the last one). Restore |
| 2799 // previous handle scope. |
| 2800 Label delete_allocated_handles; |
| 2801 __ sw(s0, MemOperand(s3, kNextOffset)); |
| 2802 __ Subu(s2, s2, Operand(1)); |
| 2803 __ sw(s2, MemOperand(s3, kLevelOffset)); |
| 2804 __ lw(at, MemOperand(s3, kLimitOffset)); |
| 2805 __ Branch(&delete_allocated_handles, ne, s1, Operand(at)); |
| 2806 |
| 2807 // Leave the API exit frame. |
| 2808 Label leave_exit_frame; |
| 2809 __ bind(&leave_exit_frame); |
| 2810 __ lw(v0, MemOperand(fp, (2 + FCA::kReturnValueOffset) * kPointerSize)); |
| 2811 __ lw(cp, MemOperand(fp, (2 + FCA::kContextSaveIndex) * kPointerSize)); |
| 2812 // ExitFrame contains four MIPS argument slots after DirectCEntryStub call |
| 2813 // so this must be accounted for. |
| 2814 __ lw(s0, MemOperand(sp, 3 * kPointerSize + kCArgsSlotsSize)); |
| 2815 __ LeaveExitFrame(false, no_reg, false); |
| 2816 |
| 2817 // Check if the function scheduled an exception. |
| 2818 Label promote_scheduled_exception; |
| 2819 __ li( |
| 2820 at, |
| 2821 Operand(ExternalReference::scheduled_exception_address(masm->isolate()))); |
| 2822 __ lw(t1, MemOperand(at)); |
| 2823 __ JumpIfNotRoot(t1, Heap::kTheHoleValueRootIndex, |
| 2824 &promote_scheduled_exception); |
| 2825 |
| 2826 // Check if the function returned a valid JavaScript value. |
| 2827 __ AssertApiCallResult(v0); |
| 2828 |
| 2829 // Drop the arguments and return. |
| 2830 __ Addu(sp, sp, Operand((FCA::kArgsLength + 1) * kPointerSize)); |
| 2831 __ Lsa(sp, sp, s0, kPointerSizeLog2); |
| 2832 __ Ret(); |
| 2833 |
| 2834 // Re-throw by promoting a scheduled exception. |
| 2835 __ bind(&promote_scheduled_exception); |
| 2836 __ TailCallRuntime(Runtime::kPromoteScheduledException); |
| 2837 |
| 2838 // HandleScope limit has changed. Delete allocated extensions. |
| 2839 __ bind(&delete_allocated_handles); |
| 2840 { |
| 2841 __ sw(s1, MemOperand(s3, kLimitOffset)); |
| 2842 __ PrepareCallCFunction(1, s1); |
| 2843 __ li(a0, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 2844 __ CallCFunction( |
| 2845 ExternalReference::delete_handle_scope_extensions(masm->isolate()), 1); |
| 2846 } |
| 2847 __ b(&leave_exit_frame); |
| 2848 } |
| 2849 |
| 2850 // static |
2699 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 2851 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
2700 // ----------- S t a t e ------------- | 2852 // ----------- S t a t e ------------- |
2701 // -- a0 : the number of arguments (not including the receiver) | 2853 // -- a0 : the number of arguments (not including the receiver) |
2702 // -- a1 : the constructor to call (checked to be a JSFunction) | 2854 // -- a1 : the constructor to call (checked to be a JSFunction) |
2703 // -- a3 : the new target (checked to be a constructor) | 2855 // -- a3 : the new target (checked to be a constructor) |
2704 // ----------------------------------- | 2856 // ----------------------------------- |
2705 __ AssertFunction(a1); | 2857 __ AssertFunction(a1); |
2706 | 2858 |
2707 // Calling convention for function specific ConstructStubs require | 2859 // Calling convention for function specific ConstructStubs require |
2708 // a2 to contain either an AllocationSite or undefined. | 2860 // a2 to contain either an AllocationSite or undefined. |
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3076 // Now jump to the instructions of the returned code object. | 3228 // Now jump to the instructions of the returned code object. |
3077 __ Jump(at, v0, Code::kHeaderSize - kHeapObjectTag); | 3229 __ Jump(at, v0, Code::kHeaderSize - kHeapObjectTag); |
3078 } | 3230 } |
3079 | 3231 |
3080 #undef __ | 3232 #undef __ |
3081 | 3233 |
3082 } // namespace internal | 3234 } // namespace internal |
3083 } // namespace v8 | 3235 } // namespace v8 |
3084 | 3236 |
3085 #endif // V8_TARGET_ARCH_MIPS | 3237 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |