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

Side by Side Diff: vm/snapshot.cc

Issue 10446112: Refactor snapshot writing code in preparation for the change to remove recursive calls to WriteObje… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 6 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
« vm/raw_object_snapshot.cc ('K') | « vm/snapshot.h ('k') | no next file » | 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/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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 default: UNREACHABLE(); break; 467 default: UNREACHABLE(); break;
468 } 468 }
469 if (kind_ == Snapshot::kFull) { 469 if (kind_ == Snapshot::kFull) {
470 obj_.SetCreatedFromSnapshot(); 470 obj_.SetCreatedFromSnapshot();
471 } 471 }
472 return obj_.raw(); 472 return obj_.raw();
473 } 473 }
474 474
475 475
476 void SnapshotWriter::WriteObject(RawObject* rawobj) { 476 void SnapshotWriter::WriteObject(RawObject* rawobj) {
477 // An object is written in one of the following ways: 477 // First check if object can be written as a simple predefined type.
478 // - Smi: the Smi value is written as is (last bit is not tagged). 478 if (CheckAndWritePredefinedObject(rawobj)) {
479 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) 479 return;
480 // - Object that has already been written: (negative id in stream | 0x3) 480 }
481 // - Object that is seen for the first time (inlined as follows): 481 // Now write the object out inline in the stream as follows:
482 // - Object is seen for the first time (inlined as follows):
482 // (object size in multiples of kObjectAlignment | 0x1) 483 // (object size in multiples of kObjectAlignment | 0x1)
483 // serialized fields of the object 484 // serialized fields of the object
484 // ...... 485 // ......
485
486 NoGCScope no_gc;
487 // writing a snap shot.
488
489 // First check if it is a Smi (i.e not a heap object).
490 if (!rawobj->IsHeapObject()) {
491 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj));
492 return;
493 }
494
495 // Check if it is a singleton null object which is shared by all isolates.
496 if (rawobj == Object::null()) {
497 WriteIndexedObject(Object::kNullObject);
498 return;
499 }
500
501 // Check if it is a singleton sentinel object which is shared by all isolates.
502 if (rawobj == Object::sentinel()) {
503 WriteIndexedObject(Object::kSentinelObject);
504 return;
505 }
506
507 // Check if it is a singleton class object which is shared by
508 // all isolates.
509 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
510 intptr_t index = Object::GetSingletonClassIndex(raw_class);
511 if (index != Object::kInvalidIndex) {
512 WriteIndexedObject(index);
513 return;
514 }
515
516 // Check if it is a singleton boolean true value.
517 if (rawobj == object_store()->true_value()) {
518 WriteIndexedObject(ObjectStore::kTrueValue);
519 return;
520 }
521
522 // Check if it is a singleton boolean false value.
523 if (rawobj == object_store()->false_value()) {
524 WriteIndexedObject(ObjectStore::kFalseValue);
525 return;
526 }
527
528 // Check if it is a code object in that case just write a Null object
529 // as we do not want code objects in the snapshot.
530 if (RawObject::ClassIdTag::decode(GetObjectTags(rawobj)) == kCode) {
531 WriteIndexedObject(Object::kNullObject);
532 return;
533 }
534
535 // Check if classes are not being serialized and it is preinitialized type.
536 if (kind_ != Snapshot::kFull) {
537 RawType* raw_type = reinterpret_cast<RawType*>(rawobj);
538 index = object_store()->GetTypeIndex(raw_type);
539 if (index != ObjectStore::kInvalidIndex) {
540 WriteIndexedObject(index);
541 return;
542 }
543 }
544
545 // Now write the object out inline in the stream.
546 WriteInlinedObject(rawobj); 486 WriteInlinedObject(rawobj);
547 } 487 }
548 488
549 489
550 void SnapshotWriter::UnmarkAll() { 490 void SnapshotWriter::UnmarkAll() {
551 NoGCScope no_gc; 491 NoGCScope no_gc;
552 for (intptr_t i = 0; i < forward_list_.length(); i++) { 492 for (intptr_t i = 0; i < forward_list_.length(); i++) {
553 RawObject* raw = forward_list_[i]->raw(); 493 RawObject* raw = forward_list_[i]->raw();
554 raw->ptr()->tags_ = forward_list_[i]->tags(); // Restore original tags. 494 raw->ptr()->tags_ = forward_list_[i]->tags(); // Restore original tags.
555 } 495 }
(...skipping 21 matching lines...) Expand all
577 uword tags = raw->ptr()->tags_; 517 uword tags = raw->ptr()->tags_;
578 if (SerializedHeaderTag::decode(tags) == kObjectId) { 518 if (SerializedHeaderTag::decode(tags) == kObjectId) {
579 intptr_t id = SerializedHeaderData::decode(tags); 519 intptr_t id = SerializedHeaderData::decode(tags);
580 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); 520 return forward_list_[id - kMaxPredefinedObjectIds]->tags();
581 } else { 521 } else {
582 return tags; 522 return tags;
583 } 523 }
584 } 524 }
585 525
586 526
587 intptr_t SnapshotWriter::MarkObject(RawObject* raw, RawClass* cls) { 527 intptr_t SnapshotWriter::MarkObject(RawObject* raw) {
588 NoGCScope no_gc; 528 NoGCScope no_gc;
589 intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds; 529 intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds;
590 ASSERT(object_id <= kMaxObjectId); 530 ASSERT(object_id <= kMaxObjectId);
591 uword value = 0; 531 uword value = 0;
592 value = SerializedHeaderTag::update(kObjectId, value); 532 value = SerializedHeaderTag::update(kObjectId, value);
593 value = SerializedHeaderData::update(object_id, value); 533 value = SerializedHeaderData::update(object_id, value);
594 uword tags = raw->ptr()->tags_; 534 uword tags = raw->ptr()->tags_;
595 raw->ptr()->tags_ = value; 535 raw->ptr()->tags_ = value;
596 ForwardObjectNode* node = new ForwardObjectNode(raw, tags); 536 ForwardObjectNode* node = new ForwardObjectNode(raw, tags);
597 ASSERT(node != NULL); 537 ASSERT(node != NULL);
598 forward_list_.Add(node); 538 forward_list_.Add(node);
599 return object_id; 539 return object_id;
600 } 540 }
601 541
602 542
543 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) {
544 // Check if object can be written in one of the following ways:
545 // - Smi: the Smi value is written as is (last bit is not tagged).
546 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3)
547 // - Object that has already been written: (negative id in stream | 0x3)
548
549 NoGCScope no_gc;
550
551 // First check if it is a Smi (i.e not a heap object).
552 if (!rawobj->IsHeapObject()) {
553 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj));
554 return true;
555 }
556
557 // Check if it is a singleton null object which is shared by all isolates.
558 if (rawobj == Object::null()) {
559 WriteIndexedObject(Object::kNullObject);
560 return true;
561 }
562
563 // Check if it is a singleton sentinel object which is shared by all isolates.
564 if (rawobj == Object::sentinel()) {
565 WriteIndexedObject(Object::kSentinelObject);
566 return true;
567 }
568
569 // Check if it is a singleton class object which is shared by
570 // all isolates.
571 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
572 intptr_t index = Object::GetSingletonClassIndex(raw_class);
573 if (index != Object::kInvalidIndex) {
574 WriteIndexedObject(index);
575 return true;
576 }
577
578 // Check if it is a singleton boolean true value.
579 if (rawobj == object_store()->true_value()) {
580 WriteIndexedObject(ObjectStore::kTrueValue);
581 return true;
582 }
583
584 // Check if it is a singleton boolean false value.
585 if (rawobj == object_store()->false_value()) {
586 WriteIndexedObject(ObjectStore::kFalseValue);
587 return true;
588 }
589
590 // Check if it is a code object in that case just write a Null object
591 // as we do not want code objects in the snapshot.
592 if (RawObject::ClassIdTag::decode(GetObjectTags(rawobj)) == kCode) {
593 WriteIndexedObject(Object::kNullObject);
594 return true;
595 }
596
597 // Check if classes are not being serialized and it is preinitialized type.
598 if (kind_ != Snapshot::kFull) {
599 RawType* raw_type = reinterpret_cast<RawType*>(rawobj);
600 index = object_store()->GetTypeIndex(raw_type);
601 if (index != ObjectStore::kInvalidIndex) {
602 WriteIndexedObject(index);
603 return true;
604 }
605 }
606
607 // Check if object has already been serialized, in that
608 // case just write the object id out.
609 uword tags = rawobj->ptr()->tags_;
610 if (SerializedHeaderTag::decode(tags) == kObjectId) {
611 intptr_t id = SerializedHeaderData::decode(tags);
612 WriteIndexedObject(id);
613 return true;
614 }
615
616 return false;
617 }
618
619
603 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { 620 void SnapshotWriter::WriteInlinedObject(RawObject* raw) {
604 NoGCScope no_gc; 621 NoGCScope no_gc;
605 uword tags = raw->ptr()->tags_; 622 uword tags = raw->ptr()->tags_;
606
607 // Check if object has already been serialized, in that
608 // case just write the object id out.
609 if (SerializedHeaderTag::decode(tags) == kObjectId) {
610 intptr_t id = SerializedHeaderData::decode(tags);
611 WriteIndexedObject(id);
612 return;
613 }
614
615 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); 623 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
616 624
617 // Object is being serialized, add it to the forward ref list and mark 625 // Object is being serialized, add it to the forward ref list and mark
618 // it so that future references to this object in the snapshot will use 626 // it so that future references to this object in the snapshot will use
619 // an object id, instead of trying to serialize it again. 627 // an object id, instead of trying to serialize it again.
620 intptr_t object_id = MarkObject(raw, cls); 628 intptr_t object_id = MarkObject(raw);
621 629
622 ObjectKind kind = cls->ptr()->instance_kind_; 630 ObjectKind kind = cls->ptr()->instance_kind_;
623 if (kind == Instance::kInstanceKind) { 631 if (kind == Instance::kInstanceKind) {
624 // Object is regular dart instance. 632 // Object is regular dart instance.
625 // TODO(5411462): figure out what we need to do if an object with native 633 // TODO(5411462): figure out what we need to do if an object with native
626 // fields is serialized (throw exception or serialize a null object). 634 // fields is serialized (throw exception or serialize a null object).
627 ASSERT(cls->ptr()->num_native_fields_ == 0); 635 ASSERT(cls->ptr()->num_native_fields_ == 0);
628 intptr_t instance_size = cls->ptr()->instance_size_; 636 intptr_t instance_size = cls->ptr()->instance_size_;
629 ASSERT(instance_size != 0); 637 ASSERT(instance_size != 0);
630 638
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 705
698 706
699 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { 707 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) {
700 for (RawObject** current = first; current <= last; current++) { 708 for (RawObject** current = first; current <= last; current++) {
701 RawObject* raw_obj = *current; 709 RawObject* raw_obj = *current;
702 writer_->WriteObject(raw_obj); 710 writer_->WriteObject(raw_obj);
703 } 711 }
704 } 712 }
705 713
706 } // namespace dart 714 } // namespace dart
OLDNEW
« vm/raw_object_snapshot.cc ('K') | « vm/snapshot.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698