Chromium Code Reviews| 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 |