| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_PPC | 5 #if V8_TARGET_ARCH_PPC |
| 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 2390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2401 // (9) Sliced string. Replace subject with parent. Go to (4). | 2401 // (9) Sliced string. Replace subject with parent. Go to (4). |
| 2402 // Load offset into r11 and replace subject string with parent. | 2402 // Load offset into r11 and replace subject string with parent. |
| 2403 __ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2403 __ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
| 2404 __ SmiUntag(r11); | 2404 __ SmiUntag(r11); |
| 2405 __ LoadP(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2405 __ LoadP(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
| 2406 __ b(&check_underlying); // Go to (4). | 2406 __ b(&check_underlying); // Go to (4). |
| 2407 #endif // V8_INTERPRETED_REGEXP | 2407 #endif // V8_INTERPRETED_REGEXP |
| 2408 } | 2408 } |
| 2409 | 2409 |
| 2410 | 2410 |
| 2411 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub, | 2411 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { |
| 2412 bool is_super) { | |
| 2413 // r3 : number of arguments to the construct function | 2412 // r3 : number of arguments to the construct function |
| 2414 // r4 : the function to call | 2413 // r4 : the function to call |
| 2415 // r5 : feedback vector | 2414 // r5 : feedback vector |
| 2416 // r6 : slot in feedback vector (Smi) | 2415 // r6 : slot in feedback vector (Smi) |
| 2417 // r7 : new target (for IsSuperConstructorCall) | |
| 2418 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2416 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
| 2419 | 2417 |
| 2420 // Number-of-arguments register must be smi-tagged to call out. | 2418 // Number-of-arguments register must be smi-tagged to call out. |
| 2421 __ SmiTag(r3); | 2419 __ SmiTag(r3); |
| 2422 if (is_super) { | 2420 __ Push(r6, r5, r4, r3); |
| 2423 __ Push(r6, r5, r4, r3, r7); | |
| 2424 } else { | |
| 2425 __ Push(r6, r5, r4, r3); | |
| 2426 } | |
| 2427 | 2421 |
| 2428 __ CallStub(stub); | 2422 __ CallStub(stub); |
| 2429 | 2423 |
| 2430 if (is_super) { | 2424 __ Pop(r6, r5, r4, r3); |
| 2431 __ Pop(r6, r5, r4, r3, r7); | |
| 2432 } else { | |
| 2433 __ Pop(r6, r5, r4, r3); | |
| 2434 } | |
| 2435 __ SmiUntag(r3); | 2425 __ SmiUntag(r3); |
| 2436 } | 2426 } |
| 2437 | 2427 |
| 2438 | 2428 |
| 2439 static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { | 2429 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
| 2440 // Cache the called function in a feedback vector slot. Cache states | 2430 // Cache the called function in a feedback vector slot. Cache states |
| 2441 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2431 // are uninitialized, monomorphic (indicated by a JSFunction), and |
| 2442 // megamorphic. | 2432 // megamorphic. |
| 2443 // r3 : number of arguments to the construct function | 2433 // r3 : number of arguments to the construct function |
| 2444 // r4 : the function to call | 2434 // r4 : the function to call |
| 2445 // r5 : feedback vector | 2435 // r5 : feedback vector |
| 2446 // r6 : slot in feedback vector (Smi) | 2436 // r6 : slot in feedback vector (Smi) |
| 2447 // r7 : new target (for IsSuperConstructorCall) | |
| 2448 Label initialize, done, miss, megamorphic, not_array_function; | 2437 Label initialize, done, miss, megamorphic, not_array_function; |
| 2449 | 2438 |
| 2450 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2439 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
| 2451 masm->isolate()->heap()->megamorphic_symbol()); | 2440 masm->isolate()->heap()->megamorphic_symbol()); |
| 2452 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2441 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
| 2453 masm->isolate()->heap()->uninitialized_symbol()); | 2442 masm->isolate()->heap()->uninitialized_symbol()); |
| 2454 | 2443 |
| 2455 // Load the cache state into r8. | 2444 // Load the cache state into r8. |
| 2456 __ SmiToPtrArrayOffset(r8, r6); | 2445 __ SmiToPtrArrayOffset(r8, r6); |
| 2457 __ add(r8, r5, r8); | 2446 __ add(r8, r5, r8); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2511 | 2500 |
| 2512 // Make sure the function is the Array() function. | 2501 // Make sure the function is the Array() function. |
| 2513 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r8); | 2502 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r8); |
| 2514 __ cmp(r4, r8); | 2503 __ cmp(r4, r8); |
| 2515 __ bne(¬_array_function); | 2504 __ bne(¬_array_function); |
| 2516 | 2505 |
| 2517 // The target function is the Array constructor, | 2506 // The target function is the Array constructor, |
| 2518 // Create an AllocationSite if we don't already have it, store it in the | 2507 // Create an AllocationSite if we don't already have it, store it in the |
| 2519 // slot. | 2508 // slot. |
| 2520 CreateAllocationSiteStub create_stub(masm->isolate()); | 2509 CreateAllocationSiteStub create_stub(masm->isolate()); |
| 2521 CallStubInRecordCallTarget(masm, &create_stub, is_super); | 2510 CallStubInRecordCallTarget(masm, &create_stub); |
| 2522 __ b(&done); | 2511 __ b(&done); |
| 2523 | 2512 |
| 2524 __ bind(¬_array_function); | 2513 __ bind(¬_array_function); |
| 2525 | 2514 |
| 2526 CreateWeakCellStub weak_cell_stub(masm->isolate()); | 2515 CreateWeakCellStub weak_cell_stub(masm->isolate()); |
| 2527 CallStubInRecordCallTarget(masm, &weak_cell_stub, is_super); | 2516 CallStubInRecordCallTarget(masm, &weak_cell_stub); |
| 2528 __ bind(&done); | 2517 __ bind(&done); |
| 2529 } | 2518 } |
| 2530 | 2519 |
| 2531 | 2520 |
| 2532 void CallConstructStub::Generate(MacroAssembler* masm) { | 2521 void CallConstructStub::Generate(MacroAssembler* masm) { |
| 2533 // r3 : number of arguments | 2522 // r3 : number of arguments |
| 2534 // r4 : the function to call | 2523 // r4 : the function to call |
| 2535 // r5 : feedback vector | 2524 // r5 : feedback vector |
| 2536 // r6 : slot in feedback vector (Smi, for RecordCallTarget) | 2525 // r6 : slot in feedback vector (Smi, for RecordCallTarget) |
| 2537 // r7 : new target (for IsSuperConstructorCall) | |
| 2538 | 2526 |
| 2539 Label non_function; | 2527 Label non_function; |
| 2540 // Check that the function is not a smi. | 2528 // Check that the function is not a smi. |
| 2541 __ JumpIfSmi(r4, &non_function); | 2529 __ JumpIfSmi(r4, &non_function); |
| 2542 // Check that the function is a JSFunction. | 2530 // Check that the function is a JSFunction. |
| 2543 __ CompareObjectType(r4, r8, r8, JS_FUNCTION_TYPE); | 2531 __ CompareObjectType(r4, r8, r8, JS_FUNCTION_TYPE); |
| 2544 __ bne(&non_function); | 2532 __ bne(&non_function); |
| 2545 | 2533 |
| 2546 if (RecordCallTarget()) { | 2534 GenerateRecordCallTarget(masm); |
| 2547 GenerateRecordCallTarget(masm, IsSuperConstructorCall()); | |
| 2548 | 2535 |
| 2549 __ SmiToPtrArrayOffset(r8, r6); | 2536 __ SmiToPtrArrayOffset(r8, r6); |
| 2550 __ add(r8, r5, r8); | 2537 __ add(r8, r5, r8); |
| 2551 // Put the AllocationSite from the feedback vector into r5, or undefined. | 2538 // Put the AllocationSite from the feedback vector into r5, or undefined. |
| 2552 __ LoadP(r5, FieldMemOperand(r8, FixedArray::kHeaderSize)); | 2539 __ LoadP(r5, FieldMemOperand(r8, FixedArray::kHeaderSize)); |
| 2553 __ LoadP(r8, FieldMemOperand(r5, AllocationSite::kMapOffset)); | 2540 __ LoadP(r8, FieldMemOperand(r5, AllocationSite::kMapOffset)); |
| 2554 __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex); | 2541 __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex); |
| 2555 if (CpuFeatures::IsSupported(ISELECT)) { | 2542 if (CpuFeatures::IsSupported(ISELECT)) { |
| 2556 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); | 2543 __ LoadRoot(r8, Heap::kUndefinedValueRootIndex); |
| 2557 __ isel(eq, r5, r5, r8); | 2544 __ isel(eq, r5, r5, r8); |
| 2558 } else { | 2545 } else { |
| 2559 Label feedback_register_initialized; | 2546 Label feedback_register_initialized; |
| 2560 __ beq(&feedback_register_initialized); | 2547 __ beq(&feedback_register_initialized); |
| 2561 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); | 2548 __ LoadRoot(r5, Heap::kUndefinedValueRootIndex); |
| 2562 __ bind(&feedback_register_initialized); | 2549 __ bind(&feedback_register_initialized); |
| 2563 } | |
| 2564 | |
| 2565 __ AssertUndefinedOrAllocationSite(r5, r8); | |
| 2566 } | 2550 } |
| 2567 | 2551 |
| 2552 __ AssertUndefinedOrAllocationSite(r5, r8); |
| 2553 |
| 2568 // Pass function as new target. | 2554 // Pass function as new target. |
| 2569 if (IsSuperConstructorCall()) { | 2555 __ mr(r6, r4); |
| 2570 __ mr(r6, r7); | |
| 2571 } else { | |
| 2572 __ mr(r6, r4); | |
| 2573 } | |
| 2574 | 2556 |
| 2575 // Tail call to the function-specific construct stub (still in the caller | 2557 // Tail call to the function-specific construct stub (still in the caller |
| 2576 // context at this point). | 2558 // context at this point). |
| 2577 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); | 2559 __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
| 2578 __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kConstructStubOffset)); | 2560 __ LoadP(r7, FieldMemOperand(r7, SharedFunctionInfo::kConstructStubOffset)); |
| 2579 __ addi(ip, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); | 2561 __ addi(ip, r7, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 2580 __ JumpToJSEntry(ip); | 2562 __ JumpToJSEntry(ip); |
| 2581 | 2563 |
| 2582 __ bind(&non_function); | 2564 __ bind(&non_function); |
| 2583 __ mr(r6, r4); | 2565 __ mr(r6, r4); |
| (...skipping 3078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5662 kStackUnwindSpace, NULL, | 5644 kStackUnwindSpace, NULL, |
| 5663 MemOperand(fp, 6 * kPointerSize), NULL); | 5645 MemOperand(fp, 6 * kPointerSize), NULL); |
| 5664 } | 5646 } |
| 5665 | 5647 |
| 5666 | 5648 |
| 5667 #undef __ | 5649 #undef __ |
| 5668 } // namespace internal | 5650 } // namespace internal |
| 5669 } // namespace v8 | 5651 } // namespace v8 |
| 5670 | 5652 |
| 5671 #endif // V8_TARGET_ARCH_PPC | 5653 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |