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_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1447 __ jmp(done); | 1447 __ jmp(done); |
1448 } | 1448 } |
1449 } | 1449 } |
1450 | 1450 |
1451 | 1451 |
1452 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, | 1452 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, |
1453 TypeofState typeof_state) { | 1453 TypeofState typeof_state) { |
1454 Variable* var = proxy->var(); | 1454 Variable* var = proxy->var(); |
1455 DCHECK(var->IsUnallocatedOrGlobalSlot() || | 1455 DCHECK(var->IsUnallocatedOrGlobalSlot() || |
1456 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); | 1456 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); |
1457 __ Move(LoadDescriptor::NameRegister(), var->name()); | 1457 if (var->IsGlobalSlot()) { |
1458 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1458 DCHECK(var->index() > 0); |
1459 __ Move(LoadDescriptor::SlotRegister(), | 1459 DCHECK(var->IsStaticGlobalObjectProperty()); |
1460 SmiFromSlot(proxy->VariableFeedbackSlot())); | 1460 // Each var occupies two slots in the context: for reads and writes. |
1461 // Inside typeof use a regular load, not a contextual load, to avoid | 1461 int slot_index = var->index(); |
1462 // a reference error. | 1462 int depth = scope()->ContextChainLength(var->scope()); |
1463 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL); | 1463 __ Move(LoadGlobalViaContextDescriptor::DepthRegister(), |
| 1464 Smi::FromInt(depth)); |
| 1465 __ Move(LoadGlobalViaContextDescriptor::SlotRegister(), |
| 1466 Smi::FromInt(slot_index)); |
| 1467 __ Move(LoadGlobalViaContextDescriptor::NameRegister(), var->name()); |
| 1468 LoadGlobalViaContextStub stub(isolate(), depth); |
| 1469 __ CallStub(&stub); |
| 1470 |
| 1471 } else { |
| 1472 __ Move(LoadDescriptor::NameRegister(), var->name()); |
| 1473 __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 1474 __ Move(LoadDescriptor::SlotRegister(), |
| 1475 SmiFromSlot(proxy->VariableFeedbackSlot())); |
| 1476 // Inside typeof use a regular load, not a contextual load, to avoid |
| 1477 // a reference error. |
| 1478 CallLoadIC(typeof_state == NOT_INSIDE_TYPEOF ? CONTEXTUAL : NOT_CONTEXTUAL); |
| 1479 } |
1464 } | 1480 } |
1465 | 1481 |
1466 | 1482 |
1467 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, | 1483 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, |
1468 TypeofState typeof_state) { | 1484 TypeofState typeof_state) { |
1469 // Record position before possible IC call. | 1485 // Record position before possible IC call. |
1470 SetExpressionPosition(proxy); | 1486 SetExpressionPosition(proxy); |
1471 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1487 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
1472 Variable* var = proxy->var(); | 1488 Variable* var = proxy->var(); |
1473 | 1489 |
(...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2652 if (var->IsContextSlot()) { | 2668 if (var->IsContextSlot()) { |
2653 __ movp(rdx, rax); | 2669 __ movp(rdx, rax); |
2654 __ RecordWriteContextSlot( | 2670 __ RecordWriteContextSlot( |
2655 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); | 2671 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); |
2656 } | 2672 } |
2657 } | 2673 } |
2658 | 2674 |
2659 | 2675 |
2660 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, | 2676 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
2661 FeedbackVectorICSlot slot) { | 2677 FeedbackVectorICSlot slot) { |
2662 if (var->IsUnallocatedOrGlobalSlot()) { | 2678 if (var->IsUnallocated()) { |
2663 // Global var, const, or let. | 2679 // Global var, const, or let. |
2664 __ Move(StoreDescriptor::NameRegister(), var->name()); | 2680 __ Move(StoreDescriptor::NameRegister(), var->name()); |
2665 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2681 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
2666 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); | 2682 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
2667 CallStoreIC(); | 2683 CallStoreIC(); |
2668 | 2684 |
| 2685 } else if (var->IsGlobalSlot()) { |
| 2686 // Global var, const, or let. |
| 2687 DCHECK(var->index() > 0); |
| 2688 DCHECK(var->IsStaticGlobalObjectProperty()); |
| 2689 // Each var occupies two slots in the context: for reads and writes. |
| 2690 int slot_index = var->index() + 1; |
| 2691 int depth = scope()->ContextChainLength(var->scope()); |
| 2692 __ Move(StoreGlobalViaContextDescriptor::DepthRegister(), |
| 2693 Smi::FromInt(depth)); |
| 2694 __ Move(StoreGlobalViaContextDescriptor::SlotRegister(), |
| 2695 Smi::FromInt(slot_index)); |
| 2696 __ Move(StoreGlobalViaContextDescriptor::NameRegister(), var->name()); |
| 2697 DCHECK(StoreGlobalViaContextDescriptor::ValueRegister().is(rax)); |
| 2698 StoreGlobalViaContextStub stub(isolate(), depth, language_mode()); |
| 2699 __ CallStub(&stub); |
| 2700 |
2669 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2701 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2670 // Non-initializing assignment to let variable needs a write barrier. | 2702 // Non-initializing assignment to let variable needs a write barrier. |
2671 DCHECK(!var->IsLookupSlot()); | 2703 DCHECK(!var->IsLookupSlot()); |
2672 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2704 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2673 Label assign; | 2705 Label assign; |
2674 MemOperand location = VarOperand(var, rcx); | 2706 MemOperand location = VarOperand(var, rcx); |
2675 __ movp(rdx, location); | 2707 __ movp(rdx, location); |
2676 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); | 2708 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); |
2677 __ j(not_equal, &assign, Label::kNear); | 2709 __ j(not_equal, &assign, Label::kNear); |
2678 __ Push(var->name()); | 2710 __ Push(var->name()); |
(...skipping 2804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5483 Assembler::target_address_at(call_target_address, | 5515 Assembler::target_address_at(call_target_address, |
5484 unoptimized_code)); | 5516 unoptimized_code)); |
5485 return OSR_AFTER_STACK_CHECK; | 5517 return OSR_AFTER_STACK_CHECK; |
5486 } | 5518 } |
5487 | 5519 |
5488 | 5520 |
5489 } // namespace internal | 5521 } // namespace internal |
5490 } // namespace v8 | 5522 } // namespace v8 |
5491 | 5523 |
5492 #endif // V8_TARGET_ARCH_X64 | 5524 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |