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

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

Issue 2640793004: Revert remove dead hole check logic (Closed)
Patch Set: Revert "[crankshaft] Fix mips/mips64 build: remove unused variable" and "[crankshaft] Remove dead Variable hole-checking code" 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 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex); 708 __ CompareRoot(rbx, Heap::kCatchContextMapRootIndex);
709 __ Check(not_equal, kDeclarationInCatchContext); 709 __ Check(not_equal, kDeclarationInCatchContext);
710 } 710 }
711 } 711 }
712 712
713 713
714 void FullCodeGenerator::VisitVariableDeclaration( 714 void FullCodeGenerator::VisitVariableDeclaration(
715 VariableDeclaration* declaration) { 715 VariableDeclaration* declaration) {
716 VariableProxy* proxy = declaration->proxy(); 716 VariableProxy* proxy = declaration->proxy();
717 Variable* variable = proxy->var(); 717 Variable* variable = proxy->var();
718 DCHECK(!variable->binding_needs_init());
719 switch (variable->location()) { 718 switch (variable->location()) {
720 case VariableLocation::UNALLOCATED: { 719 case VariableLocation::UNALLOCATED: {
720 DCHECK(!variable->binding_needs_init());
721 globals_->Add(variable->name(), zone()); 721 globals_->Add(variable->name(), zone());
722 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); 722 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
723 DCHECK(!slot.IsInvalid()); 723 DCHECK(!slot.IsInvalid());
724 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 724 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
725 globals_->Add(isolate()->factory()->undefined_value(), zone()); 725 globals_->Add(isolate()->factory()->undefined_value(), zone());
726 break; 726 break;
727 } 727 }
728 case VariableLocation::PARAMETER: 728 case VariableLocation::PARAMETER:
729 case VariableLocation::LOCAL: 729 case VariableLocation::LOCAL:
730 if (variable->binding_needs_init()) {
731 Comment cmnt(masm_, "[ VariableDeclaration");
732 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
733 __ movp(StackOperand(variable), kScratchRegister);
734 }
735 break;
736
730 case VariableLocation::CONTEXT: 737 case VariableLocation::CONTEXT:
738 if (variable->binding_needs_init()) {
739 Comment cmnt(masm_, "[ VariableDeclaration");
740 EmitDebugCheckDeclarationContext(variable);
741 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
742 __ movp(ContextOperand(rsi, variable->index()), kScratchRegister);
743 // No write barrier since the hole value is in old space.
744 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
745 }
731 break; 746 break;
732 747
733 case VariableLocation::LOOKUP: 748 case VariableLocation::LOOKUP:
734 case VariableLocation::MODULE: 749 case VariableLocation::MODULE:
735 UNREACHABLE(); 750 UNREACHABLE();
736 } 751 }
737 } 752 }
738 753
739 754
740 void FullCodeGenerator::VisitFunctionDeclaration( 755 void FullCodeGenerator::VisitFunctionDeclaration(
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 Operand(rsp, offset * kPointerSize)); 1095 Operand(rsp, offset * kPointerSize));
1081 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1096 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1082 } 1097 }
1083 1098
1084 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1099 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1085 TypeofMode typeof_mode) { 1100 TypeofMode typeof_mode) {
1086 // Record position before possible IC call. 1101 // Record position before possible IC call.
1087 SetExpressionPosition(proxy); 1102 SetExpressionPosition(proxy);
1088 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1103 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1089 Variable* var = proxy->var(); 1104 Variable* var = proxy->var();
1090 DCHECK(!var->binding_needs_init());
1091 1105
1092 // Two cases: global variable, and all other types of variables. 1106 // Two cases: global variable, and all other types of variables.
1093 switch (var->location()) { 1107 switch (var->location()) {
1094 case VariableLocation::UNALLOCATED: { 1108 case VariableLocation::UNALLOCATED: {
1095 Comment cmnt(masm_, "[ Global variable"); 1109 Comment cmnt(masm_, "[ Global variable");
1096 EmitGlobalVariableLoad(proxy, typeof_mode); 1110 EmitGlobalVariableLoad(proxy, typeof_mode);
1097 context()->Plug(rax); 1111 context()->Plug(rax);
1098 break; 1112 break;
1099 } 1113 }
1100 1114
1101 case VariableLocation::PARAMETER: 1115 case VariableLocation::PARAMETER:
1102 case VariableLocation::LOCAL: 1116 case VariableLocation::LOCAL:
1103 case VariableLocation::CONTEXT: { 1117 case VariableLocation::CONTEXT: {
1104 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); 1118 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1105 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot" 1119 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context slot"
1106 : "[ Stack slot"); 1120 : "[ Stack slot");
1121 if (proxy->hole_check_mode() == HoleCheckMode::kRequired) {
1122 // Throw a reference error when using an uninitialized let/const
1123 // binding in harmony mode.
1124 DCHECK(IsLexicalVariableMode(var->mode()));
1125 Label done;
1126 GetVar(rax, var);
1127 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1128 __ j(not_equal, &done, Label::kNear);
1129 __ Push(var->name());
1130 __ CallRuntime(Runtime::kThrowReferenceError);
1131 __ bind(&done);
1132 context()->Plug(rax);
1133 break;
1134 }
1107 context()->Plug(var); 1135 context()->Plug(var);
1108 break; 1136 break;
1109 } 1137 }
1110 1138
1111 case VariableLocation::LOOKUP: 1139 case VariableLocation::LOOKUP:
1112 case VariableLocation::MODULE: 1140 case VariableLocation::MODULE:
1113 UNREACHABLE(); 1141 UNREACHABLE();
1114 } 1142 }
1115 } 1143 }
1116 1144
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 } else { 1439 } else {
1412 VisitForAccumulatorValue(expr->value()); 1440 VisitForAccumulatorValue(expr->value());
1413 } 1441 }
1414 1442
1415 SetExpressionPosition(expr); 1443 SetExpressionPosition(expr);
1416 1444
1417 // Store the value. 1445 // Store the value.
1418 switch (assign_type) { 1446 switch (assign_type) {
1419 case VARIABLE: { 1447 case VARIABLE: {
1420 VariableProxy* proxy = expr->target()->AsVariableProxy(); 1448 VariableProxy* proxy = expr->target()->AsVariableProxy();
1421 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot()); 1449 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(),
1450 proxy->hole_check_mode());
1422 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 1451 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1423 context()->Plug(rax); 1452 context()->Plug(rax);
1424 break; 1453 break;
1425 } 1454 }
1426 case NAMED_PROPERTY: 1455 case NAMED_PROPERTY:
1427 EmitNamedPropertyAssignment(expr); 1456 EmitNamedPropertyAssignment(expr);
1428 break; 1457 break;
1429 case KEYED_PROPERTY: 1458 case KEYED_PROPERTY:
1430 EmitKeyedPropertyAssignment(expr); 1459 EmitKeyedPropertyAssignment(expr);
1431 break; 1460 break;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 FeedbackVectorSlot slot) { 1586 FeedbackVectorSlot slot) {
1558 DCHECK(expr->IsValidReferenceExpressionOrThis()); 1587 DCHECK(expr->IsValidReferenceExpressionOrThis());
1559 1588
1560 Property* prop = expr->AsProperty(); 1589 Property* prop = expr->AsProperty();
1561 LhsKind assign_type = Property::GetAssignType(prop); 1590 LhsKind assign_type = Property::GetAssignType(prop);
1562 1591
1563 switch (assign_type) { 1592 switch (assign_type) {
1564 case VARIABLE: { 1593 case VARIABLE: {
1565 VariableProxy* proxy = expr->AsVariableProxy(); 1594 VariableProxy* proxy = expr->AsVariableProxy();
1566 EffectContext context(this); 1595 EffectContext context(this);
1567 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot); 1596 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot,
1597 proxy->hole_check_mode());
1568 break; 1598 break;
1569 } 1599 }
1570 case NAMED_PROPERTY: { 1600 case NAMED_PROPERTY: {
1571 PushOperand(rax); // Preserve value. 1601 PushOperand(rax); // Preserve value.
1572 VisitForAccumulatorValue(prop->obj()); 1602 VisitForAccumulatorValue(prop->obj());
1573 __ Move(StoreDescriptor::ReceiverRegister(), rax); 1603 __ Move(StoreDescriptor::ReceiverRegister(), rax);
1574 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. 1604 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
1575 CallStoreIC(slot, prop->key()->AsLiteral()->value()); 1605 CallStoreIC(slot, prop->key()->AsLiteral()->value());
1576 break; 1606 break;
1577 } 1607 }
(...skipping 20 matching lines...) Expand all
1598 Variable* var, MemOperand location) { 1628 Variable* var, MemOperand location) {
1599 __ movp(location, rax); 1629 __ movp(location, rax);
1600 if (var->IsContextSlot()) { 1630 if (var->IsContextSlot()) {
1601 __ movp(rdx, rax); 1631 __ movp(rdx, rax);
1602 __ RecordWriteContextSlot( 1632 __ RecordWriteContextSlot(
1603 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); 1633 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs);
1604 } 1634 }
1605 } 1635 }
1606 1636
1607 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, 1637 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
1608 FeedbackVectorSlot slot) { 1638 FeedbackVectorSlot slot,
1609 DCHECK(!var->binding_needs_init()); 1639 HoleCheckMode hole_check_mode) {
1610 if (var->IsUnallocated()) { 1640 if (var->IsUnallocated()) {
1611 // Global var, const, or let. 1641 // Global var, const, or let.
1612 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); 1642 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister());
1613 CallStoreIC(slot, var->name()); 1643 CallStoreIC(slot, var->name());
1614 1644
1615 } else if (var->mode() == CONST && op != Token::INIT) { 1645 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) {
1616 if (var->throw_on_const_assignment(language_mode())) { 1646 DCHECK(!var->IsLookupSlot());
1647 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1648 MemOperand location = VarOperand(var, rcx);
1649 // Perform an initialization check for lexically declared variables.
1650 if (hole_check_mode == HoleCheckMode::kRequired) {
1651 Label assign;
1652 __ movp(rdx, location);
1653 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1654 __ j(not_equal, &assign, Label::kNear);
1655 __ Push(var->name());
1656 __ CallRuntime(Runtime::kThrowReferenceError);
1657 __ bind(&assign);
1658 }
1659 if (var->mode() != CONST) {
1660 EmitStoreToStackLocalOrContextSlot(var, location);
1661 } else if (var->throw_on_const_assignment(language_mode())) {
1617 __ CallRuntime(Runtime::kThrowConstAssignError); 1662 __ CallRuntime(Runtime::kThrowConstAssignError);
1618 } 1663 }
1664
1665 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
1666 // Initializing assignment to const {this} needs a write barrier.
1667 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1668 Label uninitialized_this;
1669 MemOperand location = VarOperand(var, rcx);
1670 __ movp(rdx, location);
1671 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1672 __ j(equal, &uninitialized_this);
1673 __ Push(var->name());
1674 __ CallRuntime(Runtime::kThrowReferenceError);
1675 __ bind(&uninitialized_this);
1676 EmitStoreToStackLocalOrContextSlot(var, location);
1677
1619 } else { 1678 } else {
1620 DCHECK(!var->is_this()); 1679 DCHECK(var->mode() != CONST || op == Token::INIT);
1621 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 1680 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1622 DCHECK(!var->IsLookupSlot()); 1681 DCHECK(!var->IsLookupSlot());
1682 // Assignment to var or initializing assignment to let/const in harmony
1683 // mode.
1623 MemOperand location = VarOperand(var, rcx); 1684 MemOperand location = VarOperand(var, rcx);
1685 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
1686 // Check for an uninitialized let binding.
1687 __ movp(rdx, location);
1688 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex);
1689 __ Check(equal, kLetBindingReInitialization);
1690 }
1624 EmitStoreToStackLocalOrContextSlot(var, location); 1691 EmitStoreToStackLocalOrContextSlot(var, location);
1625 } 1692 }
1626 } 1693 }
1627 1694
1628 1695
1629 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1696 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1630 // Assignment to a property, using a named store IC. 1697 // Assignment to a property, using a named store IC.
1631 Property* prop = expr->target()->AsProperty(); 1698 Property* prop = expr->target()->AsProperty();
1632 DCHECK(prop != NULL); 1699 DCHECK(prop != NULL);
1633 DCHECK(prop->key()->IsLiteral()); 1700 DCHECK(prop->key()->IsLiteral());
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 patch_site.EmitPatchInfo(); 2395 patch_site.EmitPatchInfo();
2329 __ bind(&done); 2396 __ bind(&done);
2330 2397
2331 // Store the value returned in rax. 2398 // Store the value returned in rax.
2332 switch (assign_type) { 2399 switch (assign_type) {
2333 case VARIABLE: { 2400 case VARIABLE: {
2334 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2401 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2335 if (expr->is_postfix()) { 2402 if (expr->is_postfix()) {
2336 // Perform the assignment as if via '='. 2403 // Perform the assignment as if via '='.
2337 { EffectContext context(this); 2404 { EffectContext context(this);
2338 EmitVariableAssignment(proxy->var(), Token::ASSIGN, 2405 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(),
2339 expr->CountSlot()); 2406 proxy->hole_check_mode());
2340 PrepareForBailoutForId(expr->AssignmentId(), 2407 PrepareForBailoutForId(expr->AssignmentId(),
2341 BailoutState::TOS_REGISTER); 2408 BailoutState::TOS_REGISTER);
2342 context.Plug(rax); 2409 context.Plug(rax);
2343 } 2410 }
2344 // For all contexts except kEffect: We have the result on 2411 // For all contexts except kEffect: We have the result on
2345 // top of the stack. 2412 // top of the stack.
2346 if (!context()->IsEffect()) { 2413 if (!context()->IsEffect()) {
2347 context()->PlugTOS(); 2414 context()->PlugTOS();
2348 } 2415 }
2349 } else { 2416 } else {
2350 // Perform the assignment as if via '='. 2417 // Perform the assignment as if via '='.
2351 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot()); 2418 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(),
2419 proxy->hole_check_mode());
2352 PrepareForBailoutForId(expr->AssignmentId(), 2420 PrepareForBailoutForId(expr->AssignmentId(),
2353 BailoutState::TOS_REGISTER); 2421 BailoutState::TOS_REGISTER);
2354 context()->Plug(rax); 2422 context()->Plug(rax);
2355 } 2423 }
2356 break; 2424 break;
2357 } 2425 }
2358 case NAMED_PROPERTY: { 2426 case NAMED_PROPERTY: {
2359 PopOperand(StoreDescriptor::ReceiverRegister()); 2427 PopOperand(StoreDescriptor::ReceiverRegister());
2360 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); 2428 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value());
2361 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 2429 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 DCHECK_EQ( 2755 DCHECK_EQ(
2688 isolate->builtins()->OnStackReplacement()->entry(), 2756 isolate->builtins()->OnStackReplacement()->entry(),
2689 Assembler::target_address_at(call_target_address, unoptimized_code)); 2757 Assembler::target_address_at(call_target_address, unoptimized_code));
2690 return ON_STACK_REPLACEMENT; 2758 return ON_STACK_REPLACEMENT;
2691 } 2759 }
2692 2760
2693 } // namespace internal 2761 } // namespace internal
2694 } // namespace v8 2762 } // namespace v8
2695 2763
2696 #endif // V8_TARGET_ARCH_X64 2764 #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