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

Side by Side Diff: src/full-codegen/mips/full-codegen-mips.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
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_MIPS 5 #if V8_TARGET_ARCH_MIPS
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 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 __ Check(ne, kDeclarationInCatchContext, 745 __ Check(ne, kDeclarationInCatchContext,
746 a1, Operand(t0)); 746 a1, Operand(t0));
747 } 747 }
748 } 748 }
749 749
750 750
751 void FullCodeGenerator::VisitVariableDeclaration( 751 void FullCodeGenerator::VisitVariableDeclaration(
752 VariableDeclaration* declaration) { 752 VariableDeclaration* declaration) {
753 VariableProxy* proxy = declaration->proxy(); 753 VariableProxy* proxy = declaration->proxy();
754 Variable* variable = proxy->var(); 754 Variable* variable = proxy->var();
755 DCHECK(!variable->binding_needs_init());
756 switch (variable->location()) { 755 switch (variable->location()) {
757 case VariableLocation::UNALLOCATED: { 756 case VariableLocation::UNALLOCATED: {
757 DCHECK(!variable->binding_needs_init());
758 globals_->Add(variable->name(), zone()); 758 globals_->Add(variable->name(), zone());
759 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); 759 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
760 DCHECK(!slot.IsInvalid()); 760 DCHECK(!slot.IsInvalid());
761 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 761 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
762 globals_->Add(isolate()->factory()->undefined_value(), zone()); 762 globals_->Add(isolate()->factory()->undefined_value(), zone());
763 break; 763 break;
764 } 764 }
765 case VariableLocation::PARAMETER: 765 case VariableLocation::PARAMETER:
766 case VariableLocation::LOCAL: 766 case VariableLocation::LOCAL:
767 if (variable->binding_needs_init()) {
768 Comment cmnt(masm_, "[ VariableDeclaration");
769 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
770 __ sw(t0, StackOperand(variable));
771 }
772 break;
773
767 case VariableLocation::CONTEXT: 774 case VariableLocation::CONTEXT:
775 if (variable->binding_needs_init()) {
776 Comment cmnt(masm_, "[ VariableDeclaration");
777 EmitDebugCheckDeclarationContext(variable);
778 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
779 __ sw(at, ContextMemOperand(cp, variable->index()));
780 // No write barrier since the_hole_value is in old space.
781 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
782 }
768 break; 783 break;
769 784
770 case VariableLocation::LOOKUP: 785 case VariableLocation::LOOKUP:
771 case VariableLocation::MODULE: 786 case VariableLocation::MODULE:
772 UNREACHABLE(); 787 UNREACHABLE();
773 } 788 }
774 } 789 }
775 790
776 791
777 void FullCodeGenerator::VisitFunctionDeclaration( 792 void FullCodeGenerator::VisitFunctionDeclaration(
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 MemOperand(sp, offset * kPointerSize)); 1137 MemOperand(sp, offset * kPointerSize));
1123 CallStoreIC(slot, isolate()->factory()->home_object_symbol()); 1138 CallStoreIC(slot, isolate()->factory()->home_object_symbol());
1124 } 1139 }
1125 1140
1126 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy, 1141 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy,
1127 TypeofMode typeof_mode) { 1142 TypeofMode typeof_mode) {
1128 // Record position before possible IC call. 1143 // Record position before possible IC call.
1129 SetExpressionPosition(proxy); 1144 SetExpressionPosition(proxy);
1130 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS); 1145 PrepareForBailoutForId(proxy->BeforeId(), BailoutState::NO_REGISTERS);
1131 Variable* var = proxy->var(); 1146 Variable* var = proxy->var();
1132 DCHECK(!var->binding_needs_init());
1133 1147
1134 // Two cases: global variables and all other types of variables. 1148 // Two cases: global variables and all other types of variables.
1135 switch (var->location()) { 1149 switch (var->location()) {
1136 case VariableLocation::UNALLOCATED: { 1150 case VariableLocation::UNALLOCATED: {
1137 Comment cmnt(masm_, "[ Global variable"); 1151 Comment cmnt(masm_, "[ Global variable");
1138 EmitGlobalVariableLoad(proxy, typeof_mode); 1152 EmitGlobalVariableLoad(proxy, typeof_mode);
1139 context()->Plug(v0); 1153 context()->Plug(v0);
1140 break; 1154 break;
1141 } 1155 }
1142 1156
1143 case VariableLocation::PARAMETER: 1157 case VariableLocation::PARAMETER:
1144 case VariableLocation::LOCAL: 1158 case VariableLocation::LOCAL:
1145 case VariableLocation::CONTEXT: { 1159 case VariableLocation::CONTEXT: {
1146 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); 1160 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1147 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1161 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1148 : "[ Stack variable"); 1162 : "[ Stack variable");
1163 if (proxy->hole_check_mode() == HoleCheckMode::kRequired) {
1164 // Throw a reference error when using an uninitialized let/const
1165 // binding in harmony mode.
1166 Label done;
1167 GetVar(v0, var);
1168 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1169 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1170 __ Branch(&done, ne, at, Operand(zero_reg));
1171 __ li(a0, Operand(var->name()));
1172 __ push(a0);
1173 __ CallRuntime(Runtime::kThrowReferenceError);
1174 __ bind(&done);
1175 context()->Plug(v0);
1176 break;
1177 }
1149 context()->Plug(var); 1178 context()->Plug(var);
1150 break; 1179 break;
1151 } 1180 }
1152 1181
1153 case VariableLocation::LOOKUP: 1182 case VariableLocation::LOOKUP:
1154 case VariableLocation::MODULE: 1183 case VariableLocation::MODULE:
1155 UNREACHABLE(); 1184 UNREACHABLE();
1156 } 1185 }
1157 } 1186 }
1158 1187
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 } else { 1489 } else {
1461 VisitForAccumulatorValue(expr->value()); 1490 VisitForAccumulatorValue(expr->value());
1462 } 1491 }
1463 1492
1464 SetExpressionPosition(expr); 1493 SetExpressionPosition(expr);
1465 1494
1466 // Store the value. 1495 // Store the value.
1467 switch (assign_type) { 1496 switch (assign_type) {
1468 case VARIABLE: { 1497 case VARIABLE: {
1469 VariableProxy* proxy = expr->target()->AsVariableProxy(); 1498 VariableProxy* proxy = expr->target()->AsVariableProxy();
1470 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot()); 1499 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(),
1500 proxy->hole_check_mode());
1471 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); 1501 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER);
1472 context()->Plug(v0); 1502 context()->Plug(v0);
1473 break; 1503 break;
1474 } 1504 }
1475 case NAMED_PROPERTY: 1505 case NAMED_PROPERTY:
1476 EmitNamedPropertyAssignment(expr); 1506 EmitNamedPropertyAssignment(expr);
1477 break; 1507 break;
1478 case KEYED_PROPERTY: 1508 case KEYED_PROPERTY:
1479 EmitKeyedPropertyAssignment(expr); 1509 EmitKeyedPropertyAssignment(expr);
1480 break; 1510 break;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 FeedbackVectorSlot slot) { 1682 FeedbackVectorSlot slot) {
1653 DCHECK(expr->IsValidReferenceExpressionOrThis()); 1683 DCHECK(expr->IsValidReferenceExpressionOrThis());
1654 1684
1655 Property* prop = expr->AsProperty(); 1685 Property* prop = expr->AsProperty();
1656 LhsKind assign_type = Property::GetAssignType(prop); 1686 LhsKind assign_type = Property::GetAssignType(prop);
1657 1687
1658 switch (assign_type) { 1688 switch (assign_type) {
1659 case VARIABLE: { 1689 case VARIABLE: {
1660 VariableProxy* proxy = expr->AsVariableProxy(); 1690 VariableProxy* proxy = expr->AsVariableProxy();
1661 EffectContext context(this); 1691 EffectContext context(this);
1662 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot); 1692 EmitVariableAssignment(proxy->var(), Token::ASSIGN, slot,
1693 proxy->hole_check_mode());
1663 break; 1694 break;
1664 } 1695 }
1665 case NAMED_PROPERTY: { 1696 case NAMED_PROPERTY: {
1666 PushOperand(result_register()); // Preserve value. 1697 PushOperand(result_register()); // Preserve value.
1667 VisitForAccumulatorValue(prop->obj()); 1698 VisitForAccumulatorValue(prop->obj());
1668 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); 1699 __ mov(StoreDescriptor::ReceiverRegister(), result_register());
1669 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. 1700 PopOperand(StoreDescriptor::ValueRegister()); // Restore value.
1670 CallStoreIC(slot, prop->key()->AsLiteral()->value()); 1701 CallStoreIC(slot, prop->key()->AsLiteral()->value());
1671 break; 1702 break;
1672 } 1703 }
(...skipping 22 matching lines...) Expand all
1695 if (var->IsContextSlot()) { 1726 if (var->IsContextSlot()) {
1696 // RecordWrite may destroy all its register arguments. 1727 // RecordWrite may destroy all its register arguments.
1697 __ Move(a3, result_register()); 1728 __ Move(a3, result_register());
1698 int offset = Context::SlotOffset(var->index()); 1729 int offset = Context::SlotOffset(var->index());
1699 __ RecordWriteContextSlot( 1730 __ RecordWriteContextSlot(
1700 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); 1731 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
1701 } 1732 }
1702 } 1733 }
1703 1734
1704 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, 1735 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
1705 FeedbackVectorSlot slot) { 1736 FeedbackVectorSlot slot,
1706 DCHECK(!var->binding_needs_init()); 1737 HoleCheckMode hole_check_mode) {
1707 if (var->IsUnallocated()) { 1738 if (var->IsUnallocated()) {
1708 // Global var, const, or let. 1739 // Global var, const, or let.
1709 __ mov(StoreDescriptor::ValueRegister(), result_register()); 1740 __ mov(StoreDescriptor::ValueRegister(), result_register());
1710 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); 1741 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister());
1711 CallStoreIC(slot, var->name()); 1742 CallStoreIC(slot, var->name());
1712 1743
1713 } else if (var->mode() == CONST && op != Token::INIT) { 1744 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) {
1714 if (var->throw_on_const_assignment(language_mode())) { 1745 DCHECK(!var->IsLookupSlot());
1746 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1747 MemOperand location = VarOperand(var, a1);
1748 // Perform an initialization check for lexically declared variables.
1749 if (hole_check_mode == HoleCheckMode::kRequired) {
1750 Label assign;
1751 __ lw(a3, location);
1752 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
1753 __ Branch(&assign, ne, a3, Operand(t0));
1754 __ li(a3, Operand(var->name()));
1755 __ push(a3);
1756 __ CallRuntime(Runtime::kThrowReferenceError);
1757 __ bind(&assign);
1758 }
1759 if (var->mode() != CONST) {
1760 EmitStoreToStackLocalOrContextSlot(var, location);
1761 } else if (var->throw_on_const_assignment(language_mode())) {
1715 __ CallRuntime(Runtime::kThrowConstAssignError); 1762 __ CallRuntime(Runtime::kThrowConstAssignError);
1716 } 1763 }
1764 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
1765 // Initializing assignment to const {this} needs a write barrier.
1766 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
1767 Label uninitialized_this;
1768 MemOperand location = VarOperand(var, a1);
1769 __ lw(a3, location);
1770 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1771 __ Branch(&uninitialized_this, eq, a3, Operand(at));
1772 __ li(a0, Operand(var->name()));
1773 __ Push(a0);
1774 __ CallRuntime(Runtime::kThrowReferenceError);
1775 __ bind(&uninitialized_this);
1776 EmitStoreToStackLocalOrContextSlot(var, location);
1777
1717 } else { 1778 } else {
1718 DCHECK(!var->is_this()); 1779 DCHECK(var->mode() != CONST || op == Token::INIT);
1719 DCHECK((var->IsStackAllocated() || var->IsContextSlot())); 1780 DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
1720 DCHECK(!var->IsLookupSlot()); 1781 DCHECK(!var->IsLookupSlot());
1782 // Assignment to var or initializing assignment to let/const in harmony
1783 // mode.
1721 MemOperand location = VarOperand(var, a1); 1784 MemOperand location = VarOperand(var, a1);
1785 if (FLAG_debug_code && var->mode() == LET && op == Token::INIT) {
1786 // Check for an uninitialized let binding.
1787 __ lw(a2, location);
1788 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
1789 __ Check(eq, kLetBindingReInitialization, a2, Operand(t0));
1790 }
1722 EmitStoreToStackLocalOrContextSlot(var, location); 1791 EmitStoreToStackLocalOrContextSlot(var, location);
1723 } 1792 }
1724 } 1793 }
1725 1794
1726 1795
1727 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { 1796 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
1728 // Assignment to a property, using a named store IC. 1797 // Assignment to a property, using a named store IC.
1729 Property* prop = expr->target()->AsProperty(); 1798 Property* prop = expr->target()->AsProperty();
1730 DCHECK(prop != NULL); 1799 DCHECK(prop != NULL);
1731 DCHECK(prop->key()->IsLiteral()); 1800 DCHECK(prop->key()->IsLiteral());
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
2431 CallIC(code, expr->CountBinOpFeedbackId()); 2500 CallIC(code, expr->CountBinOpFeedbackId());
2432 patch_site.EmitPatchInfo(); 2501 patch_site.EmitPatchInfo();
2433 __ bind(&done); 2502 __ bind(&done);
2434 2503
2435 // Store the value returned in v0. 2504 // Store the value returned in v0.
2436 switch (assign_type) { 2505 switch (assign_type) {
2437 case VARIABLE: { 2506 case VARIABLE: {
2438 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 2507 VariableProxy* proxy = expr->expression()->AsVariableProxy();
2439 if (expr->is_postfix()) { 2508 if (expr->is_postfix()) {
2440 { EffectContext context(this); 2509 { EffectContext context(this);
2441 EmitVariableAssignment(proxy->var(), Token::ASSIGN, 2510 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(),
2442 expr->CountSlot()); 2511 proxy->hole_check_mode());
2443 PrepareForBailoutForId(expr->AssignmentId(), 2512 PrepareForBailoutForId(expr->AssignmentId(),
2444 BailoutState::TOS_REGISTER); 2513 BailoutState::TOS_REGISTER);
2445 context.Plug(v0); 2514 context.Plug(v0);
2446 } 2515 }
2447 // For all contexts except EffectConstant we have the result on 2516 // For all contexts except EffectConstant we have the result on
2448 // top of the stack. 2517 // top of the stack.
2449 if (!context()->IsEffect()) { 2518 if (!context()->IsEffect()) {
2450 context()->PlugTOS(); 2519 context()->PlugTOS();
2451 } 2520 }
2452 } else { 2521 } else {
2453 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot()); 2522 EmitVariableAssignment(proxy->var(), Token::ASSIGN, expr->CountSlot(),
2523 proxy->hole_check_mode());
2454 PrepareForBailoutForId(expr->AssignmentId(), 2524 PrepareForBailoutForId(expr->AssignmentId(),
2455 BailoutState::TOS_REGISTER); 2525 BailoutState::TOS_REGISTER);
2456 context()->Plug(v0); 2526 context()->Plug(v0);
2457 } 2527 }
2458 break; 2528 break;
2459 } 2529 }
2460 case NAMED_PROPERTY: { 2530 case NAMED_PROPERTY: {
2461 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2531 __ mov(StoreDescriptor::ValueRegister(), result_register());
2462 PopOperand(StoreDescriptor::ReceiverRegister()); 2532 PopOperand(StoreDescriptor::ReceiverRegister());
2463 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value()); 2533 CallStoreIC(expr->CountSlot(), prop->key()->AsLiteral()->value());
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
2792 reinterpret_cast<uint32_t>( 2862 reinterpret_cast<uint32_t>(
2793 isolate->builtins()->OnStackReplacement()->entry())); 2863 isolate->builtins()->OnStackReplacement()->entry()));
2794 return ON_STACK_REPLACEMENT; 2864 return ON_STACK_REPLACEMENT;
2795 } 2865 }
2796 2866
2797 2867
2798 } // namespace internal 2868 } // namespace internal
2799 } // namespace v8 2869 } // namespace v8
2800 2870
2801 #endif // V8_TARGET_ARCH_MIPS 2871 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/full-codegen/ia32/full-codegen-ia32.cc ('k') | src/full-codegen/mips64/full-codegen-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698