| Index: src/scopeinfo.cc
|
| diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
|
| index 3e18368f74bde67569d01223a66717b64ad10bd2..54c43304a3a3f9f50daf9f3003563fefc1cb29a5 100644
|
| --- a/src/scopeinfo.cc
|
| +++ b/src/scopeinfo.cc
|
| @@ -55,10 +55,15 @@ 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()),
|
| + first_stack_index_(-1),
|
| 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);
|
| @@ -94,7 +99,8 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
|
| break;
|
|
|
| case Slot::LOCAL:
|
| - ASSERT(stack_slots_.length() == slot->index());
|
| + if (first_stack_index_ < 0) first_stack_index_ = slot->index();
|
| + ASSERT(stack_slots_.length() + first_stack_index_ == slot->index());
|
| stack_slots_.Add(var->name());
|
| break;
|
|
|
| @@ -148,6 +154,14 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
|
| context_modes_.Add(Variable::INTERNAL);
|
| }
|
| }
|
| +
|
| + // Add inner scope information.
|
| + ZoneList<Scope*>* inner_scopes = scope->InnerScopes();
|
| + for (int i = 0; i < inner_scopes->length(); i++) {
|
| + if (!inner_scopes->at(i)->is_catch_scope() &&
|
| + !inner_scopes->at(i)->is_with_scope()) continue;
|
| + inner_scopeinfos_.Add(SerializedScopeInfo::Create(inner_scopes->at(i)));
|
| + }
|
| }
|
|
|
|
|
| @@ -157,6 +171,16 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
|
| //
|
| // - calls eval boolean flag
|
| //
|
| +// - strict scope boolean flag
|
| +//
|
| +// - scope type
|
| +//
|
| +// - start statement position
|
| +//
|
| +// - end statement position
|
| +//
|
| +// - first stack index for stack slots
|
| +//
|
| // - number of variables in the context object (smi) (= function context
|
| // slot index + 1)
|
| // - list of pairs (name, Var mode) of context-allocated variables (starting
|
| @@ -167,6 +191,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
|
| @@ -188,8 +215,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;
|
| }
|
|
|
| @@ -200,19 +228,20 @@ 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** ReadSymbol(Object** p, Handle<T>* s) {
|
| + *s = Handle<T>(reinterpret_cast<T*>(*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;
|
| + Handle<T> s;
|
| p = ReadSymbol(p, &s);
|
| list->Add(s);
|
| }
|
| @@ -245,16 +274,22 @@ 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 = 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 = ReadInt(p, &first_stack_index_);
|
| p = ReadList<Allocator>(p, &context_slots_, &context_modes_);
|
| p = ReadList<Allocator>(p, ¶meters_);
|
| p = ReadList<Allocator>(p, &stack_slots_);
|
| + p = ReadList<Allocator>(p, &inner_scopeinfos_);
|
| ASSERT((p - p0) == FixedArray::cast(data)->length());
|
| }
|
| }
|
| @@ -272,14 +307,15 @@ static inline Object** WriteBool(Object** p, bool b) {
|
| }
|
|
|
|
|
| -static inline Object** WriteSymbol(Object** p, Handle<String> s) {
|
| +template <class T>
|
| +static inline Object** WriteSymbol(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++) {
|
| @@ -305,12 +341,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, scope type, is_strict_mode, source beg pos,
|
| + // source end pos, first stack slot, length for 4 tables:
|
| + const int extra_slots = 1 + 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->NewFixedArray(length, TENURED)));
|
| @@ -321,9 +359,14 @@ Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() {
|
| p = WriteSymbol(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 = WriteInt(p, first_stack_index_);
|
| p = WriteList(p, &context_slots_, &context_modes_);
|
| p = WriteList(p, ¶meters_);
|
| p = WriteList(p, &stack_slots_);
|
| + p = WriteList(p, &inner_scopeinfos_);
|
| ASSERT((p - p0) == length);
|
|
|
| return data;
|
| @@ -368,8 +411,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, first stack slot.
|
| + return data_start() + 7;
|
| }
|
|
|
|
|
| @@ -391,6 +435,16 @@ 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.
|
| @@ -413,6 +467,54 @@ 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);
|
| + 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;
|
| +}
|
| +
|
| +
|
| +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::FirstStackSlot() {
|
| + if (length() > 0) {
|
| + // +6 for function name, calls eval, strict mode, scope type,
|
| + // source beg pos, source end pos.
|
| + Object** p = data_start() + 6;
|
| + int source_end_pos;
|
| + p = ReadInt(p, &source_end_pos);
|
| + return source_end_pos;
|
| + }
|
| + return -1;
|
| +}
|
| +
|
| +
|
| int SerializedScopeInfo::NumberOfStackSlots() {
|
| if (length() > 0) {
|
| Object** p = StackSlotEntriesAddr();
|
| @@ -435,6 +537,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();
|
| @@ -446,6 +566,13 @@ bool SerializedScopeInfo::HasHeapAllocatedLocals() {
|
| }
|
|
|
|
|
| +bool SerializedScopeInfo::HasContext() {
|
| + return ScopeType() == Scope::WITH_SCOPE ||
|
| + ScopeType() == Scope::GLOBAL_SCOPE ||
|
| + HasHeapAllocatedLocals();
|
| +}
|
| +
|
| +
|
| int SerializedScopeInfo::StackSlotIndex(String* name) {
|
| ASSERT(name->IsSymbol());
|
| if (length() > 0) {
|
| @@ -537,6 +664,24 @@ int SerializedScopeInfo::FunctionContextSlotIndex(String* name) {
|
| }
|
|
|
|
|
| +void SerializedScopeInfo::GetLocalScopeChain(
|
| + 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->GetLocalScopeChain(chain, position);
|
| + return;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| int ContextSlotCache::Hash(Object* data, String* name) {
|
| // Uses only lower 32 bits if pointers are larger.
|
| uintptr_t addr_hash =
|
|
|