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

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

Powered by Google App Engine
This is Rietveld 408576698