| 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 #if V8_TARGET_ARCH_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
| 6 | 6 |
| 7 // Note on Mips implementation: | 7 // Note on Mips implementation: |
| 8 // | 8 // |
| 9 // The result_register() for mips is the 'v0' register, which is defined | 9 // The result_register() for mips is the 'v0' register, which is defined |
| 10 // by the ABI to contain function return values. However, the first | 10 // by the ABI to contain function return values. However, the first |
| (...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2579 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2579 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2580 FeedbackVectorSlot slot) { | 2580 FeedbackVectorSlot slot) { |
| 2581 if (var->IsUnallocated()) { | 2581 if (var->IsUnallocated()) { |
| 2582 // Global var, const, or let. | 2582 // Global var, const, or let. |
| 2583 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2583 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 2584 __ li(StoreDescriptor::NameRegister(), Operand(var->name())); | 2584 __ li(StoreDescriptor::NameRegister(), Operand(var->name())); |
| 2585 __ ld(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2585 __ ld(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2586 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2586 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2587 CallStoreIC(); | 2587 CallStoreIC(); |
| 2588 | 2588 |
| 2589 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2589 } else if (var->mode() == LET && op != Token::INIT) { |
| 2590 // Non-initializing assignment to let variable needs a write barrier. | 2590 // Non-initializing assignment to let variable needs a write barrier. |
| 2591 DCHECK(!var->IsLookupSlot()); | 2591 DCHECK(!var->IsLookupSlot()); |
| 2592 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2592 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2593 Label assign; | 2593 Label assign; |
| 2594 MemOperand location = VarOperand(var, a1); | 2594 MemOperand location = VarOperand(var, a1); |
| 2595 __ ld(a3, location); | 2595 __ ld(a3, location); |
| 2596 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); | 2596 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); |
| 2597 __ Branch(&assign, ne, a3, Operand(a4)); | 2597 __ Branch(&assign, ne, a3, Operand(a4)); |
| 2598 __ li(a3, Operand(var->name())); | 2598 __ li(a3, Operand(var->name())); |
| 2599 __ push(a3); | 2599 __ push(a3); |
| 2600 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2600 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2601 // Perform the assignment. | 2601 // Perform the assignment. |
| 2602 __ bind(&assign); | 2602 __ bind(&assign); |
| 2603 EmitStoreToStackLocalOrContextSlot(var, location); | 2603 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2604 | 2604 |
| 2605 } else if (var->mode() == CONST && op != Token::INIT_CONST) { | 2605 } else if (var->mode() == CONST && op != Token::INIT) { |
| 2606 // Assignment to const variable needs a write barrier. | 2606 // Assignment to const variable needs a write barrier. |
| 2607 DCHECK(!var->IsLookupSlot()); | 2607 DCHECK(!var->IsLookupSlot()); |
| 2608 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2608 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2609 Label const_error; | 2609 Label const_error; |
| 2610 MemOperand location = VarOperand(var, a1); | 2610 MemOperand location = VarOperand(var, a1); |
| 2611 __ ld(a3, location); | 2611 __ ld(a3, location); |
| 2612 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2612 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 2613 __ Branch(&const_error, ne, a3, Operand(at)); | 2613 __ Branch(&const_error, ne, a3, Operand(at)); |
| 2614 __ li(a3, Operand(var->name())); | 2614 __ li(a3, Operand(var->name())); |
| 2615 __ push(a3); | 2615 __ push(a3); |
| 2616 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2616 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2617 __ bind(&const_error); | 2617 __ bind(&const_error); |
| 2618 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2618 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
| 2619 | 2619 |
| 2620 } else if (var->is_this() && op == Token::INIT_CONST) { | 2620 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { |
| 2621 // Initializing assignment to const {this} needs a write barrier. | 2621 // Initializing assignment to const {this} needs a write barrier. |
| 2622 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2622 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2623 Label uninitialized_this; | 2623 Label uninitialized_this; |
| 2624 MemOperand location = VarOperand(var, a1); | 2624 MemOperand location = VarOperand(var, a1); |
| 2625 __ ld(a3, location); | 2625 __ ld(a3, location); |
| 2626 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2626 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 2627 __ Branch(&uninitialized_this, eq, a3, Operand(at)); | 2627 __ Branch(&uninitialized_this, eq, a3, Operand(at)); |
| 2628 __ li(a0, Operand(var->name())); | 2628 __ li(a0, Operand(var->name())); |
| 2629 __ Push(a0); | 2629 __ Push(a0); |
| 2630 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2630 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2631 __ bind(&uninitialized_this); | 2631 __ bind(&uninitialized_this); |
| 2632 EmitStoreToStackLocalOrContextSlot(var, location); | 2632 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2633 | 2633 |
| 2634 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2634 } else if (!var->is_const_mode() || |
| 2635 (var->mode() == CONST && op == Token::INIT)) { |
| 2635 if (var->IsLookupSlot()) { | 2636 if (var->IsLookupSlot()) { |
| 2636 // Assignment to var. | 2637 // Assignment to var. |
| 2637 __ li(a4, Operand(var->name())); | 2638 __ li(a4, Operand(var->name())); |
| 2638 __ li(a3, Operand(Smi::FromInt(language_mode()))); | 2639 __ li(a3, Operand(Smi::FromInt(language_mode()))); |
| 2639 // jssp[0] : language mode. | 2640 // jssp[0] : language mode. |
| 2640 // jssp[8] : name. | 2641 // jssp[8] : name. |
| 2641 // jssp[16] : context. | 2642 // jssp[16] : context. |
| 2642 // jssp[24] : value. | 2643 // jssp[24] : value. |
| 2643 __ Push(v0, cp, a4, a3); | 2644 __ Push(v0, cp, a4, a3); |
| 2644 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2645 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
| 2645 } else { | 2646 } else { |
| 2646 // Assignment to var or initializing assignment to let/const in harmony | 2647 // Assignment to var or initializing assignment to let/const in harmony |
| 2647 // mode. | 2648 // mode. |
| 2648 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); | 2649 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); |
| 2649 MemOperand location = VarOperand(var, a1); | 2650 MemOperand location = VarOperand(var, a1); |
| 2650 if (generate_debug_code_ && op == Token::INIT_LET) { | 2651 if (generate_debug_code_ && var->mode() == LET && op == Token::INIT) { |
| 2651 // Check for an uninitialized let binding. | 2652 // Check for an uninitialized let binding. |
| 2652 __ ld(a2, location); | 2653 __ ld(a2, location); |
| 2653 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); | 2654 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); |
| 2654 __ Check(eq, kLetBindingReInitialization, a2, Operand(a4)); | 2655 __ Check(eq, kLetBindingReInitialization, a2, Operand(a4)); |
| 2655 } | 2656 } |
| 2656 EmitStoreToStackLocalOrContextSlot(var, location); | 2657 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2657 } | 2658 } |
| 2658 | 2659 |
| 2659 } else if (op == Token::INIT_CONST_LEGACY) { | 2660 } else if (var->mode() == CONST_LEGACY && op == Token::INIT) { |
| 2660 // Const initializers need a write barrier. | 2661 // Const initializers need a write barrier. |
| 2661 DCHECK(!var->IsParameter()); // No const parameters. | 2662 DCHECK(!var->IsParameter()); // No const parameters. |
| 2662 if (var->IsLookupSlot()) { | 2663 if (var->IsLookupSlot()) { |
| 2663 __ li(a0, Operand(var->name())); | 2664 __ li(a0, Operand(var->name())); |
| 2664 __ Push(v0, cp, a0); // Context and name. | 2665 __ Push(v0, cp, a0); // Context and name. |
| 2665 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); | 2666 __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3); |
| 2666 } else { | 2667 } else { |
| 2667 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2668 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2668 Label skip; | 2669 Label skip; |
| 2669 MemOperand location = VarOperand(var, a1); | 2670 MemOperand location = VarOperand(var, a1); |
| 2670 __ ld(a2, location); | 2671 __ ld(a2, location); |
| 2671 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2672 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 2672 __ Branch(&skip, ne, a2, Operand(at)); | 2673 __ Branch(&skip, ne, a2, Operand(at)); |
| 2673 EmitStoreToStackLocalOrContextSlot(var, location); | 2674 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2674 __ bind(&skip); | 2675 __ bind(&skip); |
| 2675 } | 2676 } |
| 2676 | 2677 |
| 2677 } else { | 2678 } else { |
| 2678 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT_CONST_LEGACY); | 2679 DCHECK(var->mode() == CONST_LEGACY && op != Token::INIT); |
| 2679 if (is_strict(language_mode())) { | 2680 if (is_strict(language_mode())) { |
| 2680 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2681 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
| 2681 } | 2682 } |
| 2682 // Silently ignore store in sloppy mode. | 2683 // Silently ignore store in sloppy mode. |
| 2683 } | 2684 } |
| 2684 } | 2685 } |
| 2685 | 2686 |
| 2686 | 2687 |
| 2687 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2688 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2688 // Assignment to a property, using a named store IC. | 2689 // Assignment to a property, using a named store IC. |
| (...skipping 2374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5063 reinterpret_cast<uint64_t>( | 5064 reinterpret_cast<uint64_t>( |
| 5064 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5065 isolate->builtins()->OsrAfterStackCheck()->entry())); |
| 5065 return OSR_AFTER_STACK_CHECK; | 5066 return OSR_AFTER_STACK_CHECK; |
| 5066 } | 5067 } |
| 5067 | 5068 |
| 5068 | 5069 |
| 5069 } // namespace internal | 5070 } // namespace internal |
| 5070 } // namespace v8 | 5071 } // namespace v8 |
| 5071 | 5072 |
| 5072 #endif // V8_TARGET_ARCH_MIPS64 | 5073 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |