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 explicit SerializerReference(uint32_t bitfield) : bitfield_(bitfield) {} | |
vogelheim
2016/05/18 11:18:47
Why is this a public constructor?
(It assumes the
Yang
2016/05/18 11:58:42
The deserializer reconstructs references from seri
| |
64 SerializerReference() : bitfield_(Special(kInvalidValue)) {} | |
62 | 65 |
63 class BackReference { | 66 static SerializerReference BackReference(AllocationSpace space, |
64 public: | 67 uint32_t chunk_index, |
65 explicit BackReference(uint32_t bitfield) : bitfield_(bitfield) {} | 68 uint32_t chunk_offset) { |
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)); | 69 DCHECK(IsAligned(chunk_offset, kObjectAlignment)); |
85 DCHECK_NE(LO_SPACE, space); | 70 DCHECK_NE(LO_SPACE, space); |
86 return BackReference( | 71 return SerializerReference( |
87 SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | | 72 SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) | |
88 ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); | 73 ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits)); |
89 } | 74 } |
90 | 75 |
91 bool is_valid() const { return bitfield_ != kInvalidValue; } | 76 static SerializerReference LargeObjectReference(uint32_t index) { |
92 bool is_source() const { return bitfield_ == kSourceValue; } | 77 return SerializerReference(SpaceBits::encode(LO_SPACE) | |
93 bool is_global_proxy() const { return bitfield_ == kGlobalProxyValue; } | 78 ValueIndexBits::encode(index)); |
79 } | |
80 | |
81 static SerializerReference AttachedReference(uint32_t index) { | |
82 return SerializerReference(SpaceBits::encode(kAttachedReferenceSpace) | | |
83 ValueIndexBits::encode(index)); | |
84 } | |
85 | |
86 static SerializerReference DummyReference() { | |
87 return SerializerReference(Special(kDummyValue)); | |
88 } | |
89 | |
90 bool is_valid() const { return bitfield_ != Special(kInvalidValue); } | |
91 | |
92 bool is_back_reference() const { | |
93 return SpaceBits::decode(bitfield_) <= LAST_SPACE; | |
94 } | |
94 | 95 |
95 AllocationSpace space() const { | 96 AllocationSpace space() const { |
96 DCHECK(is_valid()); | 97 DCHECK(is_back_reference()); |
97 return SpaceBits::decode(bitfield_); | 98 return static_cast<AllocationSpace>(SpaceBits::decode(bitfield_)); |
98 } | 99 } |
99 | 100 |
100 uint32_t chunk_offset() const { | 101 uint32_t chunk_offset() const { |
101 DCHECK(is_valid()); | 102 DCHECK(is_back_reference()); |
102 return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits; | 103 return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits; |
103 } | 104 } |
104 | 105 |
105 uint32_t large_object_index() const { | 106 uint32_t large_object_index() const { |
106 DCHECK(is_valid()); | 107 DCHECK(is_back_reference()); |
107 DCHECK(chunk_index() == 0); | 108 DCHECK(chunk_index() == 0); |
108 return ChunkOffsetBits::decode(bitfield_); | 109 return ChunkOffsetBits::decode(bitfield_); |
109 } | 110 } |
110 | 111 |
111 uint32_t chunk_index() const { | 112 uint32_t chunk_index() const { |
112 DCHECK(is_valid()); | 113 DCHECK(is_back_reference()); |
113 return ChunkIndexBits::decode(bitfield_); | 114 return ChunkIndexBits::decode(bitfield_); |
114 } | 115 } |
115 | 116 |
116 uint32_t reference() const { | 117 uint32_t back_reference() const { |
117 DCHECK(is_valid()); | 118 DCHECK(is_back_reference()); |
118 return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask); | 119 return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask); |
119 } | 120 } |
120 | 121 |
121 uint32_t bitfield() const { return bitfield_; } | 122 bool is_attached_reference() const { |
123 return SpaceBits::decode(bitfield_) == kAttachedReferenceSpace; | |
124 } | |
125 | |
126 int attached_reference_index() const { | |
127 DCHECK(is_attached_reference()); | |
128 return ValueIndexBits::decode(bitfield_); | |
129 } | |
122 | 130 |
123 private: | 131 private: |
124 static const uint32_t kInvalidValue = 0xFFFFFFFF; | 132 inline static uint32_t Special(int value) { |
125 static const uint32_t kSourceValue = 0xFFFFFFFE; | 133 return SpaceBits::encode(kSpecialValueSpace) | |
126 static const uint32_t kGlobalProxyValue = 0xFFFFFFFD; | 134 ValueIndexBits::encode(value); |
127 static const uint32_t kDummyValue = 0xFFFFFFFC; | 135 } |
136 | |
137 // We use the 32-bit bitfield to encode either a back reference, a special | |
138 // value, or a attached reference index. | |
vogelheim
2016/05/18 11:18:47
super nitpick: "a attached" -> "an attached"
Yang
2016/05/18 11:58:42
Done.
| |
139 // Back reference: | |
140 // [ Space index ] [ Chunk index ] [ Chunk offset ] | |
141 // [ LO_SPACE ] [ large object index ] | |
142 // Special value | |
143 // [ kSpecialValueSpace ] [ Special value index ] | |
144 // Attached reference | |
145 // [ kAttachedReferenceSpace ] [ Attached reference index ] | |
146 | |
128 static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits; | 147 static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits; |
129 static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize; | 148 static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize; |
149 static const int kValueIndexSize = kChunkOffsetSize + kChunkIndexSize; | |
130 | 150 |
131 public: | 151 static const int kSpecialValueSpace = LAST_SPACE + 1; |
132 static const int kMaxChunkIndex = (1 << kChunkIndexSize) - 1; | 152 static const int kAttachedReferenceSpace = kSpecialValueSpace + 1; |
153 STATIC_ASSERT(kAttachedReferenceSpace < (1 << kSpaceTagSize)); | |
133 | 154 |
134 private: | 155 static const int kInvalidValue = 0; |
156 static const int kDummyValue = 1; | |
157 | |
158 // The chunk offset can also be used to encode the index of special values. | |
135 class ChunkOffsetBits : public BitField<uint32_t, 0, kChunkOffsetSize> {}; | 159 class ChunkOffsetBits : public BitField<uint32_t, 0, kChunkOffsetSize> {}; |
136 class ChunkIndexBits | 160 class ChunkIndexBits |
137 : public BitField<uint32_t, ChunkOffsetBits::kNext, kChunkIndexSize> {}; | 161 : public BitField<uint32_t, ChunkOffsetBits::kNext, kChunkIndexSize> {}; |
138 class SpaceBits | 162 class ValueIndexBits : public BitField<uint32_t, 0, kValueIndexSize> {}; |
139 : public BitField<AllocationSpace, ChunkIndexBits::kNext, kSpaceTagSize> { | 163 class SpaceBits : public BitField<int, kValueIndexSize, kSpaceTagSize> {}; |
140 }; | 164 STATIC_ASSERT(SpaceBits::kNext == 32); |
vogelheim
2016/05/18 11:18:47
Maybe assert for ValueIndexBits::kNext == ChunkInd
Yang
2016/05/18 11:58:42
Done.
| |
141 | 165 |
142 uint32_t bitfield_; | 166 uint32_t bitfield_; |
167 | |
168 friend class SerializerReferenceMap; | |
143 }; | 169 }; |
144 | 170 |
145 | |
146 // Mapping objects to their location after deserialization. | 171 // Mapping objects to their location after deserialization. |
147 // This is used during building, but not at runtime by V8. | 172 // This is used during building, but not at runtime by V8. |
148 class BackReferenceMap : public AddressMapBase { | 173 class SerializerReferenceMap : public AddressMapBase { |
149 public: | 174 public: |
150 BackReferenceMap() | 175 SerializerReferenceMap() |
151 : no_allocation_(), map_(new HashMap(HashMap::PointersMatch)) {} | 176 : no_allocation_(), |
177 map_(new HashMap(HashMap::PointersMatch)), | |
178 attached_reference_index_(0) {} | |
152 | 179 |
153 ~BackReferenceMap() { delete map_; } | 180 ~SerializerReferenceMap() { delete map_; } |
154 | 181 |
155 BackReference Lookup(HeapObject* obj) { | 182 SerializerReference Lookup(HeapObject* obj) { |
156 HashMap::Entry* entry = LookupEntry(map_, obj, false); | 183 HashMap::Entry* entry = LookupEntry(map_, obj, false); |
157 return entry ? BackReference(GetValue(entry)) : BackReference(); | 184 return entry ? SerializerReference(GetValue(entry)) : SerializerReference(); |
158 } | 185 } |
159 | 186 |
160 void Add(HeapObject* obj, BackReference b) { | 187 void Add(HeapObject* obj, SerializerReference b) { |
161 DCHECK(b.is_valid()); | 188 DCHECK(b.is_valid()); |
162 DCHECK_NULL(LookupEntry(map_, obj, false)); | 189 DCHECK_NULL(LookupEntry(map_, obj, false)); |
163 HashMap::Entry* entry = LookupEntry(map_, obj, true); | 190 HashMap::Entry* entry = LookupEntry(map_, obj, true); |
164 SetValue(entry, b.bitfield()); | 191 SetValue(entry, b.bitfield_); |
165 } | 192 } |
166 | 193 |
167 void AddSourceString(String* string) { | 194 SerializerReference AddAttachedReference(HeapObject* attached_reference) { |
168 Add(string, BackReference::SourceReference()); | 195 SerializerReference reference = |
169 } | 196 SerializerReference::AttachedReference(attached_reference_index_++); |
170 | 197 Add(attached_reference, reference); |
171 void AddGlobalProxy(HeapObject* global_proxy) { | 198 return reference; |
172 Add(global_proxy, BackReference::GlobalProxyReference()); | |
173 } | 199 } |
174 | 200 |
175 private: | 201 private: |
176 DisallowHeapAllocation no_allocation_; | 202 DisallowHeapAllocation no_allocation_; |
177 HashMap* map_; | 203 HashMap* map_; |
vogelheim
2016/05/18 11:18:47
Why not a regular (non-pointer) member?
(From wha
Yang
2016/05/18 11:58:42
Good point. Done.
| |
178 DISALLOW_COPY_AND_ASSIGN(BackReferenceMap); | 204 int attached_reference_index_; |
205 DISALLOW_COPY_AND_ASSIGN(SerializerReferenceMap); | |
179 }; | 206 }; |
180 | 207 |
181 } // namespace internal | 208 } // namespace internal |
182 } // namespace v8 | 209 } // namespace v8 |
183 | 210 |
184 #endif // V8_ADDRESS_MAP_H_ | 211 #endif // V8_ADDRESS_MAP_H_ |
OLD | NEW |