Chromium Code Reviews| 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 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 2350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2361 // (9) Sliced string. Replace subject with parent. Go to (4). | 2361 // (9) Sliced string. Replace subject with parent. Go to (4). |
| 2362 // Load offset into r9 and replace subject string with parent. | 2362 // Load offset into r9 and replace subject string with parent. |
| 2363 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2363 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
| 2364 __ SmiUntag(r9); | 2364 __ SmiUntag(r9); |
| 2365 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2365 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
| 2366 __ jmp(&check_underlying); // Go to (4). | 2366 __ jmp(&check_underlying); // Go to (4). |
| 2367 #endif // V8_INTERPRETED_REGEXP | 2367 #endif // V8_INTERPRETED_REGEXP |
| 2368 } | 2368 } |
| 2369 | 2369 |
| 2370 | 2370 |
| 2371 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { | |
| 2372 // r0 : number of arguments to the construct function | |
| 2373 // r2 : Feedback vector | |
| 2374 // r3 : slot in feedback vector (Smi) | |
| 2375 // r1 : the function to call | |
| 2376 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | |
| 2377 | |
| 2378 // Arguments register must be smi-tagged to call out. | |
| 2379 __ SmiTag(r0); | |
| 2380 __ Push(r3, r2, r1, r0); | |
| 2381 | |
| 2382 __ CallStub(stub); | |
| 2383 | |
| 2384 __ Pop(r3, r2, r1, r0); | |
| 2385 __ SmiUntag(r0); | |
| 2386 } | |
| 2387 | |
| 2388 | |
| 2371 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2389 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
| 2372 // Cache the called function in a feedback vector slot. Cache states | 2390 // Cache the called function in a feedback vector slot. Cache states |
| 2373 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2391 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 2374 // megamorphic. | 2392 // megamorphic. |
| 2375 // r0 : number of arguments to the construct function | 2393 // r0 : number of arguments to the construct function |
| 2376 // r1 : the function to call | 2394 // r1 : the function to call |
| 2377 // r2 : Feedback vector | 2395 // r2 : Feedback vector |
| 2378 // r3 : slot in feedback vector (Smi) | 2396 // r3 : slot in feedback vector (Smi) |
| 2379 Label initialize, done, miss, megamorphic, not_array_function; | 2397 Label initialize, done, miss, megamorphic, not_array_function; |
| 2380 | 2398 |
| 2381 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2399 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
| 2382 masm->isolate()->heap()->megamorphic_symbol()); | 2400 masm->isolate()->heap()->megamorphic_symbol()); |
| 2383 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2401 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
| 2384 masm->isolate()->heap()->uninitialized_symbol()); | 2402 masm->isolate()->heap()->uninitialized_symbol()); |
| 2385 | 2403 |
| 2386 // Load the cache state into r4. | 2404 // Load the cache state into r4. |
| 2387 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2405 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); |
| 2388 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); | 2406 __ ldr(r4, FieldMemOperand(r4, FixedArray::kHeaderSize)); |
| 2389 | 2407 |
| 2390 // A monomorphic cache hit or an already megamorphic state: invoke the | 2408 // A monomorphic cache hit or an already megamorphic state: invoke the |
| 2391 // function without changing the state. | 2409 // function without changing the state. |
| 2392 __ cmp(r4, r1); | 2410 Label check_megamorphic; |
| 2411 Register feedback_map = r5; | |
| 2412 Register weak_value = r8; | |
| 2413 __ ldr(weak_value, FieldMemOperand(r4, WeakCell::kValueOffset)); | |
| 2414 __ cmp(r1, weak_value); | |
| 2415 __ b(eq, &done); | |
| 2416 __ ldr(feedback_map, FieldMemOperand(r4, 0)); | |
| 2417 __ CompareRoot(feedback_map, Heap::kWeakCellMapRootIndex); | |
| 2418 __ b(ne, &check_megamorphic); | |
| 2419 | |
| 2420 // If r1 is not equal to the weak cell value, and the weak cell value is | |
| 2421 // cleared, we have a new chance to become monomorphic. | |
| 2422 __ JumpIfSmi(weak_value, &initialize); | |
| 2423 __ jmp(&megamorphic); | |
| 2424 | |
| 2425 __ bind(&check_megamorphic); | |
| 2426 __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex); | |
|
Toon Verwaest
2015/03/25 15:25:51
Checking this second might be faster...
mvstanton
2015/03/26 15:28:53
Good idea, done.
| |
| 2393 __ b(eq, &done); | 2427 __ b(eq, &done); |
| 2394 | 2428 |
| 2395 if (!FLAG_pretenuring_call_new) { | 2429 if (!FLAG_pretenuring_call_new) { |
| 2396 // If we came here, we need to see if we are the array function. | 2430 // If we came here, we need to see if we are the array function. |
| 2397 // If we didn't have a matching function, and we didn't find the megamorph | 2431 // If we didn't have a matching function, and we didn't find the megamorph |
| 2398 // sentinel, then we have in the slot either some other function or an | 2432 // sentinel, then we have in the slot either some other function or an |
| 2399 // AllocationSite. Do a map check on the object in ecx. | 2433 // AllocationSite. Do a map check on the object in ecx. |
| 2400 __ ldr(r5, FieldMemOperand(r4, 0)); | 2434 __ CompareRoot(feedback_map, Heap::kAllocationSiteMapRootIndex); |
| 2401 __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex); | |
| 2402 __ b(ne, &miss); | 2435 __ b(ne, &miss); |
| 2403 | 2436 |
| 2404 // Make sure the function is the Array() function | 2437 // Make sure the function is the Array() function |
| 2405 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | 2438 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); |
| 2406 __ cmp(r1, r4); | 2439 __ cmp(r1, r4); |
| 2407 __ b(ne, &megamorphic); | 2440 __ b(ne, &megamorphic); |
| 2408 __ jmp(&done); | 2441 __ jmp(&done); |
| 2409 } | 2442 } |
| 2410 | 2443 |
| 2411 __ bind(&miss); | 2444 __ bind(&miss); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2427 | 2460 |
| 2428 if (!FLAG_pretenuring_call_new) { | 2461 if (!FLAG_pretenuring_call_new) { |
| 2429 // Make sure the function is the Array() function | 2462 // Make sure the function is the Array() function |
| 2430 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); | 2463 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4); |
| 2431 __ cmp(r1, r4); | 2464 __ cmp(r1, r4); |
| 2432 __ b(ne, ¬_array_function); | 2465 __ b(ne, ¬_array_function); |
| 2433 | 2466 |
| 2434 // The target function is the Array constructor, | 2467 // The target function is the Array constructor, |
| 2435 // Create an AllocationSite if we don't already have it, store it in the | 2468 // Create an AllocationSite if we don't already have it, store it in the |
| 2436 // slot. | 2469 // slot. |
| 2437 { | 2470 CreateAllocationSiteStub create_stub(masm->isolate()); |
| 2438 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2471 CallStubInRecordCallTarget(masm, &create_stub); |
| 2439 | |
| 2440 // Arguments register must be smi-tagged to call out. | |
| 2441 __ SmiTag(r0); | |
| 2442 __ Push(r3, r2, r1, r0); | |
| 2443 | |
| 2444 CreateAllocationSiteStub create_stub(masm->isolate()); | |
| 2445 __ CallStub(&create_stub); | |
| 2446 | |
| 2447 __ Pop(r3, r2, r1, r0); | |
| 2448 __ SmiUntag(r0); | |
| 2449 } | |
| 2450 __ b(&done); | 2472 __ b(&done); |
| 2451 | 2473 |
| 2452 __ bind(¬_array_function); | 2474 __ bind(¬_array_function); |
| 2453 } | 2475 } |
| 2454 | 2476 |
| 2455 __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2477 CreateWeakCellStub create_stub(masm->isolate()); |
| 2456 __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 2478 CallStubInRecordCallTarget(masm, &create_stub); |
| 2457 __ str(r1, MemOperand(r4, 0)); | |
| 2458 | |
| 2459 __ Push(r4, r2, r1); | |
| 2460 __ RecordWrite(r2, r4, r1, kLRHasNotBeenSaved, kDontSaveFPRegs, | |
| 2461 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
| 2462 __ Pop(r4, r2, r1); | |
| 2463 | |
| 2464 __ bind(&done); | 2479 __ bind(&done); |
| 2465 } | 2480 } |
| 2466 | 2481 |
| 2467 | 2482 |
| 2468 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2483 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
| 2469 // Do not transform the receiver for strict mode functions. | 2484 // Do not transform the receiver for strict mode functions. |
| 2470 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 2485 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
| 2471 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); | 2486 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); |
| 2472 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + | 2487 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + |
| 2473 kSmiTagSize))); | 2488 kSmiTagSize))); |
| (...skipping 2811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5285 kStackUnwindSpace, NULL, | 5300 kStackUnwindSpace, NULL, |
| 5286 MemOperand(fp, 6 * kPointerSize), NULL); | 5301 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5287 } | 5302 } |
| 5288 | 5303 |
| 5289 | 5304 |
| 5290 #undef __ | 5305 #undef __ |
| 5291 | 5306 |
| 5292 } } // namespace v8::internal | 5307 } } // namespace v8::internal |
| 5293 | 5308 |
| 5294 #endif // V8_TARGET_ARCH_ARM | 5309 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |