diff options
author | Ben Murdoch <benm@google.com> | 2010-07-22 14:51:16 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2010-07-22 14:51:16 +0100 |
commit | 3bec4d28b1f388dbc06a9c4276e1a03e86c52b04 (patch) | |
tree | 538bb9cb5e3664733f56ba3292342ccc426eb9f9 /src/scopeinfo.cc | |
parent | 2794f167cd167a39859e9be5be3b05bdb5feb10a (diff) | |
download | android_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.cc | 326 |
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, ¶meters_); - 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, ¶meters_); + 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, ¶meters_); - 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, ¶meters_); + 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); |