| 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 |