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

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

Issue 2201193004: Use Variable::binding_needs_init() to determine hole initialization (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove one more comment Created 4 years, 4 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/x64/full-codegen-x64.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 736 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 a1, Operand(a4)); 747 a1, Operand(a4));
748 __ LoadRoot(a4, Heap::kCatchContextMapRootIndex); 748 __ LoadRoot(a4, Heap::kCatchContextMapRootIndex);
749 __ Check(ne, kDeclarationInCatchContext, 749 __ Check(ne, kDeclarationInCatchContext,
750 a1, Operand(a4)); 750 a1, Operand(a4));
751 } 751 }
752 } 752 }
753 753
754 754
755 void FullCodeGenerator::VisitVariableDeclaration( 755 void FullCodeGenerator::VisitVariableDeclaration(
756 VariableDeclaration* declaration) { 756 VariableDeclaration* declaration) {
757 // If it was not possible to allocate the variable at compile time, we
758 // need to "declare" it at runtime to make sure it actually exists in the
759 // local context.
760 VariableProxy* proxy = declaration->proxy(); 757 VariableProxy* proxy = declaration->proxy();
761 VariableMode mode = declaration->mode();
762 Variable* variable = proxy->var(); 758 Variable* variable = proxy->var();
763 bool hole_init = mode == LET || mode == CONST;
764 switch (variable->location()) { 759 switch (variable->location()) {
765 case VariableLocation::GLOBAL: 760 case VariableLocation::GLOBAL:
766 case VariableLocation::UNALLOCATED: { 761 case VariableLocation::UNALLOCATED: {
767 DCHECK(!variable->binding_needs_init()); 762 DCHECK(!variable->binding_needs_init());
768 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); 763 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
769 DCHECK(!slot.IsInvalid()); 764 DCHECK(!slot.IsInvalid());
770 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 765 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
771 globals_->Add(isolate()->factory()->undefined_value(), zone()); 766 globals_->Add(isolate()->factory()->undefined_value(), zone());
772 break; 767 break;
773 } 768 }
774 case VariableLocation::PARAMETER: 769 case VariableLocation::PARAMETER:
775 case VariableLocation::LOCAL: 770 case VariableLocation::LOCAL:
776 if (hole_init) { 771 if (variable->binding_needs_init()) {
777 Comment cmnt(masm_, "[ VariableDeclaration"); 772 Comment cmnt(masm_, "[ VariableDeclaration");
778 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); 773 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex);
779 __ sd(a4, StackOperand(variable)); 774 __ sd(a4, StackOperand(variable));
780 } 775 }
781 break; 776 break;
782 777
783 case VariableLocation::CONTEXT: 778 case VariableLocation::CONTEXT:
784 if (hole_init) { 779 if (variable->binding_needs_init()) {
785 Comment cmnt(masm_, "[ VariableDeclaration"); 780 Comment cmnt(masm_, "[ VariableDeclaration");
786 EmitDebugCheckDeclarationContext(variable); 781 EmitDebugCheckDeclarationContext(variable);
787 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 782 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
788 __ sd(at, ContextMemOperand(cp, variable->index())); 783 __ sd(at, ContextMemOperand(cp, variable->index()));
789 // No write barrier since the_hole_value is in old space. 784 // No write barrier since the_hole_value is in old space.
790 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 785 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
791 } 786 }
792 break; 787 break;
793 788
794 case VariableLocation::LOOKUP: { 789 case VariableLocation::LOOKUP: {
795 Comment cmnt(masm_, "[ VariableDeclaration"); 790 Comment cmnt(masm_, "[ VariableDeclaration");
796 DCHECK_EQ(VAR, mode); 791 DCHECK_EQ(VAR, variable->mode());
797 DCHECK(!hole_init); 792 DCHECK(!variable->binding_needs_init());
798 __ li(a2, Operand(variable->name())); 793 __ li(a2, Operand(variable->name()));
799 __ Push(a2); 794 __ Push(a2);
800 __ CallRuntime(Runtime::kDeclareEvalVar); 795 __ CallRuntime(Runtime::kDeclareEvalVar);
801 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 796 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
802 break; 797 break;
803 } 798 }
804 } 799 }
805 } 800 }
806 801
807 802
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 // introducing variables. In those cases, we do not want to 1254 // introducing variables. In those cases, we do not want to
1260 // perform a runtime call for all variables in the scope 1255 // perform a runtime call for all variables in the scope
1261 // containing the eval. 1256 // containing the eval.
1262 Variable* var = proxy->var(); 1257 Variable* var = proxy->var();
1263 if (var->mode() == DYNAMIC_GLOBAL) { 1258 if (var->mode() == DYNAMIC_GLOBAL) {
1264 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow); 1259 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1265 __ Branch(done); 1260 __ Branch(done);
1266 } else if (var->mode() == DYNAMIC_LOCAL) { 1261 } else if (var->mode() == DYNAMIC_LOCAL) {
1267 Variable* local = var->local_if_not_shadowed(); 1262 Variable* local = var->local_if_not_shadowed();
1268 __ ld(v0, ContextSlotOperandCheckExtensions(local, slow)); 1263 __ ld(v0, ContextSlotOperandCheckExtensions(local, slow));
1269 if (local->mode() == LET || local->mode() == CONST) { 1264 if (local->binding_needs_init()) {
1270 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1265 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1271 __ dsubu(at, v0, at); // Sub as compare: at == 0 on eq. 1266 __ dsubu(at, v0, at); // Sub as compare: at == 0 on eq.
1272 __ Branch(done, ne, at, Operand(zero_reg)); 1267 __ Branch(done, ne, at, Operand(zero_reg));
1273 __ li(a0, Operand(var->name())); 1268 __ li(a0, Operand(var->name()));
1274 __ push(a0); 1269 __ push(a0);
1275 __ CallRuntime(Runtime::kThrowReferenceError); 1270 __ CallRuntime(Runtime::kThrowReferenceError);
1271 } else {
1272 __ Branch(done);
1276 } 1273 }
1277 __ Branch(done);
1278 } 1274 }
1279 } 1275 }
1280 1276
1281 1277
1282 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1278 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1283 TypeofMode typeof_mode) { 1279 TypeofMode typeof_mode) {
1284 #ifdef DEBUG 1280 #ifdef DEBUG
1285 Variable* var = proxy->var(); 1281 Variable* var = proxy->var();
1286 DCHECK(var->IsUnallocatedOrGlobalSlot() || 1282 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1287 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); 1283 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
(...skipping 22 matching lines...) Expand all
1310 break; 1306 break;
1311 } 1307 }
1312 1308
1313 case VariableLocation::PARAMETER: 1309 case VariableLocation::PARAMETER:
1314 case VariableLocation::LOCAL: 1310 case VariableLocation::LOCAL:
1315 case VariableLocation::CONTEXT: { 1311 case VariableLocation::CONTEXT: {
1316 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); 1312 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1317 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1313 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1318 : "[ Stack variable"); 1314 : "[ Stack variable");
1319 if (NeedsHoleCheckForLoad(proxy)) { 1315 if (NeedsHoleCheckForLoad(proxy)) {
1320 // Let and const need a read barrier. 1316 // Throw a reference error when using an uninitialized let/const
1317 // binding in harmony mode.
1318 Label done;
1321 GetVar(v0, var); 1319 GetVar(v0, var);
1322 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1320 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1323 __ dsubu(at, v0, at); // Sub as compare: at == 0 on eq. 1321 __ dsubu(at, v0, at); // Sub as compare: at == 0 on eq.
1324 if (var->mode() == LET || var->mode() == CONST) { 1322 __ Branch(&done, ne, at, Operand(zero_reg));
1325 // Throw a reference error when using an uninitialized let/const 1323 __ li(a0, Operand(var->name()));
1326 // binding in harmony mode. 1324 __ push(a0);
1327 Label done; 1325 __ CallRuntime(Runtime::kThrowReferenceError);
1328 __ Branch(&done, ne, at, Operand(zero_reg)); 1326 __ bind(&done);
1329 __ li(a0, Operand(var->name()));
1330 __ push(a0);
1331 __ CallRuntime(Runtime::kThrowReferenceError);
1332 __ bind(&done);
1333 }
1334 context()->Plug(v0); 1327 context()->Plug(v0);
1335 break; 1328 break;
1336 } 1329 }
1337 context()->Plug(var); 1330 context()->Plug(var);
1338 break; 1331 break;
1339 } 1332 }
1340 1333
1341 case VariableLocation::LOOKUP: { 1334 case VariableLocation::LOOKUP: {
1342 Comment cmnt(masm_, "[ Lookup variable"); 1335 Comment cmnt(masm_, "[ Lookup variable");
1343 Label done, slow; 1336 Label done, slow;
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, 2155 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
2163 FeedbackVectorSlot slot) { 2156 FeedbackVectorSlot slot) {
2164 if (var->IsUnallocated()) { 2157 if (var->IsUnallocated()) {
2165 // Global var, const, or let. 2158 // Global var, const, or let.
2166 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2159 __ mov(StoreDescriptor::ValueRegister(), result_register());
2167 __ li(StoreDescriptor::NameRegister(), Operand(var->name())); 2160 __ li(StoreDescriptor::NameRegister(), Operand(var->name()));
2168 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister()); 2161 __ LoadGlobalObject(StoreDescriptor::ReceiverRegister());
2169 EmitLoadStoreICSlot(slot); 2162 EmitLoadStoreICSlot(slot);
2170 CallStoreIC(); 2163 CallStoreIC();
2171 2164
2172 } else if (var->mode() == LET && op != Token::INIT) { 2165 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) {
2173 // Non-initializing assignment to let variable needs a write barrier.
2174 DCHECK(!var->IsLookupSlot()); 2166 DCHECK(!var->IsLookupSlot());
2175 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2167 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2176 Label assign;
2177 MemOperand location = VarOperand(var, a1); 2168 MemOperand location = VarOperand(var, a1);
2178 __ ld(a3, location); 2169 // Perform an initialization check for lexically declared variables.
2179 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex); 2170 if (var->binding_needs_init()) {
2180 __ Branch(&assign, ne, a3, Operand(a4)); 2171 Label assign;
2181 __ li(a3, Operand(var->name())); 2172 __ ld(a3, location);
2182 __ push(a3); 2173 __ LoadRoot(a4, Heap::kTheHoleValueRootIndex);
2183 __ CallRuntime(Runtime::kThrowReferenceError); 2174 __ Branch(&assign, ne, a3, Operand(a4));
2184 // Perform the assignment. 2175 __ li(a3, Operand(var->name()));
2185 __ bind(&assign); 2176 __ push(a3);
2186 EmitStoreToStackLocalOrContextSlot(var, location); 2177 __ CallRuntime(Runtime::kThrowReferenceError);
2187 2178 __ bind(&assign);
2188 } else if (var->mode() == CONST && op != Token::INIT) { 2179 }
2189 // Assignment to const variable needs a write barrier. 2180 if (var->mode() == CONST) {
2190 DCHECK(!var->IsLookupSlot()); 2181 __ CallRuntime(Runtime::kThrowConstAssignError);
2191 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2182 } else {
2192 Label const_error; 2183 EmitStoreToStackLocalOrContextSlot(var, location);
2193 MemOperand location = VarOperand(var, a1); 2184 }
2194 __ ld(a3, location);
2195 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2196 __ Branch(&const_error, ne, a3, Operand(at));
2197 __ li(a3, Operand(var->name()));
2198 __ push(a3);
2199 __ CallRuntime(Runtime::kThrowReferenceError);
2200 __ bind(&const_error);
2201 __ CallRuntime(Runtime::kThrowConstAssignError);
2202
2203 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { 2185 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
2204 // Initializing assignment to const {this} needs a write barrier. 2186 // Initializing assignment to const {this} needs a write barrier.
2205 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2187 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2206 Label uninitialized_this; 2188 Label uninitialized_this;
2207 MemOperand location = VarOperand(var, a1); 2189 MemOperand location = VarOperand(var, a1);
2208 __ ld(a3, location); 2190 __ ld(a3, location);
2209 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2191 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2210 __ Branch(&uninitialized_this, eq, a3, Operand(at)); 2192 __ Branch(&uninitialized_this, eq, a3, Operand(at));
2211 __ li(a0, Operand(var->name())); 2193 __ li(a0, Operand(var->name()));
2212 __ Push(a0); 2194 __ Push(a0);
(...skipping 1574 matching lines...) Expand 10 before | Expand all | Expand 10 after
3787 reinterpret_cast<uint64_t>( 3769 reinterpret_cast<uint64_t>(
3788 isolate->builtins()->OnStackReplacement()->entry())); 3770 isolate->builtins()->OnStackReplacement()->entry()));
3789 return ON_STACK_REPLACEMENT; 3771 return ON_STACK_REPLACEMENT;
3790 } 3772 }
3791 3773
3792 3774
3793 } // namespace internal 3775 } // namespace internal
3794 } // namespace v8 3776 } // namespace v8
3795 3777
3796 #endif // V8_TARGET_ARCH_MIPS64 3778 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/full-codegen/mips/full-codegen-mips.cc ('k') | src/full-codegen/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698