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

Side by Side Diff: src/scopes.cc

Issue 981203003: Stack allocate lexical locals + hoist stack slots (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Clean-up Created 5 years, 8 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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/messages.h" 9 #include "src/messages.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 364
365 // Move unresolved variables 365 // Move unresolved variables
366 for (int i = 0; i < unresolved_.length(); i++) { 366 for (int i = 0; i < unresolved_.length(); i++) {
367 outer_scope()->unresolved_.Add(unresolved_[i], zone()); 367 outer_scope()->unresolved_.Add(unresolved_[i], zone());
368 } 368 }
369 369
370 // Propagate usage flags to outer scope. 370 // Propagate usage flags to outer scope.
371 if (uses_arguments()) outer_scope_->RecordArgumentsUsage(); 371 if (uses_arguments()) outer_scope_->RecordArgumentsUsage();
372 if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage(); 372 if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage();
373 if (uses_this()) outer_scope_->RecordThisUsage(); 373 if (uses_this()) outer_scope_->RecordThisUsage();
374 if (scope_calls_eval_) outer_scope_->RecordEvalCall();
374 375
375 return NULL; 376 return NULL;
376 } 377 }
377 378
378 379
379 Variable* Scope::LookupLocal(const AstRawString* name) { 380 Variable* Scope::LookupLocal(const AstRawString* name) {
380 Variable* result = variables_.Lookup(name); 381 Variable* result = variables_.Lookup(name);
381 if (result != NULL || scope_info_.is_null()) { 382 if (result != NULL || scope_info_.is_null()) {
382 return result; 383 return result;
383 } 384 }
385 Handle<String> name_handle = name->string();
384 // The Scope is backed up by ScopeInfo. This means it cannot operate in a 386 // The Scope is backed up by ScopeInfo. This means it cannot operate in a
385 // heap-independent mode, and all strings must be internalized immediately. So 387 // heap-independent mode, and all strings must be internalized immediately. So
386 // it's ok to get the Handle<String> here. 388 // it's ok to get the Handle<String> here.
387 Handle<String> name_handle = name->string();
388 // If we have a serialized scope info, we might find the variable there. 389 // If we have a serialized scope info, we might find the variable there.
389 // There should be no local slot with the given name. 390 // There should be no local slot with the given name.
390 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0); 391 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope());
391 392
392 // Check context slot lookup. 393 // Check context slot lookup.
393 VariableMode mode; 394 VariableMode mode;
394 Variable::Location location = Variable::CONTEXT; 395 Variable::Location location = Variable::CONTEXT;
395 InitializationFlag init_flag; 396 InitializationFlag init_flag;
396 MaybeAssignedFlag maybe_assigned_flag; 397 MaybeAssignedFlag maybe_assigned_flag;
397 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, 398 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
398 &init_flag, &maybe_assigned_flag); 399 &init_flag, &maybe_assigned_flag);
399 if (index < 0) { 400 if (index < 0) {
400 // Check parameters. 401 // Check parameters.
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 bool Scope::HasLazyCompilableOuterContext() const { 698 bool Scope::HasLazyCompilableOuterContext() const {
698 Scope* outer = outer_scope_; 699 Scope* outer = outer_scope_;
699 if (outer == NULL) return true; 700 if (outer == NULL) return true;
700 // We have to prevent lazy compilation if this scope is inside a with scope 701 // We have to prevent lazy compilation if this scope is inside a with scope
701 // and all declaration scopes between them have empty contexts. Such 702 // and all declaration scopes between them have empty contexts. Such
702 // declaration scopes may become invisible during scope info deserialization. 703 // declaration scopes may become invisible during scope info deserialization.
703 outer = outer->DeclarationScope(); 704 outer = outer->DeclarationScope();
704 bool found_non_trivial_declarations = false; 705 bool found_non_trivial_declarations = false;
705 for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) { 706 for (const Scope* scope = outer; scope != NULL; scope = scope->outer_scope_) {
706 if (scope->is_with_scope() && !found_non_trivial_declarations) return false; 707 if (scope->is_with_scope() && !found_non_trivial_declarations) return false;
708 if (scope->is_block_scope() && !scope->decls_.is_empty()) return false;
707 if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) { 709 if (scope->is_declaration_scope() && scope->num_heap_slots() > 0) {
708 found_non_trivial_declarations = true; 710 found_non_trivial_declarations = true;
709 } 711 }
710 } 712 }
711 return true; 713 return true;
712 } 714 }
713 715
714 716
715 bool Scope::AllowsLazyCompilation() const { 717 bool Scope::AllowsLazyCompilation() const {
716 return !force_eager_compilation_ && HasLazyCompilableOuterContext(); 718 return !force_eager_compilation_ && HasLazyCompilableOuterContext();
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 // an eval() call or a runtime with lookup), it must be allocated in the 1281 // an eval() call or a runtime with lookup), it must be allocated in the
1280 // context. 1282 // context.
1281 // 1283 //
1282 // Exceptions: If the scope as a whole has forced context allocation, all 1284 // Exceptions: If the scope as a whole has forced context allocation, all
1283 // variables will have context allocation, even temporaries. Otherwise 1285 // variables will have context allocation, even temporaries. Otherwise
1284 // temporary variables are always stack-allocated. Catch-bound variables are 1286 // temporary variables are always stack-allocated. Catch-bound variables are
1285 // always context-allocated. 1287 // always context-allocated.
1286 if (has_forced_context_allocation()) return true; 1288 if (has_forced_context_allocation()) return true;
1287 if (var->mode() == TEMPORARY) return false; 1289 if (var->mode() == TEMPORARY) return false;
1288 if (var->mode() == INTERNAL) return true; 1290 if (var->mode() == INTERNAL) return true;
1289 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; 1291 if (is_catch_scope() || is_module_scope()) return true;
1290 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; 1292 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true;
1291 return var->has_forced_context_allocation() || 1293 return var->has_forced_context_allocation() ||
1292 scope_calls_eval_ || 1294 scope_calls_eval_ ||
1293 inner_scope_calls_eval_ || 1295 inner_scope_calls_eval_ ||
1294 scope_contains_with_; 1296 scope_contains_with_;
1295 } 1297 }
1296 1298
1297 1299
1298 bool Scope::HasArgumentsParameter(Isolate* isolate) { 1300 bool Scope::HasArgumentsParameter(Isolate* isolate) {
1299 for (int i = 0; i < params_.length(); i++) { 1301 for (int i = 0; i < params_.length(); i++) {
1300 if (params_[i]->name().is_identical_to( 1302 if (params_[i]->name().is_identical_to(
1301 isolate->factory()->arguments_string())) { 1303 isolate->factory()->arguments_string())) {
1302 return true; 1304 return true;
1303 } 1305 }
1304 } 1306 }
1305 return false; 1307 return false;
1306 } 1308 }
1307 1309
1308 1310
1309 void Scope::AllocateStackSlot(Variable* var) { 1311 void Scope::AllocateStackSlot(Variable* var) {
1310 var->AllocateTo(Variable::LOCAL, num_stack_slots_++); 1312 if (is_block_scope()) {
1313 auto decl_scope = DeclarationScope();
rossberg 2015/04/21 14:41:02 Nit: inline into next line
Dmitry Lomov (no reviews) 2015/04/22 12:24:30 Done.
1314 decl_scope->AllocateStackSlot(var);
1315 } else {
1316 var->AllocateTo(Variable::LOCAL, num_stack_slots_++);
1317 }
1311 } 1318 }
1312 1319
1313 1320
1314 void Scope::AllocateHeapSlot(Variable* var) { 1321 void Scope::AllocateHeapSlot(Variable* var) {
1315 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++); 1322 var->AllocateTo(Variable::CONTEXT, num_heap_slots_++);
1316 } 1323 }
1317 1324
1318 1325
1319 void Scope::AllocateParameterLocals(Isolate* isolate) { 1326 void Scope::AllocateParameterLocals(Isolate* isolate) {
1320 DCHECK(is_function_scope()); 1327 DCHECK(is_function_scope());
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 AllocateNonParameterLocal(isolate, function_->proxy()->var()); 1432 AllocateNonParameterLocal(isolate, function_->proxy()->var());
1426 } 1433 }
1427 1434
1428 if (rest_parameter_) { 1435 if (rest_parameter_) {
1429 AllocateNonParameterLocal(isolate, rest_parameter_); 1436 AllocateNonParameterLocal(isolate, rest_parameter_);
1430 } 1437 }
1431 } 1438 }
1432 1439
1433 1440
1434 void Scope::AllocateVariablesRecursively(Isolate* isolate) { 1441 void Scope::AllocateVariablesRecursively(Isolate* isolate) {
1442 if (!already_resolved()) {
1443 num_stack_slots_ = 0;
1444 }
1435 // Allocate variables for inner scopes. 1445 // Allocate variables for inner scopes.
1436 for (int i = 0; i < inner_scopes_.length(); i++) { 1446 for (int i = 0; i < inner_scopes_.length(); i++) {
1437 inner_scopes_[i]->AllocateVariablesRecursively(isolate); 1447 inner_scopes_[i]->AllocateVariablesRecursively(isolate);
1438 } 1448 }
1439 1449
1440 // If scope is already resolved, we still need to allocate 1450 // If scope is already resolved, we still need to allocate
1441 // variables in inner scopes which might not had been resolved yet. 1451 // variables in inner scopes which might not had been resolved yet.
1442 if (already_resolved()) return; 1452 if (already_resolved()) return;
1443 // The number of slots required for variables. 1453 // The number of slots required for variables.
1444 num_stack_slots_ = 0;
1445 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 1454 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1446 1455
1447 // Allocate variables for this scope. 1456 // Allocate variables for this scope.
1448 // Parameters must be allocated first, if any. 1457 // Parameters must be allocated first, if any.
1449 if (is_function_scope()) AllocateParameterLocals(isolate); 1458 if (is_function_scope()) AllocateParameterLocals(isolate);
1450 AllocateNonParameterLocals(isolate); 1459 AllocateNonParameterLocals(isolate);
1451 1460
1452 // Force allocation of a context for this scope if necessary. For a 'with' 1461 // Force allocation of a context for this scope if necessary. For a 'with'
1453 // scope and for a function scope that makes an 'eval' call we need a context, 1462 // scope and for a function scope that makes an 'eval' call we need a context,
1454 // even if no local variables were statically allocated in the scope. 1463 // even if no local variables were statically allocated in the scope.
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); 1497 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
1489 } 1498 }
1490 1499
1491 1500
1492 int Scope::ContextLocalCount() const { 1501 int Scope::ContextLocalCount() const {
1493 if (num_heap_slots() == 0) return 0; 1502 if (num_heap_slots() == 0) return 0;
1494 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1503 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1495 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); 1504 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
1496 } 1505 }
1497 } } // namespace v8::internal 1506 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698