OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 #ifndef V8_HEAP_IDENTITY_MAP_H_ | |
6 #define V8_HEAP_IDENTITY_MAP_H_ | |
7 | |
8 #include "src/handles.h" | |
9 | |
10 namespace v8 { | |
11 namespace internal { | |
12 | |
13 class Heap; | |
14 | |
15 // Base class of identity maps contains shared code for all template | |
16 // instantions. | |
17 class IdentityMapBase { | |
18 public: | |
19 // Enable or disable concurrent mode for this map. Concurrent mode implies | |
20 // taking the heap's relocation lock during most operations. | |
21 void SetConcurrent(bool concurrent) { concurrent_ = concurrent; } | |
22 | |
23 protected: | |
24 // Allow Tester to access internals, including changing the address of objects | |
25 // within the {keys_} array in order to simulate a moving GC. | |
26 friend class IdentityMapTester; | |
27 | |
28 typedef void** RawEntry; | |
29 | |
30 IdentityMapBase(Heap* heap, Zone* zone) | |
31 : heap_(heap), | |
32 zone_(zone), | |
33 concurrent_(false), | |
34 gc_counter_(-1), | |
35 size_(0), | |
36 mask_(0), | |
37 keys_(nullptr), | |
38 values_(nullptr) {} | |
39 ~IdentityMapBase(); | |
40 | |
41 RawEntry GetEntry(Handle<Object> handle); | |
42 RawEntry FindEntry(Handle<Object> handle); | |
43 | |
44 private: | |
45 // Internal implementation should not be called directly by subclasses. | |
46 int LookupIndex(Object* address); | |
47 int InsertIndex(Object* address); | |
48 void Rehash(); | |
49 void Resize(); | |
50 | |
51 RawEntry Lookup(Handle<Object> handle) { | |
Benedikt Meurer
2015/04/27 04:04:18
Style nit: Since these methods are private, and al
titzer
2015/04/27 10:43:03
Done.
| |
52 AllowHandleDereference for_lookup; | |
53 int index = LookupIndex(*handle); | |
Benedikt Meurer
2015/04/27 04:04:18
How about size_t here, and check for index < size_
titzer
2015/04/27 10:43:03
I think int works better here, since we are using
| |
54 return index >= 0 ? &values_[index] : nullptr; | |
55 } | |
56 | |
57 RawEntry Insert(Handle<Object> handle) { | |
Benedikt Meurer
2015/04/27 04:04:17
Style nit: Since these methods are private, and al
titzer
2015/04/27 10:43:03
Done.
| |
58 AllowHandleDereference for_lookup; | |
59 int index = InsertIndex(*handle); | |
60 DCHECK_GE(index, 0); | |
61 return &values_[index]; | |
62 } | |
63 | |
64 int Hash(Object* address) { | |
Benedikt Meurer
2015/04/27 04:04:18
Style nit: Since these methods are private, and al
titzer
2015/04/27 10:43:03
Done.
| |
65 uintptr_t raw_address = reinterpret_cast<uintptr_t>(address); | |
66 CHECK_NE(0, raw_address); // cannot store Smi 0 as a key here, sorry. | |
67 // xor some of the upper bits, since the lower 2 or 3 are usually aligned. | |
68 return static_cast<int>((raw_address >> 11) ^ raw_address); | |
Benedikt Meurer
2015/04/27 04:04:17
Down casting to int looks wrong here. How about us
Sven Panne
2015/04/27 06:26:47
Veto from the *San sheriff, too: This line is caus
titzer
2015/04/27 07:57:51
This is the computation of a hashcode from an addr
titzer
2015/04/27 10:43:03
size_t isn't any safer than int. As per below comm
| |
69 } | |
70 | |
71 Heap* heap_; | |
72 Zone* zone_; | |
73 bool concurrent_; | |
74 int gc_counter_; | |
75 int size_; | |
76 int mask_; | |
77 Object** keys_; | |
78 void** values_; | |
79 }; | |
80 | |
81 // Implements an identity map from object addresses to a given value type {V}. | |
82 // The value type {V} must be reinterpret_cast'able to void*. | |
83 // The map is robust w.r.t. garbage collection through coordination with the | |
84 // supplied {heap}. | |
85 // Note that in general, SMIs are valid keys, but {SMI #0} is _not_ a valid key. | |
86 template <typename V> | |
87 class IdentityMap : public IdentityMapBase { | |
88 public: | |
89 IdentityMap(Heap* heap, Zone* zone) : IdentityMapBase(heap, zone) {} | |
90 | |
91 // Searches this map for the given key using the object's address | |
92 // as the identity, returning: | |
93 // found => a pointer to the storage location for the value | |
94 // not found => a pointer to a new storage location for the value | |
95 V* Get(Handle<Object> handle) { | |
96 return reinterpret_cast<V*>(GetEntry(handle)); | |
97 } | |
98 | |
99 // Searches this map for the given key using the object's address | |
100 // as the identity, returning: | |
101 // found => a pointer to the storage location for the value | |
102 // not found => {nullptr} | |
103 V* Find(Handle<Object> handle) { | |
104 return reinterpret_cast<V*>(FindEntry(handle)); | |
105 } | |
106 | |
107 // Set the value for the given key. | |
108 void Set(Handle<Object> handle, V value) { | |
109 *(reinterpret_cast<V*>(GetEntry(handle))) = value; | |
110 } | |
111 }; | |
112 } | |
113 } // namespace v8::internal | |
114 | |
115 #endif // V8_HEAP_IDENTITY_MAP_H_ | |
OLD | NEW |