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 // 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 
     19 namespace v8 {
     20 namespace internal {
     21 
     22 int 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 
     29 int 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 
     45 void 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 
     68 void ContextSlotCache::Clear() {
     69   for (int index = 0; index < kLength; index++) keys_[index].data = nullptr;
     70 }
     71 
     72 #ifdef DEBUG
     73 
     74 void 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