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

Unified Diff: runtime/vm/parser.cc

Issue 266783002: Save the entry context for a function that has captured loop variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/object_test.cc ('k') | runtime/vm/parser_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index b7ff5d3f310c81f8fc370e5355f23ee06a856994..7ce8a8be2305f9596a15fc24c30555f922b096f4 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -167,21 +167,29 @@ void ParsedFunction::AllocateVariables() {
// Allocate parameters and local variables, either in the local frame or
// in the context(s).
LocalScope* context_owner = NULL; // No context needed yet.
+ bool found_captured_variables = false;
int next_free_frame_index =
scope->AllocateVariables(first_parameter_index_,
num_params,
first_stack_local_index_,
scope,
- &context_owner);
-
- // If this function allocates context variables, but none of its enclosing
- // functions do, the context on entry is not linked as parent of the allocated
- // context but saved on entry and restored on exit as to prevent memory leaks.
- // Add and allocate a local variable to this purpose.
- if (context_owner != NULL) {
+ &context_owner,
+ &found_captured_variables);
+
+ // We save the entry context for a function when...
+ //
+ // - some variable in the function is captured by nested functions, and
+ // - the function does not capture any variables from parent functions.
+ //
+ // We used to link to the parent context in these cases, but this
+ // had the effect of unintentionally retaining parent contexts which
+ // would never be accessed. By breaking the context chain at this
+ // point, we allow these outer contexts to be collected.
+ if (found_captured_variables) {
const ContextScope& context_scope =
ContextScope::Handle(function().context_scope());
if (context_scope.IsNull() || (context_scope.num_variables() == 0)) {
+ // Allocate a local variable for saving the entry context.
LocalVariable* context_var =
new LocalVariable(function().token_pos(),
Symbols::SavedEntryContextVar(),
« no previous file with comments | « runtime/vm/object_test.cc ('k') | runtime/vm/parser_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698