| 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_ARM | 5 #if V8_TARGET_ARCH_ARM | 
| 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 2268 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2279 | 2279 | 
| 2280 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2280 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 
| 2281   // Cache the called function in a feedback vector slot.  Cache states | 2281   // Cache the called function in a feedback vector slot.  Cache states | 
| 2282   // are uninitialized, monomorphic (indicated by a JSFunction), and | 2282   // are uninitialized, monomorphic (indicated by a JSFunction), and | 
| 2283   // megamorphic. | 2283   // megamorphic. | 
| 2284   // r0 : number of arguments to the construct function | 2284   // r0 : number of arguments to the construct function | 
| 2285   // r1 : the function to call | 2285   // r1 : the function to call | 
| 2286   // r2 : feedback vector | 2286   // r2 : feedback vector | 
| 2287   // r3 : slot in feedback vector (Smi) | 2287   // r3 : slot in feedback vector (Smi) | 
| 2288   Label initialize, done, miss, megamorphic, not_array_function; | 2288   Label initialize, done, miss, megamorphic, not_array_function; | 
| 2289   Label done_increment_count; |  | 
| 2290 | 2289 | 
| 2291   DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2290   DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 
| 2292             masm->isolate()->heap()->megamorphic_symbol()); | 2291             masm->isolate()->heap()->megamorphic_symbol()); | 
| 2293   DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2292   DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 
| 2294             masm->isolate()->heap()->uninitialized_symbol()); | 2293             masm->isolate()->heap()->uninitialized_symbol()); | 
| 2295 | 2294 | 
| 2296   // Load the cache state into r5. | 2295   // Load the cache state into r5. | 
| 2297   __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2296   __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | 
| 2298   __ ldr(r5, FieldMemOperand(r5, FixedArray::kHeaderSize)); | 2297   __ ldr(r5, FieldMemOperand(r5, FixedArray::kHeaderSize)); | 
| 2299 | 2298 | 
| 2300   // A monomorphic cache hit or an already megamorphic state: invoke the | 2299   // A monomorphic cache hit or an already megamorphic state: invoke the | 
| 2301   // function without changing the state. | 2300   // function without changing the state. | 
| 2302   // We don't know if r5 is a WeakCell or a Symbol, but it's harmless to read at | 2301   // We don't know if r5 is a WeakCell or a Symbol, but it's harmless to read at | 
| 2303   // this position in a symbol (see static asserts in type-feedback-vector.h). | 2302   // this position in a symbol (see static asserts in type-feedback-vector.h). | 
| 2304   Label check_allocation_site; | 2303   Label check_allocation_site; | 
| 2305   Register feedback_map = r6; | 2304   Register feedback_map = r6; | 
| 2306   Register weak_value = r9; | 2305   Register weak_value = r9; | 
| 2307   __ ldr(weak_value, FieldMemOperand(r5, WeakCell::kValueOffset)); | 2306   __ ldr(weak_value, FieldMemOperand(r5, WeakCell::kValueOffset)); | 
| 2308   __ cmp(r1, weak_value); | 2307   __ cmp(r1, weak_value); | 
| 2309   __ b(eq, &done_increment_count); | 2308   __ b(eq, &done); | 
| 2310   __ CompareRoot(r5, Heap::kmegamorphic_symbolRootIndex); | 2309   __ CompareRoot(r5, Heap::kmegamorphic_symbolRootIndex); | 
| 2311   __ b(eq, &done); | 2310   __ b(eq, &done); | 
| 2312   __ ldr(feedback_map, FieldMemOperand(r5, HeapObject::kMapOffset)); | 2311   __ ldr(feedback_map, FieldMemOperand(r5, HeapObject::kMapOffset)); | 
| 2313   __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | 2312   __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | 
| 2314   __ b(ne, &check_allocation_site); | 2313   __ b(ne, &check_allocation_site); | 
| 2315 | 2314 | 
| 2316   // If the weak cell is cleared, we have a new chance to become monomorphic. | 2315   // If the weak cell is cleared, we have a new chance to become monomorphic. | 
| 2317   __ JumpIfSmi(weak_value, &initialize); | 2316   __ JumpIfSmi(weak_value, &initialize); | 
| 2318   __ jmp(&megamorphic); | 2317   __ jmp(&megamorphic); | 
| 2319 | 2318 | 
| 2320   __ bind(&check_allocation_site); | 2319   __ bind(&check_allocation_site); | 
| 2321   // If we came here, we need to see if we are the array function. | 2320   // If we came here, we need to see if we are the array function. | 
| 2322   // If we didn't have a matching function, and we didn't find the megamorph | 2321   // If we didn't have a matching function, and we didn't find the megamorph | 
| 2323   // sentinel, then we have in the slot either some other function or an | 2322   // sentinel, then we have in the slot either some other function or an | 
| 2324   // AllocationSite. | 2323   // AllocationSite. | 
| 2325   __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex); | 2324   __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex); | 
| 2326   __ b(ne, &miss); | 2325   __ b(ne, &miss); | 
| 2327 | 2326 | 
| 2328   // Make sure the function is the Array() function | 2327   // Make sure the function is the Array() function | 
| 2329   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r5); | 2328   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r5); | 
| 2330   __ cmp(r1, r5); | 2329   __ cmp(r1, r5); | 
| 2331   __ b(ne, &megamorphic); | 2330   __ b(ne, &megamorphic); | 
| 2332   __ jmp(&done_increment_count); | 2331   __ jmp(&done); | 
| 2333 | 2332 | 
| 2334   __ bind(&miss); | 2333   __ bind(&miss); | 
| 2335 | 2334 | 
| 2336   // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 2335   // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 
| 2337   // megamorphic. | 2336   // megamorphic. | 
| 2338   __ CompareRoot(r5, Heap::kuninitialized_symbolRootIndex); | 2337   __ CompareRoot(r5, Heap::kuninitialized_symbolRootIndex); | 
| 2339   __ b(eq, &initialize); | 2338   __ b(eq, &initialize); | 
| 2340   // MegamorphicSentinel is an immortal immovable object (undefined) so no | 2339   // MegamorphicSentinel is an immortal immovable object (undefined) so no | 
| 2341   // write-barrier is needed. | 2340   // write-barrier is needed. | 
| 2342   __ bind(&megamorphic); | 2341   __ bind(&megamorphic); | 
| 2343   __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2342   __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | 
| 2344   __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex); | 2343   __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex); | 
| 2345   __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize)); | 2344   __ str(ip, FieldMemOperand(r5, FixedArray::kHeaderSize)); | 
| 2346   __ jmp(&done); | 2345   __ jmp(&done); | 
| 2347 | 2346 | 
| 2348   // An uninitialized cache is patched with the function | 2347   // An uninitialized cache is patched with the function | 
| 2349   __ bind(&initialize); | 2348   __ bind(&initialize); | 
| 2350 | 2349 | 
| 2351   // Initialize the call counter. |  | 
| 2352   __ Move(r5, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |  | 
| 2353   __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |  | 
| 2354   __ str(r5, FieldMemOperand(r4, FixedArray::kHeaderSize + kPointerSize)); |  | 
| 2355 |  | 
| 2356   // Make sure the function is the Array() function | 2350   // Make sure the function is the Array() function | 
| 2357   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r5); | 2351   __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r5); | 
| 2358   __ cmp(r1, r5); | 2352   __ cmp(r1, r5); | 
| 2359   __ b(ne, ¬_array_function); | 2353   __ b(ne, ¬_array_function); | 
| 2360 | 2354 | 
| 2361   // The target function is the Array constructor, | 2355   // The target function is the Array constructor, | 
| 2362   // Create an AllocationSite if we don't already have it, store it in the | 2356   // Create an AllocationSite if we don't already have it, store it in the | 
| 2363   // slot. | 2357   // slot. | 
| 2364   CreateAllocationSiteStub create_stub(masm->isolate()); | 2358   CreateAllocationSiteStub create_stub(masm->isolate()); | 
| 2365   CallStubInRecordCallTarget(masm, &create_stub); | 2359   CallStubInRecordCallTarget(masm, &create_stub); | 
| 2366   __ b(&done); | 2360   __ b(&done); | 
| 2367 | 2361 | 
| 2368   __ bind(¬_array_function); | 2362   __ bind(¬_array_function); | 
| 2369   CreateWeakCellStub weak_cell_stub(masm->isolate()); | 2363   CreateWeakCellStub weak_cell_stub(masm->isolate()); | 
| 2370   CallStubInRecordCallTarget(masm, &weak_cell_stub); | 2364   CallStubInRecordCallTarget(masm, &weak_cell_stub); | 
| 2371   __ b(&done); |  | 
| 2372 |  | 
| 2373   __ bind(&done_increment_count); |  | 
| 2374   __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |  | 
| 2375   __ add(r4, r4, Operand(FixedArray::kHeaderSize + kPointerSize)); |  | 
| 2376   __ ldr(r5, FieldMemOperand(r4, 0)); |  | 
| 2377   __ add(r5, r5, Operand(Smi::FromInt(CallICNexus::kCallCountIncrement))); |  | 
| 2378   __ str(r5, FieldMemOperand(r4, 0)); |  | 
| 2379 |  | 
| 2380   __ bind(&done); | 2365   __ bind(&done); | 
| 2381 } | 2366 } | 
| 2382 | 2367 | 
| 2383 | 2368 | 
| 2384 void ConstructICStub::Generate(MacroAssembler* masm) { | 2369 void CallConstructStub::Generate(MacroAssembler* masm) { | 
| 2385   // r0 : number of arguments | 2370   // r0 : number of arguments | 
| 2386   // r1 : the function to call | 2371   // r1 : the function to call | 
| 2387   // r2 : feedback vector | 2372   // r2 : feedback vector | 
| 2388   // r3 : slot in feedback vector (Smi, for RecordCallTarget) | 2373   // r3 : slot in feedback vector (Smi, for RecordCallTarget) | 
| 2389 | 2374 | 
| 2390   Label non_function; | 2375   Label non_function; | 
| 2391   // Check that the function is not a smi. | 2376   // Check that the function is not a smi. | 
| 2392   __ JumpIfSmi(r1, &non_function); | 2377   __ JumpIfSmi(r1, &non_function); | 
| 2393   // Check that the function is a JSFunction. | 2378   // Check that the function is a JSFunction. | 
| 2394   __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE); | 2379   __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE); | 
| (...skipping 2987 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5382                            MemOperand(fp, 6 * kPointerSize), NULL); | 5367                            MemOperand(fp, 6 * kPointerSize), NULL); | 
| 5383 } | 5368 } | 
| 5384 | 5369 | 
| 5385 | 5370 | 
| 5386 #undef __ | 5371 #undef __ | 
| 5387 | 5372 | 
| 5388 }  // namespace internal | 5373 }  // namespace internal | 
| 5389 }  // namespace v8 | 5374 }  // namespace v8 | 
| 5390 | 5375 | 
| 5391 #endif  // V8_TARGET_ARCH_ARM | 5376 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW | 
|---|