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_ADDRESS_MAP_H_ |
| 6 #define V8_ADDRESS_MAP_H_ |
| 7 |
| 8 #include "src/assert-scope.h" |
| 9 #include "src/hashmap.h" |
| 10 #include "src/objects.h" |
| 11 |
| 12 namespace v8 { |
| 13 namespace internal { |
| 14 |
| 15 class AddressMapBase { |
| 16 protected: |
| 17 static void SetValue(HashMap::Entry* entry, uint32_t v) { |
| 18 entry->value = reinterpret_cast<void*>(v); |
| 19 } |
| 20 |
| 21 static uint32_t GetValue(HashMap::Entry* entry) { |
| 22 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value)); |
| 23 } |
| 24 |
| 25 inline static HashMap::Entry* LookupEntry(HashMap* map, HeapObject* obj, |
| 26 bool insert) { |
| 27 if (insert) { |
| 28 map->LookupOrInsert(Key(obj), Hash(obj)); |
| 29 } |
| 30 return map->Lookup(Key(obj), Hash(obj)); |
| 31 } |
| 32 |
| 33 private: |
| 34 static uint32_t Hash(HeapObject* obj) { |
| 35 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); |
| 36 } |
| 37 |
| 38 static void* Key(HeapObject* obj) { |
| 39 return reinterpret_cast<void*>(obj->address()); |
| 40 } |
| 41 }; |
| 42 |
| 43 |
| 44 class RootIndexMap : public AddressMapBase { |
| 45 public: |
| 46 explicit RootIndexMap(Isolate* isolate); |
| 47 |
| 48 static const int kInvalidRootIndex = -1; |
| 49 |
| 50 int Lookup(HeapObject* obj) { |
| 51 HashMap::Entry* entry = LookupEntry(map_, obj, false); |
| 52 if (entry) return GetValue(entry); |
| 53 return kInvalidRootIndex; |
| 54 } |
| 55 |
| 56 private: |
| 57 HashMap* map_; |
| 58 |
| 59 DISALLOW_COPY_AND_ASSIGN(RootIndexMap); |
| 60 }; |
| 61 |
| 62 |
| 63 class BackReference { |
| 64 public: |
| 65 explicit BackReference(uint32_t bitfield) : bitfield_(bitfield) {} |
| 66 |
| 67 BackReference() : bitfield_(kInvalidValue) {} |
| 68 |
| 69 static BackReference SourceReference() { return BackReference(kSourceValue); } |
| 70 |
| 71 static BackReference GlobalProxyReference() { |
| 72 return BackReference(kGlobalProxyValue); |
| 73 } |
| 74 |
| 75 static BackReference LargeObjectReference(uint32_t index) { |
| 76 return BackReference(SpaceBits::encode(LO_SPACE) | |
| 77 ChunkOffsetBits::encode(index)); |
| 78 } |
| 79 |
| 80 static BackReference DummyReference() { return BackReference(kDummyValue); } |
| 81 |
| 82 static BackReference Reference(AllocationSpace space, uint32_t chunk_index, |
| 83 uint32_t chunk_offset) { |
| 84 DCHECK(IsAligned(chunk_offset, kObjectAlignment)); |
| 85 DCHECK_NE(LO_SPACE, space); |
| 86 return BackReference( |
| 87 SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | |
| 88 ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); |
| 89 } |
| 90 |
| 91 bool is_valid() const { return bitfield_ != kInvalidValue; } |
| 92 bool is_source() const { return bitfield_ == kSourceValue; } |
| 93 bool is_global_proxy() const { return bitfield_ == kGlobalProxyValue; } |
| 94 |
| 95 AllocationSpace space() const { |
| 96 DCHECK(is_valid()); |
| 97 return SpaceBits::decode(bitfield_); |
| 98 } |
| 99 |
| 100 uint32_t chunk_offset() const { |
| 101 DCHECK(is_valid()); |
| 102 return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits; |
| 103 } |
| 104 |
| 105 uint32_t large_object_index() const { |
| 106 DCHECK(is_valid()); |
| 107 DCHECK(chunk_index() == 0); |
| 108 return ChunkOffsetBits::decode(bitfield_); |
| 109 } |
| 110 |
| 111 uint32_t chunk_index() const { |
| 112 DCHECK(is_valid()); |
| 113 return ChunkIndexBits::decode(bitfield_); |
| 114 } |
| 115 |
| 116 uint32_t reference() const { |
| 117 DCHECK(is_valid()); |
| 118 return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask); |
| 119 } |
| 120 |
| 121 uint32_t bitfield() const { return bitfield_; } |
| 122 |
| 123 private: |
| 124 static const uint32_t kInvalidValue = 0xFFFFFFFF; |
| 125 static const uint32_t kSourceValue = 0xFFFFFFFE; |
| 126 static const uint32_t kGlobalProxyValue = 0xFFFFFFFD; |
| 127 static const uint32_t kDummyValue = 0xFFFFFFFC; |
| 128 static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits; |
| 129 static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize; |
| 130 |
| 131 public: |
| 132 static const int kMaxChunkIndex = (1 << kChunkIndexSize) - 1; |
| 133 |
| 134 private: |
| 135 class ChunkOffsetBits : public BitField<uint32_t, 0, kChunkOffsetSize> {}; |
| 136 class ChunkIndexBits |
| 137 : public BitField<uint32_t, ChunkOffsetBits::kNext, kChunkIndexSize> {}; |
| 138 class SpaceBits |
| 139 : public BitField<AllocationSpace, ChunkIndexBits::kNext, kSpaceTagSize> { |
| 140 }; |
| 141 |
| 142 uint32_t bitfield_; |
| 143 }; |
| 144 |
| 145 |
| 146 // Mapping objects to their location after deserialization. |
| 147 // This is used during building, but not at runtime by V8. |
| 148 class BackReferenceMap : public AddressMapBase { |
| 149 public: |
| 150 BackReferenceMap() |
| 151 : no_allocation_(), map_(new HashMap(HashMap::PointersMatch)) {} |
| 152 |
| 153 ~BackReferenceMap() { delete map_; } |
| 154 |
| 155 BackReference Lookup(HeapObject* obj) { |
| 156 HashMap::Entry* entry = LookupEntry(map_, obj, false); |
| 157 return entry ? BackReference(GetValue(entry)) : BackReference(); |
| 158 } |
| 159 |
| 160 void Add(HeapObject* obj, BackReference b) { |
| 161 DCHECK(b.is_valid()); |
| 162 DCHECK_NULL(LookupEntry(map_, obj, false)); |
| 163 HashMap::Entry* entry = LookupEntry(map_, obj, true); |
| 164 SetValue(entry, b.bitfield()); |
| 165 } |
| 166 |
| 167 void AddSourceString(String* string) { |
| 168 Add(string, BackReference::SourceReference()); |
| 169 } |
| 170 |
| 171 void AddGlobalProxy(HeapObject* global_proxy) { |
| 172 Add(global_proxy, BackReference::GlobalProxyReference()); |
| 173 } |
| 174 |
| 175 private: |
| 176 DisallowHeapAllocation no_allocation_; |
| 177 HashMap* map_; |
| 178 DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); |
| 179 }; |
| 180 |
| 181 } // namespace internal |
| 182 } // namespace v8 |
| 183 |
| 184 #endif // V8_ADDRESS_MAP_H_ |
OLD | NEW |