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

Side by Side Diff: runtime/vm/scopes.cc

Issue 1317213003: Improve async code in VM by not unnecessarily capturing parameters of async and (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Avoid duplicate aliases Created 5 years, 3 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 | « runtime/vm/scopes.h ('k') | 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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/scopes.h" 5 #include "vm/scopes.h"
6 6
7 #include "vm/object.h" 7 #include "vm/object.h"
8 #include "vm/stack_frame.h" 8 #include "vm/stack_frame.h"
9 #include "vm/symbols.h" 9 #include "vm/symbols.h"
10 10
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 } 397 }
398 } 398 }
399 return NULL; 399 return NULL;
400 } 400 }
401 401
402 402
403 LocalVariable* LocalScope::LookupVariable(const String& name, bool test_only) { 403 LocalVariable* LocalScope::LookupVariable(const String& name, bool test_only) {
404 LocalScope* current_scope = this; 404 LocalScope* current_scope = this;
405 while (current_scope != NULL) { 405 while (current_scope != NULL) {
406 LocalVariable* var = current_scope->LocalLookupVariable(name); 406 LocalVariable* var = current_scope->LocalLookupVariable(name);
407 if ((var != NULL) && !var->is_invisible_) { 407 // If testing only, return the variable even if invisible.
408 if (!test_only) { 408 if ((var != NULL) && (!var->is_invisible_ || test_only)) {
409 if (var->owner()->function_level() != function_level()) { 409 if (!test_only && (var->owner()->function_level() != function_level())) {
410 var->set_is_captured(); 410 CaptureVariable(var);
411 }
412 // Insert aliases of the variable in intermediate scopes.
413 LocalScope* intermediate_scope = this;
414 while (intermediate_scope != current_scope) {
415 intermediate_scope->variables_.Add(var);
416 ASSERT(var->owner() != intermediate_scope); // Item is an alias.
417 intermediate_scope = intermediate_scope->parent();
418 }
419 } 411 }
420 return var; 412 return var;
421 } 413 }
422 current_scope = current_scope->parent(); 414 current_scope = current_scope->parent();
423 } 415 }
424 return NULL; 416 return NULL;
425 } 417 }
426 418
427 419
428 bool LocalScope::CaptureVariable(const String& name) { 420 void LocalScope::CaptureVariable(LocalVariable* variable) {
429 ASSERT(name.IsSymbol()); 421 ASSERT(variable != NULL);
430 LocalScope* current_scope = this; 422 // The variable must exist in an enclosing scope, not necessarily in this one.
431 while (current_scope != NULL) { 423 variable->set_is_captured();
432 LocalVariable* var = current_scope->LocalLookupVariable(name); 424 const int variable_function_level = variable->owner()->function_level();
433 if (var != NULL) { 425 LocalScope* scope = this;
434 var->set_is_captured(); 426 while (scope->function_level() != variable_function_level) {
435 LocalScope* scope = this; 427 // Insert an alias of the variable in the top scope of each function
436 while (var->owner()->function_level() != scope->function_level()) { 428 // level so that the variable is found in the context.
437 // Insert an alias of the variable in the top scope of each function 429 LocalScope* parent_scope = scope->parent();
438 // level so that the variable is found in the context. 430 while ((parent_scope != NULL) &&
439 LocalScope* parent_scope = scope->parent(); 431 (parent_scope->function_level() == scope->function_level())) {
440 while ((parent_scope != NULL) && 432 scope = parent_scope;
441 (parent_scope->function_level() == scope->function_level())) { 433 parent_scope = scope->parent();
442 scope = parent_scope;
443 parent_scope = scope->parent();
444 }
445 scope->variables_.Add(var);
446 ASSERT(var->owner() != scope); // Item is an alias.
447 scope = parent_scope;
448 }
449 return true;
450 } 434 }
451 current_scope = current_scope->parent(); 435 // An alias may already have been added in this scope, and in that case,
436 // in parent scopes as needed. If so, we are done.
437 if (!scope->AddVariable(variable)) {
438 return;
439 }
440 ASSERT(variable->owner() != scope); // Item is an alias.
441 scope = parent_scope;
452 } 442 }
453 return false;
454 } 443 }
455 444
456 445
457 SourceLabel* LocalScope::LookupLabel(const String& name) { 446 SourceLabel* LocalScope::LookupLabel(const String& name) {
458 LocalScope* current_scope = this; 447 LocalScope* current_scope = this;
459 while (current_scope != NULL) { 448 while (current_scope != NULL) {
460 SourceLabel* label = current_scope->LocalLookupLabel(name); 449 SourceLabel* label = current_scope->LocalLookupLabel(name);
461 if (label != NULL) { 450 if (label != NULL) {
462 return label; 451 return label;
463 } 452 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 outer_switch->AddLabel(label); 507 outer_switch->AddLabel(label);
519 } 508 }
520 } 509 }
521 } 510 }
522 return NULL; 511 return NULL;
523 } 512 }
524 513
525 514
526 int LocalScope::NumCapturedVariables() const { 515 int LocalScope::NumCapturedVariables() const {
527 // It is not necessary to traverse parent scopes, since we are only interested 516 // It is not necessary to traverse parent scopes, since we are only interested
528 // in the captured variables referenced in this scope. If this scope 517 // in the captured variables referenced in this scope. If this scope is the
529 // references a captured variable declared in a parent scope, it will contain 518 // top scope at function level 1 and it (or its children scopes) references a
530 // an alias for that variable. 519 // captured variable declared in a parent scope at function level 0, it will
520 // contain an alias for that variable.
531 521
532 // Since code generation for nested functions is postponed until first 522 // Since code generation for nested functions is postponed until first
533 // invocation, the function level of the closure scope can only be 1. 523 // invocation, the function level of the closure scope can only be 1.
534 ASSERT(function_level() == 1); 524 ASSERT(function_level() == 1);
535 525
536 int num_captured = 0; 526 int num_captured = 0;
537 for (int i = 0; i < num_variables(); i++) { 527 for (int i = 0; i < num_variables(); i++) {
538 LocalVariable* variable = VariableAt(i); 528 LocalVariable* variable = VariableAt(i);
539 // Count the aliases of captured variables belonging to outer scopes. 529 // Count the aliases of captured variables belonging to outer scopes.
540 if (variable->owner()->function_level() != 1) { 530 if (variable->owner()->function_level() != 1) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 owner_scope->set_context_level(context_scope.ContextLevelAt(i)); 611 owner_scope->set_context_level(context_scope.ContextLevelAt(i));
622 owner_scope->AddVariable(variable); 612 owner_scope->AddVariable(variable);
623 outer_scope->AddVariable(variable); // As alias. 613 outer_scope->AddVariable(variable); // As alias.
624 ASSERT(variable->owner() == owner_scope); 614 ASSERT(variable->owner() == owner_scope);
625 } 615 }
626 return outer_scope; 616 return outer_scope;
627 } 617 }
628 618
629 619
630 void LocalScope::RecursivelyCaptureAllVariables() { 620 void LocalScope::RecursivelyCaptureAllVariables() {
631 bool found = false;
632 for (intptr_t i = 0; i < num_variables(); i++) { 621 for (intptr_t i = 0; i < num_variables(); i++) {
633 if ((VariableAt(i)->name().raw() == Symbols::StackTraceVar().raw()) || 622 if ((VariableAt(i)->name().raw() == Symbols::StackTraceVar().raw()) ||
634 (VariableAt(i)->name().raw() == Symbols::ExceptionVar().raw()) || 623 (VariableAt(i)->name().raw() == Symbols::ExceptionVar().raw()) ||
635 (VariableAt(i)->name().raw() == Symbols::SavedTryContextVar().raw())) { 624 (VariableAt(i)->name().raw() == Symbols::SavedTryContextVar().raw())) {
636 // Don't capture those variables because the VM expects them to be on the 625 // Don't capture those variables because the VM expects them to be on the
637 // stack. 626 // stack.
638 continue; 627 continue;
639 } 628 }
640 found = CaptureVariable(VariableAt(i)->name()); 629 CaptureVariable(VariableAt(i));
641 ASSERT(found);
642 } 630 }
643 if (sibling() != NULL) { sibling()->RecursivelyCaptureAllVariables(); } 631 if (sibling() != NULL) { sibling()->RecursivelyCaptureAllVariables(); }
644 if (child() != NULL) { child()->RecursivelyCaptureAllVariables(); } 632 if (child() != NULL) { child()->RecursivelyCaptureAllVariables(); }
645 } 633 }
646 634
647 635
648 RawContextScope* LocalScope::CreateImplicitClosureScope(const Function& func) { 636 RawContextScope* LocalScope::CreateImplicitClosureScope(const Function& func) {
649 static const intptr_t kNumCapturedVars = 1; 637 static const intptr_t kNumCapturedVars = 1;
650 638
651 // Create a ContextScope with space for kNumCapturedVars descriptors. 639 // Create a ContextScope with space for kNumCapturedVars descriptors.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 return fixed_parameter_count - (index() - kParamEndSlotFromFp); 679 return fixed_parameter_count - (index() - kParamEndSlotFromFp);
692 } else { 680 } else {
693 // Shift negative indexes so that the lowest one is 0 (they are still 681 // Shift negative indexes so that the lowest one is 0 (they are still
694 // non-positive). 682 // non-positive).
695 return fixed_parameter_count - (index() - kFirstLocalSlotFromFp); 683 return fixed_parameter_count - (index() - kFirstLocalSlotFromFp);
696 } 684 }
697 } 685 }
698 686
699 687
700 } // namespace dart 688 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scopes.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698