| 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/hashmap.h" | 9 #include "src/hashmap.h" |
| 10 #include "src/objects.h" | 10 #include "src/objects.h" |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 private: | 33 private: |
| 34 static uint32_t Hash(HeapObject* obj) { | 34 static uint32_t Hash(HeapObject* obj) { |
| 35 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); | 35 return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address())); |
| 36 } | 36 } |
| 37 | 37 |
| 38 static void* Key(HeapObject* obj) { | 38 static void* Key(HeapObject* obj) { |
| 39 return reinterpret_cast<void*>(obj->address()); | 39 return reinterpret_cast<void*>(obj->address()); |
| 40 } | 40 } |
| 41 }; | 41 }; |
| 42 | 42 |
| 43 | |
| 44 class RootIndexMap : public AddressMapBase { | 43 class RootIndexMap : public AddressMapBase { |
| 45 public: | 44 public: |
| 46 explicit RootIndexMap(Isolate* isolate); | 45 explicit RootIndexMap(Isolate* isolate); |
| 47 | 46 |
| 48 static const int kInvalidRootIndex = -1; | 47 static const int kInvalidRootIndex = -1; |
| 49 | 48 |
| 50 int Lookup(HeapObject* obj) { | 49 int Lookup(HeapObject* obj) { |
| 51 HashMap::Entry* entry = LookupEntry(map_, obj, false); | 50 HashMap::Entry* entry = LookupEntry(map_, obj, false); |
| 52 if (entry) return GetValue(entry); | 51 if (entry) return GetValue(entry); |
| 53 return kInvalidRootIndex; | 52 return kInvalidRootIndex; |
| 54 } | 53 } |
| 55 | 54 |
| 56 private: | 55 private: |
| 57 HashMap* map_; | 56 HashMap* map_; |
| 58 | 57 |
| 59 DISALLOW_COPY_AND_ASSIGN(RootIndexMap); | 58 DISALLOW_COPY_AND_ASSIGN(RootIndexMap); |
| 60 }; | 59 }; |
| 61 | 60 |
| 61 class SerializerReference { |
| 62 public: |
| 63 SerializerReference() : bitfield_(Special(kInvalidValue)) {} |
| 62 | 64 |
| 63 class BackReference { | 65 static SerializerReference FromBitfield(uint32_t bitfield) { |
| 64 public: | 66 return SerializerReference(bitfield); |
| 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 } | 67 } |
| 74 | 68 |
| 75 static BackReference LargeObjectReference(uint32_t index) { | 69 static SerializerReference BackReference(AllocationSpace space, |
| 76 return BackReference(SpaceBits::encode(LO_SPACE) | | 70 uint32_t chunk_index, |
| 77 ChunkOffsetBits::encode(index)); | 71 uint32_t chunk_offset) { |
| 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)); | 72 DCHECK(IsAligned(chunk_offset, kObjectAlignment)); |
| 85 DCHECK_NE(LO_SPACE, space); | 73 DCHECK_NE(LO_SPACE, space); |
| 86 return BackReference( | 74 return SerializerReference( |
| 87 SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | | 75 SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | |
| 88 ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); | 76 ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); |
| 89 } | 77 } |
| 90 | 78 |
| 91 bool is_valid() const { return bitfield_ != kInvalidValue; } | 79 static SerializerReference LargeObjectReference(uint32_t index) { |
| 92 bool is_source() const { return bitfield_ == kSourceValue; } | 80 return SerializerReference(SpaceBits::encode(LO_SPACE) | |
| 93 bool is_global_proxy() const { return bitfield_ == kGlobalProxyValue; } | 81 ValueIndexBits::encode(index)); |
| 82 } |
| 83 |
| 84 static SerializerReference AttachedReference(uint32_t index) { |
| 85 return SerializerReference(SpaceBits::encode(kAttachedReferenceSpace) | |
| 86 ValueIndexBits::encode(index)); |
| 87 } |
| 88 |
| 89 static SerializerReference DummyReference() { |
| 90 return SerializerReference(Special(kDummyValue)); |
| 91 } |
| 92 |
| 93 bool is_valid() const { return bitfield_ != Special(kInvalidValue); } |
| 94 |
| 95 bool is_back_reference() const { |
| 96 return SpaceBits::decode(bitfield_) <= LAST_SPACE; |
| 97 } |
| 94 | 98 |
| 95 AllocationSpace space() const { | 99 AllocationSpace space() const { |
| 96 DCHECK(is_valid()); | 100 DCHECK(is_back_reference()); |
| 97 return SpaceBits::decode(bitfield_); | 101 return static_cast<AllocationSpace>(SpaceBits::decode(bitfield_)); |
| 98 } | 102 } |
| 99 | 103 |
| 100 uint32_t chunk_offset() const { | 104 uint32_t chunk_offset() const { |
| 101 DCHECK(is_valid()); | 105 DCHECK(is_back_reference()); |
| 102 return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits; | 106 return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits; |
| 103 } | 107 } |
| 104 | 108 |
| 105 uint32_t large_object_index() const { | 109 uint32_t large_object_index() const { |
| 106 DCHECK(is_valid()); | 110 DCHECK(is_back_reference()); |
| 107 DCHECK(chunk_index() == 0); | 111 DCHECK(chunk_index() == 0); |
| 108 return ChunkOffsetBits::decode(bitfield_); | 112 return ChunkOffsetBits::decode(bitfield_); |
| 109 } | 113 } |
| 110 | 114 |
| 111 uint32_t chunk_index() const { | 115 uint32_t chunk_index() const { |
| 112 DCHECK(is_valid()); | 116 DCHECK(is_back_reference()); |
| 113 return ChunkIndexBits::decode(bitfield_); | 117 return ChunkIndexBits::decode(bitfield_); |
| 114 } | 118 } |
| 115 | 119 |
| 116 uint32_t reference() const { | 120 uint32_t back_reference() const { |
| 117 DCHECK(is_valid()); | 121 DCHECK(is_back_reference()); |
| 118 return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask); | 122 return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask); |
| 119 } | 123 } |
| 120 | 124 |
| 121 uint32_t bitfield() const { return bitfield_; } | 125 bool is_attached_reference() const { |
| 126 return SpaceBits::decode(bitfield_) == kAttachedReferenceSpace; |
| 127 } |
| 128 |
| 129 int attached_reference_index() const { |
| 130 DCHECK(is_attached_reference()); |
| 131 return ValueIndexBits::decode(bitfield_); |
| 132 } |
| 122 | 133 |
| 123 private: | 134 private: |
| 124 static const uint32_t kInvalidValue = 0xFFFFFFFF; | 135 explicit SerializerReference(uint32_t bitfield) : bitfield_(bitfield) {} |
| 125 static const uint32_t kSourceValue = 0xFFFFFFFE; | 136 |
| 126 static const uint32_t kGlobalProxyValue = 0xFFFFFFFD; | 137 inline static uint32_t Special(int value) { |
| 127 static const uint32_t kDummyValue = 0xFFFFFFFC; | 138 return SpaceBits::encode(kSpecialValueSpace) | |
| 139 ValueIndexBits::encode(value); |
| 140 } |
| 141 |
| 142 // We use the 32-bit bitfield to encode either a back reference, a special |
| 143 // value, or an attached reference index. |
| 144 // Back reference: |
| 145 // [ Space index ] [ Chunk index ] [ Chunk offset ] |
| 146 // [ LO_SPACE ] [ large object index ] |
| 147 // Special value |
| 148 // [ kSpecialValueSpace ] [ Special value index ] |
| 149 // Attached reference |
| 150 // [ kAttachedReferenceSpace ] [ Attached reference index ] |
| 151 |
| 128 static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits; | 152 static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits; |
| 129 static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize; | 153 static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize; |
| 154 static const int kValueIndexSize = kChunkOffsetSize + kChunkIndexSize; |
| 130 | 155 |
| 131 public: | 156 static const int kSpecialValueSpace = LAST_SPACE + 1; |
| 132 static const int kMaxChunkIndex = (1 << kChunkIndexSize) - 1; | 157 static const int kAttachedReferenceSpace = kSpecialValueSpace + 1; |
| 158 STATIC_ASSERT(kAttachedReferenceSpace < (1 << kSpaceTagSize)); |
| 133 | 159 |
| 134 private: | 160 static const int kInvalidValue = 0; |
| 161 static const int kDummyValue = 1; |
| 162 |
| 163 // The chunk offset can also be used to encode the index of special values. |
| 135 class ChunkOffsetBits : public BitField<uint32_t, 0, kChunkOffsetSize> {}; | 164 class ChunkOffsetBits : public BitField<uint32_t, 0, kChunkOffsetSize> {}; |
| 136 class ChunkIndexBits | 165 class ChunkIndexBits |
| 137 : public BitField<uint32_t, ChunkOffsetBits::kNext, kChunkIndexSize> {}; | 166 : public BitField<uint32_t, ChunkOffsetBits::kNext, kChunkIndexSize> {}; |
| 138 class SpaceBits | 167 class ValueIndexBits : public BitField<uint32_t, 0, kValueIndexSize> {}; |
| 139 : public BitField<AllocationSpace, ChunkIndexBits::kNext, kSpaceTagSize> { | 168 STATIC_ASSERT(ChunkIndexBits::kNext == ValueIndexBits::kNext); |
| 140 }; | 169 class SpaceBits : public BitField<int, kValueIndexSize, kSpaceTagSize> {}; |
| 170 STATIC_ASSERT(SpaceBits::kNext == 32); |
| 141 | 171 |
| 142 uint32_t bitfield_; | 172 uint32_t bitfield_; |
| 173 |
| 174 friend class SerializerReferenceMap; |
| 143 }; | 175 }; |
| 144 | 176 |
| 145 | |
| 146 // Mapping objects to their location after deserialization. | 177 // Mapping objects to their location after deserialization. |
| 147 // This is used during building, but not at runtime by V8. | 178 // This is used during building, but not at runtime by V8. |
| 148 class BackReferenceMap : public AddressMapBase { | 179 class SerializerReferenceMap : public AddressMapBase { |
| 149 public: | 180 public: |
| 150 BackReferenceMap() | 181 SerializerReferenceMap() |
| 151 : no_allocation_(), map_(new HashMap(HashMap::PointersMatch)) {} | 182 : no_allocation_(), |
| 183 map_(HashMap::PointersMatch), |
| 184 attached_reference_index_(0) {} |
| 152 | 185 |
| 153 ~BackReferenceMap() { delete map_; } | 186 SerializerReference Lookup(HeapObject* obj) { |
| 154 | 187 HashMap::Entry* entry = LookupEntry(&map_, obj, false); |
| 155 BackReference Lookup(HeapObject* obj) { | 188 return entry ? SerializerReference(GetValue(entry)) : SerializerReference(); |
| 156 HashMap::Entry* entry = LookupEntry(map_, obj, false); | |
| 157 return entry ? BackReference(GetValue(entry)) : BackReference(); | |
| 158 } | 189 } |
| 159 | 190 |
| 160 void Add(HeapObject* obj, BackReference b) { | 191 void Add(HeapObject* obj, SerializerReference b) { |
| 161 DCHECK(b.is_valid()); | 192 DCHECK(b.is_valid()); |
| 162 DCHECK_NULL(LookupEntry(map_, obj, false)); | 193 DCHECK_NULL(LookupEntry(&map_, obj, false)); |
| 163 HashMap::Entry* entry = LookupEntry(map_, obj, true); | 194 HashMap::Entry* entry = LookupEntry(&map_, obj, true); |
| 164 SetValue(entry, b.bitfield()); | 195 SetValue(entry, b.bitfield_); |
| 165 } | 196 } |
| 166 | 197 |
| 167 void AddSourceString(String* string) { | 198 SerializerReference AddAttachedReference(HeapObject* attached_reference) { |
| 168 Add(string, BackReference::SourceReference()); | 199 SerializerReference reference = |
| 169 } | 200 SerializerReference::AttachedReference(attached_reference_index_++); |
| 170 | 201 Add(attached_reference, reference); |
| 171 void AddGlobalProxy(HeapObject* global_proxy) { | 202 return reference; |
| 172 Add(global_proxy, BackReference::GlobalProxyReference()); | |
| 173 } | 203 } |
| 174 | 204 |
| 175 private: | 205 private: |
| 176 DisallowHeapAllocation no_allocation_; | 206 DisallowHeapAllocation no_allocation_; |
| 177 HashMap* map_; | 207 HashMap map_; |
| 178 DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); | 208 int attached_reference_index_; |
| 209 DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap); |
| 179 }; | 210 }; |
| 180 | 211 |
| 181 } // namespace internal | 212 } // namespace internal |
| 182 } // namespace v8 | 213 } // namespace v8 |
| 183 | 214 |
| 184 #endif // V8_ADDRESS_MAP_H_ | 215 #endif // V8_ADDRESS_MAP_H_ |
| OLD | NEW |