Chromium Code Reviews| Index: src/scopeinfo.cc |
| =================================================================== |
| --- src/scopeinfo.cc (revision 2226) |
| +++ src/scopeinfo.cc (working copy) |
| @@ -427,15 +427,20 @@ |
| } |
|
Mads Ager (chromium)
2009/06/22 08:00:18
Remove extra lines.
|
| + |
| + |
| template<class Allocator> |
| int ScopeInfo<Allocator>::ContextSlotIndex(Code* code, |
| String* name, |
| Variable::Mode* mode) { |
| ASSERT(name->IsSymbol()); |
| + int result = ContextSlotCache::Lookup(code, 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; |
| Object** p = p0; |
| @@ -443,14 +448,18 @@ |
| while (*p != NULL) { |
| if (*p == name) { |
| ASSERT(((p - p0) & 1) == 0); |
| - if (mode != NULL) { |
| - ReadInt(p + 1, reinterpret_cast<int*>(mode)); |
| - } |
| - return ((p - p0) >> 1) + Context::MIN_CONTEXT_SLOTS; |
| + int v; |
| + ReadInt(p + 1, &v); |
| + Variable::Mode mode_value = static_cast<Variable::Mode>(v); |
| + if (mode != NULL) *mode = mode_value; |
| + result = ((p - p0) >> 1) + Context::MIN_CONTEXT_SLOTS; |
| + ContextSlotCache::Update(code, name, mode_value, result); |
| + return result; |
| } |
| p += 2; |
| } |
| } |
| + ContextSlotCache::Update(code, name, Variable::INTERNAL, -1); |
| return -1; |
| } |
| @@ -526,7 +535,78 @@ |
| } |
| +int ContextSlotCache::Hash(Code* code, 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; |
| + return (addr_hash ^ name->Hash()) % kLength; |
| +} |
| + |
| + |
| +int ContextSlotCache::Lookup(Code* code, |
| + String* name, |
| + Variable::Mode* mode) { |
| + int index = Hash(code, name); |
| + Key& key = keys_[index]; |
| + if ((key.code == code) && key.name->Equals(name)) { |
| + Value result(values_[index]); |
| + if (mode != NULL) *mode = result.mode(); |
| + return result.index() + kNotFound; |
| + } |
| + return kNotFound; |
| +} |
| + |
| + |
| +void ContextSlotCache::Update(Code* code, |
| + String* name, |
| + Variable::Mode mode, |
| + int slot_index) { |
| + String* symbol; |
| + ASSERT(slot_index > kNotFound); |
| + if (Heap::LookupSymbolIfExists(name, &symbol)) { |
| + int index = Hash(code, symbol); |
| + Key& key = keys_[index]; |
| + key.code = code; |
| + key.name = symbol; |
| + // Please note value only takes a uint as index. |
| + values_[index] = Value(mode, slot_index - kNotFound).raw(); |
| #ifdef DEBUG |
| + Check(code, name, mode, slot_index); |
| +#endif |
| + } |
| +} |
| + |
| + |
| +void ContextSlotCache::Clear() { |
| + for (int index = 0; index < kLength; index++) keys_[index].code = NULL; |
| +} |
| + |
| + |
| +ContextSlotCache::Key ContextSlotCache::keys_[ContextSlotCache::kLength]; |
| + |
| + |
| +uint32_t ContextSlotCache::values_[ContextSlotCache::kLength]; |
| + |
| + |
| +#ifdef DEBUG |
| + |
| +void ContextSlotCache::Check(Code* code, |
| + String* name, |
| + Variable::Mode mode, |
| + int slot_index) { |
| + String* symbol; |
| + if (Heap::LookupSymbolIfExists(name, &symbol)) { |
| + int index = Hash(code, name); |
| + Key& key = keys_[index]; |
| + ASSERT(key.code == code); |
| + ASSERT(key.name->Equals(name)); |
| + Value result(values_[index]); |
| + ASSERT(result.mode() == mode); |
| + ASSERT(result.index() + kNotFound == slot_index); |
| + } |
| +} |
| + |
| + |
| template <class Allocator> |
| static void PrintList(const char* list_name, |
| int nof_internal_slots, |