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/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 2150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2161 Label construct; | 2161 Label construct; |
2162 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 2162 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
2163 __ Branch(&construct, ne, a3, Operand(at)); | 2163 __ Branch(&construct, ne, a3, Operand(at)); |
2164 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 2164 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
2165 __ bind(&construct); | 2165 __ bind(&construct); |
2166 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2166 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2167 } | 2167 } |
2168 } | 2168 } |
2169 | 2169 |
2170 // static | 2170 // static |
2171 void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm, | 2171 void Builtins::Generate_ForwardVarargs(MacroAssembler* masm, |
2172 Handle<Code> code) { | 2172 Handle<Code> code) { |
2173 // ----------- S t a t e ------------- | 2173 // ----------- S t a t e ------------- |
2174 // -- a1 : the target to call (can be any Object) | 2174 // -- a0 : the number of arguments (not including the receiver) |
2175 // -- a2 : start index (to support rest parameters) | 2175 // -- a3 : the new.target (for [[Construct]] calls) |
2176 // -- ra : return address. | 2176 // -- a1 : the target to call (can be any Object) |
2177 // -- sp[0] : thisArgument | 2177 // -- a2 : start index (to support rest parameters) |
2178 // ----------------------------------- | 2178 // ----------------------------------- |
2179 | 2179 |
2180 // Check if we have an arguments adaptor frame below the function frame. | 2180 // Check if we have an arguments adaptor frame below the function frame. |
2181 Label arguments_adaptor, arguments_done; | 2181 Label arguments_adaptor, arguments_done; |
2182 __ lw(a3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 2182 __ lw(t3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
2183 __ lw(a0, MemOperand(a3, CommonFrameConstants::kContextOrFrameTypeOffset)); | 2183 __ lw(t2, MemOperand(t3, CommonFrameConstants::kContextOrFrameTypeOffset)); |
2184 __ Branch(&arguments_adaptor, eq, a0, | 2184 __ Branch(&arguments_adaptor, eq, t2, |
2185 Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); | 2185 Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR))); |
2186 { | 2186 { |
2187 __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 2187 __ lw(t2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
2188 __ lw(a0, FieldMemOperand(a0, JSFunction::kSharedFunctionInfoOffset)); | 2188 __ lw(t2, FieldMemOperand(t2, JSFunction::kSharedFunctionInfoOffset)); |
2189 __ lw(a0, | 2189 __ lw(t2, |
2190 FieldMemOperand(a0, SharedFunctionInfo::kFormalParameterCountOffset)); | 2190 FieldMemOperand(t2, SharedFunctionInfo::kFormalParameterCountOffset)); |
2191 __ mov(a3, fp); | 2191 __ mov(t3, fp); |
2192 } | 2192 } |
2193 __ Branch(&arguments_done); | 2193 __ Branch(&arguments_done); |
2194 __ bind(&arguments_adaptor); | 2194 __ bind(&arguments_adaptor); |
2195 { | 2195 { |
2196 // Just get the length from the ArgumentsAdaptorFrame. | 2196 // Just get the length from the ArgumentsAdaptorFrame. |
2197 __ lw(a0, MemOperand(a3, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2197 __ lw(t2, MemOperand(t3, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
2198 } | 2198 } |
2199 __ bind(&arguments_done); | 2199 __ bind(&arguments_done); |
2200 | 2200 |
2201 Label stack_empty, stack_done, stack_overflow; | 2201 Label stack_done, stack_overflow; |
2202 __ SmiUntag(a0); | 2202 __ SmiUntag(t2); |
2203 __ Subu(a0, a0, a2); | 2203 __ Subu(t2, t2, a2); |
2204 __ Branch(&stack_empty, le, a0, Operand(zero_reg)); | 2204 __ Branch(&stack_done, le, t2, Operand(zero_reg)); |
2205 { | 2205 { |
2206 // Check for stack overflow. | 2206 // Check for stack overflow. |
2207 Generate_StackOverflowCheck(masm, a0, t0, t1, &stack_overflow); | 2207 Generate_StackOverflowCheck(masm, t2, t0, t1, &stack_overflow); |
2208 | 2208 |
2209 // Forward the arguments from the caller frame. | 2209 // Forward the arguments from the caller frame. |
2210 { | 2210 { |
2211 Label loop; | 2211 Label loop; |
2212 __ mov(a2, a0); | 2212 __ Addu(a0, a0, t2); |
2213 __ bind(&loop); | 2213 __ bind(&loop); |
2214 { | 2214 { |
2215 __ Lsa(at, a3, a2, kPointerSizeLog2); | 2215 __ Lsa(at, t3, t2, kPointerSizeLog2); |
2216 __ lw(at, MemOperand(at, 1 * kPointerSize)); | 2216 __ lw(at, MemOperand(at, 1 * kPointerSize)); |
2217 __ push(at); | 2217 __ push(at); |
2218 __ Subu(a2, a2, Operand(1)); | 2218 __ Subu(t2, t2, Operand(1)); |
2219 __ Branch(&loop, ne, a2, Operand(zero_reg)); | 2219 __ Branch(&loop, ne, t2, Operand(zero_reg)); |
2220 } | 2220 } |
2221 } | 2221 } |
2222 } | 2222 } |
2223 __ Branch(&stack_done); | 2223 __ Branch(&stack_done); |
2224 __ bind(&stack_overflow); | 2224 __ bind(&stack_overflow); |
2225 __ TailCallRuntime(Runtime::kThrowStackOverflow); | 2225 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
2226 __ bind(&stack_empty); | |
2227 { | |
2228 // We just pass the receiver, which is already on the stack. | |
2229 __ li(a0, Operand(0)); | |
2230 } | |
2231 __ bind(&stack_done); | 2226 __ bind(&stack_done); |
2232 | 2227 |
| 2228 // Tail-call to the {code} handler. |
2233 __ Jump(code, RelocInfo::CODE_TARGET); | 2229 __ Jump(code, RelocInfo::CODE_TARGET); |
2234 } | 2230 } |
2235 | 2231 |
2236 namespace { | 2232 namespace { |
2237 | 2233 |
2238 // Drops top JavaScript frame and an arguments adaptor frame below it (if | 2234 // Drops top JavaScript frame and an arguments adaptor frame below it (if |
2239 // present) preserving all the arguments prepared for current call. | 2235 // present) preserving all the arguments prepared for current call. |
2240 // Does nothing if debugger is currently active. | 2236 // Does nothing if debugger is currently active. |
2241 // ES6 14.6.3. PrepareForTailCall | 2237 // ES6 14.6.3. PrepareForTailCall |
2242 // | 2238 // |
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3116 // Now jump to the instructions of the returned code object. | 3112 // Now jump to the instructions of the returned code object. |
3117 __ Jump(at, v0, Code::kHeaderSize - kHeapObjectTag); | 3113 __ Jump(at, v0, Code::kHeaderSize - kHeapObjectTag); |
3118 } | 3114 } |
3119 | 3115 |
3120 #undef __ | 3116 #undef __ |
3121 | 3117 |
3122 } // namespace internal | 3118 } // namespace internal |
3123 } // namespace v8 | 3119 } // namespace v8 |
3124 | 3120 |
3125 #endif // V8_TARGET_ARCH_MIPS | 3121 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |