1 // Copyright 2016 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/ast/context-slot-cache.h" 6 7 #include <stdlib.h> 8 9 #include "src/ast/scopes.h" 10 #include "src/bootstrapper.h" 11 #include "src/objects-inl.h" 12 13 namespace v8 { 14 namespace internal { 15 16 int ContextSlotCache::Hash(Object* data, String* name) { 17 // Uses only lower 32 bits if pointers are larger. 18 uintptr_t addr_hash = 19 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; 20 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); 21 } 22 23 int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, 24 InitializationFlag* init_flag, 25 MaybeAssignedFlag* maybe_assigned_flag) { 26 int index = Hash(data, name); 27 DCHECK(name->IsInternalizedString()); 28 Key& key = keys_[index]; 29 if (key.data == data && key.name == name) { 30 Value result(values_[index]); 31 if (mode != nullptr) *mode = result.mode(); 32 if (init_flag != nullptr) *init_flag = result.initialization_flag(); 33 if (maybe_assigned_flag != nullptr) 34 *maybe_assigned_flag = result.maybe_assigned_flag(); 35 return result.index() + kNotFound; 36 } 37 return kNotFound; 38 } 39 40 void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, 41 VariableMode mode, InitializationFlag init_flag, 42 MaybeAssignedFlag maybe_assigned_flag, 43 int slot_index) { 44 DCHECK(name->IsInternalizedString()); 45 DCHECK_LT(kNotFound, slot_index); 46 int index = Hash(*data, *name); 47 Key& key = keys_[index]; 48 key.data = *data; 49 key.name = *name; 50 // Please note value only takes a uint as index. 51 values_[index] = 52 Value(mode, init_flag, maybe_assigned_flag, slot_index - kNotFound).raw(); 53 #ifdef DEBUG 54 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); 55 #endif 56 } 57 58 void ContextSlotCache::Clear() { 59 for (int index = 0; index < kLength; index++) keys_[index].data = nullptr; 60 } 61 62 #ifdef DEBUG 63 64 void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, 65 VariableMode mode, 66 InitializationFlag init_flag, 67 MaybeAssignedFlag maybe_assigned_flag, 68 int slot_index) { 69 DCHECK(name->IsInternalizedString()); 70 int index = Hash(*data, *name); 71 Key& key = keys_[index]; 72 DCHECK_EQ(key.data, *data); 73 DCHECK_EQ(key.name, *name); 74 Value result(values_[index]); 75 DCHECK_EQ(result.mode(), mode); 76 DCHECK_EQ(result.initialization_flag(), init_flag); 77 DCHECK_EQ(result.maybe_assigned_flag(), maybe_assigned_flag); 78 DCHECK_EQ(result.index() + kNotFound, slot_index); 79 } 80 81 #endif // DEBUG 82 83 } // namespace internal 84 } // namespace v8 85