| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_CLUSTERED_SNAPSHOT_H_ | 5 #ifndef VM_CLUSTERED_SNAPSHOT_H_ |
| 6 #define VM_CLUSTERED_SNAPSHOT_H_ | 6 #define VM_CLUSTERED_SNAPSHOT_H_ |
| 7 | 7 |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/allocation.h" | 9 #include "vm/allocation.h" |
| 10 #include "vm/bitfield.h" | 10 #include "vm/bitfield.h" |
| 11 #include "vm/datastream.h" | 11 #include "vm/datastream.h" |
| 12 #include "vm/exceptions.h" | 12 #include "vm/exceptions.h" |
| 13 #include "vm/globals.h" | 13 #include "vm/globals.h" |
| 14 #include "vm/growable_array.h" | 14 #include "vm/growable_array.h" |
| 15 #include "vm/hash_map.h" |
| 15 #include "vm/heap.h" | 16 #include "vm/heap.h" |
| 16 #include "vm/isolate.h" | 17 #include "vm/isolate.h" |
| 17 #include "vm/object.h" | 18 #include "vm/object.h" |
| 18 #include "vm/snapshot.h" | 19 #include "vm/snapshot.h" |
| 19 #include "vm/version.h" | 20 #include "vm/version.h" |
| 20 #include "vm/visitor.h" | 21 #include "vm/visitor.h" |
| 21 | 22 |
| 22 namespace dart { | 23 namespace dart { |
| 23 | 24 |
| 24 // Forward declarations. | 25 // Forward declarations. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 // as rehashing. | 77 // as rehashing. |
| 77 virtual void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) { } | 78 virtual void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) { } |
| 78 | 79 |
| 79 protected: | 80 protected: |
| 80 // The range of the ref array that belongs to this cluster. | 81 // The range of the ref array that belongs to this cluster. |
| 81 intptr_t start_index_; | 82 intptr_t start_index_; |
| 82 intptr_t stop_index_; | 83 intptr_t stop_index_; |
| 83 }; | 84 }; |
| 84 | 85 |
| 85 | 86 |
| 86 enum { | 87 class SmiObjectIdPair { |
| 87 kRefTagSize = 1, | 88 public: |
| 88 kRefTagShift = 1, | 89 SmiObjectIdPair() : smi_(NULL), id_(0) { } |
| 89 kRefTagMask = 1, | 90 RawSmi* smi_; |
| 90 kSmiRefTag = 0x0, | 91 intptr_t id_; |
| 91 kHeapRefTag = 0x1, | 92 |
| 93 bool operator==(const SmiObjectIdPair& other) const { |
| 94 return (smi_ == other.smi_) && (id_ == other.id_); |
| 95 } |
| 92 }; | 96 }; |
| 93 | 97 |
| 94 | 98 |
| 99 class SmiObjectIdPairTrait { |
| 100 public: |
| 101 typedef RawSmi* Key; |
| 102 typedef intptr_t Value; |
| 103 typedef SmiObjectIdPair Pair; |
| 104 |
| 105 static Key KeyOf(Pair kv) { return kv.smi_; } |
| 106 static Value ValueOf(Pair kv) { return kv.id_; } |
| 107 static inline intptr_t Hashcode(Key key) { return Smi::Value(key); } |
| 108 static inline bool IsKeyEqual(Pair kv, Key key) { return kv.smi_ == key; } |
| 109 }; |
| 110 |
| 111 |
| 112 typedef DirectChainedHashMap<SmiObjectIdPairTrait> SmiObjectIdMap; |
| 113 |
| 114 |
| 95 class Serializer : public StackResource { | 115 class Serializer : public StackResource { |
| 96 public: | 116 public: |
| 97 Serializer(Thread* thread, | 117 Serializer(Thread* thread, |
| 98 Snapshot::Kind kind, | 118 Snapshot::Kind kind, |
| 99 uint8_t** buffer, | 119 uint8_t** buffer, |
| 100 ReAlloc alloc, | 120 ReAlloc alloc, |
| 101 intptr_t initial_size, | 121 intptr_t initial_size, |
| 102 InstructionsWriter* instructions_writer_); | 122 InstructionsWriter* instructions_writer_); |
| 103 ~Serializer(); | 123 ~Serializer(); |
| 104 | 124 |
| 105 intptr_t WriteVMSnapshot(const Array& symbols, const Array& scripts); | 125 intptr_t WriteVMSnapshot(const Array& symbols, const Array& scripts); |
| 106 void WriteFullSnapshot(intptr_t num_base_objects, ObjectStore* object_store); | 126 void WriteFullSnapshot(intptr_t num_base_objects, ObjectStore* object_store); |
| 107 | 127 |
| 108 void AddVMIsolateBaseObjects(); | 128 void AddVMIsolateBaseObjects(); |
| 109 | 129 |
| 110 void AddBaseObject(RawObject* base_object) { | 130 void AddBaseObject(RawObject* base_object) { |
| 111 AssignRef(base_object); | 131 AssignRef(base_object); |
| 112 num_base_objects_++; | 132 num_base_objects_++; |
| 113 } | 133 } |
| 114 | 134 |
| 115 void AssignRef(RawObject* object) { | 135 void AssignRef(RawObject* object) { |
| 116 ASSERT(next_ref_index_ != 0); | 136 ASSERT(next_ref_index_ != 0); |
| 117 heap_->SetObjectId(object, next_ref_index_); | 137 if (object->IsHeapObject()) { |
| 118 ASSERT(heap_->GetObjectId(object) == next_ref_index_); | 138 heap_->SetObjectId(object, next_ref_index_); |
| 139 ASSERT(heap_->GetObjectId(object) == next_ref_index_); |
| 140 } else { |
| 141 RawSmi* smi = Smi::RawCast(object); |
| 142 SmiObjectIdPair* existing_pair = smi_ids_.Lookup(smi); |
| 143 if (existing_pair != NULL) { |
| 144 ASSERT(existing_pair->id_ == 1); |
| 145 existing_pair->id_ = next_ref_index_; |
| 146 } else { |
| 147 SmiObjectIdPair new_pair; |
| 148 new_pair.smi_ = smi; |
| 149 new_pair.id_ = next_ref_index_; |
| 150 smi_ids_.Insert(new_pair); |
| 151 } |
| 152 } |
| 119 next_ref_index_++; | 153 next_ref_index_++; |
| 120 } | 154 } |
| 121 | 155 |
| 122 void Push(RawObject* object) { | 156 void Push(RawObject* object) { |
| 123 if (!object->IsHeapObject()) { | 157 if (!object->IsHeapObject()) { |
| 158 RawSmi* smi = Smi::RawCast(object); |
| 159 if (smi_ids_.Lookup(smi) == NULL) { |
| 160 SmiObjectIdPair pair; |
| 161 pair.smi_ = smi; |
| 162 pair.id_ = 1; |
| 163 smi_ids_.Insert(pair); |
| 164 stack_.Add(object); |
| 165 num_written_objects_++; |
| 166 } |
| 124 return; | 167 return; |
| 125 } | 168 } |
| 126 | 169 |
| 127 if (object->IsCode() && !Snapshot::IncludesCode(kind_)) { | 170 if (object->IsCode() && !Snapshot::IncludesCode(kind_)) { |
| 128 return; // Do not trace, will write null. | 171 return; // Do not trace, will write null. |
| 129 } | 172 } |
| 130 | 173 |
| 131 if (object->IsSendPort()) { | 174 if (object->IsSendPort()) { |
| 132 // TODO(rmacnak): Do a better job of resetting fields in precompilation | 175 // TODO(rmacnak): Do a better job of resetting fields in precompilation |
| 133 // and assert this is unreachable. | 176 // and assert this is unreachable. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 void Write(T value) { | 216 void Write(T value) { |
| 174 WriteStream::Raw<sizeof(T), T>::Write(&stream_, value); | 217 WriteStream::Raw<sizeof(T), T>::Write(&stream_, value); |
| 175 } | 218 } |
| 176 | 219 |
| 177 void WriteBytes(const uint8_t* addr, intptr_t len) { | 220 void WriteBytes(const uint8_t* addr, intptr_t len) { |
| 178 stream_.WriteBytes(addr, len); | 221 stream_.WriteBytes(addr, len); |
| 179 } | 222 } |
| 180 | 223 |
| 181 void WriteRef(RawObject* object) { | 224 void WriteRef(RawObject* object) { |
| 182 if (!object->IsHeapObject()) { | 225 if (!object->IsHeapObject()) { |
| 183 ASSERT(static_cast<intptr_t>(kSmiRefTag) == | 226 RawSmi* smi = Smi::RawCast(object); |
| 184 static_cast<intptr_t>(kSmiTag)); | 227 intptr_t id = smi_ids_.Lookup(smi)->id_; |
| 185 Write<intptr_t>(reinterpret_cast<intptr_t>(object)); | 228 if (id == 0) { |
| 229 FATAL("Missing ref"); |
| 230 } |
| 231 Write<int32_t>(id); |
| 186 return; | 232 return; |
| 187 } | 233 } |
| 188 | 234 |
| 189 intptr_t id = heap_->GetObjectId(object); | 235 intptr_t id = heap_->GetObjectId(object); |
| 190 if (id == 0) { | 236 if (id == 0) { |
| 191 if (object->IsCode() && !Snapshot::IncludesCode(kind_)) { | 237 if (object->IsCode() && !Snapshot::IncludesCode(kind_)) { |
| 192 WriteRef(Object::null()); | 238 WriteRef(Object::null()); |
| 193 return; | 239 return; |
| 194 } | 240 } |
| 195 if (object->IsSendPort()) { | 241 if (object->IsSendPort()) { |
| 196 // TODO(rmacnak): Do a better job of resetting fields in precompilation | 242 // TODO(rmacnak): Do a better job of resetting fields in precompilation |
| 197 // and assert this is unreachable. | 243 // and assert this is unreachable. |
| 198 WriteRef(Object::null()); | 244 WriteRef(Object::null()); |
| 199 return; | 245 return; |
| 200 } | 246 } |
| 201 FATAL("Missing ref"); | 247 FATAL("Missing ref"); |
| 202 } | 248 } |
| 203 Write<intptr_t>((id << kRefTagShift) | kHeapRefTag); | 249 Write<int32_t>(id); |
| 204 } | 250 } |
| 205 | 251 |
| 206 void WriteTokenPosition(TokenPosition pos) { | 252 void WriteTokenPosition(TokenPosition pos) { |
| 207 Write<int32_t>(pos.SnapshotEncode()); | 253 Write<int32_t>(pos.SnapshotEncode()); |
| 208 } | 254 } |
| 209 | 255 |
| 210 void WriteCid(intptr_t cid) { | 256 void WriteCid(intptr_t cid) { |
| 211 COMPILE_ASSERT(RawObject::kClassIdTagSize <= 32); | 257 COMPILE_ASSERT(RawObject::kClassIdTagSize <= 32); |
| 212 Write<int32_t>(cid); | 258 Write<int32_t>(cid); |
| 213 } | 259 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 227 Zone* zone_; | 273 Zone* zone_; |
| 228 Snapshot::Kind kind_; | 274 Snapshot::Kind kind_; |
| 229 WriteStream stream_; | 275 WriteStream stream_; |
| 230 InstructionsWriter* instructions_writer_; | 276 InstructionsWriter* instructions_writer_; |
| 231 SerializationCluster** clusters_by_cid_; | 277 SerializationCluster** clusters_by_cid_; |
| 232 GrowableArray<RawObject*> stack_; | 278 GrowableArray<RawObject*> stack_; |
| 233 intptr_t num_cids_; | 279 intptr_t num_cids_; |
| 234 intptr_t num_base_objects_; | 280 intptr_t num_base_objects_; |
| 235 intptr_t num_written_objects_; | 281 intptr_t num_written_objects_; |
| 236 intptr_t next_ref_index_; | 282 intptr_t next_ref_index_; |
| 283 SmiObjectIdMap smi_ids_; |
| 237 | 284 |
| 238 DISALLOW_IMPLICIT_CONSTRUCTORS(Serializer); | 285 DISALLOW_IMPLICIT_CONSTRUCTORS(Serializer); |
| 239 }; | 286 }; |
| 240 | 287 |
| 241 | 288 |
| 242 class Deserializer : public StackResource { | 289 class Deserializer : public StackResource { |
| 243 public: | 290 public: |
| 244 Deserializer(Thread* thread, | 291 Deserializer(Thread* thread, |
| 245 Snapshot::Kind kind, | 292 Snapshot::Kind kind, |
| 246 const uint8_t* buffer, | 293 const uint8_t* buffer, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 next_ref_index_++; | 340 next_ref_index_++; |
| 294 } | 341 } |
| 295 | 342 |
| 296 RawObject* Ref(intptr_t index) const { | 343 RawObject* Ref(intptr_t index) const { |
| 297 ASSERT(index > 0); | 344 ASSERT(index > 0); |
| 298 ASSERT(index <= num_objects_); | 345 ASSERT(index <= num_objects_); |
| 299 return refs_->ptr()->data()[index]; | 346 return refs_->ptr()->data()[index]; |
| 300 } | 347 } |
| 301 | 348 |
| 302 RawObject* ReadRef() { | 349 RawObject* ReadRef() { |
| 303 intptr_t index = Read<intptr_t>(); | 350 int32_t index = Read<int32_t>(); |
| 304 if ((index & kRefTagMask) == kSmiRefTag) { | 351 return Ref(index); |
| 305 ASSERT(static_cast<intptr_t>(kSmiRefTag) == | |
| 306 static_cast<intptr_t>(kSmiTag)); | |
| 307 return reinterpret_cast<RawSmi*>(index); | |
| 308 } | |
| 309 return Ref(index >> kRefTagShift); | |
| 310 } | 352 } |
| 311 | 353 |
| 312 TokenPosition ReadTokenPosition() { | 354 TokenPosition ReadTokenPosition() { |
| 313 return TokenPosition::SnapshotDecode(Read<int32_t>()); | 355 return TokenPosition::SnapshotDecode(Read<int32_t>()); |
| 314 } | 356 } |
| 315 | 357 |
| 316 intptr_t ReadCid() { | 358 intptr_t ReadCid() { |
| 317 COMPILE_ASSERT(RawObject::kClassIdTagSize <= 32); | 359 COMPILE_ASSERT(RawObject::kClassIdTagSize <= 32); |
| 318 return Read<int32_t>(); | 360 return Read<int32_t>(); |
| 319 } | 361 } |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 intptr_t size_; | 511 intptr_t size_; |
| 470 const uint8_t* instructions_buffer_; | 512 const uint8_t* instructions_buffer_; |
| 471 const uint8_t* data_buffer_; | 513 const uint8_t* data_buffer_; |
| 472 | 514 |
| 473 DISALLOW_COPY_AND_ASSIGN(IsolateSnapshotReader); | 515 DISALLOW_COPY_AND_ASSIGN(IsolateSnapshotReader); |
| 474 }; | 516 }; |
| 475 | 517 |
| 476 } // namespace dart | 518 } // namespace dart |
| 477 | 519 |
| 478 #endif // VM_CLUSTERED_SNAPSHOT_H_ | 520 #endif // VM_CLUSTERED_SNAPSHOT_H_ |
| OLD | NEW |