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

Unified Diff: src/scopes.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 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/serialize.cc » ('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 6800)
+++ src/scopes.cc (working copy)
@@ -112,68 +112,92 @@
// Dummy constructor
Scope::Scope(Type type)
- : outer_scope_(NULL),
- inner_scopes_(0),
- type_(type),
- scope_name_(Factory::empty_symbol()),
+ : inner_scopes_(0),
variables_(false),
temps_(0),
params_(0),
- dynamics_(NULL),
unresolved_(0),
- decls_(0),
- receiver_(NULL),
- function_(NULL),
- arguments_(NULL),
- arguments_shadow_(NULL),
- illegal_redecl_(NULL),
- scope_inside_with_(false),
- scope_contains_with_(false),
- 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) {
+ decls_(0) {
+ SetDefaults(type, NULL, NULL);
+ ASSERT(!resolved());
}
Scope::Scope(Scope* outer_scope, Type type)
- : outer_scope_(outer_scope),
- inner_scopes_(4),
- type_(type),
- scope_name_(Factory::empty_symbol()),
+ : inner_scopes_(4),
+ variables_(),
temps_(4),
params_(4),
- dynamics_(NULL),
unresolved_(16),
- decls_(4),
- receiver_(NULL),
- function_(NULL),
- arguments_(NULL),
- arguments_shadow_(NULL),
- illegal_redecl_(NULL),
- scope_inside_with_(false),
- scope_contains_with_(false),
- 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) {
+ decls_(4) {
+ SetDefaults(type, outer_scope, NULL);
// At some point we might want to provide outer scopes to
// eval scopes (by walking the stack and reading the scope info).
// In that case, the ASSERT below needs to be adjusted.
ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL));
ASSERT(!HasIllegalRedeclaration());
+ ASSERT(!resolved());
}
+Scope::Scope(Scope* inner_scope, SerializedScopeInfo* scope_info)
+ : inner_scopes_(4),
+ variables_(),
+ temps_(4),
+ params_(4),
+ unresolved_(16),
+ decls_(4) {
+ ASSERT(scope_info != NULL);
+ SetDefaults(FUNCTION_SCOPE, inner_scope->outer_scope(), scope_info);
+ ASSERT(resolved());
+ InsertAfterScope(inner_scope);
+ if (scope_info->HasHeapAllocatedLocals()) {
+ num_heap_slots_ = scope_info_->NumberOfContextSlots();
+ }
+
+ // This scope's arguments shadow (if present) is context-allocated if an inner
+ // scope accesses this one's parameters. Allocate the arguments_shadow_
+ // variable if necessary.
+ Variable::Mode mode;
+ int arguments_shadow_index =
+ scope_info_->ContextSlotIndex(Heap::arguments_shadow_symbol(), &mode);
+ if (arguments_shadow_index >= 0) {
+ ASSERT(mode == Variable::INTERNAL);
+ arguments_shadow_ = new Variable(this,
+ Factory::arguments_shadow_symbol(),
+ Variable::INTERNAL,
+ true,
+ Variable::ARGUMENTS);
+ arguments_shadow_->set_rewrite(
+ new Slot(arguments_shadow_, Slot::CONTEXT, arguments_shadow_index));
+ arguments_shadow_->set_is_used(true);
+ }
+}
+
+
+
bool Scope::Analyze(CompilationInfo* info) {
ASSERT(info->function() != NULL);
Scope* top = info->function()->scope();
+
+ // If we have a serialized scope info, reuse it.
+ if (!info->closure().is_null()) {
+ SerializedScopeInfo* scope_info = info->closure()->shared()->scope_info();
+ if (scope_info != SerializedScopeInfo::Empty()) {
+ Scope* scope = top;
+ JSFunction* current = *info->closure();
+ do {
+ current = current->context()->closure();
+ SerializedScopeInfo* scope_info = current->shared()->scope_info();
+ if (scope_info != SerializedScopeInfo::Empty()) {
+ scope = new Scope(scope, scope_info);
+ } else {
+ ASSERT(current->context()->IsGlobalContext());
+ }
+ } while (!current->context()->IsGlobalContext());
+ }
+ }
+
while (top->outer_scope() != NULL) top = top->outer_scope();
top->AllocateVariables(info->calling_context());
@@ -191,6 +215,8 @@
void Scope::Initialize(bool inside_with) {
+ ASSERT(!resolved());
+
// Add this scope as a new inner scope of the outer scope.
if (outer_scope_ != NULL) {
outer_scope_->inner_scopes_.Add(this);
@@ -210,7 +236,7 @@
Variable* var =
variables_.Declare(this, Factory::this_symbol(), Variable::VAR,
false, Variable::THIS);
- var->rewrite_ = new Slot(var, Slot::PARAMETER, -1);
+ var->set_rewrite(new Slot(var, Slot::PARAMETER, -1));
receiver_ = var;
if (is_function_scope()) {
@@ -224,7 +250,56 @@
Variable* Scope::LocalLookup(Handle<String> name) {
- return variables_.Lookup(name);
+ Variable* result = variables_.Lookup(name);
+ if (result != NULL || !resolved()) {
+ return result;
+ }
+ // If the scope is resolved, we can find a variable in serialized scope info.
+
+ // We should never lookup 'arguments' in this scope
+ // as it is implicitly present in any scope.
+ ASSERT(*name != *Factory::arguments_symbol());
+
+ // Assert that there is no local slot with the given name.
+ ASSERT(scope_info_->StackSlotIndex(*name) < 0);
+
+ // Check context slot lookup.
+ Variable::Mode mode;
+ int index = scope_info_->ContextSlotIndex(*name, &mode);
+ if (index >= 0) {
+ Variable* var =
+ variables_.Declare(this, name, mode, true, Variable::NORMAL);
+ var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
+ return var;
+ }
+
+ index = scope_info_->ParameterIndex(*name);
+ if (index >= 0) {
+ // ".arguments" must be present in context slots.
+ ASSERT(arguments_shadow_ != NULL);
+ Variable* var =
+ variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
+ Property* rewrite =
+ new Property(new VariableProxy(arguments_shadow_),
+ new Literal(Handle<Object>(Smi::FromInt(index))),
+ RelocInfo::kNoPosition,
+ Property::SYNTHETIC);
+ rewrite->set_is_arguments_access(true);
+ var->set_rewrite(rewrite);
+ return var;
+ }
+
+ index = scope_info_->FunctionContextSlotIndex(*name);
+ if (index >= 0) {
+ // Check that there is no local slot with the given name.
+ ASSERT(scope_info_->StackSlotIndex(*name) < 0);
+ Variable* var =
+ variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
+ var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
+ return var;
+ }
+
+ return NULL;
}
@@ -250,6 +325,7 @@
// DYNAMIC variables are introduces during variable allocation,
// INTERNAL variables are allocated explicitly, and TEMPORARY
// variables are allocated via NewTemporary().
+ ASSERT(!resolved());
ASSERT(mode == Variable::VAR || mode == Variable::CONST);
return variables_.Declare(this, name, mode, true, Variable::NORMAL);
}
@@ -273,6 +349,7 @@
// Note that we must not share the unresolved variables with
// the same name because they may be removed selectively via
// RemoveUnresolved().
+ ASSERT(!resolved());
VariableProxy* proxy = new VariableProxy(name, false, inside_with);
unresolved_.Add(proxy);
return proxy;
@@ -292,6 +369,7 @@
Variable* Scope::NewTemporary(Handle<String> name) {
+ ASSERT(!resolved());
Variable* var =
new Variable(this, name, Variable::TEMPORARY, true, Variable::NORMAL);
temps_.Add(var);
@@ -305,8 +383,7 @@
void Scope::SetIllegalRedeclaration(Expression* expression) {
- // Only set the illegal redeclaration expression the
- // first time the function is called.
+ // Record only the first illegal redeclaration.
if (!HasIllegalRedeclaration()) {
illegal_redecl_ = expression;
}
@@ -550,7 +627,7 @@
// Declare a new non-local.
var = map->Declare(NULL, name, mode, true, Variable::NORMAL);
// Allocate it by giving it a dynamic lookup.
- var->rewrite_ = new Slot(var, Slot::LOOKUP, -1);
+ var->set_rewrite(new Slot(var, Slot::LOOKUP, -1));
}
return var;
}
@@ -612,8 +689,9 @@
ASSERT(var != NULL);
// If this is a lookup from an inner scope, mark the variable.
- if (inner_lookup)
- var->is_accessed_from_inner_scope_ = true;
+ if (inner_lookup) {
+ var->MarkAsAccessedFromInnerScope();
+ }
// If the variable we have found is just a guess, invalidate the
// result. If the found variable is local, record that fact so we
@@ -753,7 +831,7 @@
// via an eval() call. This is only possible if the variable has a
// visible name.
if ((var->is_this() || var->name()->length() > 0) &&
- (var->is_accessed_from_inner_scope_ ||
+ (var->is_accessed_from_inner_scope() ||
scope_calls_eval_ || inner_scope_calls_eval_ ||
scope_contains_with_)) {
var->set_is_used(true);
@@ -771,7 +849,7 @@
// context.
return
var->mode() != Variable::TEMPORARY &&
- (var->is_accessed_from_inner_scope_ ||
+ (var->is_accessed_from_inner_scope() ||
scope_calls_eval_ || inner_scope_calls_eval_ ||
scope_contains_with_ || var->is_global());
}
@@ -787,12 +865,12 @@
void Scope::AllocateStackSlot(Variable* var) {
- var->rewrite_ = new Slot(var, Slot::LOCAL, num_stack_slots_++);
+ var->set_rewrite(new Slot(var, Slot::LOCAL, num_stack_slots_++));
}
void Scope::AllocateHeapSlot(Variable* var) {
- var->rewrite_ = new Slot(var, Slot::CONTEXT, num_heap_slots_++);
+ var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++));
}
@@ -857,7 +935,7 @@
// It is ok to set this only now, because arguments is a local
// variable that is allocated after the parameters have been
// allocated.
- arguments_shadow_->is_accessed_from_inner_scope_ = true;
+ arguments_shadow_->MarkAsAccessedFromInnerScope();
}
Property* rewrite =
new Property(new VariableProxy(arguments_shadow_),
@@ -865,7 +943,7 @@
RelocInfo::kNoPosition,
Property::SYNTHETIC);
rewrite->set_is_arguments_access(true);
- var->rewrite_ = rewrite;
+ var->set_rewrite(rewrite);
}
}
@@ -880,23 +958,23 @@
ASSERT(var->scope() == this);
if (MustAllocate(var)) {
if (MustAllocateInContext(var)) {
- ASSERT(var->rewrite_ == NULL ||
+ ASSERT(var->rewrite() == NULL ||
(var->AsSlot() != NULL &&
var->AsSlot()->type() == Slot::CONTEXT));
- if (var->rewrite_ == NULL) {
+ if (var->rewrite() == NULL) {
// Only set the heap allocation if the parameter has not
// been allocated yet.
AllocateHeapSlot(var);
}
} else {
- ASSERT(var->rewrite_ == NULL ||
+ ASSERT(var->rewrite() == NULL ||
(var->AsSlot() != NULL &&
var->AsSlot()->type() == Slot::PARAMETER));
// Set the parameter index always, even if the parameter
// was seen before! (We need to access the actual parameter
// supplied for the last occurrence of a multiply declared
// parameter.)
- var->rewrite_ = new Slot(var, Slot::PARAMETER, i);
+ var->set_rewrite(new Slot(var, Slot::PARAMETER, i));
}
}
}
@@ -906,10 +984,10 @@
void Scope::AllocateNonParameterLocal(Variable* var) {
ASSERT(var->scope() == this);
- ASSERT(var->rewrite_ == NULL ||
+ ASSERT(var->rewrite() == NULL ||
(!var->IsVariable(Factory::result_symbol())) ||
(var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL));
- if (var->rewrite_ == NULL && MustAllocate(var)) {
+ if (var->rewrite() == NULL && MustAllocate(var)) {
if (MustAllocateInContext(var)) {
AllocateHeapSlot(var);
} else {
@@ -943,15 +1021,18 @@
void Scope::AllocateVariablesRecursively() {
- // The number of slots required for variables.
- num_stack_slots_ = 0;
- num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
-
// Allocate variables for inner scopes.
for (int i = 0; i < inner_scopes_.length(); i++) {
inner_scopes_[i]->AllocateVariablesRecursively();
}
+ // If scope is already resolved, we still need to allocate
+ // variables in inner scopes which might not had been resolved yet.
+ if (resolved()) return;
+ // The number of slots required for variables.
+ num_stack_slots_ = 0;
+ num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
+
// Allocate variables for this scope.
// Parameters must be allocated first, if any.
if (is_function_scope()) AllocateParameterLocals();
« no previous file with comments | « src/scopes.h ('k') | src/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698