Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: runtime/vm/snapshot.cc

Issue 1260033004: Fix for issue 23244 (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: indent-code Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/snapshot.h ('k') | tests/language/issue23244_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/snapshot.h ('k') | tests/language/issue23244_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698