Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: src/full-codegen/x64/full-codegen-x64.cc

Issue 2615033002: [fullcodegen] Remove dead hole check logic (Closed)
Patch Set: x87 Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/full-codegen/s390/full-codegen-s390.cc ('k') | src/full-codegen/x87/full-codegen-x87.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/ast/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/builtins/builtins-constructor.h" 9 #include "src/builtins/builtins-constructor.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex); 710 __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex);
711 __ Check(not_equal, kDeclarationInCatchContext); 711 __ Check(not_equal, kDeclarationInCatchContext);
712 } 712 }
713 } 713 }
714 714
715 715
716 void FullCodeGenerator::VisitVariableDeclaration( 716 void FullCodeGenerator::VisitVariableDeclaration(
717 VariableDeclaration* declaration) { 717 VariableDeclaration* declaration) {
718 VariableProxy* proxy = declaration->proxy(); 718 VariableProxy* proxy = declaration->proxy();
719 Variable* variable = proxy->var(); 719 Variable* variable = proxy->var();
720 DCHECK(!variable->binding_needs_init());
720 switch (variable->location()) { 721 switch (variable->location()) {
721 case VariableLocation::UNALLOCATED: { 722 case VariableLocation::UNALLOCATED: {
722 DCHECK(!variable->binding_needs_init());
723 globals_->Add(variable->name(), zone()); 723 globals_->Add(variable->name(), zone());
724 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); 724 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
725 DCHECK(!slot.IsInvalid()); 725 DCHECK(!slot.IsInvalid());
726 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 726 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
727 globals_->Add(isolate()->factory()->undefined_value(), zone()); 727 globals_->Add(isolate()->factory()->undefined_value(), zone());
728 break; 728 break;
729 } 729 }
730 case VariableLocation::PARAMETER: 730 case VariableLocation::PARAMETER:
731 case VariableLocation::LOCAL: 731 case VariableLocation::LOCAL:
732 if (variable->binding_needs_init()) {
733 Comment cmnt(masm_, "[ VariableDeclaration");
734 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
735 __ movp(StackOperand(variable), kScratchRegister);
736 }
737 break;
738
739 case VariableLocation::CONTEXT: 732 case VariableLocation::CONTEXT:
740 if (variable->binding_needs_init()) {
741 Comment cmnt(masm_, "[ VariableDeclaration");
742 EmitDebugCheckDeclarationContext(variable);
743 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
744 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister);
745 // No write barrier since the hole value is in old space.
746 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
747 }
748 break; 733 break;
749 734
750 case VariableLocation::LOOKUP: 735 case VariableLocation::LOOKUP:
751 case VariableLocation::MODULE: 736 case VariableLocation::MODULE:
752 UNREACHABLE(); 737 UNREACHABLE();
753 } 738 }
754 } 739 }
755 740
756 741
757 void FullCodeGenerator::VisitFunctionDeclaration( 742 void FullCodeGenerator::VisitFunctionDeclaration(
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1097 Operand(rsp, offset * kPointerSize)); 1082 Operand(rsp, offset * kPointerSize));
1098 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1083 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1099 } 1084 }
1100 1085
1101 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1086 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1102 TypeofMode typeof_mode) { 1087 TypeofMode typeof_mode) {
1103 // Record position before possible IC call. 1088 // Record position before possible IC call.
1104 SetExpressionPosition(proxy); 1089 SetExpressionPosition(proxy);
1105 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1090 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1106 Variable* var = proxy->var(); 1091 Variable* var = proxy->var();
1092 DCHECK(!var->binding_needs_init());
1107 1093
1108 // Two cases: global variable, and all other types of variables. 1094 // Two cases: global variable, and all other types of variables.
1109 switch (var->location()) { 1095 switch (var->location()) {
1110 case VariableLocation::UNALLOCATED: { 1096 case VariableLocation::UNALLOCATED: {
1111 Comment cmnt(masm_, "[ Global variable"); 1097 Comment cmnt(masm_, "[ Global variable");
1112 EmitGlobalVariableLoad(proxy, typeof_mode); 1098 EmitGlobalVariableLoad(proxy, typeof_mode);
1113 context()->Plug(rax); 1099 context()->Plug(rax);
1114 break; 1100 break;
1115 } 1101 }
1116 1102
1117 case VariableLocation::PARAMETER: 1103 case VariableLocation::PARAMETER:
1118 case VariableLocation::LOCAL: 1104 case VariableLocation::LOCAL:
1119 case VariableLocation::CONTEXT: { 1105 case VariableLocation::CONTEXT: {
1120 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); 1106 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1121 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" 1107 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot"
1122 : "[ Stack slot"); 1108 : "[ Stack slot");
1123 if (proxy->hole_check_mode() == HoleCheckMode::kRequired) {
1124 // Throw a reference error when using an uninitialized let/const
1125 // binding in harmony mode.
1126 DCHECK(IsLexicalVariableMode(var->mode()));
1127 Label done;
1128 GetVar(rax, var);
1129 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1130 __ j(not_equal, &done, Label::kNear);
1131 __ Push(var->name());
1132 __ CallRuntime(Runtime::kThrowReferenceError);
1133 __ bind(&done);
1134 context()->Plug(rax);
1135 break;
1136 }
1137 context()->Plug(var); 1109 context()->Plug(var);
1138 break; 1110 break;
1139 } 1111 }
1140 1112
1141 case VariableLocation::LOOKUP: 1113 case VariableLocation::LOOKUP:
1142 case VariableLocation::MODULE: 1114 case VariableLocation::MODULE:
1143 UNREACHABLE(); 1115 UNREACHABLE();
1144 } 1116 }
1145 } 1117 }
1146 1118
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 } else { 1410 } else {
1439 VisitForAccumulatorValue(expr->value()); 1411 VisitForAccumulatorValue(expr->value());
1440 } 1412 }
1441 1413
1442 SetExpressionPosition(expr); 1414 SetExpressionPosition(expr);
1443 1415
1444 // Store the value. 1416 // Store the value.
1445 switch (assign_type) { 1417 switch (assign_type) {
1446 case VARIABLE: { 1418 case VARIABLE: {
1447 VariableProxy* proxy = expr->target()->AsVariableProxy(); 1419 VariableProxy* proxy = expr->target()->AsVariableProxy();
1448 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), 1420 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot());
1449 proxy->hole_check_mode());
1450 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 1421 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1451 context()->Plug(rax); 1422 context()->Plug(rax);
1452 break; 1423 break;
1453 } 1424 }
1454 case NAMED_PROPERTY: 1425 case NAMED_PROPERTY:
1455 EmitNamedPropertyAssignment(expr); 1426 EmitNamedPropertyAssignment(expr);
1456 break; 1427 break;
1457 case KEYED_PROPERTY: 1428 case KEYED_PROPERTY:
1458 EmitKeyedPropertyAssignment(expr); 1429 EmitKeyedPropertyAssignment(expr);
1459 break; 1430 break;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1585 FeedbackVectorSlot slot) { 1556 FeedbackVectorSlot slot) {
1586 DCHECK(expr->IsValidReferenceExpressionOrThis()); 1557 DCHECK(expr->IsValidReferenceExpressionOrThis());
1587 1558
1588 Property* prop = expr->AsProperty(); 1559 Property* prop = expr->AsProperty();
1589 LhsKind assign_type = Property::GetAssignType(prop); 1560 LhsKind assign_type = Property::GetAssignType(prop);
1590 1561
1591 switch (assign_type) { 1562 switch (assign_type) {
1592 case VARIABLE: { 1563 case VARIABLE: {
1593 VariableProxy* proxy = expr->AsVariableProxy(); 1564 VariableProxy* proxy = expr->AsVariableProxy();
1594 EffectContext context(this); 1565 EffectContext context(this);
1595 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot, 1566 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot);
1596 proxy->hole_check_mode());
1597 break; 1567 break;
1598 } 1568 }
1599 case NAMED_PROPERTY: { 1569 case NAMED_PROPERTY: {
1600 PushOperand(rax); // Preserve value. 1570 PushOperand(rax); // Preserve value.
1601 VisitForAccumulatorValue(prop->obj()); 1571 VisitForAccumulatorValue(prop->obj());
1602 __ Move(StoreDescriptor::ReceiverRegister(), rax); 1572 __ Move(StoreDescriptor::ReceiverRegister(), rax);
1603 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. 1573 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
1604 CallStoreIC(slot, prop->key()->AsLiteral()->value()); 1574 CallStoreIC(slot, prop->key()->AsLiteral()->value());
1605 break; 1575 break;
1606 } 1576 }
(...skipping 20 matching lines...) Expand all
1627 Variable* var, MemOperand location) { 1597 Variable* var, MemOperand location) {
1628 __ movp(location, rax); 1598 __ movp(location, rax);
1629 if (var->IsContextSlot()) { 1599 if (var->IsContextSlot()) {
1630 __ movp(rdx, rax); 1600 __ movp(rdx, rax);
1631 __ RecordWriteContextSlot( 1601 __ RecordWriteContextSlot(
1632 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); 1602 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs);
1633 } 1603 }
1634 } 1604 }
1635 1605
1636 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, 1606 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
1637 FeedbackVectorSlot slot, 1607 FeedbackVectorSlot slot) {
1638 HoleCheckMode hole_check_mode) { 1608 DCHECK(!var->binding_needs_init());
1639 if (var->IsUnallocated()) { 1609 if (var->IsUnallocated()) {
1640 // Global var, const, or let. 1610 // Global var, const, or let.
1641 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); 1611 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister());
1642 CallStoreIC(slot, var->name()); 1612 CallStoreIC(slot, var->name());
1643 1613
1644 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) { 1614 } else if (var->mode() == CONST && op != Token::INIT) {
1645 DCHECK(!var->IsLookupSlot()); 1615 if (var->throw_on_const_assignment(language_mode())) {
1646 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1647 MemOperand location = VarOperand(var, rcx);
1648 // Perform an initialization check for lexically declared variables.
1649 if (hole_check_mode == HoleCheckMode::kRequired) {
1650 Label assign;
1651 __ movp(rdx, location);
1652 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1653 __ j(not_equal, &assign, Label::kNear);
1654 __ Push(var->name());
1655 __ CallRuntime(Runtime::kThrowReferenceError);
1656 __ bind(&assign);
1657 }
1658 if (var->mode() != CONST) {
1659 EmitStoreToStackLocalOrContextSlot(var, location);
1660 } else if (var->throw_on_const_assignment(language_mode())) {
1661 __ CallRuntime(Runtime::kThrowConstAssignError); 1616 __ CallRuntime(Runtime::kThrowConstAssignError);
1662 } 1617 }
1663
1664 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
1665 // Initializing assignment to const {this} needs a write barrier.
1666 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1667 Label uninitialized_this;
1668 MemOperand location = VarOperand(var, rcx);
1669 __ movp(rdx, location);
1670 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1671 __ j(equal, &uninitialized_this);
1672 __ Push(var->name());
1673 __ CallRuntime(Runtime::kThrowReferenceError);
1674 __ bind(&uninitialized_this);
1675 EmitStoreToStackLocalOrContextSlot(var, location);
1676
1677 } else { 1618 } else {
1678 DCHECK(var->mode() != CONST || op == Token::INIT); 1619 DCHECK(!var->is_this());
1679 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 1620 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1680 DCHECK(!var->IsLookupSlot()); 1621 DCHECK(!var->IsLookupSlot());
1681 // Assignment to var or initializing assignment to let/const in harmony
1682 // mode.
1683 MemOperand location = VarOperand(var, rcx); 1622 MemOperand location = VarOperand(var, rcx);
1684 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
1685 // Check for an uninitialized let binding.
1686 __ movp(rdx, location);
1687 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1688 __ Check(equal, kLetBindingReInitialization);
1689 }
1690 EmitStoreToStackLocalOrContextSlot(var, location); 1623 EmitStoreToStackLocalOrContextSlot(var, location);
1691 } 1624 }
1692 } 1625 }
1693 1626
1694 1627
1695 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1628 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1696 // Assignment to a property, using a named store IC. 1629 // Assignment to a property, using a named store IC.
1697 Property* prop = expr->target()->AsProperty(); 1630 Property* prop = expr->target()->AsProperty();
1698 DCHECK(prop != NULL); 1631 DCHECK(prop != NULL);
1699 DCHECK(prop->key()->IsLiteral()); 1632 DCHECK(prop->key()->IsLiteral());
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
2416 patch_site.EmitPatchInfo(); 2349 patch_site.EmitPatchInfo();
2417 __ bind(&done); 2350 __ bind(&done);
2418 2351
2419 // Store the value returned in rax. 2352 // Store the value returned in rax.
2420 switch (assign_type) { 2353 switch (assign_type) {
2421 case VARIABLE: { 2354 case VARIABLE: {
2422 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2355 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2423 if (expr->is_postfix()) { 2356 if (expr->is_postfix()) {
2424 // Perform the assignment as if via '='. 2357 // Perform the assignment as if via '='.
2425 { EffectContext context(this); 2358 { EffectContext context(this);
2426 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), 2359 EmitVariableAssignment(proxy->var(), Token::ASSIGN,
2427 proxy->hole_check_mode()); 2360 expr->CountSlot());
2428 PrepareForBailoutForId(expr->AssignmentId(), 2361 PrepareForBailoutForId(expr->AssignmentId(),
2429 BailoutState::TOS_REGISTER); 2362 BailoutState::TOS_REGISTER);
2430 context.Plug(rax); 2363 context.Plug(rax);
2431 } 2364 }
2432 // For all contexts except kEffect: We have the result on 2365 // For all contexts except kEffect: We have the result on
2433 // top of the stack. 2366 // top of the stack.
2434 if (!context()->IsEffect()) { 2367 if (!context()->IsEffect()) {
2435 context()->PlugTOS(); 2368 context()->PlugTOS();
2436 } 2369 }
2437 } else { 2370 } else {
2438 // Perform the assignment as if via '='. 2371 // Perform the assignment as if via '='.
2439 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(), 2372 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot());
2440 proxy->hole_check_mode());
2441 PrepareForBailoutForId(expr->AssignmentId(), 2373 PrepareForBailoutForId(expr->AssignmentId(),
2442 BailoutState::TOS_REGISTER); 2374 BailoutState::TOS_REGISTER);
2443 context()->Plug(rax); 2375 context()->Plug(rax);
2444 } 2376 }
2445 break; 2377 break;
2446 } 2378 }
2447 case NAMED_PROPERTY: { 2379 case NAMED_PROPERTY: {
2448 PopOperand(StoreDescriptor::ReceiverRegister()); 2380 PopOperand(StoreDescriptor::ReceiverRegister());
2449 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); 2381 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value());
2450 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 2382 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2776 DCHECK_EQ( 2708 DCHECK_EQ(
2777 isolate->builtins()->OnStackReplacement()->entry(), 2709 isolate->builtins()->OnStackReplacement()->entry(),
2778 Assembler::target_address_at(call_target_address, unoptimized_code)); 2710 Assembler::target_address_at(call_target_address, unoptimized_code));
2779 return ON_STACK_REPLACEMENT; 2711 return ON_STACK_REPLACEMENT;
2780 } 2712 }
2781 2713
2782 } // namespace internal 2714 } // namespace internal
2783 } // namespace v8 2715 } // namespace v8
2784 2716
2785 #endif // V8_TARGET_ARCH_X64 2717 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/full-codegen/s390/full-codegen-s390.cc ('k') | src/full-codegen/x87/full-codegen-x87.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698