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

Unified Diff: src/scopes.cc

Issue 20419: Optimize loads from variables that might be shadowed by variables... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 10 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 | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/scopes.cc
===================================================================
--- src/scopes.cc (revision 1289)
+++ src/scopes.cc (working copy)
@@ -139,6 +139,7 @@
scope_calls_eval_(false),
outer_scope_calls_eval_(false),
inner_scope_calls_eval_(false),
+ outer_scope_is_eval_scope_(false),
force_eager_compilation_(false),
num_stack_slots_(0),
num_heap_slots_(0) {
@@ -312,7 +313,8 @@
// and assume they may invoke eval themselves. Eventually we could capture
// this information in the ScopeInfo and then use it here (by traversing
// the call chain stack, at compile time).
- PropagateScopeInfo(is_eval_scope());
+ bool eval_scope = is_eval_scope();
+ PropagateScopeInfo(eval_scope, eval_scope);
// 2) Resolve variables.
Scope* global_scope = NULL;
@@ -442,6 +444,7 @@
if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
if (outer_scope_calls_eval_) Indent(n1, "// outer scope calls 'eval'\n");
if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
+ if (outer_scope_is_eval_scope_) Indent(n1, "// outer scope is 'eval' scope\n");
if (num_stack_slots_ > 0) { Indent(n1, "// ");
PrintF("%d stack slots\n", num_stack_slots_); }
if (num_heap_slots_ > 0) { Indent(n1, "// ");
@@ -482,20 +485,18 @@
#endif // DEBUG
-Variable* Scope::NonLocal(Handle<String> name) {
- // Space optimization: reuse existing non-local with the same name.
+Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
+ // Space optimization: reuse existing non-local with the same name
+ // and mode.
for (int i = 0; i < nonlocals_.length(); i++) {
Variable* var = nonlocals_[i];
- if (var->name().is_identical_to(name)) {
- ASSERT(var->mode() == Variable::DYNAMIC);
+ if (var->name().is_identical_to(name) && var->mode() == mode) {
return var;
}
}
- // Otherwise create a new new-local and add it to the list.
- Variable* var = new Variable(
- NULL /* we don't know the scope */,
- name, Variable::DYNAMIC, true, false);
+ // Otherwise create a new non-local and add it to the list.
+ Variable* var = new Variable(NULL, name, mode, true, false);
nonlocals_.Add(var);
// Allocate it by giving it a dynamic lookup.
@@ -511,7 +512,9 @@
// because the variable is just a guess (and may be shadowed by another
// variable that is introduced dynamically via an 'eval' call or a 'with'
// statement).
-Variable* Scope::LookupRecursive(Handle<String> name, bool inner_lookup) {
+Variable* Scope::LookupRecursive(Handle<String> name,
+ bool inner_lookup,
+ Variable** invalidated_local) {
// If we find a variable, but the current scope calls 'eval', the found
// variable may not be the correct one (the 'eval' may introduce a
// property with the same name). In that case, remember that the variable
@@ -542,7 +545,7 @@
var = function_;
} else if (outer_scope_ != NULL) {
- var = outer_scope_->LookupRecursive(name, true /* inner lookup */);
+ var = outer_scope_->LookupRecursive(name, true, invalidated_local);
// We may have found a variable in an outer scope. However, if
// the current scope is inside a 'with', the actual variable may
// be a property introduced via the 'with' statement. Then, the
@@ -563,8 +566,10 @@
var->is_accessed_from_inner_scope_ = true;
// If the variable we have found is just a guess, invalidate the result.
- if (guess)
+ if (guess) {
+ *invalidated_local = var;
var = NULL;
+ }
return var;
}
@@ -578,7 +583,8 @@
if (proxy->var() != NULL) return;
// Otherwise, try to resolve the variable.
- Variable* var = LookupRecursive(proxy->name(), false);
+ Variable* invalidated_local = NULL;
+ Variable* var = LookupRecursive(proxy->name(), false, &invalidated_local);
if (proxy->inside_with()) {
// If we are inside a local 'with' statement, all bets are off
@@ -587,7 +593,7 @@
// Note that we must do a lookup anyway, because if we find one,
// we must mark that variable as potentially accessed from this
// inner scope (the property may not be in the 'with' object).
- var = NonLocal(proxy->name());
+ var = NonLocal(proxy->name(), Variable::DYNAMIC);
} else {
// We are not inside a local 'with' statement.
@@ -601,12 +607,23 @@
// or we don't know about the outer scope (because we are
// in an eval scope).
if (!is_global_scope() &&
- (is_eval_scope() || outer_scope_calls_eval_ ||
- scope_calls_eval_ || scope_inside_with_)) {
- // We must look up the variable at runtime, and we don't
- // know anything else.
- var = NonLocal(proxy->name());
+ (scope_inside_with_ || outer_scope_is_eval_scope_)) {
+ // If we are inside a with statement or the code is executed
+ // using eval, we give up and look up the variable at runtime.
+ var = NonLocal(proxy->name(), Variable::DYNAMIC);
+ } else if (!is_global_scope() &&
+ (scope_calls_eval_ || outer_scope_calls_eval_)) {
+ // If the code is not executed using eval and there are no
+ // with scopes, either we have a local or a global variable
+ // that might be shadowed by an eval-introduced variable.
+ if (invalidated_local != NULL) {
+ var = NonLocal(proxy->name(), Variable::DYNAMIC_LOCAL);
+ var->set_local_if_not_shadowed(invalidated_local);
+ } else {
+ var = NonLocal(proxy->name(), Variable::DYNAMIC_GLOBAL);
+ }
+
} else {
// We must have a global variable.
ASSERT(global_scope != NULL);
@@ -643,15 +660,21 @@
}
-bool Scope::PropagateScopeInfo(bool outer_scope_calls_eval) {
+bool Scope::PropagateScopeInfo(bool outer_scope_calls_eval,
+ bool outer_scope_is_eval_scope) {
if (outer_scope_calls_eval) {
outer_scope_calls_eval_ = true;
}
- bool b = scope_calls_eval_ || outer_scope_calls_eval_;
+ if (outer_scope_is_eval_scope) {
+ outer_scope_is_eval_scope_ = true;
+ }
+
+ bool calls_eval = scope_calls_eval_ || outer_scope_calls_eval_;
+ bool is_eval = is_eval_scope() || outer_scope_is_eval_scope_;
for (int i = 0; i < inner_scopes_.length(); i++) {
Scope* inner_scope = inner_scopes_[i];
- if (inner_scope->PropagateScopeInfo(b)) {
+ if (inner_scope->PropagateScopeInfo(calls_eval, is_eval)) {
inner_scope_calls_eval_ = true;
}
if (inner_scope->force_eager_compilation_) {
« no previous file with comments | « src/scopes.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698