| 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/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/exceptions.h" | 10 #include "vm/exceptions.h" |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 uword address = heap->TryAllocate(size, Heap::kOld); | 357 uword address = heap->TryAllocate(size, Heap::kOld); |
| 358 if (address == 0) { | 358 if (address == 0) { |
| 359 // Use the preallocated out of memory exception to avoid calling | 359 // Use the preallocated out of memory exception to avoid calling |
| 360 // into dart code or allocating any code. | 360 // into dart code or allocating any code. |
| 361 const Instance& exception = | 361 const Instance& exception = |
| 362 Instance::Handle(object_store()->out_of_memory()); | 362 Instance::Handle(object_store()->out_of_memory()); |
| 363 Exceptions::Throw(exception); | 363 Exceptions::Throw(exception); |
| 364 UNREACHABLE(); | 364 UNREACHABLE(); |
| 365 } | 365 } |
| 366 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); | 366 RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag); |
| 367 raw_obj->ptr()->class_ = cls.raw(); | |
| 368 uword tags = 0; | 367 uword tags = 0; |
| 369 intptr_t index = cls.index(); | 368 intptr_t index = cls.index(); |
| 370 ASSERT(index != kIllegalObjectKind); | 369 ASSERT(index != kIllegalObjectKind); |
| 371 tags = RawObject::ClassTag::update(index, tags); | 370 tags = RawObject::ClassTag::update(index, tags); |
| 372 tags = RawObject::SizeTag::update(size, tags); | 371 tags = RawObject::SizeTag::update(size, tags); |
| 373 raw_obj->ptr()->tags_ = tags; | 372 raw_obj->ptr()->tags_ = tags; |
| 374 return raw_obj; | 373 return raw_obj; |
| 375 } | 374 } |
| 376 | 375 |
| 377 | 376 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 } | 515 } |
| 517 | 516 |
| 518 // Check if it is a singleton boolean false value. | 517 // Check if it is a singleton boolean false value. |
| 519 if (rawobj == object_store()->false_value()) { | 518 if (rawobj == object_store()->false_value()) { |
| 520 WriteIndexedObject(ObjectStore::kFalseValue); | 519 WriteIndexedObject(ObjectStore::kFalseValue); |
| 521 return; | 520 return; |
| 522 } | 521 } |
| 523 | 522 |
| 524 // Check if it is a code object in that case just write a Null object | 523 // Check if it is a code object in that case just write a Null object |
| 525 // as we do not want code objects in the snapshot. | 524 // as we do not want code objects in the snapshot. |
| 526 if (rawobj->ptr()->class_ == Object::code_class()) { | 525 if (RawObject::GetClass(GetObjectTags(rawobj)) == Object::code_class()) { |
| 527 WriteIndexedObject(Object::kNullObject); | 526 WriteIndexedObject(Object::kNullObject); |
| 528 return; | 527 return; |
| 529 } | 528 } |
| 530 | 529 |
| 531 // Check if classes are not being serialized and it is preinitialized type. | 530 // Check if classes are not being serialized and it is preinitialized type. |
| 532 if (kind_ != Snapshot::kFull) { | 531 if (kind_ != Snapshot::kFull) { |
| 533 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); | 532 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); |
| 534 index = object_store()->GetTypeIndex(raw_type); | 533 index = object_store()->GetTypeIndex(raw_type); |
| 535 if (index != ObjectStore::kInvalidIndex) { | 534 if (index != ObjectStore::kInvalidIndex) { |
| 536 WriteIndexedObject(index); | 535 WriteIndexedObject(index); |
| 537 return; | 536 return; |
| 538 } | 537 } |
| 539 } | 538 } |
| 540 | 539 |
| 541 // Now write the object out inline in the stream. | 540 // Now write the object out inline in the stream. |
| 542 WriteInlinedObject(rawobj); | 541 WriteInlinedObject(rawobj); |
| 543 } | 542 } |
| 544 | 543 |
| 545 | 544 |
| 546 void SnapshotWriter::UnmarkAll() { | 545 void SnapshotWriter::UnmarkAll() { |
| 547 NoGCScope no_gc; | 546 NoGCScope no_gc; |
| 548 for (intptr_t i = 0; i < forward_list_.length(); i++) { | 547 for (intptr_t i = 0; i < forward_list_.length(); i++) { |
| 549 RawObject* raw = forward_list_[i]->raw(); | 548 RawObject* raw = forward_list_[i]->raw(); |
| 550 raw->ptr()->class_ = forward_list_[i]->cls(); // Restore original class. | 549 raw->ptr()->tags_ = forward_list_[i]->tags(); // Restore original class. |
| 551 } | 550 } |
| 552 } | 551 } |
| 553 | 552 |
| 554 | 553 |
| 555 void SnapshotWriter::WriteFullSnapshot() { | 554 void SnapshotWriter::WriteFullSnapshot() { |
| 556 ASSERT(kind_ == Snapshot::kFull); | 555 ASSERT(kind_ == Snapshot::kFull); |
| 557 Isolate* isolate = Isolate::Current(); | 556 Isolate* isolate = Isolate::Current(); |
| 558 ASSERT(isolate != NULL); | 557 ASSERT(isolate != NULL); |
| 559 ObjectStore* object_store = isolate->object_store(); | 558 ObjectStore* object_store = isolate->object_store(); |
| 560 ASSERT(object_store != NULL); | 559 ASSERT(object_store != NULL); |
| 561 | 560 |
| 562 // Write out all the objects in the object store of the isolate which | 561 // Write out all the objects in the object store of the isolate which |
| 563 // is the root set for all dart allocated objects at this point. | 562 // is the root set for all dart allocated objects at this point. |
| 564 SnapshotWriterVisitor visitor(this); | 563 SnapshotWriterVisitor visitor(this); |
| 565 object_store->VisitObjectPointers(&visitor); | 564 object_store->VisitObjectPointers(&visitor); |
| 566 | 565 |
| 567 // Finalize the snapshot buffer. | 566 // Finalize the snapshot buffer. |
| 568 FinalizeBuffer(); | 567 FinalizeBuffer(); |
| 569 } | 568 } |
| 570 | 569 |
| 571 | 570 |
| 571 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
| 572 uword tags = raw->ptr()->tags_; |
| 573 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
| 574 intptr_t id = SerializedHeaderData::decode(tags); |
| 575 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); |
| 576 } else { |
| 577 return tags; |
| 578 } |
| 579 } |
| 580 |
| 581 |
| 572 intptr_t SnapshotWriter::MarkObject(RawObject* raw, RawClass* cls) { | 582 intptr_t SnapshotWriter::MarkObject(RawObject* raw, RawClass* cls) { |
| 573 NoGCScope no_gc; | 583 NoGCScope no_gc; |
| 574 intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds; | 584 intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds; |
| 575 ASSERT(object_id <= kMaxObjectId); | 585 ASSERT(object_id <= kMaxObjectId); |
| 576 uword value = 0; | 586 uword value = 0; |
| 577 value = SerializedHeaderTag::update(kObjectId, value); | 587 value = SerializedHeaderTag::update(kObjectId, value); |
| 578 value = SerializedHeaderData::update(object_id, value); | 588 value = SerializedHeaderData::update(object_id, value); |
| 579 raw->ptr()->class_ = reinterpret_cast<RawClass*>(value); | 589 uword tags = raw->ptr()->tags_; |
| 580 ForwardObjectNode* node = new ForwardObjectNode(raw, cls); | 590 raw->ptr()->tags_ = value; |
| 591 ForwardObjectNode* node = new ForwardObjectNode(raw, tags); |
| 581 ASSERT(node != NULL); | 592 ASSERT(node != NULL); |
| 582 forward_list_.Add(node); | 593 forward_list_.Add(node); |
| 583 return object_id; | 594 return object_id; |
| 584 } | 595 } |
| 585 | 596 |
| 586 | 597 |
| 587 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { | 598 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { |
| 588 NoGCScope no_gc; | 599 NoGCScope no_gc; |
| 589 RawClass* cls = raw->ptr()->class_; | 600 uword tags = raw->ptr()->tags_; |
| 590 | 601 |
| 591 // Check if object has already been serialized, in that | 602 // Check if object has already been serialized, in that |
| 592 // case just write the object id out. | 603 // case just write the object id out. |
| 593 if (SerializedHeaderTag::decode(reinterpret_cast<uword>(cls)) == kObjectId) { | 604 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
| 594 intptr_t id = SerializedHeaderData::decode(reinterpret_cast<intptr_t>(cls)); | 605 intptr_t id = SerializedHeaderData::decode(tags); |
| 595 WriteIndexedObject(id); | 606 WriteIndexedObject(id); |
| 596 return; | 607 return; |
| 597 } | 608 } |
| 598 | 609 |
| 610 RawClass* cls = raw->GetClass(); |
| 611 |
| 599 // Object is being serialized, add it to the forward ref list and mark | 612 // Object is being serialized, add it to the forward ref list and mark |
| 600 // it so that future references to this object in the snapshot will use | 613 // it so that future references to this object in the snapshot will use |
| 601 // an object id, instead of trying to serialize it again. | 614 // an object id, instead of trying to serialize it again. |
| 602 intptr_t object_id = MarkObject(raw, cls); | 615 intptr_t object_id = MarkObject(raw, cls); |
| 603 | 616 |
| 604 ObjectKind kind = cls->ptr()->instance_kind_; | 617 ObjectKind kind = cls->ptr()->instance_kind_; |
| 605 if (kind == Instance::kInstanceKind) { | 618 if (kind == Instance::kInstanceKind) { |
| 606 // Object is regular dart instance. | 619 // Object is regular dart instance. |
| 607 // TODO(5411462): figure out what we need to do if an object with native | 620 // TODO(5411462): figure out what we need to do if an object with native |
| 608 // fields is serialized (throw exception or serialize a null object). | 621 // fields is serialized (throw exception or serialize a null object). |
| 609 ASSERT(cls->ptr()->num_native_fields_ == 0); | 622 ASSERT(cls->ptr()->num_native_fields_ == 0); |
| 610 intptr_t instance_size = cls->ptr()->instance_size_; | 623 intptr_t instance_size = cls->ptr()->instance_size_; |
| 611 ASSERT(instance_size != 0); | 624 ASSERT(instance_size != 0); |
| 612 | 625 |
| 613 // Write out the serialization header value for this object. | 626 // Write out the serialization header value for this object. |
| 614 WriteSerializationMarker(kInlined, object_id); | 627 WriteSerializationMarker(kInlined, object_id); |
| 615 | 628 |
| 616 // Indicate this is an instance object. | 629 // Indicate this is an instance object. |
| 617 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); | 630 WriteIntptrValue(SerializedHeaderData::encode(kInstanceId)); |
| 618 | 631 |
| 619 // Write out the tags. | 632 // Write out the tags. |
| 620 WriteIntptrValue(raw->ptr()->tags_); | 633 WriteIntptrValue(tags); |
| 621 | 634 |
| 622 // Write out the class information for this object. | 635 // Write out the class information for this object. |
| 623 WriteObject(cls); | 636 WriteObject(cls); |
| 624 | 637 |
| 625 // Write out all the fields for the object. | 638 // Write out all the fields for the object. |
| 626 intptr_t offset = Object::InstanceSize(); | 639 intptr_t offset = Object::InstanceSize(); |
| 627 while (offset < instance_size) { | 640 while (offset < instance_size) { |
| 628 WriteObject(*reinterpret_cast<RawObject**>( | 641 WriteObject(*reinterpret_cast<RawObject**>( |
| 629 reinterpret_cast<uword>(raw->ptr()) + offset)); | 642 reinterpret_cast<uword>(raw->ptr()) + offset)); |
| 630 offset += kWordSize; | 643 offset += kWordSize; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 | 692 |
| 680 | 693 |
| 681 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 694 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 682 for (RawObject** current = first; current <= last; current++) { | 695 for (RawObject** current = first; current <= last; current++) { |
| 683 RawObject* raw_obj = *current; | 696 RawObject* raw_obj = *current; |
| 684 writer_->WriteObject(raw_obj); | 697 writer_->WriteObject(raw_obj); |
| 685 } | 698 } |
| 686 } | 699 } |
| 687 | 700 |
| 688 } // namespace dart | 701 } // namespace dart |
| OLD | NEW |