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

Unified Diff: src/scopeinfo.cc

Issue 7979001: Scope tree serialization and ScopeIterator cleanup. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 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 side-by-side diff with in-line comments
Download patch
Index: src/scopeinfo.cc
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index ad31ca47c613350f3293787df8a0eebe4a3c4705..919f97e5197c6b423c4551d7573320e6440cf8d6 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -51,10 +51,14 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
: function_name_(FACTORY->empty_symbol()),
calls_eval_(scope->calls_eval()),
is_strict_mode_(scope->is_strict_mode()),
+ type_(scope->type()),
+ source_beg_statement_pos_(scope->SourceBegStatementPos()),
+ source_end_statement_pos_(scope->SourceEndStatementPos()),
parameters_(scope->num_parameters()),
stack_slots_(scope->num_stack_slots()),
context_slots_(scope->num_heap_slots()),
- context_modes_(scope->num_heap_slots()) {
+ context_modes_(scope->num_heap_slots()),
+ inner_scopeinfos_(scope->InnerScopes()->length()) {
// Add parameters.
for (int i = 0; i < scope->num_parameters(); i++) {
ASSERT(parameters_.length() == i);
@@ -141,6 +145,15 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
context_modes_.Add(Variable::INTERNAL);
}
}
+
+ // Add nested scope information. Only nested block, catch or with scopes are
+ // tracked, but no inner function scopes.
+ ZoneList<Scope*>* inner_scopes = scope->InnerScopes();
+ for (int i = 0; i < inner_scopes->length(); i++) {
+ if (!inner_scopes->at(i)->is_declaration_scope()) {
+ inner_scopeinfos_.Add(SerializedScopeInfo::Create(inner_scopes->at(i)));
+ }
+ }
}
@@ -150,6 +163,14 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
//
// - calls eval boolean flag
Kevin Millikin (Chromium) 2011/10/05 08:43:36 This is a separate change, but this class should b
Steven 2011/10/06 19:09:27 Yes I agree. We will talk about this cleanup later
//
+// - is strict mode scope
+//
+// - scope type
+//
+// - start statement position
+//
+// - end statement position
+//
// - number of variables in the context object (smi) (= function context
// slot index + 1)
// - list of pairs (name, Var mode) of context-allocated variables (starting
@@ -160,6 +181,9 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
//
// - number of variables on the stack (smi)
// - list of names of stack-allocated variables (starting with stack slot 0)
+//
+// - number of immediate nested scopes (smi)
+// - list of handles to serialized scope infos for nested scopes
// The ScopeInfo representation could be simplified and the ScopeInfo
// re-implemented (with almost the same interface). Here is a
@@ -181,8 +205,9 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
// present)
-static inline Object** ReadInt(Object** p, int* x) {
- *x = (reinterpret_cast<Smi*>(*p++))->value();
+template <class T>
+static inline Object** ReadInt(Object** p, T* x) {
+ *x = static_cast<T>((reinterpret_cast<Smi*>(*p++))->value());
return p;
}
@@ -193,20 +218,21 @@ static inline Object** ReadBool(Object** p, bool* x) {
}
-static inline Object** ReadSymbol(Object** p, Handle<String>* s) {
- *s = Handle<String>(reinterpret_cast<String*>(*p++));
+template <class T>
+static inline Object** ReadObject(Object** p, Handle<T>* s) {
+ *s = Handle<T>::cast(Handle<Object>(*p++));
return p;
}
-template <class Allocator>
-static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) {
+template <class Allocator, class T>
+static Object** ReadList(Object** p, List<Handle<T>, Allocator >* list) {
ASSERT(list->is_empty());
int n;
p = ReadInt(p, &n);
while (n-- > 0) {
- Handle<String> s;
- p = ReadSymbol(p, &s);
+ Handle<T> s;
+ p = ReadObject(p, &s);
list->Add(s);
}
return p;
@@ -223,7 +249,7 @@ static Object** ReadList(Object** p,
while (n-- > 0) {
Handle<String> s;
int m;
- p = ReadSymbol(p, &s);
+ p = ReadObject(p, &s);
p = ReadInt(p, &m);
list->Add(s);
modes->Add(static_cast<Variable::Mode>(m));
@@ -238,16 +264,21 @@ ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data)
parameters_(4),
stack_slots_(8),
context_slots_(8),
- context_modes_(8) {
+ context_modes_(8),
+ inner_scopeinfos_(4) {
if (data->length() > 0) {
Object** p0 = data->data_start();
Object** p = p0;
- p = ReadSymbol(p, &function_name_);
+ p = ReadObject(p, &function_name_);
p = ReadBool(p, &calls_eval_);
p = ReadBool(p, &is_strict_mode_);
+ p = ReadInt(p, &type_);
+ p = ReadInt(p, &source_beg_statement_pos_);
+ p = ReadInt(p, &source_end_statement_pos_);
p = ReadList<Allocator>(p, &context_slots_, &context_modes_);
p = ReadList<Allocator>(p, &parameters_);
p = ReadList<Allocator>(p, &stack_slots_);
+ p = ReadList<Allocator>(p, &inner_scopeinfos_);
ASSERT((p - p0) == FixedArray::cast(data)->length());
}
}
@@ -265,18 +296,19 @@ static inline Object** WriteBool(Object** p, bool b) {
}
-static inline Object** WriteSymbol(Object** p, Handle<String> s) {
+template <class T>
+static inline Object** WriteObject(Object** p, Handle<T> s) {
*p++ = *s;
return p;
}
-template <class Allocator>
-static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) {
+template <class Allocator, class T>
+static Object** WriteList(Object** p, List<Handle<T>, Allocator >* list) {
const int n = list->length();
p = WriteInt(p, n);
for (int i = 0; i < n; i++) {
- p = WriteSymbol(p, list->at(i));
+ p = WriteObject(p, list->at(i));
}
return p;
}
@@ -289,7 +321,7 @@ static Object** WriteList(Object** p,
const int n = list->length();
p = WriteInt(p, n);
for (int i = 0; i < n; i++) {
- p = WriteSymbol(p, list->at(i));
+ p = WriteObject(p, list->at(i));
p = WriteInt(p, modes->at(i));
}
return p;
@@ -298,12 +330,14 @@ static Object** WriteList(Object** p,
template<class Allocator>
Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() {
- // function name, calls eval, is_strict_mode, length for 3 tables:
- const int extra_slots = 1 + 1 + 1 + 3;
+ // function name, calls eval, is_strict_mode, scope type, source beg pos,
+ // source end pos, length for 4 tables:
+ const int extra_slots = 1 + 1 + 1 + 1 + 1 + 1 + 4;
int length = extra_slots +
context_slots_.length() * 2 +
parameters_.length() +
- stack_slots_.length();
+ stack_slots_.length() +
+ inner_scopeinfos_.length();
Handle<SerializedScopeInfo> data(
SerializedScopeInfo::cast(*FACTORY->NewSerializedScopeInfo(length)));
@@ -311,12 +345,16 @@ Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() {
Object** p0 = data->data_start();
Object** p = p0;
- p = WriteSymbol(p, function_name_);
+ p = WriteObject(p, function_name_);
p = WriteBool(p, calls_eval_);
p = WriteBool(p, is_strict_mode_);
+ p = WriteInt(p, type_);
+ p = WriteInt(p, source_beg_statement_pos_);
+ p = WriteInt(p, source_end_statement_pos_);
p = WriteList(p, &context_slots_, &context_modes_);
p = WriteList(p, &parameters_);
p = WriteList(p, &stack_slots_);
+ p = WriteList(p, &inner_scopeinfos_);
ASSERT((p - p0) == length);
return data;
@@ -361,8 +399,9 @@ SerializedScopeInfo* SerializedScopeInfo::Empty() {
Object** SerializedScopeInfo::ContextEntriesAddr() {
ASSERT(length() > 0);
- // +3 for function name, calls eval, strict mode.
- return data_start() + 3;
+ // +6 for function name, calls eval, strict mode, scope type, source beg pos,
+ // source end pos.
+ return data_start() + 6;
}
@@ -384,6 +423,15 @@ Object** SerializedScopeInfo::StackSlotEntriesAddr() {
}
+Object** SerializedScopeInfo::NestedScopeEntriesAddr() {
+ ASSERT(length() > 0);
+ Object** p = StackSlotEntriesAddr();
+ int number_of_stack_slots;
+ p = ReadInt(p, &number_of_stack_slots);
+ return p + number_of_stack_slots;
+}
+
+
bool SerializedScopeInfo::CallsEval() {
if (length() > 0) {
Object** p = data_start() + 1; // +1 for function name.
@@ -406,6 +454,41 @@ bool SerializedScopeInfo::IsStrictMode() {
}
+Scope::Type SerializedScopeInfo::ScopeType() {
+ ASSERT(length() > 0);
+ // +3 for function name, calls eval, strict mode.
+ Object** p = data_start() + 3;
+ Scope::Type type;
+ p = ReadInt(p, &type);
Kevin Millikin (Chromium) 2011/10/05 08:43:36 Future refactoring: if you decide to keep the stre
+ return type;
+}
+
+
+int SerializedScopeInfo::SourceBegStatementPos() {
+ if (length() > 0) {
+ // +4 for function name, calls eval, strict mode, scope type.
+ Object** p = data_start() + 4;
+ int source_beg_statement_pos;
+ p = ReadInt(p, &source_beg_statement_pos);
+ return source_beg_statement_pos;
+ }
+ return -1;
Kevin Millikin (Chromium) 2011/10/05 08:43:36 -1 is RelocInfo::kNoPosition?
Steven 2011/10/06 19:09:27 Yes it is. Using the named constant now. On 2011/1
+}
+
+
+int SerializedScopeInfo::SourceEndStatementPos() {
+ if (length() > 0) {
+ // +5 for function name, calls eval, strict mode, scope type,
+ // source beg pos.
+ Object** p = data_start() + 5;
+ int source_end_statement_pos;
+ p = ReadInt(p, &source_end_statement_pos);
+ return source_end_statement_pos;
+ }
+ return -1;
+}
+
+
int SerializedScopeInfo::NumberOfStackSlots() {
if (length() > 0) {
Object** p = StackSlotEntriesAddr();
@@ -428,6 +511,24 @@ int SerializedScopeInfo::NumberOfContextSlots() {
}
+int SerializedScopeInfo::NumberOfNestedScopes() {
+ if (length() > 0) {
+ Object** p = NestedScopeEntriesAddr();
+ int number_of_nested_scopes;
+ ReadInt(p, &number_of_nested_scopes);
+ return number_of_nested_scopes;
+ }
+ return 0;
+}
+
+
+Handle<SerializedScopeInfo> SerializedScopeInfo::NestedScope(int i) {
+ ASSERT(0 <= i && i < NumberOfNestedScopes());
+ Object* p = *(NestedScopeEntriesAddr() + i + 1);
+ return Handle<SerializedScopeInfo>(reinterpret_cast<SerializedScopeInfo*>(p));
+}
+
+
bool SerializedScopeInfo::HasHeapAllocatedLocals() {
if (length() > 0) {
Object** p = ContextEntriesAddr();
@@ -439,6 +540,12 @@ bool SerializedScopeInfo::HasHeapAllocatedLocals() {
}
+bool SerializedScopeInfo::HasContext() {
+ return HasHeapAllocatedLocals() ||
+ ScopeType() == Scope::WITH_SCOPE;
+}
+
+
int SerializedScopeInfo::StackSlotIndex(String* name) {
ASSERT(name->IsSymbol());
if (length() > 0) {
@@ -530,6 +637,24 @@ int SerializedScopeInfo::FunctionContextSlotIndex(String* name) {
}
+void SerializedScopeInfo::GetNestedScopeChain(
+ List<Handle<SerializedScopeInfo> >* chain,
+ int position) {
+ chain->Add(Handle<SerializedScopeInfo>(this));
+
+ for (int i = 0; i < NumberOfNestedScopes(); i++) {
+ Handle<SerializedScopeInfo> scope = NestedScope(i);
+ int beg_pos = scope->SourceBegStatementPos();
+ int end_pos = scope->SourceEndStatementPos();
+ ASSERT(beg_pos >= 0 && end_pos >= 0);
+ if (beg_pos <= position && position <= end_pos) {
+ scope->GetNestedScopeChain(chain, position);
+ return;
+ }
+ }
+}
+
+
int ContextSlotCache::Hash(Object* data, String* name) {
// Uses only lower 32 bits if pointers are larger.
uintptr_t addr_hash =

Powered by Google App Engine
This is Rietveld 408576698