Index: src/scopeinfo.cc |
=================================================================== |
--- src/scopeinfo.cc (revision 5059) |
+++ src/scopeinfo.cc (working copy) |
@@ -204,12 +204,6 @@ |
} |
-static inline Object** ReadSentinel(Object** p) { |
- ASSERT(*p == NULL); |
- return p + 1; |
-} |
- |
- |
template <class Allocator> |
static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) { |
ASSERT(list->is_empty()); |
@@ -220,7 +214,7 @@ |
p = ReadSymbol(p, &s); |
list->Add(s); |
} |
- return ReadSentinel(p); |
+ return p; |
} |
@@ -239,42 +233,19 @@ |
list->Add(s); |
modes->Add(static_cast<Variable::Mode>(m)); |
} |
- return ReadSentinel(p); |
+ return p; |
} |
template<class Allocator> |
-Handle<Object> ScopeInfo<Allocator>::CreateHeapObject(Scope* scope) { |
- ScopeInfo<ZoneListAllocationPolicy> sinfo(scope); |
- return sinfo.Serialize(); |
-} |
- |
- |
-template<class Allocator> |
-Object* ScopeInfo<Allocator>::EmptyHeapObject() { |
- return Heap::empty_fixed_array(); |
-} |
- |
- |
-inline bool IsNotEmpty(Object* data) { |
- return FixedArray::cast(data)->length() != 0; |
-} |
- |
- |
-inline Object** GetDataStart(Object* data) { |
- return FixedArray::cast(data)->data_start(); |
-} |
- |
- |
-template<class Allocator> |
-ScopeInfo<Allocator>::ScopeInfo(Object* data) |
+ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data) |
: function_name_(Factory::empty_symbol()), |
parameters_(4), |
stack_slots_(8), |
context_slots_(8), |
context_modes_(8) { |
- if (IsNotEmpty(data)) { |
- Object** p0 = GetDataStart(data); |
+ if (data->length() > 0) { |
+ Object** p0 = data->data_start(); |
Object** p = p0; |
p = ReadSymbol(p, &function_name_); |
p = ReadBool(p, &calls_eval_); |
@@ -304,12 +275,6 @@ |
} |
-static inline Object** WriteSentinel(Object** p) { |
- *p++ = NULL; |
- return p; |
-} |
- |
- |
template <class Allocator> |
static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) { |
const int n = list->length(); |
@@ -317,7 +282,7 @@ |
for (int i = 0; i < n; i++) { |
p = WriteSymbol(p, list->at(i)); |
} |
- return WriteSentinel(p); |
+ return p; |
} |
@@ -331,23 +296,24 @@ |
p = WriteSymbol(p, list->at(i)); |
p = WriteInt(p, modes->at(i)); |
} |
- return WriteSentinel(p); |
+ return p; |
} |
template<class Allocator> |
-Handle<Object> ScopeInfo<Allocator>::Serialize() { |
- // function name, calls eval, length & sentinel for 3 tables: |
- const int extra_slots = 1 + 1 + 2 * 3; |
+Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { |
+ // function name, calls eval, length for 3 tables: |
+ const int extra_slots = 1 + 1 + 3; |
int length = extra_slots + |
context_slots_.length() * 2 + |
parameters_.length() + |
stack_slots_.length(); |
- Handle<Object> data(Factory::NewFixedArray(length, TENURED)); |
+ Handle<SerializedScopeInfo> data( |
+ SerializedScopeInfo::cast(*Factory::NewFixedArray(length, TENURED))); |
AssertNoAllocation nogc; |
- Object** p0 = GetDataStart(*data); |
+ Object** p0 = data->data_start(); |
Object** p = p0; |
p = WriteSymbol(p, function_name_); |
p = WriteBool(p, calls_eval_); |
@@ -360,36 +326,69 @@ |
} |
-static Object** ContextEntriesAddr(Object* data) { |
- ASSERT(IsNotEmpty(data)); |
- // +2 for function name and calls eval: |
- return GetDataStart(data) + 2; |
+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); |
+ } |
} |
-static Object** ParameterEntriesAddr(Object* data) { |
- ASSERT(IsNotEmpty(data)); |
- Object** p = ContextEntriesAddr(data); |
- int n; // number of context slots; |
- p = ReadInt(p, &n); |
- return p + n*2 + 1; // *2 for pairs, +1 for sentinel |
+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; |
+ } |
+ return number_of_locals; |
} |
-static Object** StackSlotEntriesAddr(Object* data) { |
- ASSERT(IsNotEmpty(data)); |
- Object** p = ParameterEntriesAddr(data); |
- int n; // number of parameter slots; |
- p = ReadInt(p, &n); |
- return p + n + 1; // +1 for sentinel |
+Handle<SerializedScopeInfo> SerializedScopeInfo::Create(Scope* scope) { |
+ ScopeInfo<ZoneListAllocationPolicy> sinfo(scope); |
+ return sinfo.Serialize(); |
} |
-template<class Allocator> |
-bool ScopeInfo<Allocator>::CallsEval(Object* data) { |
- if (IsNotEmpty(data)) { |
- // +1 for function name: |
- Object** p = GetDataStart(data) + 1; |
+SerializedScopeInfo* SerializedScopeInfo::Empty() { |
+ return reinterpret_cast<SerializedScopeInfo*>(Heap::empty_fixed_array()); |
+} |
+ |
+ |
+Object** SerializedScopeInfo::ContextEntriesAddr() { |
+ ASSERT(length() > 0); |
+ return data_start() + 2; // +2 for function name and calls eval. |
+} |
+ |
+ |
+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 |
+} |
+ |
+ |
+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 SerializedScopeInfo::CallsEval() { |
+ if (length() > 0) { |
+ Object** p = data_start() + 1; // +1 for function name. |
bool calls_eval; |
p = ReadBool(p, &calls_eval); |
return calls_eval; |
@@ -398,53 +397,49 @@ |
} |
-template<class Allocator> |
-int ScopeInfo<Allocator>::NumberOfStackSlots(Object* data) { |
- if (IsNotEmpty(data)) { |
- Object** p = StackSlotEntriesAddr(data); |
- int n; // number of stack slots; |
- ReadInt(p, &n); |
- return n; |
+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; |
} |
-template<class Allocator> |
-int ScopeInfo<Allocator>::NumberOfContextSlots(Object* data) { |
- if (IsNotEmpty(data)) { |
- Object** p = ContextEntriesAddr(data); |
- int n; // number of context slots; |
- ReadInt(p, &n); |
- return n + Context::MIN_CONTEXT_SLOTS; |
+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; |
} |
-template<class Allocator> |
-bool ScopeInfo<Allocator>::HasHeapAllocatedLocals(Object* data) { |
- if (IsNotEmpty(data)) { |
- Object** p = ContextEntriesAddr(data); |
- int n; // number of context slots; |
- ReadInt(p, &n); |
- return n > 0; |
+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; |
} |
-template<class Allocator> |
-int ScopeInfo<Allocator>::StackSlotIndex(Object* data, String* name) { |
+int SerializedScopeInfo::StackSlotIndex(String* name) { |
ASSERT(name->IsSymbol()); |
- if (IsNotEmpty(data)) { |
- // Loop below depends on the NULL sentinel after the stack slot names. |
- ASSERT(NumberOfStackSlots(data) > 0 || |
- *(StackSlotEntriesAddr(data) + 1) == NULL); |
- // slots start after length entry |
- Object** p0 = StackSlotEntriesAddr(data) + 1; |
+ 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; |
- while (*p != NULL) { |
+ Object** end = p0 + number_of_stack_slots; |
+ while (p != end) { |
if (*p == name) return static_cast<int>(p - p0); |
p++; |
} |
@@ -452,24 +447,18 @@ |
return -1; |
} |
- |
-template<class Allocator> |
-int ScopeInfo<Allocator>::ContextSlotIndex(Object* data, |
- String* name, |
- Variable::Mode* mode) { |
+int SerializedScopeInfo::ContextSlotIndex(String* name, Variable::Mode* mode) { |
ASSERT(name->IsSymbol()); |
- int result = ContextSlotCache::Lookup(data, name, mode); |
+ int result = ContextSlotCache::Lookup(this, name, mode); |
if (result != ContextSlotCache::kNotFound) return result; |
- if (IsNotEmpty(data)) { |
- // Loop below depends on the NULL sentinel after the context slot names. |
- ASSERT(NumberOfContextSlots(data) >= Context::MIN_CONTEXT_SLOTS || |
- *(ContextEntriesAddr(data) + 1) == NULL); |
- |
- // slots start after length entry |
- Object** p0 = ContextEntriesAddr(data) + 1; |
+ 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; |
- // contexts may have no variable slots (in the presence of eval()). |
- while (*p != NULL) { |
+ Object** end = p0 + number_of_context_slots * 2; |
+ while (p != end) { |
if (*p == name) { |
ASSERT(((p - p0) & 1) == 0); |
int v; |
@@ -477,21 +466,20 @@ |
Variable::Mode mode_value = static_cast<Variable::Mode>(v); |
if (mode != NULL) *mode = mode_value; |
result = static_cast<int>((p - p0) >> 1) + Context::MIN_CONTEXT_SLOTS; |
- ContextSlotCache::Update(data, name, mode_value, result); |
+ ContextSlotCache::Update(this, name, mode_value, result); |
return result; |
} |
p += 2; |
} |
} |
- ContextSlotCache::Update(data, name, Variable::INTERNAL, -1); |
+ ContextSlotCache::Update(this, name, Variable::INTERNAL, -1); |
return -1; |
} |
-template<class Allocator> |
-int ScopeInfo<Allocator>::ParameterIndex(Object* data, String* name) { |
+int SerializedScopeInfo::ParameterIndex(String* name) { |
ASSERT(name->IsSymbol()); |
- if (IsNotEmpty(data)) { |
+ if (length() > 0) { |
// We must read parameters from the end since for |
// multiply declared parameters the value of the |
// last declaration of that parameter is used |
@@ -502,10 +490,10 @@ |
// 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(data); |
- int n; // number of parameters |
- Object** p0 = ReadInt(p, &n); |
- p = p0 + n; |
+ 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); |
@@ -515,50 +503,23 @@ |
} |
-template<class Allocator> |
-int ScopeInfo<Allocator>::FunctionContextSlotIndex(Object* data, String* name) { |
+int SerializedScopeInfo::FunctionContextSlotIndex(String* name) { |
ASSERT(name->IsSymbol()); |
- if (IsNotEmpty(data)) { |
- Object** p = GetDataStart(data); |
+ if (length() > 0) { |
+ Object** p = data_start(); |
if (*p == name) { |
- p = ContextEntriesAddr(data); |
- int n; // number of context slots |
- ReadInt(p, &n); |
- ASSERT(n != 0); |
+ p = ContextEntriesAddr(); |
+ int number_of_context_slots; |
+ ReadInt(p, &number_of_context_slots); |
+ ASSERT(number_of_context_slots != 0); |
// The function context slot is the last entry. |
- return n + Context::MIN_CONTEXT_SLOTS - 1; |
+ return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1; |
} |
} |
return -1; |
} |
-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 the |
- // number Context::MIN_CONTEXT_SLOTS number 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); |
- } |
-} |
- |
- |
-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; |
- } |
- return number_of_locals; |
-} |
- |
- |
int ContextSlotCache::Hash(Object* data, String* name) { |
// Uses only lower 32 bits if pointers are larger. |
uintptr_t addr_hash = |