OLD | NEW |
---|---|
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_ADDRESS_MAP_H_ | 5 #ifndef V8_ADDRESS_MAP_H_ |
6 #define V8_ADDRESS_MAP_H_ | 6 #define V8_ADDRESS_MAP_H_ |
7 | 7 |
8 #include "src/assert-scope.h" | 8 #include "src/assert-scope.h" |
9 #include "src/base/hashmap.h" | 9 #include "src/base/hashmap.h" |
10 #include "src/objects.h" | 10 #include "src/objects.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 | 14 |
15 class AddressMapBase { | 15 template <typename Type> |
16 protected: | 16 class PointerToIndexHashMap |
17 static void SetValue(base::HashMap::Entry* entry, uint32_t v) { | 17 : public base::TemplateHashMapImpl<intptr_t, uint32_t, |
vogelheim
2016/11/10 09:37:10
nitpick: why intptr_t, not uintptr_t ?
Do we hav
Yang
2016/11/10 10:36:19
No reason really. Changed.
| |
18 entry->value = reinterpret_cast<void*>(v); | 18 base::KeyEqualityMatcher<intptr_t>, |
19 base::DefaultAllocationPolicy> { | |
20 public: | |
21 typedef base::TemplateHashMapEntry<intptr_t, uint32_t> Entry; | |
22 | |
23 inline void Set(Type value, uint32_t index) { | |
24 intptr_t key = Key(value); | |
25 LookupOrInsert(key, Hash(key))->value = index; | |
19 } | 26 } |
20 | 27 |
21 static uint32_t GetValue(base::HashMap::Entry* entry) { | 28 inline bool Has(Type value) { |
22 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); | 29 intptr_t key = Key(value); |
30 return Lookup(key, Hash(key)) != nullptr; | |
23 } | 31 } |
24 | 32 |
25 inline static base::HashMap::Entry* LookupEntry(base::HashMap* map, | 33 inline uint32_t Get(Type value) { |
26 HeapObject* obj, | 34 DCHECK(Has(value)); |
27 bool insert) { | 35 intptr_t key = Key(value); |
28 if (insert) { | 36 return Lookup(key, Hash(key))->value; |
29 map->LookupOrInsert(Key(obj), Hash(obj)); | |
30 } | |
31 return map->Lookup(Key(obj), Hash(obj)); | |
32 } | 37 } |
33 | 38 |
34 private: | 39 private: |
35 static uint32_t Hash(HeapObject* obj) { | 40 static intptr_t Key(Type value) { return reinterpret_cast<intptr_t>(value); } |
vogelheim
2016/11/10 09:37:10
nitpick: So... 'typename Type' must be a pointer t
Yang
2016/11/10 10:36:19
Yeah, but then I can't really use PointerToIndexHa
| |
36 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); | |
37 } | |
38 | 41 |
39 static void* Key(HeapObject* obj) { | 42 static uint32_t Hash(intptr_t key) { |
40 return reinterpret_cast<void*>(obj->address()); | 43 return static_cast<uint32_t>(key >> kPointerSizeLog2); |
41 } | 44 } |
42 }; | 45 }; |
43 | 46 |
44 class RootIndexMap : public AddressMapBase { | 47 class AddressToIndexHashMap : public PointerToIndexHashMap<Address> {}; |
48 class HeapObjectToIndexHashMap : public PointerToIndexHashMap<HeapObject*> {}; | |
49 | |
50 class RootIndexMap { | |
45 public: | 51 public: |
46 explicit RootIndexMap(Isolate* isolate); | 52 explicit RootIndexMap(Isolate* isolate); |
47 | 53 |
48 static const int kInvalidRootIndex = -1; | 54 static const int kInvalidRootIndex = -1; |
49 | 55 |
50 int Lookup(HeapObject* obj) { | 56 int Lookup(HeapObject* obj) { |
51 base::HashMap::Entry* entry = LookupEntry(map_, obj, false); | 57 if (map_->Has(obj)) return map_->Get(obj); |
52 if (entry) return GetValue(entry); | |
53 return kInvalidRootIndex; | 58 return kInvalidRootIndex; |
54 } | 59 } |
55 | 60 |
56 private: | 61 private: |
57 base::HashMap* map_; | 62 HeapObjectToIndexHashMap* map_; |
58 | 63 |
59 DISALLOW_COPY_AND_ASSIGN(RootIndexMap); | 64 DISALLOW_COPY_AND_ASSIGN(RootIndexMap); |
60 }; | 65 }; |
61 | 66 |
62 class SerializerReference { | 67 class SerializerReference { |
63 public: | 68 public: |
64 SerializerReference() : bitfield_(Special(kInvalidValue)) {} | 69 SerializerReference() : bitfield_(Special(kInvalidValue)) {} |
65 | 70 |
66 static SerializerReference FromBitfield(uint32_t bitfield) { | 71 static SerializerReference FromBitfield(uint32_t bitfield) { |
67 return SerializerReference(bitfield); | 72 return SerializerReference(bitfield); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
179 class SpaceBits : public BitField<int, kValueIndexSize, kSpaceTagSize> {}; | 184 class SpaceBits : public BitField<int, kValueIndexSize, kSpaceTagSize> {}; |
180 STATIC_ASSERT(SpaceBits::kNext == 32); | 185 STATIC_ASSERT(SpaceBits::kNext == 32); |
181 | 186 |
182 uint32_t bitfield_; | 187 uint32_t bitfield_; |
183 | 188 |
184 friend class SerializerReferenceMap; | 189 friend class SerializerReferenceMap; |
185 }; | 190 }; |
186 | 191 |
187 // Mapping objects to their location after deserialization. | 192 // Mapping objects to their location after deserialization. |
188 // This is used during building, but not at runtime by V8. | 193 // This is used during building, but not at runtime by V8. |
189 class SerializerReferenceMap : public AddressMapBase { | 194 class SerializerReferenceMap { |
190 public: | 195 public: |
191 SerializerReferenceMap() | 196 SerializerReferenceMap() |
192 : no_allocation_(), map_(), attached_reference_index_(0) {} | 197 : no_allocation_(), map_(), attached_reference_index_(0) {} |
193 | 198 |
194 SerializerReference Lookup(HeapObject* obj) { | 199 SerializerReference Lookup(HeapObject* obj) { |
195 base::HashMap::Entry* entry = LookupEntry(&map_, obj, false); | 200 return map_.Has(obj) ? SerializerReference(map_.Get(obj)) |
vogelheim
2016/11/10 09:37:10
The way Has + Get are implemented, this Lookup per
Yang
2016/11/10 10:36:19
Unfortunately Get is allowed to return 0 as valid
vogelheim
2016/11/10 10:59:28
Now that you mention it: maybe const-ify Get + Has
| |
196 return entry ? SerializerReference(GetValue(entry)) : SerializerReference(); | 201 : SerializerReference(); |
197 } | 202 } |
198 | 203 |
199 void Add(HeapObject* obj, SerializerReference b) { | 204 void Add(HeapObject* obj, SerializerReference b) { |
200 DCHECK(b.is_valid()); | 205 DCHECK(b.is_valid()); |
201 DCHECK_NULL(LookupEntry(&map_, obj, false)); | 206 DCHECK(!map_.Has(obj)); |
202 base::HashMap::Entry* entry = LookupEntry(&map_, obj, true); | 207 map_.Set(obj, b.bitfield_); |
203 SetValue(entry, b.bitfield_); | |
204 } | 208 } |
205 | 209 |
206 SerializerReference AddAttachedReference(HeapObject* attached_reference) { | 210 SerializerReference AddAttachedReference(HeapObject* attached_reference) { |
207 SerializerReference reference = | 211 SerializerReference reference = |
208 SerializerReference::AttachedReference(attached_reference_index_++); | 212 SerializerReference::AttachedReference(attached_reference_index_++); |
209 Add(attached_reference, reference); | 213 Add(attached_reference, reference); |
210 return reference; | 214 return reference; |
211 } | 215 } |
212 | 216 |
213 private: | 217 private: |
214 DisallowHeapAllocation no_allocation_; | 218 DisallowHeapAllocation no_allocation_; |
215 base::HashMap map_; | 219 HeapObjectToIndexHashMap map_; |
216 int attached_reference_index_; | 220 int attached_reference_index_; |
217 DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap); | 221 DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap); |
218 }; | 222 }; |
219 | 223 |
220 } // namespace internal | 224 } // namespace internal |
221 } // namespace v8 | 225 } // namespace v8 |
222 | 226 |
223 #endif // V8_ADDRESS_MAP_H_ | 227 #endif // V8_ADDRESS_MAP_H_ |
OLD | NEW |