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

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

Issue 10450014: Request for comments on overall approach. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix scavenger and freelist handling Created 8 years, 7 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 | Annotate | Revision Log
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/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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698