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

Side by Side Diff: src/ast/scopes.cc

Issue 2210243002: Put Scopes into temporary Zone (second try) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: adding 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/ast/scopes.h ('k') | src/objects.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 #include "src/ast/scopes.h" 5 #include "src/ast/scopes.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "src/accessors.h" 9 #include "src/accessors.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 return false; 350 return false;
351 } 351 }
352 } 352 }
353 353
354 #ifdef DEBUG 354 #ifdef DEBUG
355 if (info->script_is_native() ? FLAG_print_builtin_scopes 355 if (info->script_is_native() ? FLAG_print_builtin_scopes
356 : FLAG_print_scopes) { 356 : FLAG_print_scopes) {
357 scope->Print(); 357 scope->Print();
358 } 358 }
359 scope->CheckScopePositions(); 359 scope->CheckScopePositions();
360 scope->CheckZones();
360 #endif 361 #endif
361 362
362 info->set_scope(scope); 363 info->set_scope(scope);
363 return true; 364 return true;
364 } 365 }
365 366
366 void Scope::DeclareThis(AstValueFactory* ast_value_factory) { 367 void Scope::DeclareThis(AstValueFactory* ast_value_factory) {
367 DCHECK(!already_resolved()); 368 DCHECK(!already_resolved());
368 DCHECK(is_declaration_scope()); 369 DCHECK(is_declaration_scope());
369 DCHECK(has_this_declaration()); 370 DCHECK(has_this_declaration());
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 AstNodeFactory* factory) { 574 AstNodeFactory* factory) {
574 if (function_ != NULL && function_->proxy()->raw_name() == name) { 575 if (function_ != NULL && function_->proxy()->raw_name() == name) {
575 return function_->proxy()->var(); 576 return function_->proxy()->var();
576 } else if (!scope_info_.is_null()) { 577 } else if (!scope_info_.is_null()) {
577 // If we are backed by a scope info, try to lookup the variable there. 578 // If we are backed by a scope info, try to lookup the variable there.
578 VariableMode mode; 579 VariableMode mode;
579 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); 580 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode);
580 if (index < 0) return NULL; 581 if (index < 0) return NULL;
581 Variable* var = new (zone()) 582 Variable* var = new (zone())
582 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized); 583 Variable(this, name, mode, Variable::NORMAL, kCreatedInitialized);
584 DCHECK_NOT_NULL(factory);
583 VariableProxy* proxy = factory->NewVariableProxy(var); 585 VariableProxy* proxy = factory->NewVariableProxy(var);
584 VariableDeclaration* declaration = 586 VariableDeclaration* declaration =
585 factory->NewVariableDeclaration(proxy, mode, this, kNoSourcePosition); 587 factory->NewVariableDeclaration(proxy, mode, this, kNoSourcePosition);
588 DCHECK_EQ(factory->zone(), zone());
586 DeclareFunctionVar(declaration); 589 DeclareFunctionVar(declaration);
587 var->AllocateTo(VariableLocation::CONTEXT, index); 590 var->AllocateTo(VariableLocation::CONTEXT, index);
588 return var; 591 return var;
589 } else { 592 } else {
590 return NULL; 593 return NULL;
591 } 594 }
592 } 595 }
593 596
594 597
595 Variable* Scope::Lookup(const AstRawString* name) { 598 Variable* Scope::Lookup(const AstRawString* name) {
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue; 963 if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue;
961 Handle<String> name = proxy->name(); 964 Handle<String> name = proxy->name();
962 non_locals = StringSet::Add(non_locals, name); 965 non_locals = StringSet::Add(non_locals, name);
963 } 966 }
964 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 967 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
965 non_locals = scope->CollectNonLocals(non_locals); 968 non_locals = scope->CollectNonLocals(non_locals);
966 } 969 }
967 return non_locals; 970 return non_locals;
968 } 971 }
969 972
973 void Scope::AnalyzePartially(Scope* migrate_to,
974 AstNodeFactory* ast_node_factory) {
975 // Gather info from inner scopes.
976 PropagateScopeInfo(false);
977
978 // Try to resolve unresolved variables for this Scope and migrate those which
979 // cannot be resolved inside. It doesn't make sense to try to resolve them in
980 // the outer Scopes here, because they are incomplete.
981 MigrateUnresolvableLocals(migrate_to, ast_node_factory, this);
982
983 // Push scope data up to migrate_to. Note that migrate_to and this Scope
984 // describe the same Scope, just in different Zones.
985 PropagateUsageFlagsToScope(migrate_to);
986 if (inner_scope_calls_eval_) {
987 migrate_to->inner_scope_calls_eval_ = true;
988 }
989 DCHECK(!force_eager_compilation_);
990 migrate_to->set_start_position(start_position_);
991 migrate_to->set_end_position(end_position_);
992 migrate_to->language_mode_ = language_mode_;
993 migrate_to->arity_ = arity_;
994 migrate_to->force_context_allocation_ = force_context_allocation_;
995 outer_scope_->RemoveInnerScope(this);
996 DCHECK_EQ(outer_scope_, migrate_to->outer_scope_);
997 DCHECK_EQ(outer_scope_->zone(), migrate_to->zone());
998 DCHECK_EQ(NeedsHomeObject(), migrate_to->NeedsHomeObject());
999 DCHECK_EQ(asm_function_, migrate_to->asm_function_);
1000 DCHECK_EQ(arguments() != nullptr, migrate_to->arguments() != nullptr);
1001 }
970 1002
971 #ifdef DEBUG 1003 #ifdef DEBUG
972 static const char* Header(ScopeType scope_type, FunctionKind function_kind, 1004 static const char* Header(ScopeType scope_type, FunctionKind function_kind,
973 bool is_declaration_scope) { 1005 bool is_declaration_scope) {
974 switch (scope_type) { 1006 switch (scope_type) {
975 case EVAL_SCOPE: return "eval"; 1007 case EVAL_SCOPE: return "eval";
976 // TODO(adamk): Should we print concise method scopes specially? 1008 // TODO(adamk): Should we print concise method scopes specially?
977 case FUNCTION_SCOPE: 1009 case FUNCTION_SCOPE:
978 if (IsGeneratorFunction(function_kind)) return "function*"; 1010 if (IsGeneratorFunction(function_kind)) return "function*";
979 if (IsAsyncFunction(function_kind)) return "async function"; 1011 if (IsAsyncFunction(function_kind)) return "async function";
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 // A scope is allowed to have invalid positions if it is hidden and has no 1200 // A scope is allowed to have invalid positions if it is hidden and has no
1169 // inner scopes 1201 // inner scopes
1170 if (!is_hidden() && inner_scope_ == nullptr) { 1202 if (!is_hidden() && inner_scope_ == nullptr) {
1171 CHECK_NE(kNoSourcePosition, start_position()); 1203 CHECK_NE(kNoSourcePosition, start_position());
1172 CHECK_NE(kNoSourcePosition, end_position()); 1204 CHECK_NE(kNoSourcePosition, end_position());
1173 } 1205 }
1174 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1206 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1175 scope->CheckScopePositions(); 1207 scope->CheckScopePositions();
1176 } 1208 }
1177 } 1209 }
1210
1211 void Scope::CheckZones() {
1212 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1213 CHECK_EQ(scope->zone(), zone());
1214 }
1215 }
1178 #endif // DEBUG 1216 #endif // DEBUG
1179 1217
1180 1218
1181 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { 1219 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
1182 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); 1220 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone());
1183 VariableMap* map = dynamics_->GetMap(mode); 1221 VariableMap* map = dynamics_->GetMap(mode);
1184 Variable* var = map->Lookup(name); 1222 Variable* var = map->Lookup(name);
1185 if (var == NULL) { 1223 if (var == NULL) {
1186 // Declare a new non-local. 1224 // Declare a new non-local.
1187 InitializationFlag init_flag = (mode == VAR) 1225 InitializationFlag init_flag = (mode == VAR)
1188 ? kCreatedInitialized : kNeedsInitialization; 1226 ? kCreatedInitialized : kNeedsInitialization;
1189 var = map->Declare(NULL, 1227 var = map->Declare(NULL,
1190 name, 1228 name,
1191 mode, 1229 mode,
1192 Variable::NORMAL, 1230 Variable::NORMAL,
1193 init_flag); 1231 init_flag);
1194 // Allocate it by giving it a dynamic lookup. 1232 // Allocate it by giving it a dynamic lookup.
1195 var->AllocateTo(VariableLocation::LOOKUP, -1); 1233 var->AllocateTo(VariableLocation::LOOKUP, -1);
1196 } 1234 }
1197 return var; 1235 return var;
1198 } 1236 }
1199 1237
1200
1201 Variable* Scope::LookupRecursive(VariableProxy* proxy, 1238 Variable* Scope::LookupRecursive(VariableProxy* proxy,
1202 BindingKind* binding_kind, 1239 BindingKind* binding_kind,
1203 AstNodeFactory* factory) { 1240 AstNodeFactory* factory,
1241 Scope* max_outer_scope) {
1204 DCHECK(binding_kind != NULL); 1242 DCHECK(binding_kind != NULL);
1205 if (already_resolved() && is_with_scope()) { 1243 if (already_resolved() && is_with_scope()) {
1206 // Short-cut: if the scope is deserialized from a scope info, variable 1244 // Short-cut: if the scope is deserialized from a scope info, variable
1207 // allocation is already fixed. We can simply return with dynamic lookup. 1245 // allocation is already fixed. We can simply return with dynamic lookup.
1208 *binding_kind = DYNAMIC_LOOKUP; 1246 *binding_kind = DYNAMIC_LOOKUP;
1209 return NULL; 1247 return NULL;
1210 } 1248 }
1211 1249
1212 // Try to find the variable in this scope. 1250 // Try to find the variable in this scope.
1213 Variable* var = LookupLocal(proxy->raw_name()); 1251 Variable* var = LookupLocal(proxy->raw_name());
1214 1252
1215 // We found a variable and we are done. (Even if there is an 'eval' in 1253 // We found a variable and we are done. (Even if there is an 'eval' in
1216 // this scope which introduces the same variable again, the resulting 1254 // this scope which introduces the same variable again, the resulting
1217 // variable remains the same.) 1255 // variable remains the same.)
1218 if (var != NULL) { 1256 if (var != NULL) {
1219 *binding_kind = BOUND; 1257 *binding_kind = BOUND;
1220 return var; 1258 return var;
1221 } 1259 }
1222 1260
1223 // We did not find a variable locally. Check against the function variable, 1261 // We did not find a variable locally. Check against the function variable,
1224 // if any. We can do this for all scopes, since the function variable is 1262 // if any. We can do this for all scopes, since the function variable is
1225 // only present - if at all - for function scopes. 1263 // only present - if at all - for function scopes.
1226 *binding_kind = UNBOUND; 1264 *binding_kind = UNBOUND;
1227 var = LookupFunctionVar(proxy->raw_name(), factory); 1265 var = LookupFunctionVar(proxy->raw_name(), factory);
1228 if (var != NULL) { 1266 if (var != NULL) {
1229 *binding_kind = BOUND; 1267 *binding_kind = BOUND;
1230 } else if (outer_scope_ != NULL) { 1268 } else if (outer_scope_ != nullptr && this != max_outer_scope) {
1231 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory); 1269 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory,
1270 max_outer_scope);
1232 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) { 1271 if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
1233 var->ForceContextAllocation(); 1272 var->ForceContextAllocation();
1234 } 1273 }
1235 } else { 1274 } else {
1236 DCHECK(is_script_scope()); 1275 DCHECK(is_script_scope() || this == max_outer_scope);
1237 } 1276 }
1238 1277
1239 // "this" can't be shadowed by "eval"-introduced bindings or by "with" scopes. 1278 // "this" can't be shadowed by "eval"-introduced bindings or by "with" scopes.
1240 // TODO(wingo): There are other variables in this category; add them. 1279 // TODO(wingo): There are other variables in this category; add them.
1241 bool name_can_be_shadowed = var == nullptr || !var->is_this(); 1280 bool name_can_be_shadowed = var == nullptr || !var->is_this();
1242 1281
1243 if (is_with_scope() && name_can_be_shadowed) { 1282 if (is_with_scope() && name_can_be_shadowed) {
1244 DCHECK(!already_resolved()); 1283 DCHECK(!already_resolved());
1245 // The current scope is a with scope, so the variable binding can not be 1284 // The current scope is a with scope, so the variable binding can not be
1246 // statically resolved. However, note that it was necessary to do a lookup 1285 // statically resolved. However, note that it was necessary to do a lookup
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 } 1398 }
1360 1399
1361 // Resolve unresolved variables for inner scopes. 1400 // Resolve unresolved variables for inner scopes.
1362 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1401 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1363 if (!scope->ResolveVariablesRecursively(info, factory)) return false; 1402 if (!scope->ResolveVariablesRecursively(info, factory)) return false;
1364 } 1403 }
1365 1404
1366 return true; 1405 return true;
1367 } 1406 }
1368 1407
1408 void Scope::MigrateUnresolvableLocals(Scope* migrate_to,
1409 AstNodeFactory* ast_node_factory,
1410 Scope* max_outer_scope) {
1411 BindingKind binding_kind;
1412 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
1413 proxy = next) {
1414 next = proxy->next_unresolved();
1415 // Note that we pass nullptr as AstNodeFactory: this phase should not create
1416 // any new AstNodes, since none of the Scopes involved are backed up by
1417 // ScopeInfo.
1418 if (LookupRecursive(proxy, &binding_kind, nullptr, max_outer_scope) ==
1419 nullptr) {
1420 // Re-create the VariableProxies in the right Zone and insert them into
1421 // migrate_to.
1422 DCHECK(!proxy->is_resolved());
1423 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
1424 migrate_to->AddUnresolved(copy);
1425 }
1426 }
1427
1428 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1429 scope->MigrateUnresolvableLocals(migrate_to, ast_node_factory,
1430 max_outer_scope);
1431 }
1432 }
1369 1433
1370 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) { 1434 void Scope::PropagateScopeInfo(bool outer_scope_calls_sloppy_eval ) {
1371 if (outer_scope_calls_sloppy_eval) { 1435 if (outer_scope_calls_sloppy_eval) {
1372 outer_scope_calls_sloppy_eval_ = true; 1436 outer_scope_calls_sloppy_eval_ = true;
1373 } 1437 }
1374 1438
1375 bool calls_sloppy_eval = 1439 bool calls_sloppy_eval =
1376 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_; 1440 this->calls_sloppy_eval() || outer_scope_calls_sloppy_eval_;
1377 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { 1441 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) {
1378 inner->PropagateScopeInfo(calls_sloppy_eval); 1442 inner->PropagateScopeInfo(calls_sloppy_eval);
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 function_ != NULL && function_->proxy()->var()->IsContextSlot(); 1718 function_ != NULL && function_->proxy()->var()->IsContextSlot();
1655 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1719 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1656 (is_function_var_in_context ? 1 : 0); 1720 (is_function_var_in_context ? 1 : 0);
1657 } 1721 }
1658 1722
1659 1723
1660 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1724 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1661 1725
1662 } // namespace internal 1726 } // namespace internal
1663 } // namespace v8 1727 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698