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