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 |