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

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

Issue 2223803002: X87: Use Variable::binding_needs_init() to determine hole initialization. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « no previous file | no next file » | 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_X87 5 #if V8_TARGET_ARCH_X87
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 __ cmp(ebx, isolate()->factory()->with_context_map()); 699 __ cmp(ebx, isolate()->factory()->with_context_map());
700 __ Check(not_equal, kDeclarationInWithContext); 700 __ Check(not_equal, kDeclarationInWithContext);
701 __ cmp(ebx, isolate()->factory()->catch_context_map()); 701 __ cmp(ebx, isolate()->factory()->catch_context_map());
702 __ Check(not_equal, kDeclarationInCatchContext); 702 __ Check(not_equal, kDeclarationInCatchContext);
703 } 703 }
704 } 704 }
705 705
706 706
707 void FullCodeGenerator::VisitVariableDeclaration( 707 void FullCodeGenerator::VisitVariableDeclaration(
708 VariableDeclaration* declaration) { 708 VariableDeclaration* declaration) {
709 // If it was not possible to allocate the variable at compile time, we
710 // need to "declare" it at runtime to make sure it actually exists in the
711 // local context.
712 VariableProxy* proxy = declaration->proxy(); 709 VariableProxy* proxy = declaration->proxy();
713 VariableMode mode = declaration->mode();
714 Variable* variable = proxy->var(); 710 Variable* variable = proxy->var();
715 bool hole_init = mode == LET || mode == CONST;
716 switch (variable->location()) { 711 switch (variable->location()) {
717 case VariableLocation::GLOBAL: 712 case VariableLocation::GLOBAL:
718 case VariableLocation::UNALLOCATED: { 713 case VariableLocation::UNALLOCATED: {
719 DCHECK(!variable->binding_needs_init()); 714 DCHECK(!variable->binding_needs_init());
720 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot(); 715 FeedbackVectorSlot slot = proxy->VariableFeedbackSlot();
721 DCHECK(!slot.IsInvalid()); 716 DCHECK(!slot.IsInvalid());
722 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone()); 717 globals_->Add(handle(Smi::FromInt(slot.ToInt()), isolate()), zone());
723 globals_->Add(isolate()->factory()->undefined_value(), zone()); 718 globals_->Add(isolate()->factory()->undefined_value(), zone());
724 break; 719 break;
725 } 720 }
726 case VariableLocation::PARAMETER: 721 case VariableLocation::PARAMETER:
727 case VariableLocation::LOCAL: 722 case VariableLocation::LOCAL:
728 if (hole_init) { 723 if (variable->binding_needs_init()) {
729 Comment cmnt(masm_, "[ VariableDeclaration"); 724 Comment cmnt(masm_, "[ VariableDeclaration");
730 __ mov(StackOperand(variable), 725 __ mov(StackOperand(variable),
731 Immediate(isolate()->factory()->the_hole_value())); 726 Immediate(isolate()->factory()->the_hole_value()));
732 } 727 }
733 break; 728 break;
734 729
735 case VariableLocation::CONTEXT: 730 case VariableLocation::CONTEXT:
736 if (hole_init) { 731 if (variable->binding_needs_init()) {
737 Comment cmnt(masm_, "[ VariableDeclaration"); 732 Comment cmnt(masm_, "[ VariableDeclaration");
738 EmitDebugCheckDeclarationContext(variable); 733 EmitDebugCheckDeclarationContext(variable);
739 __ mov(ContextOperand(esi, variable->index()), 734 __ mov(ContextOperand(esi, variable->index()),
740 Immediate(isolate()->factory()->the_hole_value())); 735 Immediate(isolate()->factory()->the_hole_value()));
741 // No write barrier since the hole value is in old space. 736 // No write barrier since the hole value is in old space.
742 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 737 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
743 } 738 }
744 break; 739 break;
745 740
746 case VariableLocation::LOOKUP: { 741 case VariableLocation::LOOKUP: {
747 Comment cmnt(masm_, "[ VariableDeclaration"); 742 Comment cmnt(masm_, "[ VariableDeclaration");
748 DCHECK_EQ(VAR, mode); 743 DCHECK_EQ(VAR, variable->mode());
749 DCHECK(!hole_init); 744 DCHECK(!variable->binding_needs_init());
750 __ push(Immediate(variable->name())); 745 __ push(Immediate(variable->name()));
751 __ CallRuntime(Runtime::kDeclareEvalVar); 746 __ CallRuntime(Runtime::kDeclareEvalVar);
752 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS); 747 PrepareForBailoutForId(proxy->id(), BailoutState::NO_REGISTERS);
753 break; 748 break;
754 } 749 }
755 } 750 }
756 } 751 }
757 752
758 void FullCodeGenerator::VisitFunctionDeclaration( 753 void FullCodeGenerator::VisitFunctionDeclaration(
759 FunctionDeclaration* declaration) { 754 FunctionDeclaration* declaration) {
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 // introducing variables. In those cases, we do not want to 1177 // introducing variables. In those cases, we do not want to
1183 // perform a runtime call for all variables in the scope 1178 // perform a runtime call for all variables in the scope
1184 // containing the eval. 1179 // containing the eval.
1185 Variable* var = proxy->var(); 1180 Variable* var = proxy->var();
1186 if (var->mode() == DYNAMIC_GLOBAL) { 1181 if (var->mode() == DYNAMIC_GLOBAL) {
1187 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow); 1182 EmitLoadGlobalCheckExtensions(proxy, typeof_mode, slow);
1188 __ jmp(done); 1183 __ jmp(done);
1189 } else if (var->mode() == DYNAMIC_LOCAL) { 1184 } else if (var->mode() == DYNAMIC_LOCAL) {
1190 Variable* local = var->local_if_not_shadowed(); 1185 Variable* local = var->local_if_not_shadowed();
1191 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); 1186 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
1192 if (local->mode() == LET || local->mode() == CONST) { 1187 if (local->binding_needs_init()) {
1193 __ cmp(eax, isolate()->factory()->the_hole_value()); 1188 __ cmp(eax, isolate()->factory()->the_hole_value());
1194 __ j(not_equal, done); 1189 __ j(not_equal, done);
1195 __ push(Immediate(var->name())); 1190 __ push(Immediate(var->name()));
1196 __ CallRuntime(Runtime::kThrowReferenceError); 1191 __ CallRuntime(Runtime::kThrowReferenceError);
1192 } else {
1193 __ jmp(done);
1197 } 1194 }
1198 __ jmp(done);
1199 } 1195 }
1200 } 1196 }
1201 1197
1202 1198
1203 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy, 1199 void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
1204 TypeofMode typeof_mode) { 1200 TypeofMode typeof_mode) {
1205 #ifdef DEBUG 1201 #ifdef DEBUG
1206 Variable* var = proxy->var(); 1202 Variable* var = proxy->var();
1207 DCHECK(var->IsUnallocatedOrGlobalSlot() || 1203 DCHECK(var->IsUnallocatedOrGlobalSlot() ||
1208 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL)); 1204 (var->IsLookupSlot() && var->mode() == DYNAMIC_GLOBAL));
(...skipping 22 matching lines...) Expand all
1231 } 1227 }
1232 1228
1233 case VariableLocation::PARAMETER: 1229 case VariableLocation::PARAMETER:
1234 case VariableLocation::LOCAL: 1230 case VariableLocation::LOCAL:
1235 case VariableLocation::CONTEXT: { 1231 case VariableLocation::CONTEXT: {
1236 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode); 1232 DCHECK_EQ(NOT_INSIDE_TYPEOF, typeof_mode);
1237 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable" 1233 Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
1238 : "[ Stack variable"); 1234 : "[ Stack variable");
1239 1235
1240 if (NeedsHoleCheckForLoad(proxy)) { 1236 if (NeedsHoleCheckForLoad(proxy)) {
1241 // Let and const need a read barrier. 1237 // Throw a reference error when using an uninitialized let/const
1238 // binding in harmony mode.
1242 Label done; 1239 Label done;
1243 GetVar(eax, var); 1240 GetVar(eax, var);
1244 __ cmp(eax, isolate()->factory()->the_hole_value()); 1241 __ cmp(eax, isolate()->factory()->the_hole_value());
1245 __ j(not_equal, &done, Label::kNear); 1242 __ j(not_equal, &done, Label::kNear);
1246 if (var->mode() == LET || var->mode() == CONST) { 1243 __ push(Immediate(var->name()));
1247 // Throw a reference error when using an uninitialized let/const 1244 __ CallRuntime(Runtime::kThrowReferenceError);
1248 // binding in harmony mode.
1249 __ push(Immediate(var->name()));
1250 __ CallRuntime(Runtime::kThrowReferenceError);
1251 }
1252 __ bind(&done); 1245 __ bind(&done);
1253 context()->Plug(eax); 1246 context()->Plug(eax);
1254 break; 1247 break;
1255 } 1248 }
1256 context()->Plug(var); 1249 context()->Plug(var);
1257 break; 1250 break;
1258 } 1251 }
1259 1252
1260 case VariableLocation::LOOKUP: { 1253 case VariableLocation::LOOKUP: {
1261 Comment cmnt(masm_, "[ Lookup variable"); 1254 Comment cmnt(masm_, "[ Lookup variable");
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
2066 if (var->IsUnallocated()) { 2059 if (var->IsUnallocated()) {
2067 // Global var, const, or let. 2060 // Global var, const, or let.
2068 __ mov(StoreDescriptor::NameRegister(), var->name()); 2061 __ mov(StoreDescriptor::NameRegister(), var->name());
2069 __ mov(StoreDescriptor::ReceiverRegister(), NativeContextOperand()); 2062 __ mov(StoreDescriptor::ReceiverRegister(), NativeContextOperand());
2070 __ mov(StoreDescriptor::ReceiverRegister(), 2063 __ mov(StoreDescriptor::ReceiverRegister(),
2071 ContextOperand(StoreDescriptor::ReceiverRegister(), 2064 ContextOperand(StoreDescriptor::ReceiverRegister(),
2072 Context::EXTENSION_INDEX)); 2065 Context::EXTENSION_INDEX));
2073 EmitLoadStoreICSlot(slot); 2066 EmitLoadStoreICSlot(slot);
2074 CallStoreIC(); 2067 CallStoreIC();
2075 2068
2076 } else if (var->mode() == LET && op != Token::INIT) { 2069 } else if (IsLexicalVariableMode(var->mode()) && op != Token::INIT) {
2077 // Non-initializing assignment to let variable needs a write barrier.
2078 DCHECK(!var->IsLookupSlot()); 2070 DCHECK(!var->IsLookupSlot());
2079 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2071 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2080 Label assign;
2081 MemOperand location = VarOperand(var, ecx); 2072 MemOperand location = VarOperand(var, ecx);
2082 __ mov(edx, location); 2073 // Perform an initialization check for lexically declared variables.
2083 __ cmp(edx, isolate()->factory()->the_hole_value()); 2074 if (var->binding_needs_init()) {
2084 __ j(not_equal, &assign, Label::kNear); 2075 Label assign;
2085 __ push(Immediate(var->name())); 2076 __ mov(edx, location);
2086 __ CallRuntime(Runtime::kThrowReferenceError); 2077 __ cmp(edx, isolate()->factory()->the_hole_value());
2087 __ bind(&assign); 2078 __ j(not_equal, &assign, Label::kNear);
2088 EmitStoreToStackLocalOrContextSlot(var, location); 2079 __ push(Immediate(var->name()));
2089 2080 __ CallRuntime(Runtime::kThrowReferenceError);
2090 } else if (var->mode() == CONST && op != Token::INIT) { 2081 __ bind(&assign);
2091 // Assignment to const variable needs a write barrier. 2082 }
2092 DCHECK(!var->IsLookupSlot()); 2083 if (var->mode() == CONST) {
2093 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2084 __ CallRuntime(Runtime::kThrowConstAssignError);
2094 Label const_error; 2085 } else {
2095 MemOperand location = VarOperand(var, ecx); 2086 EmitStoreToStackLocalOrContextSlot(var, location);
2096 __ mov(edx, location); 2087 }
2097 __ cmp(edx, isolate()->factory()->the_hole_value());
2098 __ j(not_equal, &const_error, Label::kNear);
2099 __ push(Immediate(var->name()));
2100 __ CallRuntime(Runtime::kThrowReferenceError);
2101 __ bind(&const_error);
2102 __ CallRuntime(Runtime::kThrowConstAssignError);
2103
2104 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) { 2088 } else if (var->is_this() && var->mode() == CONST && op == Token::INIT) {
2105 // Initializing assignment to const {this} needs a write barrier. 2089 // Initializing assignment to const {this} needs a write barrier.
2106 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2090 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2107 Label uninitialized_this; 2091 Label uninitialized_this;
2108 MemOperand location = VarOperand(var, ecx); 2092 MemOperand location = VarOperand(var, ecx);
2109 __ mov(edx, location); 2093 __ mov(edx, location);
2110 __ cmp(edx, isolate()->factory()->the_hole_value()); 2094 __ cmp(edx, isolate()->factory()->the_hole_value());
2111 __ j(equal, &uninitialized_this); 2095 __ j(equal, &uninitialized_this);
2112 __ push(Immediate(var->name())); 2096 __ push(Immediate(var->name()));
2113 __ CallRuntime(Runtime::kThrowReferenceError); 2097 __ CallRuntime(Runtime::kThrowReferenceError);
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
3669 isolate->builtins()->OnStackReplacement()->entry(), 3653 isolate->builtins()->OnStackReplacement()->entry(),
3670 Assembler::target_address_at(call_target_address, unoptimized_code)); 3654 Assembler::target_address_at(call_target_address, unoptimized_code));
3671 return ON_STACK_REPLACEMENT; 3655 return ON_STACK_REPLACEMENT;
3672 } 3656 }
3673 3657
3674 3658
3675 } // namespace internal 3659 } // namespace internal
3676 } // namespace v8 3660 } // namespace v8
3677 3661
3678 #endif // V8_TARGET_ARCH_X87 3662 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698