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/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 2163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2174 __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2174 __ Addu(at, t0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
2175 __ Jump(at); | 2175 __ Jump(at); |
2176 | 2176 |
2177 __ bind(&non_function); | 2177 __ bind(&non_function); |
2178 __ mov(a3, a1); | 2178 __ mov(a3, a1); |
2179 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); | 2179 __ Jump(isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET); |
2180 } | 2180 } |
2181 | 2181 |
2182 | 2182 |
2183 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { | 2183 void CallICStub::HandleArrayCase(MacroAssembler* masm, Label* miss) { |
| 2184 // a0 - number of arguments - if argc_in_register() is true. |
2184 // a1 - function | 2185 // a1 - function |
2185 // a3 - slot id | 2186 // a3 - slot id |
2186 // a2 - vector | 2187 // a2 - vector |
2187 // t0 - loaded from vector[slot] | 2188 // t0 - loaded from vector[slot] |
2188 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, at); | 2189 __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, at); |
2189 __ Branch(miss, ne, a1, Operand(at)); | 2190 __ Branch(miss, ne, a1, Operand(at)); |
2190 | 2191 |
2191 __ li(a0, Operand(arg_count())); | |
2192 | |
2193 // Increment the call count for monomorphic function calls. | 2192 // Increment the call count for monomorphic function calls. |
2194 __ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize); | 2193 __ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize); |
2195 __ lw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); | 2194 __ lw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); |
2196 __ Addu(a3, a3, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2195 __ Addu(a3, a3, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
2197 __ sw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); | 2196 __ sw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); |
2198 | 2197 |
2199 __ mov(a2, t0); | 2198 __ mov(a2, t0); |
2200 __ mov(a3, a1); | 2199 __ mov(a3, a1); |
2201 ArrayConstructorStub stub(masm->isolate(), arg_count()); | 2200 if (argc_in_register()) { |
2202 __ TailCallStub(&stub); | 2201 // Pass a default ArgumentCountKey::Any since the argc is only available |
| 2202 // in a0. We do not have the actual count here. |
| 2203 ArrayConstructorStub stub(masm->isolate()); |
| 2204 __ TailCallStub(&stub); |
| 2205 } else { |
| 2206 // arg_count() is expected in a0 if the arg_count() >= 2 |
| 2207 // (ArgumentCountKey::MORE_THAN_ONE). |
| 2208 ArrayConstructorStub stub(masm->isolate(), arg_count()); |
| 2209 __ TailCallStub(&stub); |
| 2210 } |
2203 } | 2211 } |
2204 | 2212 |
2205 | 2213 |
2206 void CallICStub::Generate(MacroAssembler* masm) { | 2214 void CallICStub::Generate(MacroAssembler* masm) { |
| 2215 // a0 - number of arguments - if argc_in_register() is true. |
2207 // a1 - function | 2216 // a1 - function |
2208 // a3 - slot id (Smi) | 2217 // a3 - slot id (Smi) |
2209 // a2 - vector | 2218 // a2 - vector |
2210 Label extra_checks_or_miss, call, call_function; | 2219 Label extra_checks_or_miss, call, call_function; |
2211 int argc = arg_count(); | 2220 if (!argc_in_register()) { |
2212 ParameterCount actual(argc); | 2221 int argc = arg_count(); |
| 2222 __ li(a0, argc); |
| 2223 } |
2213 | 2224 |
2214 // The checks. First, does r1 match the recorded monomorphic target? | 2225 // The checks. First, does a1 match the recorded monomorphic target? |
2215 __ Lsa(t0, a2, a3, kPointerSizeLog2 - kSmiTagSize); | 2226 __ Lsa(t0, a2, a3, kPointerSizeLog2 - kSmiTagSize); |
2216 __ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize)); | 2227 __ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize)); |
2217 | 2228 |
2218 // We don't know that we have a weak cell. We might have a private symbol | 2229 // We don't know that we have a weak cell. We might have a private symbol |
2219 // or an AllocationSite, but the memory is safe to examine. | 2230 // or an AllocationSite, but the memory is safe to examine. |
2220 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to | 2231 // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to |
2221 // FixedArray. | 2232 // FixedArray. |
2222 // WeakCell::kValueOffset - contains a JSFunction or Smi(0) | 2233 // WeakCell::kValueOffset - contains a JSFunction or Smi(0) |
2223 // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not | 2234 // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not |
2224 // computed, meaning that it can't appear to be a pointer. If the low bit is | 2235 // computed, meaning that it can't appear to be a pointer. If the low bit is |
(...skipping 13 matching lines...) Expand all Loading... |
2238 | 2249 |
2239 // Increment the call count for monomorphic function calls. | 2250 // Increment the call count for monomorphic function calls. |
2240 __ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize); | 2251 __ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize); |
2241 __ lw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); | 2252 __ lw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); |
2242 __ Addu(a3, a3, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2253 __ Addu(a3, a3, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
2243 __ sw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); | 2254 __ sw(a3, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); |
2244 | 2255 |
2245 __ bind(&call_function); | 2256 __ bind(&call_function); |
2246 __ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(), | 2257 __ Jump(masm->isolate()->builtins()->CallFunction(convert_mode(), |
2247 tail_call_mode()), | 2258 tail_call_mode()), |
2248 RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg), | 2259 RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg)); |
2249 USE_DELAY_SLOT); | |
2250 __ li(a0, Operand(argc)); // In delay slot. | |
2251 | 2260 |
2252 __ bind(&extra_checks_or_miss); | 2261 __ bind(&extra_checks_or_miss); |
2253 Label uninitialized, miss, not_allocation_site; | 2262 Label uninitialized, miss, not_allocation_site; |
2254 | 2263 |
2255 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 2264 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
2256 __ Branch(&call, eq, t0, Operand(at)); | 2265 __ Branch(&call, eq, t0, Operand(at)); |
2257 | 2266 |
2258 // Verify that t0 contains an AllocationSite | 2267 // Verify that t0 contains an AllocationSite |
2259 __ lw(t1, FieldMemOperand(t0, HeapObject::kMapOffset)); | 2268 __ lw(t1, FieldMemOperand(t0, HeapObject::kMapOffset)); |
2260 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 2269 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
(...skipping 16 matching lines...) Expand all Loading... |
2277 // to handle it here. More complex cases are dealt with in the runtime. | 2286 // to handle it here. More complex cases are dealt with in the runtime. |
2278 __ AssertNotSmi(t0); | 2287 __ AssertNotSmi(t0); |
2279 __ GetObjectType(t0, t1, t1); | 2288 __ GetObjectType(t0, t1, t1); |
2280 __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE)); | 2289 __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE)); |
2281 __ Lsa(t0, a2, a3, kPointerSizeLog2 - kSmiTagSize); | 2290 __ Lsa(t0, a2, a3, kPointerSizeLog2 - kSmiTagSize); |
2282 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 2291 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
2283 __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); | 2292 __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); |
2284 | 2293 |
2285 __ bind(&call); | 2294 __ bind(&call); |
2286 __ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()), | 2295 __ Jump(masm->isolate()->builtins()->Call(convert_mode(), tail_call_mode()), |
2287 RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg), | 2296 RelocInfo::CODE_TARGET, al, zero_reg, Operand(zero_reg)); |
2288 USE_DELAY_SLOT); | |
2289 __ li(a0, Operand(argc)); // In delay slot. | |
2290 | 2297 |
2291 __ bind(&uninitialized); | 2298 __ bind(&uninitialized); |
2292 | 2299 |
2293 // We are going monomorphic, provided we actually have a JSFunction. | 2300 // We are going monomorphic, provided we actually have a JSFunction. |
2294 __ JumpIfSmi(a1, &miss); | 2301 __ JumpIfSmi(a1, &miss); |
2295 | 2302 |
2296 // Goto miss case if we do not have a function. | 2303 // Goto miss case if we do not have a function. |
2297 __ GetObjectType(a1, t0, t0); | 2304 __ GetObjectType(a1, t0, t0); |
2298 __ Branch(&miss, ne, t0, Operand(JS_FUNCTION_TYPE)); | 2305 __ Branch(&miss, ne, t0, Operand(JS_FUNCTION_TYPE)); |
2299 | 2306 |
(...skipping 13 matching lines...) Expand all Loading... |
2313 __ li(t0, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); | 2320 __ li(t0, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |
2314 __ sw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); | 2321 __ sw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize)); |
2315 | 2322 |
2316 // Store the function. Use a stub since we need a frame for allocation. | 2323 // Store the function. Use a stub since we need a frame for allocation. |
2317 // a2 - vector | 2324 // a2 - vector |
2318 // a3 - slot | 2325 // a3 - slot |
2319 // a1 - function | 2326 // a1 - function |
2320 { | 2327 { |
2321 FrameScope scope(masm, StackFrame::INTERNAL); | 2328 FrameScope scope(masm, StackFrame::INTERNAL); |
2322 CreateWeakCellStub create_stub(masm->isolate()); | 2329 CreateWeakCellStub create_stub(masm->isolate()); |
2323 __ Push(a1); | 2330 __ SmiTag(a0); |
| 2331 __ Push(a0, a1); |
2324 __ CallStub(&create_stub); | 2332 __ CallStub(&create_stub); |
2325 __ Pop(a1); | 2333 __ Pop(a0, a1); |
| 2334 __ SmiUntag(a0); |
2326 } | 2335 } |
2327 | 2336 |
2328 __ Branch(&call_function); | 2337 __ Branch(&call_function); |
2329 | 2338 |
2330 // We are here because tracing is on or we encountered a MISS case we can't | 2339 // We are here because tracing is on or we encountered a MISS case we can't |
2331 // handle here. | 2340 // handle here. |
2332 __ bind(&miss); | 2341 __ bind(&miss); |
2333 GenerateMiss(masm); | 2342 GenerateMiss(masm); |
2334 | 2343 |
2335 __ Branch(&call); | 2344 __ Branch(&call); |
2336 } | 2345 } |
2337 | 2346 |
2338 | 2347 |
2339 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 2348 void CallICStub::GenerateMiss(MacroAssembler* masm) { |
2340 FrameScope scope(masm, StackFrame::INTERNAL); | 2349 FrameScope scope(masm, StackFrame::INTERNAL); |
2341 | 2350 |
2342 // Push the receiver and the function and feedback info. | 2351 __ SmiTag(a0); |
2343 __ Push(a1, a2, a3); | 2352 // Push number of arguments, receiver, function and feedback info. |
| 2353 __ Push(a0, a1, a2, a3); |
2344 | 2354 |
2345 // Call the entry. | 2355 // Call the entry. |
2346 __ CallRuntime(Runtime::kCallIC_Miss); | 2356 __ CallRuntime(Runtime::kCallIC_Miss); |
2347 | 2357 |
2348 // Move result to a1 and exit the internal frame. | 2358 // Move result to a1 and exit the internal frame. |
2349 __ mov(a1, v0); | 2359 __ mov(a1, v0); |
| 2360 |
| 2361 // Restore a0. |
| 2362 __ Pop(a0); |
| 2363 __ SmiUntag(a0); |
2350 } | 2364 } |
2351 | 2365 |
2352 | 2366 |
2353 // StringCharCodeAtGenerator. | 2367 // StringCharCodeAtGenerator. |
2354 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 2368 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
2355 DCHECK(!t0.is(index_)); | 2369 DCHECK(!t0.is(index_)); |
2356 DCHECK(!t0.is(result_)); | 2370 DCHECK(!t0.is(result_)); |
2357 DCHECK(!t0.is(object_)); | 2371 DCHECK(!t0.is(object_)); |
2358 if (check_mode_ == RECEIVER_IS_UNKNOWN) { | 2372 if (check_mode_ == RECEIVER_IS_UNKNOWN) { |
2359 // If the receiver is a smi trigger the non-string case. | 2373 // If the receiver is a smi trigger the non-string case. |
(...skipping 3427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5787 return_value_operand, NULL); | 5801 return_value_operand, NULL); |
5788 } | 5802 } |
5789 | 5803 |
5790 | 5804 |
5791 #undef __ | 5805 #undef __ |
5792 | 5806 |
5793 } // namespace internal | 5807 } // namespace internal |
5794 } // namespace v8 | 5808 } // namespace v8 |
5795 | 5809 |
5796 #endif // V8_TARGET_ARCH_MIPS | 5810 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |