summaryrefslogtreecommitdiffstats
path: root/src/scopeinfo.cc
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-07-22 14:51:16 +0100
committerBen Murdoch <benm@google.com>2010-07-22 14:51:16 +0100
commit3bec4d28b1f388dbc06a9c4276e1a03e86c52b04 (patch)
tree538bb9cb5e3664733f56ba3292342ccc426eb9f9 /src/scopeinfo.cc
parent2794f167cd167a39859e9be5be3b05bdb5feb10a (diff)
downloadandroid_external_v8-3bec4d28b1f388dbc06a9c4276e1a03e86c52b04.tar.gz
android_external_v8-3bec4d28b1f388dbc06a9c4276e1a03e86c52b04.tar.bz2
android_external_v8-3bec4d28b1f388dbc06a9c4276e1a03e86c52b04.zip
Update V8 to r5091 as required by WebKit r63859.
Change-Id: I8e35d765e6f6c7f89eccff900e1cabe2d5dd6110
Diffstat (limited to 'src/scopeinfo.cc')
-rw-r--r--src/scopeinfo.cc326
1 files changed, 151 insertions, 175 deletions
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index 2091ca72..7e7f1525 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -148,7 +148,7 @@ ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
}
-// Encoding format in the Code object:
+// Encoding format in a FixedArray object:
//
// - function name
//
@@ -204,12 +204,6 @@ static inline Object** ReadSymbol(Object** p, Handle<String>* s) {
}
-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 @@ static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) {
p = ReadSymbol(p, &s);
list->Add(s);
}
- return ReadSentinel(p);
+ return p;
}
@@ -239,27 +233,27 @@ static Object** ReadList(Object** p,
list->Add(s);
modes->Add(static_cast<Variable::Mode>(m));
}
- return ReadSentinel(p);
+ return p;
}
template<class Allocator>
-ScopeInfo<Allocator>::ScopeInfo(Code* code)
+ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data)
: function_name_(Factory::empty_symbol()),
parameters_(4),
stack_slots_(8),
context_slots_(8),
context_modes_(8) {
- if (code == NULL || code->sinfo_size() == 0) return;
-
- Object** p0 = &Memory::Object_at(code->sinfo_start());
- Object** p = p0;
- p = ReadSymbol(p, &function_name_);
- p = ReadBool(p, &calls_eval_);
- p = ReadList<Allocator>(p, &context_slots_, &context_modes_);
- p = ReadList<Allocator>(p, &parameters_);
- p = ReadList<Allocator>(p, &stack_slots_);
- ASSERT((p - p0) * kPointerSize == code->sinfo_size());
+ if (data->length() > 0) {
+ Object** p0 = data->data_start();
+ Object** p = p0;
+ p = ReadSymbol(p, &function_name_);
+ p = ReadBool(p, &calls_eval_);
+ 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());
+ }
}
@@ -281,12 +275,6 @@ static inline Object** WriteSymbol(Object** p, Handle<String> s) {
}
-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();
@@ -294,7 +282,7 @@ static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) {
for (int i = 0; i < n; i++) {
p = WriteSymbol(p, list->at(i));
}
- return WriteSentinel(p);
+ return p;
}
@@ -308,73 +296,99 @@ static Object** WriteList(Object** p,
p = WriteSymbol(p, list->at(i));
p = WriteInt(p, modes->at(i));
}
- return WriteSentinel(p);
+ return p;
}
template<class Allocator>
-int ScopeInfo<Allocator>::Serialize(Code* code) {
- // function name, calls eval, length & sentinel for 3 tables:
- const int extra_slots = 1 + 1 + 2 * 3;
- int size = (extra_slots +
- context_slots_.length() * 2 +
- parameters_.length() +
- stack_slots_.length()) * kPointerSize;
-
- if (code != NULL) {
- CHECK(code->sinfo_size() == size);
- Object** p0 = &Memory::Object_at(code->sinfo_start());
- Object** p = p0;
- p = WriteSymbol(p, function_name_);
- p = WriteBool(p, calls_eval_);
- p = WriteList(p, &context_slots_, &context_modes_);
- p = WriteList(p, &parameters_);
- p = WriteList(p, &stack_slots_);
- ASSERT((p - p0) * kPointerSize == size);
- }
+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<SerializedScopeInfo> data(
+ SerializedScopeInfo::cast(*Factory::NewFixedArray(length, TENURED)));
+ AssertNoAllocation nogc;
+
+ Object** p0 = data->data_start();
+ Object** p = p0;
+ p = WriteSymbol(p, function_name_);
+ p = WriteBool(p, calls_eval_);
+ p = WriteList(p, &context_slots_, &context_modes_);
+ p = WriteList(p, &parameters_);
+ p = WriteList(p, &stack_slots_);
+ ASSERT((p - p0) == length);
- return size;
+ return data;
}
template<class Allocator>
-void ScopeInfo<Allocator>::IterateScopeInfo(Code* code, ObjectVisitor* v) {
- Object** start = &Memory::Object_at(code->sinfo_start());
- Object** end = &Memory::Object_at(code->sinfo_start() + code->sinfo_size());
- v->VisitPointers(start, end);
+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** ContextEntriesAddr(Code* code) {
- ASSERT(code->sinfo_size() > 0);
- // +2 for function name and calls eval:
- return &Memory::Object_at(code->sinfo_start()) + 2;
+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** ParameterEntriesAddr(Code* code) {
- ASSERT(code->sinfo_size() > 0);
- Object** p = ContextEntriesAddr(code);
- int n; // number of context slots;
- p = ReadInt(p, &n);
- return p + n*2 + 1; // *2 for pairs, +1 for sentinel
+Handle<SerializedScopeInfo> SerializedScopeInfo::Create(Scope* scope) {
+ ScopeInfo<ZoneListAllocationPolicy> sinfo(scope);
+ return sinfo.Serialize();
}
-static Object** StackSlotEntriesAddr(Code* code) {
- ASSERT(code->sinfo_size() > 0);
- Object** p = ParameterEntriesAddr(code);
- int n; // number of parameter slots;
- p = ReadInt(p, &n);
- return p + n + 1; // +1 for sentinel
+SerializedScopeInfo* SerializedScopeInfo::Empty() {
+ return reinterpret_cast<SerializedScopeInfo*>(Heap::empty_fixed_array());
}
-template<class Allocator>
-bool ScopeInfo<Allocator>::CallsEval(Code* code) {
- if (code->sinfo_size() > 0) {
- // +1 for function name:
- Object** p = &Memory::Object_at(code->sinfo_start()) + 1;
+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;
@@ -383,53 +397,49 @@ bool ScopeInfo<Allocator>::CallsEval(Code* code) {
}
-template<class Allocator>
-int ScopeInfo<Allocator>::NumberOfStackSlots(Code* code) {
- if (code->sinfo_size() > 0) {
- Object** p = StackSlotEntriesAddr(code);
- 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(Code* code) {
- if (code->sinfo_size() > 0) {
- Object** p = ContextEntriesAddr(code);
- 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(Code* code) {
- if (code->sinfo_size() > 0) {
- Object** p = ContextEntriesAddr(code);
- 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(Code* code, String* name) {
+int SerializedScopeInfo::StackSlotIndex(String* name) {
ASSERT(name->IsSymbol());
- if (code->sinfo_size() > 0) {
- // Loop below depends on the NULL sentinel after the stack slot names.
- ASSERT(NumberOfStackSlots(code) > 0 ||
- *(StackSlotEntriesAddr(code) + 1) == NULL);
- // slots start after length entry
- Object** p0 = StackSlotEntriesAddr(code) + 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++;
}
@@ -437,24 +447,18 @@ int ScopeInfo<Allocator>::StackSlotIndex(Code* code, String* name) {
return -1;
}
-
-template<class Allocator>
-int ScopeInfo<Allocator>::ContextSlotIndex(Code* code,
- String* name,
- Variable::Mode* mode) {
+int SerializedScopeInfo::ContextSlotIndex(String* name, Variable::Mode* mode) {
ASSERT(name->IsSymbol());
- int result = ContextSlotCache::Lookup(code, name, mode);
+ int result = ContextSlotCache::Lookup(this, name, mode);
if (result != ContextSlotCache::kNotFound) return result;
- if (code->sinfo_size() > 0) {
- // Loop below depends on the NULL sentinel after the context slot names.
- ASSERT(NumberOfContextSlots(code) >= Context::MIN_CONTEXT_SLOTS ||
- *(ContextEntriesAddr(code) + 1) == NULL);
-
- // slots start after length entry
- Object** p0 = ContextEntriesAddr(code) + 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;
@@ -462,21 +466,20 @@ int ScopeInfo<Allocator>::ContextSlotIndex(Code* code,
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(code, name, mode_value, result);
+ ContextSlotCache::Update(this, name, mode_value, result);
return result;
}
p += 2;
}
}
- ContextSlotCache::Update(code, name, Variable::INTERNAL, -1);
+ ContextSlotCache::Update(this, name, Variable::INTERNAL, -1);
return -1;
}
-template<class Allocator>
-int ScopeInfo<Allocator>::ParameterIndex(Code* code, String* name) {
+int SerializedScopeInfo::ParameterIndex(String* name) {
ASSERT(name->IsSymbol());
- if (code->sinfo_size() > 0) {
+ 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
@@ -487,10 +490,10 @@ int ScopeInfo<Allocator>::ParameterIndex(Code* code, String* name) {
// 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(code);
- 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);
@@ -500,64 +503,37 @@ int ScopeInfo<Allocator>::ParameterIndex(Code* code, String* name) {
}
-template<class Allocator>
-int ScopeInfo<Allocator>::FunctionContextSlotIndex(Code* code, String* name) {
+int SerializedScopeInfo::FunctionContextSlotIndex(String* name) {
ASSERT(name->IsSymbol());
- if (code->sinfo_size() > 0) {
- Object** p = &Memory::Object_at(code->sinfo_start());
+ if (length() > 0) {
+ Object** p = data_start();
if (*p == name) {
- p = ContextEntriesAddr(code);
- 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(Code* code, String* name) {
+int ContextSlotCache::Hash(Object* data, String* name) {
// Uses only lower 32 bits if pointers are larger.
uintptr_t addr_hash =
- static_cast<uint32_t>(reinterpret_cast<uintptr_t>(code)) >> 2;
+ static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
}
-int ContextSlotCache::Lookup(Code* code,
+int ContextSlotCache::Lookup(Object* data,
String* name,
Variable::Mode* mode) {
- int index = Hash(code, name);
+ int index = Hash(data, name);
Key& key = keys_[index];
- if ((key.code == code) && key.name->Equals(name)) {
+ if ((key.data == data) && key.name->Equals(name)) {
Value result(values_[index]);
if (mode != NULL) *mode = result.mode();
return result.index() + kNotFound;
@@ -566,28 +542,28 @@ int ContextSlotCache::Lookup(Code* code,
}
-void ContextSlotCache::Update(Code* code,
+void ContextSlotCache::Update(Object* data,
String* name,
Variable::Mode mode,
int slot_index) {
String* symbol;
ASSERT(slot_index > kNotFound);
if (Heap::LookupSymbolIfExists(name, &symbol)) {
- int index = Hash(code, symbol);
+ int index = Hash(data, symbol);
Key& key = keys_[index];
- key.code = code;
+ key.data = data;
key.name = symbol;
// Please note value only takes a uint as index.
values_[index] = Value(mode, slot_index - kNotFound).raw();
#ifdef DEBUG
- ValidateEntry(code, name, mode, slot_index);
+ ValidateEntry(data, name, mode, slot_index);
#endif
}
}
void ContextSlotCache::Clear() {
- for (int index = 0; index < kLength; index++) keys_[index].code = NULL;
+ for (int index = 0; index < kLength; index++) keys_[index].data = NULL;
}
@@ -599,15 +575,15 @@ uint32_t ContextSlotCache::values_[ContextSlotCache::kLength];
#ifdef DEBUG
-void ContextSlotCache::ValidateEntry(Code* code,
+void ContextSlotCache::ValidateEntry(Object* data,
String* name,
Variable::Mode mode,
int slot_index) {
String* symbol;
if (Heap::LookupSymbolIfExists(name, &symbol)) {
- int index = Hash(code, name);
+ int index = Hash(data, name);
Key& key = keys_[index];
- ASSERT(key.code == code);
+ ASSERT(key.data == data);
ASSERT(key.name->Equals(name));
Value result(values_[index]);
ASSERT(result.mode() == mode);