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 2366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2377 // (9) Sliced string. Replace subject with parent. Go to (4). | 2377 // (9) Sliced string. Replace subject with parent. Go to (4). |
2378 // Load offset into r9 and replace subject string with parent. | 2378 // Load offset into r9 and replace subject string with parent. |
2379 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2379 __ ldr(r9, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
2380 __ SmiUntag(r9); | 2380 __ SmiUntag(r9); |
2381 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2381 __ ldr(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
2382 __ jmp(&check_underlying); // Go to (4). | 2382 __ jmp(&check_underlying); // Go to (4). |
2383 #endif // V8_INTERPRETED_REGEXP | 2383 #endif // V8_INTERPRETED_REGEXP |
2384 } | 2384 } |
2385 | 2385 |
2386 | 2386 |
2387 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { | 2387 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, |
| 2388 bool is_super) { |
2388 // r0 : number of arguments to the construct function | 2389 // r0 : number of arguments to the construct function |
2389 // r1 : the function to call | 2390 // r1 : the function to call |
2390 // r2 : feedback vector | 2391 // r2 : feedback vector |
2391 // r3 : slot in feedback vector (Smi) | 2392 // r3 : slot in feedback vector (Smi) |
2392 // r4 : original constructor | 2393 // r4 : original constructor (for IsSuperConstructorCall) |
2393 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2394 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
2394 | 2395 |
2395 // Number-of-arguments register must be smi-tagged to call out. | 2396 // Number-of-arguments register must be smi-tagged to call out. |
2396 __ SmiTag(r0); | 2397 __ SmiTag(r0); |
2397 __ Push(r3, r2, r1, r0); | 2398 __ Push(r3, r2, r1, r0); |
2398 __ Push(r4); | 2399 if (is_super) { |
| 2400 __ Push(r4); |
| 2401 } |
2399 | 2402 |
2400 __ CallStub(stub); | 2403 __ CallStub(stub); |
2401 | 2404 |
2402 __ Pop(r4); | 2405 if (is_super) { |
| 2406 __ Pop(r4); |
| 2407 } |
2403 __ Pop(r3, r2, r1, r0); | 2408 __ Pop(r3, r2, r1, r0); |
2404 __ SmiUntag(r0); | 2409 __ SmiUntag(r0); |
2405 } | 2410 } |
2406 | 2411 |
2407 | 2412 |
2408 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2413 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { |
2409 // Cache the called function in a feedback vector slot. Cache states | 2414 // Cache the called function in a feedback vector slot. Cache states |
2410 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2415 // are uninitialized, monomorphic (indicated by a JSFunction), and |
2411 // megamorphic. | 2416 // megamorphic. |
2412 // r0 : number of arguments to the construct function | 2417 // r0 : number of arguments to the construct function |
2413 // r1 : the function to call | 2418 // r1 : the function to call |
2414 // r2 : feedback vector | 2419 // r2 : feedback vector |
2415 // r3 : slot in feedback vector (Smi) | 2420 // r3 : slot in feedback vector (Smi) |
2416 // r4 : original constructor | 2421 // r4 : original constructor (for IsSuperConstructorCall) |
2417 Label initialize, done, miss, megamorphic, not_array_function; | 2422 Label initialize, done, miss, megamorphic, not_array_function; |
2418 | 2423 |
2419 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2424 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
2420 masm->isolate()->heap()->megamorphic_symbol()); | 2425 masm->isolate()->heap()->megamorphic_symbol()); |
2421 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2426 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
2422 masm->isolate()->heap()->uninitialized_symbol()); | 2427 masm->isolate()->heap()->uninitialized_symbol()); |
2423 | 2428 |
2424 // Load the cache state into r5. | 2429 // Load the cache state into r5. |
2425 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2430 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); |
2426 __ ldr(r5, FieldMemOperand(r5, FixedArray::kHeaderSize)); | 2431 __ ldr(r5, FieldMemOperand(r5, FixedArray::kHeaderSize)); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2481 if (!FLAG_pretenuring_call_new) { | 2486 if (!FLAG_pretenuring_call_new) { |
2482 // Make sure the function is the Array() function | 2487 // Make sure the function is the Array() function |
2483 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r5); | 2488 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r5); |
2484 __ cmp(r1, r5); | 2489 __ cmp(r1, r5); |
2485 __ b(ne, ¬_array_function); | 2490 __ b(ne, ¬_array_function); |
2486 | 2491 |
2487 // The target function is the Array constructor, | 2492 // The target function is the Array constructor, |
2488 // Create an AllocationSite if we don't already have it, store it in the | 2493 // Create an AllocationSite if we don't already have it, store it in the |
2489 // slot. | 2494 // slot. |
2490 CreateAllocationSiteStub create_stub(masm->isolate()); | 2495 CreateAllocationSiteStub create_stub(masm->isolate()); |
2491 CallStubInRecordCallTarget(masm, &create_stub); | 2496 CallStubInRecordCallTarget(masm, &create_stub, is_super); |
2492 __ b(&done); | 2497 __ b(&done); |
2493 | 2498 |
2494 __ bind(¬_array_function); | 2499 __ bind(¬_array_function); |
2495 } | 2500 } |
2496 | 2501 |
2497 CreateWeakCellStub create_stub(masm->isolate()); | 2502 CreateWeakCellStub create_stub(masm->isolate()); |
2498 CallStubInRecordCallTarget(masm, &create_stub); | 2503 CallStubInRecordCallTarget(masm, &create_stub, is_super); |
2499 __ bind(&done); | 2504 __ bind(&done); |
2500 } | 2505 } |
2501 | 2506 |
2502 | 2507 |
2503 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2508 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
2504 // Do not transform the receiver for strict mode functions. | 2509 // Do not transform the receiver for strict mode functions. |
2505 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); | 2510 __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
2506 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); | 2511 __ ldr(r4, FieldMemOperand(r3, SharedFunctionInfo::kCompilerHintsOffset)); |
2507 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + | 2512 __ tst(r4, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + |
2508 kSmiTagSize))); | 2513 kSmiTagSize))); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2621 // r4 : original constructor (for IsSuperConstructorCall) | 2626 // r4 : original constructor (for IsSuperConstructorCall) |
2622 Label slow, non_function_call; | 2627 Label slow, non_function_call; |
2623 | 2628 |
2624 // Check that the function is not a smi. | 2629 // Check that the function is not a smi. |
2625 __ JumpIfSmi(r1, &non_function_call); | 2630 __ JumpIfSmi(r1, &non_function_call); |
2626 // Check that the function is a JSFunction. | 2631 // Check that the function is a JSFunction. |
2627 __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE); | 2632 __ CompareObjectType(r1, r5, r5, JS_FUNCTION_TYPE); |
2628 __ b(ne, &slow); | 2633 __ b(ne, &slow); |
2629 | 2634 |
2630 if (RecordCallTarget()) { | 2635 if (RecordCallTarget()) { |
2631 GenerateRecordCallTarget(masm); | 2636 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); |
2632 | 2637 |
2633 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); | 2638 __ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3)); |
2634 if (FLAG_pretenuring_call_new) { | 2639 if (FLAG_pretenuring_call_new) { |
2635 // Put the AllocationSite from the feedback vector into r2. | 2640 // Put the AllocationSite from the feedback vector into r2. |
2636 // By adding kPointerSize we encode that we know the AllocationSite | 2641 // By adding kPointerSize we encode that we know the AllocationSite |
2637 // entry is at the feedback vector slot given by r3 + 1. | 2642 // entry is at the feedback vector slot given by r3 + 1. |
2638 __ ldr(r2, FieldMemOperand(r5, FixedArray::kHeaderSize + kPointerSize)); | 2643 __ ldr(r2, FieldMemOperand(r5, FixedArray::kHeaderSize + kPointerSize)); |
2639 } else { | 2644 } else { |
2640 Label feedback_register_initialized; | 2645 Label feedback_register_initialized; |
2641 // Put the AllocationSite from the feedback vector into r2, or undefined. | 2646 // Put the AllocationSite from the feedback vector into r2, or undefined. |
(...skipping 2732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5374 MemOperand(fp, 6 * kPointerSize), NULL); | 5379 MemOperand(fp, 6 * kPointerSize), NULL); |
5375 } | 5380 } |
5376 | 5381 |
5377 | 5382 |
5378 #undef __ | 5383 #undef __ |
5379 | 5384 |
5380 } // namespace internal | 5385 } // namespace internal |
5381 } // namespace v8 | 5386 } // namespace v8 |
5382 | 5387 |
5383 #endif // V8_TARGET_ARCH_ARM | 5388 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |