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// FIXME(mstarzinger, marja): This is weird, but required because of the missing 12// (disallowed) include: src/factory.h -> src/objects-inl.h 13#include "src/objects-inl.h" 14// FIXME(mstarzinger, marja): This is weird, but required because of the missing 15// (disallowed) include: src/feedback-vector.h -> 16// src/feedback-vector-inl.h 17#include "src/feedback-vector-inl.h" 18 19namespace v8 { 20namespace internal { 21 22int ContextSlotCache::Hash(Object* data, String* name) { 23 // Uses only lower 32 bits if pointers are larger. 24 uintptr_t addr_hash = 25 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; 26 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); 27} 28 29int ContextSlotCache::Lookup(Object* data, String* name, VariableMode* mode, 30 InitializationFlag* init_flag, 31 MaybeAssignedFlag* maybe_assigned_flag) { 32 int index = Hash(data, name); 33 Key& key = keys_[index]; 34 if ((key.data == data) && key.name->Equals(name)) { 35 Value result(values_[index]); 36 if (mode != nullptr) *mode = result.mode(); 37 if (init_flag != nullptr) *init_flag = result.initialization_flag(); 38 if (maybe_assigned_flag != nullptr) 39 *maybe_assigned_flag = result.maybe_assigned_flag(); 40 return result.index() + kNotFound; 41 } 42 return kNotFound; 43} 44 45void ContextSlotCache::Update(Handle<Object> data, Handle<String> name, 46 VariableMode mode, InitializationFlag init_flag, 47 MaybeAssignedFlag maybe_assigned_flag, 48 int slot_index) { 49 DisallowHeapAllocation no_gc; 50 Handle<String> internalized_name; 51 DCHECK(slot_index > kNotFound); 52 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name) 53 .ToHandle(&internalized_name)) { 54 int index = Hash(*data, *internalized_name); 55 Key& key = keys_[index]; 56 key.data = *data; 57 key.name = *internalized_name; 58 // Please note value only takes a uint as index. 59 values_[index] = 60 Value(mode, init_flag, maybe_assigned_flag, slot_index - kNotFound) 61 .raw(); 62#ifdef DEBUG 63 ValidateEntry(data, name, mode, init_flag, maybe_assigned_flag, slot_index); 64#endif 65 } 66} 67 68void ContextSlotCache::Clear() { 69 for (int index = 0; index < kLength; index++) keys_[index].data = nullptr; 70} 71 72#ifdef DEBUG 73 74void ContextSlotCache::ValidateEntry(Handle<Object> data, Handle<String> name, 75 VariableMode mode, 76 InitializationFlag init_flag, 77 MaybeAssignedFlag maybe_assigned_flag, 78 int slot_index) { 79 DisallowHeapAllocation no_gc; 80 Handle<String> internalized_name; 81 if (StringTable::InternalizeStringIfExists(name->GetIsolate(), name) 82 .ToHandle(&internalized_name)) { 83 int index = Hash(*data, *name); 84 Key& key = keys_[index]; 85 DCHECK(key.data == *data); 86 DCHECK(key.name->Equals(*name)); 87 Value result(values_[index]); 88 DCHECK(result.mode() == mode); 89 DCHECK(result.initialization_flag() == init_flag); 90 DCHECK(result.maybe_assigned_flag() == maybe_assigned_flag); 91 DCHECK(result.index() + kNotFound == slot_index); 92 } 93} 94 95#endif // DEBUG 96 97} // namespace internal 98} // namespace v8 99