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