OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/snapshot/serializer.h" | 5 #include "src/snapshot/serializer.h" |
6 | 6 |
7 #include "src/macro-assembler.h" | 7 #include "src/macro-assembler.h" |
8 #include "src/snapshot/natives.h" | 8 #include "src/snapshot/natives.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 reference.large_object_index() < seen_large_objects_index_; | 133 reference.large_object_index() < seen_large_objects_index_; |
134 } else if (chunk_index == completed_chunks_[space].length()) { | 134 } else if (chunk_index == completed_chunks_[space].length()) { |
135 return reference.chunk_offset() < pending_chunk_[space]; | 135 return reference.chunk_offset() < pending_chunk_[space]; |
136 } else { | 136 } else { |
137 return chunk_index < completed_chunks_[space].length() && | 137 return chunk_index < completed_chunks_[space].length() && |
138 reference.chunk_offset() < completed_chunks_[space][chunk_index]; | 138 reference.chunk_offset() < completed_chunks_[space][chunk_index]; |
139 } | 139 } |
140 } | 140 } |
141 #endif // DEBUG | 141 #endif // DEBUG |
142 | 142 |
143 bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code, | 143 bool Serializer::SerializeHotObject(HeapObject* obj, HowToCode how_to_code, |
144 WhereToPoint where_to_point, int skip) { | 144 WhereToPoint where_to_point, int skip) { |
145 if (how_to_code == kPlain && where_to_point == kStartOfObject) { | 145 if (how_to_code != kPlain || where_to_point != kStartOfObject) return false; |
146 // Encode a reference to a hot object by its index in the working set. | 146 // Encode a reference to a hot object by its index in the working set. |
147 int index = hot_objects_.Find(obj); | 147 int index = hot_objects_.Find(obj); |
148 if (index != HotObjectsList::kNotFound) { | 148 if (index == HotObjectsList::kNotFound) return false; |
149 DCHECK(index >= 0 && index < kNumberOfHotObjects); | 149 DCHECK(index >= 0 && index < kNumberOfHotObjects); |
150 if (FLAG_trace_serializer) { | 150 if (FLAG_trace_serializer) { |
151 PrintF(" Encoding hot object %d:", index); | 151 PrintF(" Encoding hot object %d:", index); |
152 obj->ShortPrint(); | 152 obj->ShortPrint(); |
153 PrintF("\n"); | 153 PrintF("\n"); |
154 } | 154 } |
155 if (skip != 0) { | 155 if (skip != 0) { |
156 sink_.Put(kHotObjectWithSkip + index, "HotObjectWithSkip"); | 156 sink_.Put(kHotObjectWithSkip + index, "HotObjectWithSkip"); |
157 sink_.PutInt(skip, "HotObjectSkipDistance"); | 157 sink_.PutInt(skip, "HotObjectSkipDistance"); |
158 } else { | 158 } else { |
159 sink_.Put(kHotObject + index, "HotObject"); | 159 sink_.Put(kHotObject + index, "HotObject"); |
160 } | 160 } |
161 return true; | 161 return true; |
| 162 } |
| 163 bool Serializer::SerializeBackReference(HeapObject* obj, HowToCode how_to_code, |
| 164 WhereToPoint where_to_point, int skip) { |
| 165 SerializerReference reference = reference_map_.Lookup(obj); |
| 166 if (!reference.is_valid()) return false; |
| 167 // Encode the location of an already deserialized object in order to write |
| 168 // its location into a later object. We can encode the location as an |
| 169 // offset fromthe start of the deserialized objects or as an offset |
| 170 // backwards from thecurrent allocation pointer. |
| 171 if (reference.is_attached_reference()) { |
| 172 FlushSkip(skip); |
| 173 if (FLAG_trace_serializer) { |
| 174 PrintF(" Encoding attached reference %d\n", |
| 175 reference.attached_reference_index()); |
162 } | 176 } |
| 177 PutAttachedReference(reference, how_to_code, where_to_point); |
| 178 } else { |
| 179 DCHECK(reference.is_back_reference()); |
| 180 if (FLAG_trace_serializer) { |
| 181 PrintF(" Encoding back reference to: "); |
| 182 obj->ShortPrint(); |
| 183 PrintF("\n"); |
| 184 } |
| 185 |
| 186 PutAlignmentPrefix(obj); |
| 187 AllocationSpace space = reference.space(); |
| 188 if (skip == 0) { |
| 189 sink_.Put(kBackref + how_to_code + where_to_point + space, "BackRef"); |
| 190 } else { |
| 191 sink_.Put(kBackrefWithSkip + how_to_code + where_to_point + space, |
| 192 "BackRefWithSkip"); |
| 193 sink_.PutInt(skip, "BackRefSkipDistance"); |
| 194 } |
| 195 PutBackReference(obj, reference); |
163 } | 196 } |
164 SerializerReference reference = reference_map_.Lookup(obj); | 197 return true; |
165 if (reference.is_valid()) { | |
166 // Encode the location of an already deserialized object in order to write | |
167 // its location into a later object. We can encode the location as an | |
168 // offset fromthe start of the deserialized objects or as an offset | |
169 // backwards from thecurrent allocation pointer. | |
170 if (reference.is_attached_reference()) { | |
171 FlushSkip(skip); | |
172 if (FLAG_trace_serializer) { | |
173 PrintF(" Encoding attached reference %d\n", | |
174 reference.attached_reference_index()); | |
175 } | |
176 PutAttachedReference(reference, how_to_code, where_to_point); | |
177 } else { | |
178 DCHECK(reference.is_back_reference()); | |
179 if (FLAG_trace_serializer) { | |
180 PrintF(" Encoding back reference to: "); | |
181 obj->ShortPrint(); | |
182 PrintF("\n"); | |
183 } | |
184 | |
185 PutAlignmentPrefix(obj); | |
186 AllocationSpace space = reference.space(); | |
187 if (skip == 0) { | |
188 sink_.Put(kBackref + how_to_code + where_to_point + space, "BackRef"); | |
189 } else { | |
190 sink_.Put(kBackrefWithSkip + how_to_code + where_to_point + space, | |
191 "BackRefWithSkip"); | |
192 sink_.PutInt(skip, "BackRefSkipDistance"); | |
193 } | |
194 PutBackReference(obj, reference); | |
195 } | |
196 return true; | |
197 } | |
198 return false; | |
199 } | 198 } |
200 | 199 |
201 void Serializer::PutRoot(int root_index, HeapObject* object, | 200 void Serializer::PutRoot(int root_index, HeapObject* object, |
202 SerializerDeserializer::HowToCode how_to_code, | 201 SerializerDeserializer::HowToCode how_to_code, |
203 SerializerDeserializer::WhereToPoint where_to_point, | 202 SerializerDeserializer::WhereToPoint where_to_point, |
204 int skip) { | 203 int skip) { |
205 if (FLAG_trace_serializer) { | 204 if (FLAG_trace_serializer) { |
206 PrintF(" Encoding root %d:", root_index); | 205 PrintF(" Encoding root %d:", root_index); |
207 object->ShortPrint(); | 206 object->ShortPrint(); |
208 PrintF("\n"); | 207 PrintF("\n"); |
209 } | 208 } |
210 | 209 |
211 if (how_to_code == kPlain && where_to_point == kStartOfObject && | 210 if (how_to_code == kPlain && where_to_point == kStartOfObject && |
212 root_index < kNumberOfRootArrayConstants && | 211 root_index < kNumberOfRootArrayConstants && |
213 !isolate()->heap()->InNewSpace(object)) { | 212 !isolate()->heap()->InNewSpace(object)) { |
214 if (skip == 0) { | 213 if (skip == 0) { |
215 sink_.Put(kRootArrayConstants + root_index, "RootConstant"); | 214 sink_.Put(kRootArrayConstants + root_index, "RootConstant"); |
216 } else { | 215 } else { |
217 sink_.Put(kRootArrayConstantsWithSkip + root_index, "RootConstant"); | 216 sink_.Put(kRootArrayConstantsWithSkip + root_index, "RootConstant"); |
218 sink_.PutInt(skip, "SkipInPutRoot"); | 217 sink_.PutInt(skip, "SkipInPutRoot"); |
219 } | 218 } |
220 } else { | 219 } else { |
221 FlushSkip(skip); | 220 FlushSkip(skip); |
222 sink_.Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); | 221 sink_.Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); |
223 sink_.PutInt(root_index, "root_index"); | 222 sink_.PutInt(root_index, "root_index"); |
| 223 hot_objects_.Add(object); |
224 } | 224 } |
225 } | 225 } |
226 | 226 |
227 void Serializer::PutSmi(Smi* smi) { | 227 void Serializer::PutSmi(Smi* smi) { |
228 sink_.Put(kOnePointerRawData, "Smi"); | 228 sink_.Put(kOnePointerRawData, "Smi"); |
229 byte* bytes = reinterpret_cast<byte*>(&smi); | 229 byte* bytes = reinterpret_cast<byte*>(&smi); |
230 for (int i = 0; i < kPointerSize; i++) sink_.Put(bytes[i], "Byte"); | 230 for (int i = 0; i < kPointerSize; i++) sink_.Put(bytes[i], "Byte"); |
231 } | 231 } |
232 | 232 |
233 void Serializer::PutBackReference(HeapObject* object, | 233 void Serializer::PutBackReference(HeapObject* object, |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 if (to_skip != 0 && return_skip == kIgnoringReturn) { | 774 if (to_skip != 0 && return_skip == kIgnoringReturn) { |
775 sink_->Put(kSkip, "Skip"); | 775 sink_->Put(kSkip, "Skip"); |
776 sink_->PutInt(to_skip, "SkipDistance"); | 776 sink_->PutInt(to_skip, "SkipDistance"); |
777 to_skip = 0; | 777 to_skip = 0; |
778 } | 778 } |
779 return to_skip; | 779 return to_skip; |
780 } | 780 } |
781 | 781 |
782 } // namespace internal | 782 } // namespace internal |
783 } // namespace v8 | 783 } // namespace v8 |
OLD | NEW |