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_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 2521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2532 // (9) Sliced string. Replace subject with parent. Go to (4). | 2532 // (9) Sliced string. Replace subject with parent. Go to (4). |
2533 // Load offset into t0 and replace subject string with parent. | 2533 // Load offset into t0 and replace subject string with parent. |
2534 __ ld(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset)); | 2534 __ ld(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset)); |
2535 __ SmiUntag(t0); | 2535 __ SmiUntag(t0); |
2536 __ ld(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); | 2536 __ ld(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); |
2537 __ jmp(&check_underlying); // Go to (4). | 2537 __ jmp(&check_underlying); // Go to (4). |
2538 #endif // V8_INTERPRETED_REGEXP | 2538 #endif // V8_INTERPRETED_REGEXP |
2539 } | 2539 } |
2540 | 2540 |
2541 | 2541 |
| 2542 static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) { |
| 2543 // a0 : number of arguments to the construct function |
| 2544 // a2 : Feedback vector |
| 2545 // a3 : slot in feedback vector (Smi) |
| 2546 // a1 : the function to call |
| 2547 FrameScope scope(masm, StackFrame::INTERNAL); |
| 2548 const RegList kSavedRegs = 1 << 4 | // a0 |
| 2549 1 << 5 | // a1 |
| 2550 1 << 6 | // a2 |
| 2551 1 << 7; // a3 |
| 2552 |
| 2553 // Arguments register must be smi-tagged to call out. |
| 2554 __ SmiTag(a0); |
| 2555 __ MultiPush(kSavedRegs); |
| 2556 |
| 2557 __ CallStub(stub); |
| 2558 |
| 2559 __ MultiPop(kSavedRegs); |
| 2560 __ SmiUntag(a0); |
| 2561 } |
| 2562 |
| 2563 |
2542 static void GenerateRecordCallTarget(MacroAssembler* masm) { | 2564 static void GenerateRecordCallTarget(MacroAssembler* masm) { |
2543 // Cache the called function in a feedback vector slot. Cache states | 2565 // Cache the called function in a feedback vector slot. Cache states |
2544 // are uninitialized, monomorphic (indicated by a JSFunction), and | 2566 // are uninitialized, monomorphic (indicated by a JSFunction), and |
2545 // megamorphic. | 2567 // megamorphic. |
2546 // a0 : number of arguments to the construct function | 2568 // a0 : number of arguments to the construct function |
2547 // a1 : the function to call | 2569 // a1 : the function to call |
2548 // a2 : Feedback vector | 2570 // a2 : Feedback vector |
2549 // a3 : slot in feedback vector (Smi) | 2571 // a3 : slot in feedback vector (Smi) |
2550 Label initialize, done, miss, megamorphic, not_array_function; | 2572 Label initialize, done, miss, megamorphic, not_array_function; |
2551 | 2573 |
2552 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), | 2574 DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()), |
2553 masm->isolate()->heap()->megamorphic_symbol()); | 2575 masm->isolate()->heap()->megamorphic_symbol()); |
2554 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), | 2576 DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()), |
2555 masm->isolate()->heap()->uninitialized_symbol()); | 2577 masm->isolate()->heap()->uninitialized_symbol()); |
2556 | 2578 |
2557 // Load the cache state into a4. | 2579 // Load the cache state into a4. |
2558 __ dsrl(a4, a3, 32 - kPointerSizeLog2); | 2580 __ dsrl(a4, a3, 32 - kPointerSizeLog2); |
2559 __ Daddu(a4, a2, Operand(a4)); | 2581 __ Daddu(a4, a2, Operand(a4)); |
2560 __ ld(a4, FieldMemOperand(a4, FixedArray::kHeaderSize)); | 2582 __ ld(a4, FieldMemOperand(a4, FixedArray::kHeaderSize)); |
2561 | 2583 |
2562 // A monomorphic cache hit or an already megamorphic state: invoke the | 2584 // A monomorphic cache hit or an already megamorphic state: invoke the |
2563 // function without changing the state. | 2585 // function without changing the state. |
2564 __ Branch(&done, eq, a4, Operand(a1)); | 2586 Label check_allocation_site; |
| 2587 Register feedback_map = a5; |
| 2588 Register weak_value = t0; |
| 2589 __ ld(weak_value, FieldMemOperand(a4, WeakCell::kValueOffset)); |
| 2590 __ Branch(&done, eq, a1, Operand(weak_value)); |
| 2591 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
| 2592 __ Branch(&done, eq, a4, Operand(at)); |
| 2593 __ ld(feedback_map, FieldMemOperand(a4, 0)); |
| 2594 __ LoadRoot(at, Heap::kWeakCellMapRootIndex); |
| 2595 __ Branch(FLAG_pretenuring_call_new ? &miss : &check_allocation_site, ne, |
| 2596 feedback_map, Operand(at)); |
| 2597 |
| 2598 // If a1 is not equal to the weak cell value, and the weak cell value is |
| 2599 // cleared, we have a new chance to become monomorphic. |
| 2600 __ JumpIfSmi(weak_value, &initialize); |
| 2601 __ jmp(&megamorphic); |
2565 | 2602 |
2566 if (!FLAG_pretenuring_call_new) { | 2603 if (!FLAG_pretenuring_call_new) { |
| 2604 __ bind(&check_allocation_site); |
2567 // If we came here, we need to see if we are the array function. | 2605 // If we came here, we need to see if we are the array function. |
2568 // If we didn't have a matching function, and we didn't find the megamorph | 2606 // If we didn't have a matching function, and we didn't find the megamorph |
2569 // sentinel, then we have in the slot either some other function or an | 2607 // sentinel, then we have in the slot either some other function or an |
2570 // AllocationSite. Do a map check on the object in a3. | 2608 // AllocationSite. Do a map check on the object in a3. |
2571 __ ld(a5, FieldMemOperand(a4, 0)); | |
2572 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 2609 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
2573 __ Branch(&miss, ne, a5, Operand(at)); | 2610 __ Branch(&miss, ne, feedback_map, Operand(at)); |
2574 | 2611 |
2575 // Make sure the function is the Array() function | 2612 // Make sure the function is the Array() function |
2576 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); | 2613 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); |
2577 __ Branch(&megamorphic, ne, a1, Operand(a4)); | 2614 __ Branch(&megamorphic, ne, a1, Operand(a4)); |
2578 __ jmp(&done); | 2615 __ jmp(&done); |
2579 } | 2616 } |
2580 | 2617 |
2581 __ bind(&miss); | 2618 __ bind(&miss); |
2582 | 2619 |
2583 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 2620 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
2584 // megamorphic. | 2621 // megamorphic. |
2585 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); | 2622 __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex); |
2586 __ Branch(&initialize, eq, a4, Operand(at)); | 2623 __ Branch(&initialize, eq, a4, Operand(at)); |
2587 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 2624 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
2588 // write-barrier is needed. | 2625 // write-barrier is needed. |
2589 __ bind(&megamorphic); | 2626 __ bind(&megamorphic); |
2590 __ dsrl(a4, a3, 32- kPointerSizeLog2); | 2627 __ dsrl(a4, a3, 32 - kPointerSizeLog2); |
2591 __ Daddu(a4, a2, Operand(a4)); | 2628 __ Daddu(a4, a2, Operand(a4)); |
2592 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); | 2629 __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex); |
2593 __ sd(at, FieldMemOperand(a4, FixedArray::kHeaderSize)); | 2630 __ sd(at, FieldMemOperand(a4, FixedArray::kHeaderSize)); |
2594 __ jmp(&done); | 2631 __ jmp(&done); |
2595 | 2632 |
2596 // An uninitialized cache is patched with the function. | 2633 // An uninitialized cache is patched with the function. |
2597 __ bind(&initialize); | 2634 __ bind(&initialize); |
2598 if (!FLAG_pretenuring_call_new) { | 2635 if (!FLAG_pretenuring_call_new) { |
2599 // Make sure the function is the Array() function. | 2636 // Make sure the function is the Array() function. |
2600 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); | 2637 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4); |
2601 __ Branch(¬_array_function, ne, a1, Operand(a4)); | 2638 __ Branch(¬_array_function, ne, a1, Operand(a4)); |
2602 | 2639 |
2603 // The target function is the Array constructor, | 2640 // The target function is the Array constructor, |
2604 // Create an AllocationSite if we don't already have it, store it in the | 2641 // Create an AllocationSite if we don't already have it, store it in the |
2605 // slot. | 2642 // slot. |
2606 { | 2643 CreateAllocationSiteStub create_stub(masm->isolate()); |
2607 FrameScope scope(masm, StackFrame::INTERNAL); | 2644 CallStubInRecordCallTarget(masm, &create_stub); |
2608 const RegList kSavedRegs = | |
2609 1 << 4 | // a0 | |
2610 1 << 5 | // a1 | |
2611 1 << 6 | // a2 | |
2612 1 << 7; // a3 | |
2613 | |
2614 // Arguments register must be smi-tagged to call out. | |
2615 __ SmiTag(a0); | |
2616 __ MultiPush(kSavedRegs); | |
2617 | |
2618 CreateAllocationSiteStub create_stub(masm->isolate()); | |
2619 __ CallStub(&create_stub); | |
2620 | |
2621 __ MultiPop(kSavedRegs); | |
2622 __ SmiUntag(a0); | |
2623 } | |
2624 __ Branch(&done); | 2645 __ Branch(&done); |
2625 | 2646 |
2626 __ bind(¬_array_function); | 2647 __ bind(¬_array_function); |
2627 } | 2648 } |
2628 | 2649 |
2629 __ dsrl(a4, a3, 32 - kPointerSizeLog2); | 2650 CreateWeakCellStub create_stub(masm->isolate()); |
2630 __ Daddu(a4, a2, Operand(a4)); | 2651 CallStubInRecordCallTarget(masm, &create_stub); |
2631 __ Daddu(a4, a4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | |
2632 __ sd(a1, MemOperand(a4, 0)); | |
2633 | |
2634 __ Push(a4, a2, a1); | |
2635 __ RecordWrite(a2, a4, a1, kRAHasNotBeenSaved, kDontSaveFPRegs, | |
2636 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | |
2637 __ Pop(a4, a2, a1); | |
2638 | |
2639 __ bind(&done); | 2652 __ bind(&done); |
2640 } | 2653 } |
2641 | 2654 |
2642 | 2655 |
2643 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { | 2656 static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) { |
2644 __ ld(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 2657 __ ld(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
2645 | 2658 |
2646 // Do not transform the receiver for strict mode functions. | 2659 // Do not transform the receiver for strict mode functions. |
2647 int32_t strict_mode_function_mask = | 2660 int32_t strict_mode_function_mask = |
2648 1 << SharedFunctionInfo::kStrictModeBitWithinByte ; | 2661 1 << SharedFunctionInfo::kStrictModeBitWithinByte ; |
(...skipping 2894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5543 kStackUnwindSpace, kInvalidStackOffset, | 5556 kStackUnwindSpace, kInvalidStackOffset, |
5544 MemOperand(fp, 6 * kPointerSize), NULL); | 5557 MemOperand(fp, 6 * kPointerSize), NULL); |
5545 } | 5558 } |
5546 | 5559 |
5547 | 5560 |
5548 #undef __ | 5561 #undef __ |
5549 | 5562 |
5550 } } // namespace v8::internal | 5563 } } // namespace v8::internal |
5551 | 5564 |
5552 #endif // V8_TARGET_ARCH_MIPS64 | 5565 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |