OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #include "vm/snapshot.h" | 5 #include "vm/snapshot.h" |
6 | 6 |
7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 (kind == Snapshot::kFull) ? | 199 (kind == Snapshot::kFull) ? |
200 Object::vm_isolate_snapshot_object_table().Length() : 0), | 200 Object::vm_isolate_snapshot_object_table().Length() : 0), |
201 backward_references_(backward_refs) { | 201 backward_references_(backward_refs) { |
202 } | 202 } |
203 | 203 |
204 | 204 |
205 RawObject* SnapshotReader::ReadObject() { | 205 RawObject* SnapshotReader::ReadObject() { |
206 // Setup for long jump in case there is an exception while reading. | 206 // Setup for long jump in case there is an exception while reading. |
207 LongJumpScope jump; | 207 LongJumpScope jump; |
208 if (setjmp(*jump.Set()) == 0) { | 208 if (setjmp(*jump.Set()) == 0) { |
209 PassiveObject& obj = PassiveObject::Handle(isolate(), ReadObjectImpl()); | 209 PassiveObject& obj = |
| 210 PassiveObject::Handle(isolate(), ReadObjectImpl(kAsInlinedObject)); |
210 for (intptr_t i = 0; i < backward_references_->length(); i++) { | 211 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
211 if (!(*backward_references_)[i].is_deserialized()) { | 212 if (!(*backward_references_)[i].is_deserialized()) { |
212 ReadObjectImpl(); | 213 ReadObjectImpl(kAsInlinedObject); |
213 (*backward_references_)[i].set_state(kIsDeserialized); | 214 (*backward_references_)[i].set_state(kIsDeserialized); |
214 } | 215 } |
215 } | 216 } |
216 return obj.raw(); | 217 return obj.raw(); |
217 } else { | 218 } else { |
218 // An error occurred while reading, return the error object. | 219 // An error occurred while reading, return the error object. |
219 const Error& err = Error::Handle(isolate()->object_store()->sticky_error()); | 220 const Error& err = Error::Handle(isolate()->object_store()->sticky_error()); |
220 isolate()->object_store()->clear_sticky_error(); | 221 isolate()->object_store()->clear_sticky_error(); |
221 return err.raw(); | 222 return err.raw(); |
222 } | 223 } |
223 } | 224 } |
224 | 225 |
225 | 226 |
226 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) { | 227 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) { |
227 ASSERT(kind_ != Snapshot::kFull); | 228 ASSERT(kind_ != Snapshot::kFull); |
228 // Read the class header information and lookup the class. | 229 // Read the class header information and lookup the class. |
229 intptr_t class_header = Read<int32_t>(); | 230 intptr_t class_header = Read<int32_t>(); |
230 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 231 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
231 ASSERT(!IsVMIsolateObject(class_header) || | 232 ASSERT(!IsVMIsolateObject(class_header) || |
232 !IsSingletonClassId(GetVMIsolateObjectId(class_header))); | 233 !IsSingletonClassId(GetVMIsolateObjectId(class_header))); |
233 ASSERT((SerializedHeaderTag::decode(class_header) != kObjectId) || | 234 ASSERT((SerializedHeaderTag::decode(class_header) != kObjectId) || |
234 !IsObjectStoreClassId(SerializedHeaderData::decode(class_header))); | 235 !IsObjectStoreClassId(SerializedHeaderData::decode(class_header))); |
235 Class& cls = Class::ZoneHandle(zone(), Class::null()); | 236 Class& cls = Class::ZoneHandle(zone(), Class::null()); |
236 AddBackRef(object_id, &cls, kIsDeserialized); | 237 AddBackRef(object_id, &cls, kIsDeserialized); |
237 // Read the library/class information and lookup the class. | 238 // Read the library/class information and lookup the class. |
238 str_ ^= ReadObjectImpl(class_header); | 239 str_ ^= ReadObjectImpl(class_header, kAsInlinedObject); |
239 library_ = Library::LookupLibrary(str_); | 240 library_ = Library::LookupLibrary(str_); |
240 if (library_.IsNull() || !library_.Loaded()) { | 241 if (library_.IsNull() || !library_.Loaded()) { |
241 SetReadException("Invalid object found in message."); | 242 SetReadException("Invalid object found in message."); |
242 } | 243 } |
243 str_ ^= ReadObjectImpl(); | 244 str_ ^= ReadObjectImpl(kAsInlinedObject); |
244 cls = library_.LookupClass(str_); | 245 cls = library_.LookupClass(str_); |
245 if (cls.IsNull()) { | 246 if (cls.IsNull()) { |
246 SetReadException("Invalid object found in message."); | 247 SetReadException("Invalid object found in message."); |
247 } | 248 } |
248 cls.EnsureIsFinalized(isolate()); | 249 cls.EnsureIsFinalized(isolate()); |
249 return cls.raw(); | 250 return cls.raw(); |
250 } | 251 } |
251 | 252 |
252 | 253 |
253 RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id, | 254 RawObject* SnapshotReader::ReadStaticImplicitClosure(intptr_t object_id, |
254 intptr_t class_header) { | 255 intptr_t class_header) { |
255 ASSERT(kind_ == Snapshot::kMessage); | 256 ASSERT(kind_ == Snapshot::kMessage); |
256 | 257 |
257 // First create a function object and associate it with the specified | 258 // First create a function object and associate it with the specified |
258 // 'object_id'. | 259 // 'object_id'. |
259 Function& func = Function::Handle(isolate(), Function::null()); | 260 Function& func = Function::Handle(isolate(), Function::null()); |
260 Instance& obj = Instance::ZoneHandle(zone(), Instance::null()); | 261 Instance& obj = Instance::ZoneHandle(zone(), Instance::null()); |
261 AddBackRef(object_id, &obj, kIsDeserialized); | 262 AddBackRef(object_id, &obj, kIsDeserialized); |
262 | 263 |
263 // Read the library/class/function information and lookup the function. | 264 // Read the library/class/function information and lookup the function. |
264 str_ ^= ReadObjectImpl(); | 265 str_ ^= ReadObjectImpl(kAsInlinedObject); |
265 library_ = Library::LookupLibrary(str_); | 266 library_ = Library::LookupLibrary(str_); |
266 if (library_.IsNull() || !library_.Loaded()) { | 267 if (library_.IsNull() || !library_.Loaded()) { |
267 SetReadException("Invalid Library object found in message."); | 268 SetReadException("Invalid Library object found in message."); |
268 } | 269 } |
269 str_ ^= ReadObjectImpl(); | 270 str_ ^= ReadObjectImpl(kAsInlinedObject); |
270 if (str_.Equals(Symbols::TopLevel())) { | 271 if (str_.Equals(Symbols::TopLevel())) { |
271 str_ ^= ReadObjectImpl(); | 272 str_ ^= ReadObjectImpl(kAsInlinedObject); |
272 func = library_.LookupFunctionAllowPrivate(str_); | 273 func = library_.LookupFunctionAllowPrivate(str_); |
273 } else { | 274 } else { |
274 cls_ = library_.LookupClassAllowPrivate(str_); | 275 cls_ = library_.LookupClassAllowPrivate(str_); |
275 if (cls_.IsNull()) { | 276 if (cls_.IsNull()) { |
276 OS::Print("Name of class not found %s\n", str_.ToCString()); | 277 OS::Print("Name of class not found %s\n", str_.ToCString()); |
277 SetReadException("Invalid Class object found in message."); | 278 SetReadException("Invalid Class object found in message."); |
278 } | 279 } |
279 cls_.EnsureIsFinalized(isolate()); | 280 cls_.EnsureIsFinalized(isolate()); |
280 str_ ^= ReadObjectImpl(); | 281 str_ ^= ReadObjectImpl(kAsInlinedObject); |
281 func = cls_.LookupFunctionAllowPrivate(str_); | 282 func = cls_.LookupFunctionAllowPrivate(str_); |
282 } | 283 } |
283 if (func.IsNull()) { | 284 if (func.IsNull()) { |
284 SetReadException("Invalid function object found in message."); | 285 SetReadException("Invalid function object found in message."); |
285 } | 286 } |
286 func = func.ImplicitClosureFunction(); | 287 func = func.ImplicitClosureFunction(); |
287 ASSERT(!func.IsNull()); | 288 ASSERT(!func.IsNull()); |
288 | 289 |
289 // Return the associated implicit static closure. | 290 // Return the associated implicit static closure. |
290 obj = func.ImplicitStaticClosure(); | 291 obj = func.ImplicitStaticClosure(); |
291 return obj.raw(); | 292 return obj.raw(); |
292 } | 293 } |
293 | 294 |
294 | 295 |
295 RawObject* SnapshotReader::ReadObjectImpl() { | |
296 int64_t value = Read<int64_t>(); | |
297 if ((value & kSmiTagMask) == kSmiTag) { | |
298 return NewInteger(value); | |
299 } | |
300 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | |
301 return ReadObjectImpl(static_cast<intptr_t>(value)); | |
302 } | |
303 | |
304 | |
305 intptr_t SnapshotReader::NextAvailableObjectId() const { | 296 intptr_t SnapshotReader::NextAvailableObjectId() const { |
306 return backward_references_->length() + | 297 return backward_references_->length() + |
307 kMaxPredefinedObjectIds + max_vm_isolate_object_id_; | 298 kMaxPredefinedObjectIds + max_vm_isolate_object_id_; |
308 } | 299 } |
309 | 300 |
310 | 301 |
311 void SnapshotReader::SetReadException(const char* msg) { | 302 void SnapshotReader::SetReadException(const char* msg) { |
312 Isolate* isolate = Isolate::Current(); | 303 Isolate* isolate = Isolate::Current(); |
313 const String& error_str = String::Handle(isolate, String::New(msg)); | 304 const String& error_str = String::Handle(isolate, String::New(msg)); |
314 const Array& args = Array::Handle(isolate, Array::New(1)); | 305 const Array& args = Array::Handle(isolate, Array::New(1)); |
315 args.SetAt(0, error_str); | 306 args.SetAt(0, error_str); |
316 Object& result = Object::Handle(isolate); | 307 Object& result = Object::Handle(isolate); |
317 const Library& library = Library::Handle(isolate, Library::CoreLibrary()); | 308 const Library& library = Library::Handle(isolate, Library::CoreLibrary()); |
318 result = DartLibraryCalls::InstanceCreate(library, | 309 result = DartLibraryCalls::InstanceCreate(library, |
319 Symbols::ArgumentError(), | 310 Symbols::ArgumentError(), |
320 Symbols::Dot(), | 311 Symbols::Dot(), |
321 args); | 312 args); |
322 const Stacktrace& stacktrace = Stacktrace::Handle(isolate); | 313 const Stacktrace& stacktrace = Stacktrace::Handle(isolate); |
323 const UnhandledException& error = UnhandledException::Handle( | 314 const UnhandledException& error = UnhandledException::Handle( |
324 isolate, UnhandledException::New(Instance::Cast(result), stacktrace)); | 315 isolate, UnhandledException::New(Instance::Cast(result), stacktrace)); |
325 isolate->long_jump_base()->Jump(1, error); | 316 isolate->long_jump_base()->Jump(1, error); |
326 } | 317 } |
327 | 318 |
328 | 319 |
329 RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const { | 320 RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const { |
330 return Object::vm_isolate_snapshot_object_table().At(index); | 321 return Object::vm_isolate_snapshot_object_table().At(index); |
331 } | 322 } |
332 | 323 |
333 | 324 |
334 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { | 325 RawObject* SnapshotReader::ReadObjectImpl(bool as_reference) { |
| 326 int64_t header_value = Read<int64_t>(); |
| 327 if ((header_value & kSmiTagMask) == kSmiTag) { |
| 328 return NewInteger(header_value); |
| 329 } |
| 330 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
| 331 return ReadObjectImpl(static_cast<intptr_t>(header_value), as_reference); |
| 332 } |
| 333 |
| 334 |
| 335 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value, |
| 336 bool as_reference) { |
335 if (IsVMIsolateObject(header_value)) { | 337 if (IsVMIsolateObject(header_value)) { |
336 return ReadVMIsolateObject(header_value); | 338 return ReadVMIsolateObject(header_value); |
337 } else { | 339 } else { |
338 if (SerializedHeaderTag::decode(header_value) == kObjectId) { | 340 if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
339 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); | 341 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
340 } | 342 } |
341 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); | 343 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
342 intptr_t object_id = SerializedHeaderData::decode(header_value); | 344 intptr_t object_id = SerializedHeaderData::decode(header_value); |
343 if (object_id == kOmittedObjectId) { | 345 if (object_id == kOmittedObjectId) { |
344 object_id = NextAvailableObjectId(); | 346 object_id = NextAvailableObjectId(); |
345 } | 347 } |
346 return ReadInlinedObject(object_id); | 348 |
| 349 // Read the class header information. |
| 350 intptr_t class_header = Read<int32_t>(); |
| 351 intptr_t tags = ReadTags(); |
| 352 if (as_reference && !RawObject::IsCanonical(tags)) { |
| 353 return ReadObjectRef(object_id, class_header, tags); |
| 354 } else { |
| 355 return ReadInlinedObject(object_id, class_header, tags); |
| 356 } |
347 } | 357 } |
348 } | 358 } |
349 | 359 |
350 | 360 |
351 RawObject* SnapshotReader::ReadObjectRef() { | 361 RawObject* SnapshotReader::ReadObjectRef(intptr_t object_id, |
352 int64_t header_value = Read<int64_t>(); | 362 intptr_t class_header, |
353 if ((header_value & kSmiTagMask) == kSmiTag) { | 363 intptr_t tags) { |
354 return NewInteger(header_value); | |
355 } | |
356 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); | |
357 intptr_t value = static_cast<intptr_t>(header_value); | |
358 if (IsVMIsolateObject(value)) { | |
359 return ReadVMIsolateObject(value); | |
360 } else if (SerializedHeaderTag::decode(value) == kObjectId) { | |
361 return ReadIndexedObject(SerializedHeaderData::decode(value)); | |
362 } | |
363 ASSERT(SerializedHeaderTag::decode(value) == kInlined); | |
364 intptr_t object_id = SerializedHeaderData::decode(value); | |
365 if (object_id == kOmittedObjectId) { | |
366 object_id = NextAvailableObjectId(); | |
367 } | |
368 ASSERT(GetBackRef(object_id) == NULL); | |
369 | |
370 // Read the class header information and lookup the class. | |
371 intptr_t class_header = Read<int32_t>(); | |
372 | |
373 // Since we are only reading an object reference, If it is an instance kind | 364 // Since we are only reading an object reference, If it is an instance kind |
374 // then we only need to figure out the class of the object and allocate an | 365 // then we only need to figure out the class of the object and allocate an |
375 // instance of it. The individual fields will be read later. | 366 // instance of it. The individual fields will be read later. |
376 intptr_t header_id = SerializedHeaderData::decode(class_header); | 367 intptr_t header_id = SerializedHeaderData::decode(class_header); |
377 if (header_id == kInstanceObjectId) { | 368 if (header_id == kInstanceObjectId) { |
378 Instance& result = Instance::ZoneHandle(zone(), Instance::null()); | 369 Instance& result = Instance::ZoneHandle(zone(), Instance::null()); |
379 AddBackRef(object_id, &result, kIsNotDeserialized); | 370 AddBackRef(object_id, &result, kIsNotDeserialized); |
380 | 371 |
381 cls_ ^= ReadObjectImpl(); // Read class information. | 372 cls_ ^= ReadObjectImpl(kAsInlinedObject); // Read class information. |
382 ASSERT(!cls_.IsNull()); | 373 ASSERT(!cls_.IsNull()); |
383 intptr_t instance_size = cls_.instance_size(); | 374 intptr_t instance_size = cls_.instance_size(); |
384 ASSERT(instance_size > 0); | 375 ASSERT(instance_size > 0); |
385 if (kind_ == Snapshot::kFull) { | 376 if (kind_ == Snapshot::kFull) { |
386 result ^= AllocateUninitialized(cls_.id(), instance_size); | 377 result ^= AllocateUninitialized(cls_.id(), instance_size); |
387 } else { | 378 } else { |
388 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); | 379 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); |
389 } | 380 } |
390 return result.raw(); | 381 return result.raw(); |
391 } else if (header_id == kStaticImplicitClosureObjectId) { | 382 } else if (header_id == kStaticImplicitClosureObjectId) { |
392 // We skip the tags that have been written as the implicit static | 383 // We skip the tags that have been written as the implicit static |
393 // closure is going to be created in this isolate or the canonical | 384 // closure is going to be created in this isolate or the canonical |
394 // version already created in the isolate will be used. | 385 // version already created in the isolate will be used. |
395 ReadTags(); | |
396 return ReadStaticImplicitClosure(object_id, class_header); | 386 return ReadStaticImplicitClosure(object_id, class_header); |
397 } | 387 } |
398 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 388 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
399 | 389 |
400 // Similarly Array and ImmutableArray objects are also similarly only | 390 // Similarly Array and ImmutableArray objects are also similarly only |
401 // allocated here, the individual array elements are read later. | 391 // allocated here, the individual array elements are read later. |
402 intptr_t class_id = LookupInternalClass(class_header); | 392 intptr_t class_id = LookupInternalClass(class_header); |
403 if (class_id == kArrayCid) { | 393 if (class_id == kArrayCid) { |
404 // Read the length and allocate an object based on the len. | 394 // Read the length and allocate an object based on the len. |
405 intptr_t len = ReadSmiValue(); | 395 intptr_t len = ReadSmiValue(); |
(...skipping 11 matching lines...) Expand all Loading... |
417 Array& array = Array::ZoneHandle( | 407 Array& array = Array::ZoneHandle( |
418 zone(), | 408 zone(), |
419 (kind_ == Snapshot::kFull) ? | 409 (kind_ == Snapshot::kFull) ? |
420 NewImmutableArray(len) : ImmutableArray::New(len, HEAP_SPACE(kind_))); | 410 NewImmutableArray(len) : ImmutableArray::New(len, HEAP_SPACE(kind_))); |
421 AddBackRef(object_id, &array, kIsNotDeserialized); | 411 AddBackRef(object_id, &array, kIsNotDeserialized); |
422 | 412 |
423 return array.raw(); | 413 return array.raw(); |
424 } | 414 } |
425 | 415 |
426 // For all other internal VM classes we read the object inline. | 416 // For all other internal VM classes we read the object inline. |
427 intptr_t tags = ReadTags(); | |
428 switch (class_id) { | 417 switch (class_id) { |
429 #define SNAPSHOT_READ(clazz) \ | 418 #define SNAPSHOT_READ(clazz) \ |
430 case clazz::kClassId: { \ | 419 case clazz::kClassId: { \ |
| 420 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ |
| 421 break; \ |
| 422 } |
| 423 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
| 424 #undef SNAPSHOT_READ |
| 425 #define SNAPSHOT_READ(clazz) \ |
| 426 case kTypedData##clazz##Cid: \ |
| 427 |
| 428 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 429 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 430 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_); |
| 431 break; |
| 432 } |
| 433 #undef SNAPSHOT_READ |
| 434 #define SNAPSHOT_READ(clazz) \ |
| 435 case kExternalTypedData##clazz##Cid: \ |
| 436 |
| 437 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 438 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 439 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); |
| 440 break; |
| 441 } |
| 442 #undef SNAPSHOT_READ |
| 443 default: UNREACHABLE(); break; |
| 444 } |
| 445 if (kind_ == Snapshot::kFull) { |
| 446 pobj_.SetCreatedFromSnapshot(); |
| 447 } |
| 448 return pobj_.raw(); |
| 449 } |
| 450 |
| 451 |
| 452 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id, |
| 453 intptr_t class_header, |
| 454 intptr_t tags) { |
| 455 // Lookup the class based on the class header information. |
| 456 intptr_t header_id = SerializedHeaderData::decode(class_header); |
| 457 if (header_id == kInstanceObjectId) { |
| 458 // Object is regular dart instance. |
| 459 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); |
| 460 intptr_t instance_size = 0; |
| 461 if (result == NULL) { |
| 462 result = &(Instance::ZoneHandle(zone(), Instance::null())); |
| 463 AddBackRef(object_id, result, kIsDeserialized); |
| 464 cls_ ^= ReadObjectImpl(kAsInlinedObject); |
| 465 ASSERT(!cls_.IsNull()); |
| 466 instance_size = cls_.instance_size(); |
| 467 ASSERT(instance_size > 0); |
| 468 // Allocate the instance and read in all the fields for the object. |
| 469 if (kind_ == Snapshot::kFull) { |
| 470 *result ^= AllocateUninitialized(cls_.id(), instance_size); |
| 471 } else { |
| 472 *result ^= Object::Allocate(cls_.id(), |
| 473 instance_size, |
| 474 HEAP_SPACE(kind_)); |
| 475 } |
| 476 } else { |
| 477 cls_ ^= ReadObjectImpl(kAsInlinedObject); |
| 478 ASSERT(!cls_.IsNull()); |
| 479 instance_size = cls_.instance_size(); |
| 480 } |
| 481 intptr_t next_field_offset = cls_.next_field_offset(); |
| 482 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
| 483 ASSERT(next_field_offset > 0); |
| 484 // Instance::NextFieldOffset() returns the offset of the first field in |
| 485 // a Dart object. |
| 486 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
| 487 intptr_t offset = Instance::NextFieldOffset(); |
| 488 intptr_t result_cid = result->GetClassId(); |
| 489 while (offset < next_field_offset) { |
| 490 pobj_ = ReadObjectImpl(as_reference); |
| 491 result->SetFieldAtOffset(offset, pobj_); |
| 492 if ((offset != type_argument_field_offset) && |
| 493 (kind_ == Snapshot::kMessage)) { |
| 494 // TODO(fschneider): Consider hoisting these lookups out of the loop. |
| 495 // This would involve creating a handle, since cls_ can't be reused |
| 496 // across the call to ReadObjectRef. |
| 497 cls_ = isolate()->class_table()->At(result_cid); |
| 498 array_ = cls_.OffsetToFieldMap(); |
| 499 field_ ^= array_.At(offset >> kWordSizeLog2); |
| 500 ASSERT(!field_.IsNull()); |
| 501 ASSERT(field_.Offset() == offset); |
| 502 obj_ = pobj_.raw(); |
| 503 field_.RecordStore(obj_); |
| 504 } |
| 505 // TODO(fschneider): Verify the guarded cid and length for other kinds of |
| 506 // snapshot (kFull, kScript) with asserts. |
| 507 offset += kWordSize; |
| 508 } |
| 509 if (kind_ == Snapshot::kFull) { |
| 510 // We create an uninitialized object in the case of full snapshots, so |
| 511 // we need to initialize any remaining padding area with the Null object. |
| 512 while (offset < instance_size) { |
| 513 result->SetFieldAtOffset(offset, Object::null_object()); |
| 514 offset += kWordSize; |
| 515 } |
| 516 result->SetCreatedFromSnapshot(); |
| 517 } else if (RawObject::IsCanonical(tags)) { |
| 518 *result = result->CheckAndCanonicalize(NULL); |
| 519 ASSERT(!result->IsNull()); |
| 520 } |
| 521 return result->raw(); |
| 522 } else if (header_id == kStaticImplicitClosureObjectId) { |
| 523 // We do not use the tags as the implicit static closure |
| 524 // is going to be created in this isolate or the canonical |
| 525 // version already created in the isolate will be used. |
| 526 return ReadStaticImplicitClosure(object_id, class_header); |
| 527 } |
| 528 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 529 intptr_t class_id = LookupInternalClass(class_header); |
| 530 switch (class_id) { |
| 531 #define SNAPSHOT_READ(clazz) \ |
| 532 case clazz::kClassId: { \ |
431 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ | 533 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ |
432 break; \ | 534 break; \ |
433 } | 535 } |
434 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | 536 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
435 #undef SNAPSHOT_READ | 537 #undef SNAPSHOT_READ |
436 #define SNAPSHOT_READ(clazz) \ | 538 #define SNAPSHOT_READ(clazz) \ |
437 case kTypedData##clazz##Cid: \ | 539 case kTypedData##clazz##Cid: \ |
438 | 540 |
439 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | 541 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
440 tags = RawObject::ClassIdTag::update(class_id, tags); | 542 tags = RawObject::ClassIdTag::update(class_id, tags); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 | 618 |
517 // TODO(asiva): Add a check here to ensure we have the right heap | 619 // TODO(asiva): Add a check here to ensure we have the right heap |
518 // size for the full snapshot being read. | 620 // size for the full snapshot being read. |
519 { | 621 { |
520 NoSafepointScope no_safepoint; | 622 NoSafepointScope no_safepoint; |
521 HeapLocker hl(isolate, old_space()); | 623 HeapLocker hl(isolate, old_space()); |
522 | 624 |
523 // Read in all the objects stored in the object store. | 625 // Read in all the objects stored in the object store. |
524 intptr_t num_flds = (object_store->to() - object_store->from()); | 626 intptr_t num_flds = (object_store->to() - object_store->from()); |
525 for (intptr_t i = 0; i <= num_flds; i++) { | 627 for (intptr_t i = 0; i <= num_flds; i++) { |
526 *(object_store->from() + i) = ReadObjectImpl(); | 628 *(object_store->from() + i) = ReadObjectImpl(kAsInlinedObject); |
527 } | 629 } |
528 for (intptr_t i = 0; i < backward_references_->length(); i++) { | 630 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
529 if (!(*backward_references_)[i].is_deserialized()) { | 631 if (!(*backward_references_)[i].is_deserialized()) { |
530 ReadObjectImpl(); | 632 ReadObjectImpl(kAsInlinedObject); |
531 (*backward_references_)[i].set_state(kIsDeserialized); | 633 (*backward_references_)[i].set_state(kIsDeserialized); |
532 } | 634 } |
533 } | 635 } |
534 | 636 |
535 // Validate the class table. | 637 // Validate the class table. |
536 #if defined(DEBUG) | 638 #if defined(DEBUG) |
537 isolate->ValidateClassTable(); | 639 isolate->ValidateClassTable(); |
538 #endif | 640 #endif |
539 | 641 |
540 // Setup native resolver for bootstrap impl. | 642 // Setup native resolver for bootstrap impl. |
(...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 } | 1106 } |
1005 ASSERT(object_id >= kMaxPredefinedObjectIds); | 1107 ASSERT(object_id >= kMaxPredefinedObjectIds); |
1006 intptr_t index = (object_id - kMaxPredefinedObjectIds); | 1108 intptr_t index = (object_id - kMaxPredefinedObjectIds); |
1007 if (index < max_vm_isolate_object_id_) { | 1109 if (index < max_vm_isolate_object_id_) { |
1008 return VmIsolateSnapshotObject(index); | 1110 return VmIsolateSnapshotObject(index); |
1009 } | 1111 } |
1010 return GetBackRef(object_id)->raw(); | 1112 return GetBackRef(object_id)->raw(); |
1011 } | 1113 } |
1012 | 1114 |
1013 | 1115 |
1014 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) { | |
1015 // Read the class header information and lookup the class. | |
1016 intptr_t class_header = Read<int32_t>(); | |
1017 intptr_t tags = ReadTags(); | |
1018 intptr_t header_id = SerializedHeaderData::decode(class_header); | |
1019 if (header_id == kInstanceObjectId) { | |
1020 // Object is regular dart instance. | |
1021 Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id)); | |
1022 intptr_t instance_size = 0; | |
1023 if (result == NULL) { | |
1024 result = &(Instance::ZoneHandle(zone(), Instance::null())); | |
1025 AddBackRef(object_id, result, kIsDeserialized); | |
1026 cls_ ^= ReadObjectImpl(); | |
1027 ASSERT(!cls_.IsNull()); | |
1028 instance_size = cls_.instance_size(); | |
1029 ASSERT(instance_size > 0); | |
1030 // Allocate the instance and read in all the fields for the object. | |
1031 if (kind_ == Snapshot::kFull) { | |
1032 *result ^= AllocateUninitialized(cls_.id(), instance_size); | |
1033 } else { | |
1034 *result ^= Object::Allocate(cls_.id(), | |
1035 instance_size, | |
1036 HEAP_SPACE(kind_)); | |
1037 } | |
1038 } else { | |
1039 cls_ ^= ReadObjectImpl(); | |
1040 ASSERT(!cls_.IsNull()); | |
1041 instance_size = cls_.instance_size(); | |
1042 } | |
1043 intptr_t next_field_offset = cls_.next_field_offset(); | |
1044 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); | |
1045 ASSERT(next_field_offset > 0); | |
1046 // Instance::NextFieldOffset() returns the offset of the first field in | |
1047 // a Dart object. | |
1048 bool is_canonical = RawObject::IsCanonical(tags); | |
1049 intptr_t offset = Instance::NextFieldOffset(); | |
1050 intptr_t result_cid = result->GetClassId(); | |
1051 while (offset < next_field_offset) { | |
1052 pobj_ = is_canonical ? ReadObjectImpl() : ReadObjectRef(); | |
1053 result->SetFieldAtOffset(offset, pobj_); | |
1054 if ((offset != type_argument_field_offset) && | |
1055 (kind_ == Snapshot::kMessage)) { | |
1056 // TODO(fschneider): Consider hoisting these lookups out of the loop. | |
1057 // This would involve creating a handle, since cls_ can't be reused | |
1058 // across the call to ReadObjectRef. | |
1059 cls_ = isolate()->class_table()->At(result_cid); | |
1060 array_ = cls_.OffsetToFieldMap(); | |
1061 field_ ^= array_.At(offset >> kWordSizeLog2); | |
1062 ASSERT(!field_.IsNull()); | |
1063 ASSERT(field_.Offset() == offset); | |
1064 obj_ = pobj_.raw(); | |
1065 field_.RecordStore(obj_); | |
1066 } | |
1067 // TODO(fschneider): Verify the guarded cid and length for other kinds of | |
1068 // snapshot (kFull, kScript) with asserts. | |
1069 offset += kWordSize; | |
1070 } | |
1071 if (kind_ == Snapshot::kFull) { | |
1072 // We create an uninitialized object in the case of full snapshots, so | |
1073 // we need to initialize any remaining padding area with the Null object. | |
1074 while (offset < instance_size) { | |
1075 result->SetFieldAtOffset(offset, Object::null_object()); | |
1076 offset += kWordSize; | |
1077 } | |
1078 result->SetCreatedFromSnapshot(); | |
1079 } else if (RawObject::IsCanonical(tags)) { | |
1080 *result = result->CheckAndCanonicalize(NULL); | |
1081 ASSERT(!result->IsNull()); | |
1082 } | |
1083 return result->raw(); | |
1084 } else if (header_id == kStaticImplicitClosureObjectId) { | |
1085 // We do not use the tags as the implicit static closure | |
1086 // is going to be created in this isolate or the canonical | |
1087 // version already created in the isolate will be used. | |
1088 return ReadStaticImplicitClosure(object_id, class_header); | |
1089 } | |
1090 ASSERT((class_header & kSmiTagMask) != kSmiTag); | |
1091 intptr_t class_id = LookupInternalClass(class_header); | |
1092 switch (class_id) { | |
1093 #define SNAPSHOT_READ(clazz) \ | |
1094 case clazz::kClassId: { \ | |
1095 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ | |
1096 break; \ | |
1097 } | |
1098 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | |
1099 #undef SNAPSHOT_READ | |
1100 #define SNAPSHOT_READ(clazz) \ | |
1101 case kTypedData##clazz##Cid: \ | |
1102 | |
1103 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | |
1104 tags = RawObject::ClassIdTag::update(class_id, tags); | |
1105 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_); | |
1106 break; | |
1107 } | |
1108 #undef SNAPSHOT_READ | |
1109 #define SNAPSHOT_READ(clazz) \ | |
1110 case kExternalTypedData##clazz##Cid: \ | |
1111 | |
1112 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | |
1113 tags = RawObject::ClassIdTag::update(class_id, tags); | |
1114 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); | |
1115 break; | |
1116 } | |
1117 #undef SNAPSHOT_READ | |
1118 default: UNREACHABLE(); break; | |
1119 } | |
1120 if (kind_ == Snapshot::kFull) { | |
1121 pobj_.SetCreatedFromSnapshot(); | |
1122 } | |
1123 return pobj_.raw(); | |
1124 } | |
1125 | |
1126 | |
1127 void SnapshotReader::ArrayReadFrom(const Array& result, | 1116 void SnapshotReader::ArrayReadFrom(const Array& result, |
1128 intptr_t len, | 1117 intptr_t len, |
1129 intptr_t tags) { | 1118 intptr_t tags) { |
1130 // Set the object tags. | 1119 // Set the object tags. |
1131 result.set_tags(tags); | 1120 result.set_tags(tags); |
1132 | 1121 |
1133 // Setup the object fields. | 1122 // Setup the object fields. |
1134 *TypeArgumentsHandle() ^= ReadObjectImpl(); | 1123 *TypeArgumentsHandle() ^= ReadObjectImpl(kAsInlinedObject); |
1135 result.SetTypeArguments(*TypeArgumentsHandle()); | 1124 result.SetTypeArguments(*TypeArgumentsHandle()); |
1136 | 1125 |
1137 bool is_canonical = RawObject::IsCanonical(tags); | 1126 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
1138 | 1127 |
1139 for (intptr_t i = 0; i < len; i++) { | 1128 for (intptr_t i = 0; i < len; i++) { |
1140 *PassiveObjectHandle() = is_canonical ? ReadObjectImpl() : ReadObjectRef(); | 1129 *PassiveObjectHandle() = ReadObjectImpl(as_reference); |
1141 result.SetAt(i, *PassiveObjectHandle()); | 1130 result.SetAt(i, *PassiveObjectHandle()); |
1142 } | 1131 } |
1143 } | 1132 } |
1144 | 1133 |
1145 | 1134 |
1146 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, | 1135 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, |
1147 intptr_t size, | 1136 intptr_t size, |
1148 Zone* zone) | 1137 Zone* zone) |
1149 : SnapshotReader(buffer, | 1138 : SnapshotReader(buffer, |
1150 size, | 1139 size, |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1277 forward_list_(forward_list), | 1266 forward_list_(forward_list), |
1278 exception_type_(Exceptions::kNone), | 1267 exception_type_(Exceptions::kNone), |
1279 exception_msg_(NULL), | 1268 exception_msg_(NULL), |
1280 unmarked_objects_(false), | 1269 unmarked_objects_(false), |
1281 can_send_any_object_(can_send_any_object) { | 1270 can_send_any_object_(can_send_any_object) { |
1282 ASSERT(forward_list_ != NULL); | 1271 ASSERT(forward_list_ != NULL); |
1283 } | 1272 } |
1284 | 1273 |
1285 | 1274 |
1286 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1275 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
1287 WriteObjectImpl(rawobj); | 1276 WriteObjectImpl(rawobj, kAsInlinedObject); |
1288 WriteForwardedObjects(); | 1277 WriteForwardedObjects(); |
1289 } | 1278 } |
1290 | 1279 |
1291 #define VM_OBJECT_CLASS_LIST(V) \ | 1280 #define VM_OBJECT_CLASS_LIST(V) \ |
1292 V(OneByteString) \ | 1281 V(OneByteString) \ |
1293 V(Mint) \ | 1282 V(Mint) \ |
1294 V(Bigint) \ | 1283 V(Bigint) \ |
1295 V(Double) \ | 1284 V(Double) \ |
1296 | 1285 |
1297 #define VM_OBJECT_WRITE(clazz) \ | 1286 #define VM_OBJECT_WRITE(clazz) \ |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 break; | 1389 break; |
1401 } | 1390 } |
1402 } | 1391 } |
1403 } | 1392 } |
1404 UNREACHABLE(); | 1393 UNREACHABLE(); |
1405 } | 1394 } |
1406 | 1395 |
1407 #undef VM_OBJECT_WRITE | 1396 #undef VM_OBJECT_WRITE |
1408 | 1397 |
1409 | 1398 |
1410 void SnapshotWriter::WriteObjectRef(RawObject* raw) { | |
1411 // First check if object can be written as a simple predefined type. | |
1412 if (CheckAndWritePredefinedObject(raw)) { | |
1413 return; | |
1414 } | |
1415 | |
1416 NoSafepointScope no_safepoint; | |
1417 RawClass* cls = class_table_->At(raw->GetClassId()); | |
1418 intptr_t class_id = cls->ptr()->id_; | |
1419 ASSERT(class_id == raw->GetClassId()); | |
1420 if (class_id >= kNumPredefinedCids) { | |
1421 WriteInstanceRef(raw, cls); | |
1422 return; | |
1423 } | |
1424 if (class_id == kArrayCid) { | |
1425 // Object is being referenced, add it to the forward ref list and mark | |
1426 // it so that future references to this object in the snapshot will use | |
1427 // this object id. Mark it as not having been serialized yet so that we | |
1428 // will serialize the object when we go through the forward list. | |
1429 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); | |
1430 | |
1431 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | |
1432 | |
1433 // Write out the serialization header value for this object. | |
1434 WriteInlinedObjectHeader(kOmittedObjectId); | |
1435 | |
1436 // Write out the class information. | |
1437 WriteIndexedObject(kArrayCid); | |
1438 | |
1439 // Write out the length field. | |
1440 Write<RawObject*>(rawarray->ptr()->length_); | |
1441 | |
1442 return; | |
1443 } | |
1444 if (class_id == kImmutableArrayCid) { | |
1445 // Object is being referenced, add it to the forward ref list and mark | |
1446 // it so that future references to this object in the snapshot will use | |
1447 // this object id. Mark it as not having been serialized yet so that we | |
1448 // will serialize the object when we go through the forward list. | |
1449 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); | |
1450 | |
1451 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | |
1452 | |
1453 // Write out the serialization header value for this object. | |
1454 WriteInlinedObjectHeader(kOmittedObjectId); | |
1455 | |
1456 // Write out the class information. | |
1457 WriteIndexedObject(kImmutableArrayCid); | |
1458 | |
1459 // Write out the length field. | |
1460 Write<RawObject*>(rawarray->ptr()->length_); | |
1461 | |
1462 return; | |
1463 } | |
1464 if (RawObject::IsImplicitFieldClassId(class_id)) { | |
1465 WriteInstanceRef(raw, cls); | |
1466 return; | |
1467 } | |
1468 // Add object to the forward ref list and mark it so that future references | |
1469 // to this object in the snapshot will use this object id. Mark it as having | |
1470 // been serialized so that we do not serialize the object when we go through | |
1471 // the forward list. | |
1472 forward_list_->MarkAndAddObject(raw, kIsSerialized); | |
1473 switch (class_id) { | |
1474 #define SNAPSHOT_WRITE(clazz) \ | |
1475 case clazz::kClassId: { \ | |
1476 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ | |
1477 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ | |
1478 return; \ | |
1479 } \ | |
1480 | |
1481 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) | |
1482 #undef SNAPSHOT_WRITE | |
1483 #define SNAPSHOT_WRITE(clazz) \ | |
1484 case kTypedData##clazz##Cid: \ | |
1485 | |
1486 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { | |
1487 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); | |
1488 raw_obj->WriteTo(this, kOmittedObjectId, kind_); | |
1489 return; | |
1490 } | |
1491 #undef SNAPSHOT_WRITE | |
1492 #define SNAPSHOT_WRITE(clazz) \ | |
1493 case kExternalTypedData##clazz##Cid: \ | |
1494 | |
1495 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { | |
1496 RawExternalTypedData* raw_obj = | |
1497 reinterpret_cast<RawExternalTypedData*>(raw); | |
1498 raw_obj->WriteTo(this, kOmittedObjectId, kind_); | |
1499 return; | |
1500 } | |
1501 #undef SNAPSHOT_WRITE | |
1502 default: break; | |
1503 } | |
1504 UNREACHABLE(); | |
1505 } | |
1506 | |
1507 | |
1508 // An object visitor which will iterate over all the script objects in the heap | 1399 // An object visitor which will iterate over all the script objects in the heap |
1509 // and either count them or collect them into an array. This is used during | 1400 // and either count them or collect them into an array. This is used during |
1510 // full snapshot generation of the VM isolate to write out all script | 1401 // full snapshot generation of the VM isolate to write out all script |
1511 // objects and their accompanying token streams. | 1402 // objects and their accompanying token streams. |
1512 class ScriptVisitor : public ObjectVisitor { | 1403 class ScriptVisitor : public ObjectVisitor { |
1513 public: | 1404 public: |
1514 explicit ScriptVisitor(Isolate* isolate) : | 1405 explicit ScriptVisitor(Isolate* isolate) : |
1515 ObjectVisitor(isolate), | 1406 ObjectVisitor(isolate), |
1516 objHandle_(Object::Handle(isolate)), | 1407 objHandle_(Object::Handle(isolate)), |
1517 count_(0), | 1408 count_(0), |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1846 if (index != kInvalidIndex) { | 1737 if (index != kInvalidIndex) { |
1847 WriteIndexedObject(index); | 1738 WriteIndexedObject(index); |
1848 return true; | 1739 return true; |
1849 } | 1740 } |
1850 } | 1741 } |
1851 | 1742 |
1852 return false; | 1743 return false; |
1853 } | 1744 } |
1854 | 1745 |
1855 | 1746 |
1856 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { | 1747 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { |
1857 // First check if object can be written as a simple predefined type. | 1748 // First check if object can be written as a simple predefined type. |
1858 if (CheckAndWritePredefinedObject(raw)) { | 1749 if (CheckAndWritePredefinedObject(raw)) { |
1859 return; | 1750 return; |
1860 } | 1751 } |
1861 | 1752 |
1862 // Object is being serialized, add it to the forward ref list and mark | 1753 if (as_reference && !raw->IsCanonical()) { |
1863 // it so that future references to this object in the snapshot will use | 1754 WriteObjectRef(raw); |
1864 // an object id, instead of trying to serialize it again. | 1755 } else { |
1865 forward_list_->MarkAndAddObject(raw, kIsSerialized); | 1756 // Object is being serialized, add it to the forward ref list and mark |
| 1757 // it so that future references to this object in the snapshot will use |
| 1758 // an object id, instead of trying to serialize it again. |
| 1759 forward_list_->MarkAndAddObject(raw, kIsSerialized); |
1866 | 1760 |
1867 WriteInlinedObject(raw); | 1761 WriteInlinedObject(raw); |
| 1762 } |
1868 } | 1763 } |
1869 | 1764 |
1870 | 1765 |
| 1766 void SnapshotWriter::WriteObjectRef(RawObject* raw) { |
| 1767 NoSafepointScope no_safepoint; |
| 1768 RawClass* cls = class_table_->At(raw->GetClassId()); |
| 1769 intptr_t class_id = cls->ptr()->id_; |
| 1770 ASSERT(class_id == raw->GetClassId()); |
| 1771 if (class_id >= kNumPredefinedCids || |
| 1772 RawObject::IsImplicitFieldClassId(class_id)) { |
| 1773 WriteInstanceRef(raw, cls); |
| 1774 return; |
| 1775 } |
| 1776 if (class_id == kArrayCid || class_id == kImmutableArrayCid) { |
| 1777 intptr_t tags = GetObjectTags(raw); |
| 1778 |
| 1779 // Object is being referenced, add it to the forward ref list and mark |
| 1780 // it so that future references to this object in the snapshot will use |
| 1781 // this object id. Mark it as not having been serialized yet so that we |
| 1782 // will serialize the object when we go through the forward list. |
| 1783 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); |
| 1784 |
| 1785 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
| 1786 |
| 1787 // Write out the serialization header value for this object. |
| 1788 WriteInlinedObjectHeader(kOmittedObjectId); |
| 1789 |
| 1790 // Write out the class information. |
| 1791 WriteIndexedObject(class_id); |
| 1792 WriteTags(tags); |
| 1793 |
| 1794 // Write out the length field. |
| 1795 Write<RawObject*>(rawarray->ptr()->length_); |
| 1796 |
| 1797 return; |
| 1798 } |
| 1799 // Add object to the forward ref list and mark it so that future references |
| 1800 // to this object in the snapshot will use this object id. Mark it as having |
| 1801 // been serialized so that we do not serialize the object when we go through |
| 1802 // the forward list. |
| 1803 forward_list_->MarkAndAddObject(raw, kIsSerialized); |
| 1804 switch (class_id) { |
| 1805 #define SNAPSHOT_WRITE(clazz) \ |
| 1806 case clazz::kClassId: { \ |
| 1807 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ |
| 1808 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ |
| 1809 return; \ |
| 1810 } \ |
| 1811 |
| 1812 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
| 1813 #undef SNAPSHOT_WRITE |
| 1814 #define SNAPSHOT_WRITE(clazz) \ |
| 1815 case kTypedData##clazz##Cid: \ |
| 1816 |
| 1817 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
| 1818 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); |
| 1819 raw_obj->WriteTo(this, kOmittedObjectId, kind_); |
| 1820 return; |
| 1821 } |
| 1822 #undef SNAPSHOT_WRITE |
| 1823 #define SNAPSHOT_WRITE(clazz) \ |
| 1824 case kExternalTypedData##clazz##Cid: \ |
| 1825 |
| 1826 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { |
| 1827 RawExternalTypedData* raw_obj = |
| 1828 reinterpret_cast<RawExternalTypedData*>(raw); |
| 1829 raw_obj->WriteTo(this, kOmittedObjectId, kind_); |
| 1830 return; |
| 1831 } |
| 1832 #undef SNAPSHOT_WRITE |
| 1833 default: break; |
| 1834 } |
| 1835 UNREACHABLE(); |
| 1836 } |
| 1837 |
| 1838 |
1871 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { | 1839 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { |
1872 // Now write the object out inline in the stream as follows: | 1840 // Now write the object out inline in the stream as follows: |
1873 // - Object is seen for the first time (inlined as follows): | 1841 // - Object is seen for the first time (inlined as follows): |
1874 // (object size in multiples of kObjectAlignment | 0x1) | 1842 // (object size in multiples of kObjectAlignment | 0x1) |
1875 // serialized fields of the object | 1843 // serialized fields of the object |
1876 // ...... | 1844 // ...... |
1877 NoSafepointScope no_safepoint; | 1845 NoSafepointScope no_safepoint; |
1878 uword tags = raw->ptr()->tags_; | 1846 uword tags = raw->ptr()->tags_; |
1879 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 1847 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
1880 intptr_t object_id = SerializedHeaderData::decode(tags); | 1848 intptr_t object_id = SerializedHeaderData::decode(tags); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1987 ASSERT(!IsSingletonClassId(class_id) && !IsObjectStoreClassId(class_id)); | 1955 ASSERT(!IsSingletonClassId(class_id) && !IsObjectStoreClassId(class_id)); |
1988 // TODO(5411462): Should restrict this to only core-lib classes in this | 1956 // TODO(5411462): Should restrict this to only core-lib classes in this |
1989 // case. | 1957 // case. |
1990 // Write out the class and tags information. | 1958 // Write out the class and tags information. |
1991 WriteVMIsolateObject(kClassCid); | 1959 WriteVMIsolateObject(kClassCid); |
1992 WriteTags(GetObjectTags(cls)); | 1960 WriteTags(GetObjectTags(cls)); |
1993 | 1961 |
1994 // Write out the library url and class name. | 1962 // Write out the library url and class name. |
1995 RawLibrary* library = cls->ptr()->library_; | 1963 RawLibrary* library = cls->ptr()->library_; |
1996 ASSERT(library != Library::null()); | 1964 ASSERT(library != Library::null()); |
1997 WriteObjectImpl(library->ptr()->url_); | 1965 WriteObjectImpl(library->ptr()->url_, kAsInlinedObject); |
1998 WriteObjectImpl(cls->ptr()->name_); | 1966 WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject); |
1999 } | 1967 } |
2000 | 1968 |
2001 | 1969 |
2002 void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id, | 1970 void SnapshotWriter::WriteStaticImplicitClosure(intptr_t object_id, |
2003 RawFunction* func, | 1971 RawFunction* func, |
2004 intptr_t tags) { | 1972 intptr_t tags) { |
2005 // Write out the serialization header value for this object. | 1973 // Write out the serialization header value for this object. |
2006 WriteInlinedObjectHeader(object_id); | 1974 WriteInlinedObjectHeader(object_id); |
2007 | 1975 |
2008 // Indicate this is a static implicit closure object. | 1976 // Indicate this is a static implicit closure object. |
2009 Write<int32_t>(SerializedHeaderData::encode(kStaticImplicitClosureObjectId)); | 1977 Write<int32_t>(SerializedHeaderData::encode(kStaticImplicitClosureObjectId)); |
2010 | 1978 |
2011 // Write out the tags. | 1979 // Write out the tags. |
2012 WriteTags(tags); | 1980 WriteTags(tags); |
2013 | 1981 |
2014 // Write out the library url, class name and signature function name. | 1982 // Write out the library url, class name and signature function name. |
2015 RawClass* cls = GetFunctionOwner(func); | 1983 RawClass* cls = GetFunctionOwner(func); |
2016 ASSERT(cls != Class::null()); | 1984 ASSERT(cls != Class::null()); |
2017 RawLibrary* library = cls->ptr()->library_; | 1985 RawLibrary* library = cls->ptr()->library_; |
2018 ASSERT(library != Library::null()); | 1986 ASSERT(library != Library::null()); |
2019 WriteObjectImpl(library->ptr()->url_); | 1987 WriteObjectImpl(library->ptr()->url_, kAsInlinedObject); |
2020 WriteObjectImpl(cls->ptr()->name_); | 1988 WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject); |
2021 WriteObjectImpl(func->ptr()->name_); | 1989 WriteObjectImpl(func->ptr()->name_, kAsInlinedObject); |
2022 } | 1990 } |
2023 | 1991 |
2024 | 1992 |
2025 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, | 1993 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, |
2026 intptr_t array_kind, | 1994 intptr_t array_kind, |
2027 intptr_t tags, | 1995 intptr_t tags, |
2028 RawSmi* length, | 1996 RawSmi* length, |
2029 RawTypeArguments* type_arguments, | 1997 RawTypeArguments* type_arguments, |
2030 RawObject* data[]) { | 1998 RawObject* data[]) { |
2031 intptr_t len = Smi::Value(length); | 1999 intptr_t len = Smi::Value(length); |
2032 | 2000 |
2033 // Write out the serialization header value for this object. | 2001 // Write out the serialization header value for this object. |
2034 WriteInlinedObjectHeader(object_id); | 2002 WriteInlinedObjectHeader(object_id); |
2035 | 2003 |
2036 // Write out the class and tags information. | 2004 // Write out the class and tags information. |
2037 WriteIndexedObject(array_kind); | 2005 WriteIndexedObject(array_kind); |
2038 WriteTags(tags); | 2006 WriteTags(tags); |
2039 | 2007 |
2040 // Write out the length field. | 2008 // Write out the length field. |
2041 Write<RawObject*>(length); | 2009 Write<RawObject*>(length); |
2042 | 2010 |
2043 // Write out the type arguments. | 2011 // Write out the type arguments. |
2044 WriteObjectImpl(type_arguments); | 2012 WriteObjectImpl(type_arguments, kAsInlinedObject); |
2045 | 2013 |
2046 // Write out the individual object ids. | 2014 // Write out the individual object ids. |
2047 bool is_canonical = RawObject::IsCanonical(tags); | 2015 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
2048 for (intptr_t i = 0; i < len; i++) { | 2016 for (intptr_t i = 0; i < len; i++) { |
2049 if (is_canonical) { | 2017 WriteObjectImpl(data[i], as_reference); |
2050 WriteObjectImpl(data[i]); | |
2051 } else { | |
2052 WriteObjectRef(data[i]); | |
2053 } | |
2054 } | 2018 } |
2055 } | 2019 } |
2056 | 2020 |
2057 | 2021 |
2058 RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls, | 2022 RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls, |
2059 RawObject* obj) { | 2023 RawObject* obj) { |
2060 if (Class::IsSignatureClass(cls)) { | 2024 if (Class::IsSignatureClass(cls)) { |
2061 // 'obj' is a closure as its class is a signature class, extract | 2025 // 'obj' is a closure as its class is a signature class, extract |
2062 // the function object to check if this closure can be sent in an | 2026 // the function object to check if this closure can be sent in an |
2063 // isolate message. | 2027 // isolate message. |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2152 // Write out the serialization header value for this object. | 2116 // Write out the serialization header value for this object. |
2153 WriteInlinedObjectHeader(object_id); | 2117 WriteInlinedObjectHeader(object_id); |
2154 | 2118 |
2155 // Indicate this is an instance object. | 2119 // Indicate this is an instance object. |
2156 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2120 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
2157 | 2121 |
2158 // Write out the tags. | 2122 // Write out the tags. |
2159 WriteTags(tags); | 2123 WriteTags(tags); |
2160 | 2124 |
2161 // Write out the class information for this object. | 2125 // Write out the class information for this object. |
2162 WriteObjectImpl(cls); | 2126 WriteObjectImpl(cls, kAsInlinedObject); |
2163 | 2127 |
2164 // Write out all the fields for the object. | 2128 // Write out all the fields for the object. |
2165 // Instance::NextFieldOffset() returns the offset of the first field in | 2129 // Instance::NextFieldOffset() returns the offset of the first field in |
2166 // a Dart object. | 2130 // a Dart object. |
2167 bool is_canonical = RawObject::IsCanonical(tags); | 2131 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
2168 intptr_t offset = Instance::NextFieldOffset(); | 2132 intptr_t offset = Instance::NextFieldOffset(); |
2169 while (offset < next_field_offset) { | 2133 while (offset < next_field_offset) { |
2170 RawObject* raw_obj = *reinterpret_cast<RawObject**>( | 2134 RawObject* raw_obj = *reinterpret_cast<RawObject**>( |
2171 reinterpret_cast<uword>(raw->ptr()) + offset); | 2135 reinterpret_cast<uword>(raw->ptr()) + offset); |
2172 if (is_canonical) { | 2136 WriteObjectImpl(raw_obj, as_reference); |
2173 WriteObjectImpl(raw_obj); | |
2174 } else { | |
2175 WriteObjectRef(raw_obj); | |
2176 } | |
2177 offset += kWordSize; | 2137 offset += kWordSize; |
2178 } | 2138 } |
2179 return; | 2139 return; |
2180 } | 2140 } |
2181 | 2141 |
2182 | 2142 |
2183 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { | 2143 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { |
2184 // Check if the instance has native fields and throw an exception if it does. | 2144 // Check if the instance has native fields and throw an exception if it does. |
2185 CheckForNativeFields(cls); | 2145 CheckForNativeFields(cls); |
2186 | 2146 |
(...skipping 11 matching lines...) Expand all Loading... |
2198 intptr_t object_id = SerializedHeaderData::decode(tags); | 2158 intptr_t object_id = SerializedHeaderData::decode(tags); |
2199 tags = forward_list_->NodeForObjectId(object_id)->tags(); | 2159 tags = forward_list_->NodeForObjectId(object_id)->tags(); |
2200 WriteStaticImplicitClosure(object_id, func, tags); | 2160 WriteStaticImplicitClosure(object_id, func, tags); |
2201 return; | 2161 return; |
2202 } | 2162 } |
2203 | 2163 |
2204 // Object is being referenced, add it to the forward ref list and mark | 2164 // Object is being referenced, add it to the forward ref list and mark |
2205 // it so that future references to this object in the snapshot will use | 2165 // it so that future references to this object in the snapshot will use |
2206 // this object id. Mark it as not having been serialized yet so that we | 2166 // this object id. Mark it as not having been serialized yet so that we |
2207 // will serialize the object when we go through the forward list. | 2167 // will serialize the object when we go through the forward list. |
| 2168 intptr_t tags = raw->ptr()->tags_; |
2208 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); | 2169 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); |
2209 | 2170 |
2210 // Write out the serialization header value for this object. | 2171 // Write out the serialization header value for this object. |
2211 WriteInlinedObjectHeader(kOmittedObjectId); | 2172 WriteInlinedObjectHeader(kOmittedObjectId); |
2212 | 2173 |
2213 // Indicate this is an instance object. | 2174 // Indicate this is an instance object. |
2214 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2175 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
| 2176 WriteTags(tags); |
2215 | 2177 |
2216 // Write out the class information for this object. | 2178 // Write out the class information for this object. |
2217 WriteObjectImpl(cls); | 2179 WriteObjectImpl(cls, kAsInlinedObject); |
2218 } | 2180 } |
2219 | 2181 |
2220 | 2182 |
2221 bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) { | 2183 bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) { |
2222 return library == object_store()->typed_data_library(); | 2184 return library == object_store()->typed_data_library(); |
2223 } | 2185 } |
2224 | 2186 |
2225 | 2187 |
2226 intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) { | 2188 intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) { |
2227 intptr_t length = Object::vm_isolate_snapshot_object_table().Length(); | 2189 intptr_t length = Object::vm_isolate_snapshot_object_table().Length(); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2306 } | 2268 } |
2307 } else { | 2269 } else { |
2308 ThrowException(exception_type(), exception_msg()); | 2270 ThrowException(exception_type(), exception_msg()); |
2309 } | 2271 } |
2310 } | 2272 } |
2311 | 2273 |
2312 | 2274 |
2313 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 2275 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
2314 for (RawObject** current = first; current <= last; current++) { | 2276 for (RawObject** current = first; current <= last; current++) { |
2315 RawObject* raw_obj = *current; | 2277 RawObject* raw_obj = *current; |
2316 if (as_references_) { | 2278 writer_->WriteObjectImpl(raw_obj, as_references_); |
2317 writer_->WriteObjectRef(raw_obj); | |
2318 } else { | |
2319 writer_->WriteObjectImpl(raw_obj); | |
2320 } | |
2321 } | 2279 } |
2322 } | 2280 } |
2323 | 2281 |
2324 | 2282 |
2325 MessageWriter::MessageWriter(uint8_t** buffer, | 2283 MessageWriter::MessageWriter(uint8_t** buffer, |
2326 ReAlloc alloc, | 2284 ReAlloc alloc, |
2327 bool can_send_any_object) | 2285 bool can_send_any_object) |
2328 : SnapshotWriter(Snapshot::kMessage, | 2286 : SnapshotWriter(Snapshot::kMessage, |
2329 buffer, | 2287 buffer, |
2330 alloc, | 2288 alloc, |
(...skipping 17 matching lines...) Expand all Loading... |
2348 NoSafepointScope no_safepoint; | 2306 NoSafepointScope no_safepoint; |
2349 WriteObject(obj.raw()); | 2307 WriteObject(obj.raw()); |
2350 UnmarkAll(); | 2308 UnmarkAll(); |
2351 } else { | 2309 } else { |
2352 ThrowException(exception_type(), exception_msg()); | 2310 ThrowException(exception_type(), exception_msg()); |
2353 } | 2311 } |
2354 } | 2312 } |
2355 | 2313 |
2356 | 2314 |
2357 } // namespace dart | 2315 } // namespace dart |
OLD | NEW |