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
Hash(Object * data,String * name)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
Lookup(Object * data,String * name,VariableMode * mode,InitializationFlag * init_flag,MaybeAssignedFlag * maybe_assigned_flag)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
Update(Handle<Object> data,Handle<String> name,VariableMode mode,InitializationFlag init_flag,MaybeAssignedFlag maybe_assigned_flag,int slot_index)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
Clear()58 void ContextSlotCache::Clear() {
59 for (int index = 0; index < kLength; index++) keys_[index].data = nullptr;
60 }
61
62 #ifdef DEBUG
63
ValidateEntry(Handle<Object> data,Handle<String> name,VariableMode mode,InitializationFlag init_flag,MaybeAssignedFlag maybe_assigned_flag,int slot_index)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