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

Unified Diff: src/scopeinfo.cc

Issue 8352039: Cleanup ScopeInfo and SerializedScopeInfo. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Converted ScopeInfo accessors to CamelCase. Created 9 years, 1 month 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
« src/frames.cc ('K') | « src/scopeinfo.h ('k') | src/scopes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/scopeinfo.cc
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index 8ea5f1e734151684828637ea1138dbc8250bbe34..f7933a98946d98c7480f99fc935809ab6a6d95ad 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -46,475 +46,304 @@ static int CompareLocal(Variable* const* v, Variable* const* w) {
}
-template<class Allocator>
-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()),
- parameters_(scope->num_parameters()),
- stack_slots_(scope->num_stack_slots()),
- context_slots_(scope->num_heap_slots()),
- context_modes_(scope->num_heap_slots()) {
- // Add parameters.
- for (int i = 0; i < scope->num_parameters(); i++) {
- ASSERT(parameters_.length() == i);
- parameters_.Add(scope->parameter(i)->name());
- }
+Handle<ScopeInfo> ScopeInfo::Create(Scope* scope) {
+ ZoneList<Variable*> variables(32); // 32 is a wild guess
+ ASSERT(variables.is_empty());
+ scope->CollectUsedVariables(&variables);
- // Add stack locals and collect heap locals.
- // We are assuming that the locals' slots are allocated in
- // increasing order, so we can simply add them to the
- // ScopeInfo lists. However, due to usage analysis, this is
- // not true for context-allocated locals: Some of them
- // may be parameters which are allocated before the
- // non-parameter locals. When the non-parameter locals are
- // sorted according to usage, the allocated slot indices may
- // not be in increasing order with the variable list anymore.
- // Thus, we first collect the context-allocated locals, and then
- // sort them by context slot index before adding them to the
- // ScopeInfo list.
- List<Variable*, Allocator> locals(32); // 32 is a wild guess
- ASSERT(locals.is_empty());
- scope->CollectUsedVariables(&locals);
- locals.Sort(&CompareLocal);
+ ZoneList<Variable*> stack_locals(scope->num_stack_slots());
+ ZoneList<Variable*> context_locals(scope->num_heap_slots());
- List<Variable*, Allocator> heap_locals(locals.length());
- for (int i = 0; i < locals.length(); i++) {
- Variable* var = locals[i];
- if (var->is_used()) {
- switch (var->location()) {
- case Variable::UNALLOCATED:
- case Variable::PARAMETER:
- break;
+ // Collect stack and context locals.
+ for (int i = 0; i < variables.length(); i++) {
+ Variable* var = variables[i];
+ ASSERT(var->is_used());
+ switch (var->location()) {
+ case Variable::UNALLOCATED:
+ case Variable::PARAMETER:
+ break;
- case Variable::LOCAL:
- ASSERT(stack_slots_.length() == var->index());
- stack_slots_.Add(var->name());
- break;
+ case Variable::LOCAL:
+ stack_locals.Add(var);
+ break;
- case Variable::CONTEXT:
- heap_locals.Add(var);
- break;
+ case Variable::CONTEXT:
+ context_locals.Add(var);
+ break;
- case Variable::LOOKUP:
- // We don't expect lookup variables in the locals list.
- UNREACHABLE();
- break;
- }
+ case Variable::LOOKUP:
+ // We don't expect lookup variables in the locals list.
+ UNREACHABLE();
+ break;
}
}
- // Add heap locals.
- if (scope->num_heap_slots() > 0) {
- // Add user-defined slots.
- for (int i = 0; i < heap_locals.length(); i++) {
- ASSERT(heap_locals[i]->index() - Context::MIN_CONTEXT_SLOTS ==
- context_slots_.length());
- ASSERT(heap_locals[i]->index() - Context::MIN_CONTEXT_SLOTS ==
- context_modes_.length());
- context_slots_.Add(heap_locals[i]->name());
- context_modes_.Add(heap_locals[i]->mode());
+ // Determine use and location of the function variable if it is present.
+ FunctionVariableInfo function_name_info;
+ VariableMode function_variable_mode;
+ if (scope->is_function_scope() && scope->function() != NULL) {
+ Variable* var = scope->function()->var();
+ if (!var->is_used()) {
+ function_name_info = UNUSED;
+ } else if (var->IsContextSlot()) {
+ function_name_info = CONTEXT;
+ } else {
+ ASSERT(var->IsStackLocal());
+ function_name_info = STACK;
}
-
+ function_variable_mode = var->mode();
} else {
- ASSERT(heap_locals.length() == 0);
+ function_name_info = NONE;
+ function_variable_mode = VAR;
}
- // Add the function context slot, if present.
- // For now, this must happen at the very end because of the
- // ordering of the scope info slots and the respective slot indices.
- if (scope->is_function_scope()) {
- VariableProxy* proxy = scope->function();
- if (proxy != NULL &&
- proxy->var()->is_used() &&
- proxy->var()->IsContextSlot()) {
- function_name_ = proxy->name();
- // Note that we must not find the function name in the context slot
- // list - instead it must be handled separately in the
- // Contexts::Lookup() function. Thus record an empty symbol here so we
- // get the correct number of context slots.
- ASSERT(proxy->var()->index() - Context::MIN_CONTEXT_SLOTS ==
- context_slots_.length());
- ASSERT(proxy->var()->index() - Context::MIN_CONTEXT_SLOTS ==
- context_modes_.length());
- context_slots_.Add(FACTORY->empty_symbol());
- context_modes_.Add(proxy->var()->mode());
- }
- }
-}
+ const bool has_function_name = function_name_info != NONE;
+ const int num_parameters = scope->num_parameters();
+ const int num_stack_locals = stack_locals.length();
+ const int num_context_locals = context_locals.length();
+ const int length = kVariablePartIndex
+ + num_parameters + num_stack_locals + 2 * num_context_locals
+ + (has_function_name ? 2 : 0);
+ Handle<ScopeInfo> scope_info = FACTORY->NewScopeInfo(length);
-// Encoding format in a FixedArray object:
-//
-// - function name
-//
-// - calls eval boolean flag
-//
-// - is strict mode scope
-//
-// - scope type
-//
-// - number of variables in the context object (smi) (= function context
-// slot index + 1)
-// - list of pairs (name, Var mode) of context-allocated variables (starting
-// with context slot 0)
-//
-// - number of parameters (smi)
-// - list of parameter names (starting with parameter 0 first)
-//
-// - number of variables on the stack (smi)
-// - list of names of stack-allocated variables (starting with stack slot 0)
-
-// The ScopeInfo representation could be simplified and the ScopeInfo
-// re-implemented (with almost the same interface). Here is a
-// suggestion for the new format:
-//
-// - have a single list with all variable names (parameters, stack locals,
-// context locals), followed by a list of non-Object* values containing
-// the variables information (what kind, index, attributes)
-// - searching the linear list of names is fast and yields an index into the
-// list if the variable name is found
-// - that list index is then used to find the variable information in the
-// subsequent list
-// - the list entries don't have to be in any particular order, so all the
-// current sorting business can go away
-// - the ScopeInfo lookup routines can be reduced to perhaps a single lookup
-// which returns all information at once
-// - when gathering the information from a Scope, we only need to iterate
-// through the local variables (parameters and context info is already
-// present)
-
-
-template <class T>
-static inline Object** ReadInt(Object** p, T* x) {
- *x = static_cast<T>((reinterpret_cast<Smi*>(*p++))->value());
- return p;
-}
-
-
-static inline Object** ReadBool(Object** p, bool* x) {
- *x = (reinterpret_cast<Smi*>(*p++))->value() != 0;
- return p;
-}
-
-
-template <class T>
-static inline Object** ReadObject(Object** p, Handle<T>* s) {
- *s = Handle<T>::cast(Handle<Object>(*p++));
- return p;
-}
+ // Encode the flags.
+ int flags = TypeField::encode(scope->type()) |
+ CallsEvalField::encode(scope->calls_eval()) |
+ StrictModeField::encode(scope->is_strict_mode()) |
+ FunctionVariableField::encode(function_name_info) |
+ FunctionVariableMode::encode(function_variable_mode);
+ scope_info->SetFlags(flags);
+ scope_info->SetNumParameters(num_parameters);
+ scope_info->SetNumStackLocals(num_stack_locals);
+ scope_info->SetNumContextLocals(num_context_locals);
+ int index = kVariablePartIndex;
+ // Add parameters.
+ ASSERT(index == scope_info->ParameterEntriesIndex());
+ for (int i = 0; i < num_parameters; ++i) {
+ scope_info->set(index++, *scope->parameter(i)->name());
+ }
-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<T> s;
- p = ReadObject(p, &s);
- list->Add(s);
+ // Add stack locals' names. We are assuming that the stack locals'
+ // slots are allocated in increasing order, so we can simply add
+ // them to the ScopeInfo object.
+ ASSERT(index == scope_info->StackLocalEntriesIndex());
+ for (int i = 0; i < num_stack_locals; ++i) {
+ ASSERT(stack_locals[i]->index() == i);
+ scope_info->set(index++, *stack_locals[i]->name());
}
- return p;
-}
+ // Due to usage analysis, context-allocated locals are not necessarily in
+ // increasing order: Some of them may be parameters which are allocated before
+ // the non-parameter locals. When the non-parameter locals are sorted
+ // according to usage, the allocated slot indices may not be in increasing
+ // order with the variable list anymore. Thus, we first need to sort them by
+ // context slot index before adding them to the ScopeInfo object.
+ context_locals.Sort(&CompareLocal);
-template <class Allocator>
-static Object** ReadList(Object** p,
- List<Handle<String>, Allocator>* list,
- List<VariableMode, Allocator>* modes) {
- ASSERT(list->is_empty());
- int n;
- p = ReadInt(p, &n);
- while (n-- > 0) {
- Handle<String> s;
- int m;
- p = ReadObject(p, &s);
- p = ReadInt(p, &m);
- list->Add(s);
- modes->Add(static_cast<VariableMode>(m));
+ // Add context locals' names.
+ ASSERT(index == scope_info->ContextLocalNameEntriesIndex());
+ for (int i = 0; i < num_context_locals; ++i) {
+ scope_info->set(index++, *context_locals[i]->name());
}
- return p;
-}
-
-template<class Allocator>
-ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data)
- : function_name_(FACTORY->empty_symbol()),
- parameters_(4),
- stack_slots_(8),
- context_slots_(8),
- context_modes_(8) {
- if (data->length() > 0) {
- Object** p0 = data->data_start();
- Object** p = p0;
- p = ReadObject(p, &function_name_);
- p = ReadBool(p, &calls_eval_);
- p = ReadBool(p, &is_strict_mode_);
- p = ReadInt(p, &type_);
- p = ReadList<Allocator>(p, &context_slots_, &context_modes_);
- p = ReadList<Allocator>(p, &parameters_);
- p = ReadList<Allocator>(p, &stack_slots_);
- ASSERT((p - p0) == FixedArray::cast(data)->length());
+ // Add context locals' modes.
+ ASSERT(index == scope_info->ContextLocalModeEntriesIndex());
+ for (int i = 0; i < num_context_locals; ++i) {
+ scope_info->set(index++, Smi::FromInt(context_locals[i]->mode()));
}
-}
+ // If present, add the function variable name and its index.
+ ASSERT(index == scope_info->FunctionNameEntryIndex());
+ if (has_function_name) {
+ int var_index = scope->function()->var()->index();
+ scope_info->set(index++, *scope->function()->name());
+ scope_info->set(index++, Smi::FromInt(var_index));
+ ASSERT(function_name_info != STACK ||
+ (var_index == scope_info->NumStackLocals() &&
+ var_index == scope_info->NumberOfStackSlots() - 1));
+ ASSERT(function_name_info != CONTEXT ||
+ var_index == scope_info->ContextLength() - 1);
+ }
-static inline Object** WriteInt(Object** p, int x) {
- *p++ = Smi::FromInt(x);
- return p;
+ ASSERT(index == scope_info->length());
+ ASSERT(scope->num_parameters() == scope_info->NumParameters());
+ ASSERT(scope->num_stack_slots() == scope_info->NumberOfStackSlots());
+ ASSERT(scope->num_heap_slots() == scope_info->ContextLength());
+ return scope_info;
}
-static inline Object** WriteBool(Object** p, bool b) {
- *p++ = Smi::FromInt(b ? 1 : 0);
- return p;
+ScopeInfo* ScopeInfo::Empty() {
+ return reinterpret_cast<ScopeInfo*>(HEAP->empty_fixed_array());
}
-template <class T>
-static inline Object** WriteObject(Object** p, Handle<T> s) {
- *p++ = *s;
- return p;
+ScopeType ScopeInfo::Type() {
+ ASSERT(length() > 0);
+ return TypeField::decode(Flags());
}
-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 = WriteObject(p, list->at(i));
- }
- return p;
+bool ScopeInfo::CallsEval() {
+ return length() > 0 && CallsEvalField::decode(Flags());
}
-template <class Allocator>
-static Object** WriteList(Object** p,
- List<Handle<String>, Allocator>* list,
- List<VariableMode, Allocator>* modes) {
- const int n = list->length();
- p = WriteInt(p, n);
- for (int i = 0; i < n; i++) {
- p = WriteObject(p, list->at(i));
- p = WriteInt(p, modes->at(i));
- }
- return p;
+bool ScopeInfo::IsStrictMode() {
+ return length() > 0 && StrictModeField::decode(Flags());
}
-template<class Allocator>
-Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() {
- // function name, calls eval, is_strict_mode, scope type,
- // length for 3 tables:
- const int extra_slots = 1 + 1 + 1 + 1 + 3;
- int length = extra_slots +
- context_slots_.length() * 2 +
- parameters_.length() +
- stack_slots_.length();
-
- Handle<SerializedScopeInfo> data(
- SerializedScopeInfo::cast(*FACTORY->NewSerializedScopeInfo(length)));
- AssertNoAllocation nogc;
-
- Object** p0 = data->data_start();
- Object** p = p0;
- p = WriteObject(p, function_name_);
- p = WriteBool(p, calls_eval_);
- p = WriteBool(p, is_strict_mode_);
- p = WriteInt(p, type_);
- p = WriteList(p, &context_slots_, &context_modes_);
- p = WriteList(p, &parameters_);
- p = WriteList(p, &stack_slots_);
- ASSERT((p - p0) == length);
-
- return data;
+int ScopeInfo::NumberOfLocals() {
+ return NumStackLocals() + NumContextLocals();
}
-template<class Allocator>
-Handle<String> ScopeInfo<Allocator>::LocalName(int i) const {
- // A local variable can be allocated either on the stack or in the context.
- // For variables allocated in the context they are always preceded by
- // Context::MIN_CONTEXT_SLOTS of fixed allocated slots in the context.
- if (i < number_of_stack_slots()) {
- return stack_slot_name(i);
- } else {
- return context_slot_name(i - number_of_stack_slots() +
- Context::MIN_CONTEXT_SLOTS);
+int ScopeInfo::NumberOfStackSlots() {
+ if (length() > 0) {
+ bool function_name_stack_slot =
+ FunctionVariableField::decode(Flags()) == STACK;
+ return NumStackLocals() + (function_name_stack_slot ? 1 : 0);
}
+ return 0;
}
-template<class Allocator>
-int ScopeInfo<Allocator>::NumberOfLocals() const {
- int number_of_locals = number_of_stack_slots();
- if (number_of_context_slots() > 0) {
- ASSERT(number_of_context_slots() >= Context::MIN_CONTEXT_SLOTS);
- number_of_locals += number_of_context_slots() - Context::MIN_CONTEXT_SLOTS;
+int ScopeInfo::ContextLength() {
+ if (length() > 0) {
+ int context_locals = NumContextLocals();
+ bool function_name_context_slot =
+ FunctionVariableField::decode(Flags()) == CONTEXT;
+ bool has_context = context_locals > 0 ||
+ function_name_context_slot ||
+ Type() == WITH_SCOPE ||
+ (Type() == FUNCTION_SCOPE && CallsEval());
+ if (has_context) {
+ return Context::MIN_CONTEXT_SLOTS + context_locals +
+ (function_name_context_slot ? 1 : 0);
+ }
}
- return number_of_locals;
-}
-
-
-Handle<SerializedScopeInfo> SerializedScopeInfo::Create(Scope* scope) {
- ScopeInfo<ZoneListAllocationPolicy> sinfo(scope);
- return sinfo.Serialize();
-}
-
-
-SerializedScopeInfo* SerializedScopeInfo::Empty() {
- return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array());
-}
-
-
-Object** SerializedScopeInfo::ContextEntriesAddr() {
- ASSERT(length() > 0);
- // +4 for function name, calls eval, strict mode, scope type.
- return data_start() + 4;
+ return 0;
}
-Object** SerializedScopeInfo::ParameterEntriesAddr() {
- ASSERT(length() > 0);
- Object** p = ContextEntriesAddr();
- int number_of_context_slots;
- p = ReadInt(p, &number_of_context_slots);
- return p + number_of_context_slots*2; // *2 for pairs
+bool ScopeInfo::HasFunctionName() {
+ if (length() > 0) {
+ return NONE != FunctionVariableField::decode(Flags());
+ } else {
+ return false;
+ }
}
-Object** SerializedScopeInfo::StackSlotEntriesAddr() {
- ASSERT(length() > 0);
- Object** p = ParameterEntriesAddr();
- int number_of_parameter_slots;
- p = ReadInt(p, &number_of_parameter_slots);
- return p + number_of_parameter_slots;
+bool ScopeInfo::HasHeapAllocatedLocals() {
+ if (length() > 0) {
+ return NumContextLocals() > 0;
+ } else {
+ return false;
+ }
}
-bool SerializedScopeInfo::CallsEval() {
+bool ScopeInfo::HasContext() {
if (length() > 0) {
- Object** p = data_start() + 1; // +1 for function name.
- bool calls_eval;
- p = ReadBool(p, &calls_eval);
- return calls_eval;
+ return ContextLength() > 0;
+ } else {
+ return false;
}
- return false;
}
-bool SerializedScopeInfo::IsStrictMode() {
- if (length() > 0) {
- Object** p = data_start() + 2; // +2 for function name, calls eval.
- bool strict_mode;
- p = ReadBool(p, &strict_mode);
- return strict_mode;
- }
- return false;
+String* ScopeInfo::FunctionName() {
+ ASSERT(HasFunctionName());
+ return String::cast(get(FunctionNameEntryIndex()));
}
-ScopeType SerializedScopeInfo::Type() {
- ASSERT(length() > 0);
- // +3 for function name, calls eval, strict mode.
- Object** p = data_start() + 3;
- ScopeType type;
- p = ReadInt(p, &type);
- return type;
+String* ScopeInfo::ParameterName(int var) {
+ ASSERT(0 <= var && var < NumParameters());
+ int info_index = ParameterEntriesIndex() + var;
+ return String::cast(get(info_index));
}
-int SerializedScopeInfo::NumberOfStackSlots() {
- if (length() > 0) {
- Object** p = StackSlotEntriesAddr();
- int number_of_stack_slots;
- ReadInt(p, &number_of_stack_slots);
- return number_of_stack_slots;
- }
- return 0;
+String* ScopeInfo::LocalName(int var) {
+ ASSERT(0 <= var && var < NumberOfLocals());
+ ASSERT(StackLocalEntriesIndex() + NumStackLocals() ==
+ ContextLocalNameEntriesIndex());
+ int info_index = StackLocalEntriesIndex() + var;
+ return String::cast(get(info_index));
}
-int SerializedScopeInfo::NumberOfContextSlots() {
- if (length() > 0) {
- Object** p = ContextEntriesAddr();
- int number_of_context_slots;
- ReadInt(p, &number_of_context_slots);
- return number_of_context_slots + Context::MIN_CONTEXT_SLOTS;
- }
- return 0;
+String* ScopeInfo::StackLocalName(int var) {
+ ASSERT(0 <= var && var < NumStackLocals());
+ int info_index = StackLocalEntriesIndex() + var;
+ return String::cast(get(info_index));
}
-bool SerializedScopeInfo::HasHeapAllocatedLocals() {
- if (length() > 0) {
- Object** p = ContextEntriesAddr();
- int number_of_context_slots;
- ReadInt(p, &number_of_context_slots);
- return number_of_context_slots > 0;
- }
- return false;
+String* ScopeInfo::ContextLocalName(int var) {
+ ASSERT(0 <= var && var < NumContextLocals());
+ int info_index = ContextLocalNameEntriesIndex() + var;
+ return String::cast(get(info_index));
}
-bool SerializedScopeInfo::HasContext() {
- return HasHeapAllocatedLocals() ||
- Type() == WITH_SCOPE;
+VariableMode ScopeInfo::ContextLocalMode(int var) {
+ ASSERT(0 <= var && var < NumContextLocals());
+ int info_index = ContextLocalModeEntriesIndex() + var;
+ return static_cast<VariableMode>(Smi::cast(get(info_index))->value());
}
-int SerializedScopeInfo::StackSlotIndex(String* name) {
+int ScopeInfo::StackSlotIndex(String* name) {
ASSERT(name->IsSymbol());
if (length() > 0) {
- // Slots start after length entry.
- Object** p0 = StackSlotEntriesAddr();
- int number_of_stack_slots;
- p0 = ReadInt(p0, &number_of_stack_slots);
- Object** p = p0;
- Object** end = p0 + number_of_stack_slots;
- while (p != end) {
- if (*p == name) return static_cast<int>(p - p0);
- p++;
+ int start = StackLocalEntriesIndex();
+ int end = StackLocalEntriesIndex() + NumStackLocals();
+ for (int i = start; i < end; ++i) {
+ if (name == get(i)) {
+ return i - start;
+ }
}
}
return -1;
}
-int SerializedScopeInfo::ContextSlotIndex(String* name, VariableMode* mode) {
+
+int ScopeInfo::ContextSlotIndex(String* name, VariableMode* mode) {
ASSERT(name->IsSymbol());
- Isolate* isolate = GetIsolate();
- int result = isolate->context_slot_cache()->Lookup(this, name, mode);
- if (result != ContextSlotCache::kNotFound) return result;
+ ASSERT(mode != NULL);
if (length() > 0) {
- // Slots start after length entry.
- Object** p0 = ContextEntriesAddr();
- int number_of_context_slots;
- p0 = ReadInt(p0, &number_of_context_slots);
- Object** p = p0;
- Object** end = p0 + number_of_context_slots * 2;
- while (p != end) {
- if (*p == name) {
- ASSERT(((p - p0) & 1) == 0);
- int v;
- ReadInt(p + 1, &v);
- VariableMode mode_value = static_cast<VariableMode>(v);
- if (mode != NULL) *mode = mode_value;
- result = static_cast<int>((p - p0) >> 1) + Context::MIN_CONTEXT_SLOTS;
- isolate->context_slot_cache()->Update(this, name, mode_value, result);
+ ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache();
+ int result = context_slot_cache->Lookup(this, name, mode);
+ if (result != ContextSlotCache::kNotFound) {
+ ASSERT(result < ContextLength());
+ return result;
+ }
+
+ int start = ContextLocalNameEntriesIndex();
+ int end = ContextLocalNameEntriesIndex() + NumContextLocals();
+ for (int i = start; i < end; ++i) {
+ if (name == get(i)) {
+ int var = i - start;
+ *mode = ContextLocalMode(var);
+ result = Context::MIN_CONTEXT_SLOTS + var;
+ context_slot_cache->Update(this, name, *mode, result);
+ ASSERT(result < ContextLength());
return result;
}
- p += 2;
}
+ context_slot_cache->Update(this, name, INTERNAL, -1);
}
- isolate->context_slot_cache()->Update(this, name, INTERNAL, -1);
return -1;
}
-int SerializedScopeInfo::ParameterIndex(String* name) {
+int ScopeInfo::ParameterIndex(String* name) {
ASSERT(name->IsSymbol());
if (length() > 0) {
// We must read parameters from the end since for
@@ -522,49 +351,58 @@ int SerializedScopeInfo::ParameterIndex(String* name) {
// last declaration of that parameter is used
// inside a function (and thus we need to look
// at the last index). Was bug# 1110337.
- //
- // Eventually, we should only register such parameters
- // once, with corresponding index. This requires a new
- // implementation of the ScopeInfo code. See also other
- // comments in this file regarding this.
- Object** p = ParameterEntriesAddr();
- int number_of_parameter_slots;
- Object** p0 = ReadInt(p, &number_of_parameter_slots);
- p = p0 + number_of_parameter_slots;
- while (p > p0) {
- p--;
- if (*p == name) return static_cast<int>(p - p0);
+ int start = ParameterEntriesIndex();
+ int end = ParameterEntriesIndex() + NumParameters();
+ for (int i = end - 1; i >= start; --i) {
+ if (name == get(i)) {
+ return i - start;
+ }
}
}
return -1;
}
-int SerializedScopeInfo::FunctionContextSlotIndex(String* name,
- VariableMode* mode) {
+int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
ASSERT(name->IsSymbol());
+ ASSERT(mode != NULL);
if (length() > 0) {
- Object** p = data_start();
- if (*p == name) {
- p = ContextEntriesAddr();
- int number_of_context_slots;
- p = ReadInt(p, &number_of_context_slots);
- ASSERT(number_of_context_slots != 0);
- // The function context slot is the last entry.
- if (mode != NULL) {
- // Seek to context slot entry.
- p += (number_of_context_slots - 1) * 2;
- // Seek to mode.
- ++p;
- ReadInt(p, mode);
- }
- return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1;
+ if (FunctionVariableField::decode(Flags()) == CONTEXT &&
+ FunctionName() == name) {
+ *mode = FunctionVariableMode::decode(Flags());
+ return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
}
}
return -1;
}
+int ScopeInfo::ParameterEntriesIndex() {
+ ASSERT(length() > 0);
+ return kVariablePartIndex;
+}
+
+
+int ScopeInfo::StackLocalEntriesIndex() {
+ return ParameterEntriesIndex() + NumParameters();
+}
+
+
+int ScopeInfo::ContextLocalNameEntriesIndex() {
+ return StackLocalEntriesIndex() + NumStackLocals();
+}
+
+
+int ScopeInfo::ContextLocalModeEntriesIndex() {
+ return ContextLocalNameEntriesIndex() + NumContextLocals();
+}
+
+
+int ScopeInfo::FunctionNameEntryIndex() {
+ return ContextLocalModeEntriesIndex() + NumContextLocals();
+}
+
+
int ContextSlotCache::Hash(Object* data, String* name) {
// Uses only lower 32 bits if pointers are larger.
uintptr_t addr_hash =
@@ -631,46 +469,50 @@ void ContextSlotCache::ValidateEntry(Object* data,
}
-template <class Allocator>
static void PrintList(const char* list_name,
int nof_internal_slots,
- List<Handle<String>, Allocator>& list) {
- if (list.length() > 0) {
+ int start,
+ int end,
+ ScopeInfo* scope_info) {
+ if (start < end) {
PrintF("\n // %s\n", list_name);
if (nof_internal_slots > 0) {
PrintF(" %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1);
}
- for (int i = 0; i < list.length(); i++) {
- PrintF(" %2d ", i + nof_internal_slots);
- list[i]->ShortPrint();
+ for (int i = nof_internal_slots; start < end; ++i, ++start) {
+ PrintF(" %2d ", i);
+ String::cast(scope_info->get(start))->ShortPrint();
PrintF("\n");
}
}
}
-template<class Allocator>
-void ScopeInfo<Allocator>::Print() {
+void ScopeInfo::Print() {
PrintF("ScopeInfo ");
- if (function_name_->length() > 0)
- function_name_->ShortPrint();
- else
+ if (HasFunctionName()) {
+ FunctionName()->ShortPrint();
+ } else {
PrintF("/* no function name */");
+ }
PrintF("{");
- PrintList<Allocator>("parameters", 0, parameters_);
- PrintList<Allocator>("stack slots", 0, stack_slots_);
- PrintList<Allocator>("context slots", Context::MIN_CONTEXT_SLOTS,
- context_slots_);
+ PrintList("parameters", 0,
+ ParameterEntriesIndex(),
+ ParameterEntriesIndex() + NumParameters(),
+ this);
+ PrintList("stack slots", 0,
+ StackLocalEntriesIndex(),
+ StackLocalEntriesIndex() + NumStackLocals(),
+ this);
+ PrintList("context slots",
+ Context::MIN_CONTEXT_SLOTS,
+ ContextLocalNameEntriesIndex(),
+ ContextLocalNameEntriesIndex() + NumContextLocals(),
+ this);
PrintF("}\n");
}
#endif // DEBUG
-
-// Make sure the classes get instantiated by the template system.
-template class ScopeInfo<FreeStoreAllocationPolicy>;
-template class ScopeInfo<PreallocatedStorage>;
-template class ScopeInfo<ZoneListAllocationPolicy>;
-
} } // namespace v8::internal
« src/frames.cc ('K') | « src/scopeinfo.h ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698