| 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 |