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

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: More cleanup 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();
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1377 } 1384 }
1378 } 1385 }
1379 } 1386 }
1380 } 1387 }
1381 1388
1382 1389
1383 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) { 1390 void Scope::AllocateNonParameterLocal(Isolate* isolate, Variable* var) {
1384 DCHECK(var->scope() == this); 1391 DCHECK(var->scope() == this);
1385 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) || 1392 DCHECK(!var->IsVariable(isolate->factory()->dot_result_string()) ||
1386 !var->IsStackLocal()); 1393 !var->IsStackLocal());
1394 // printf("Allocating:"); var->name()->Print();
rossberg 2015/04/17 15:16:27 Clean up
Dmitry Lomov (no reviews) 2015/04/20 11:53:21 Done.
1387 if (var->IsUnallocated() && MustAllocate(var)) { 1395 if (var->IsUnallocated() && MustAllocate(var)) {
1388 if (MustAllocateInContext(var)) { 1396 if (MustAllocateInContext(var)) {
1397 // printf(" to context\n");
1389 AllocateHeapSlot(var); 1398 AllocateHeapSlot(var);
1390 } else { 1399 } else {
1400 // printf(" to stack\n");
1391 AllocateStackSlot(var); 1401 AllocateStackSlot(var);
1392 } 1402 }
1393 } 1403 }
1404 // else { printf(" already allocated\n"); }
1394 } 1405 }
1395 1406
1396 1407
1397 void Scope::AllocateNonParameterLocals(Isolate* isolate) { 1408 void Scope::AllocateNonParameterLocals(Isolate* isolate) {
1398 // All variables that have no rewrite yet are non-parameter locals. 1409 // All variables that have no rewrite yet are non-parameter locals.
1399 for (int i = 0; i < temps_.length(); i++) { 1410 for (int i = 0; i < temps_.length(); i++) {
1400 AllocateNonParameterLocal(isolate, temps_[i]); 1411 AllocateNonParameterLocal(isolate, temps_[i]);
1401 } 1412 }
1402 1413
1403 for (int i = 0; i < internals_.length(); i++) { 1414 for (int i = 0; i < internals_.length(); i++) {
(...skipping 21 matching lines...) Expand all
1425 AllocateNonParameterLocal(isolate, function_->proxy()->var()); 1436 AllocateNonParameterLocal(isolate, function_->proxy()->var());
1426 } 1437 }
1427 1438
1428 if (rest_parameter_) { 1439 if (rest_parameter_) {
1429 AllocateNonParameterLocal(isolate, rest_parameter_); 1440 AllocateNonParameterLocal(isolate, rest_parameter_);
1430 } 1441 }
1431 } 1442 }
1432 1443
1433 1444
1434 void Scope::AllocateVariablesRecursively(Isolate* isolate) { 1445 void Scope::AllocateVariablesRecursively(Isolate* isolate) {
1446 if (!already_resolved()) {
1447 num_stack_slots_ = 0;
1448 }
1435 // Allocate variables for inner scopes. 1449 // Allocate variables for inner scopes.
1436 for (int i = 0; i < inner_scopes_.length(); i++) { 1450 for (int i = 0; i < inner_scopes_.length(); i++) {
1437 inner_scopes_[i]->AllocateVariablesRecursively(isolate); 1451 inner_scopes_[i]->AllocateVariablesRecursively(isolate);
1438 } 1452 }
1439 1453
1440 // If scope is already resolved, we still need to allocate 1454 // If scope is already resolved, we still need to allocate
1441 // variables in inner scopes which might not had been resolved yet. 1455 // variables in inner scopes which might not had been resolved yet.
1442 if (already_resolved()) return; 1456 if (already_resolved()) return;
1443 // The number of slots required for variables. 1457 // The number of slots required for variables.
1444 num_stack_slots_ = 0;
1445 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 1458 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
1446 1459
1447 // Allocate variables for this scope. 1460 // Allocate variables for this scope.
1448 // Parameters must be allocated first, if any. 1461 // Parameters must be allocated first, if any.
1449 if (is_function_scope()) AllocateParameterLocals(isolate); 1462 if (is_function_scope()) AllocateParameterLocals(isolate);
1450 AllocateNonParameterLocals(isolate); 1463 AllocateNonParameterLocals(isolate);
1451 1464
1452 // Force allocation of a context for this scope if necessary. For a 'with' 1465 // 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, 1466 // 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. 1467 // 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); 1501 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
1489 } 1502 }
1490 1503
1491 1504
1492 int Scope::ContextLocalCount() const { 1505 int Scope::ContextLocalCount() const {
1493 if (num_heap_slots() == 0) return 0; 1506 if (num_heap_slots() == 0) return 0;
1494 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1507 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1495 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); 1508 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
1496 } 1509 }
1497 } } // namespace v8::internal 1510 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698