Home | History | Annotate | Download | only in ast
      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