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

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

Issue 1388543008: 1. Write the backing data array of a GrowableObjectArray as a reference (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: sync-to-tot Created 5 years, 2 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/isolate/isolate.status » ('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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 NewObjectPool(len)); 493 NewObjectPool(len));
494 AddBackRef(object_id, &pool, kIsNotDeserialized); 494 AddBackRef(object_id, &pool, kIsNotDeserialized);
495 495
496 return pool.raw(); 496 return pool.raw();
497 } 497 }
498 498
499 // For all other internal VM classes we read the object inline. 499 // For all other internal VM classes we read the object inline.
500 switch (class_id) { 500 switch (class_id) {
501 #define SNAPSHOT_READ(clazz) \ 501 #define SNAPSHOT_READ(clazz) \
502 case clazz::kClassId: { \ 502 case clazz::kClassId: { \
503 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ 503 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, true); \
504 break; \ 504 break; \
505 } 505 }
506 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) 506 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
507 #undef SNAPSHOT_READ 507 #undef SNAPSHOT_READ
508 #define SNAPSHOT_READ(clazz) \ 508 #define SNAPSHOT_READ(clazz) \
509 case kTypedData##clazz##Cid: \ 509 case kTypedData##clazz##Cid: \
510 510
511 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { 511 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
512 tags = RawObject::ClassIdTag::update(class_id, tags); 512 tags = RawObject::ClassIdTag::update(class_id, tags);
513 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_); 513 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_, true);
514 break; 514 break;
515 } 515 }
516 #undef SNAPSHOT_READ 516 #undef SNAPSHOT_READ
517 #define SNAPSHOT_READ(clazz) \ 517 #define SNAPSHOT_READ(clazz) \
518 case kExternalTypedData##clazz##Cid: \ 518 case kExternalTypedData##clazz##Cid: \
519 519
520 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { 520 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
521 tags = RawObject::ClassIdTag::update(class_id, tags); 521 tags = RawObject::ClassIdTag::update(class_id, tags);
522 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); 522 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, true);
523 break; 523 break;
524 } 524 }
525 #undef SNAPSHOT_READ 525 #undef SNAPSHOT_READ
526 default: UNREACHABLE(); break; 526 default: UNREACHABLE(); break;
527 } 527 }
528 return pobj_.raw(); 528 return pobj_.raw();
529 } 529 }
530 530
531 531
532 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id, 532 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 // We do not use the tags as the implicit static closure 611 // We do not use the tags as the implicit static closure
612 // is going to be created in this isolate or the canonical 612 // is going to be created in this isolate or the canonical
613 // version already created in the isolate will be used. 613 // version already created in the isolate will be used.
614 return ReadStaticImplicitClosure(object_id, class_header); 614 return ReadStaticImplicitClosure(object_id, class_header);
615 } 615 }
616 ASSERT((class_header & kSmiTagMask) != kSmiTag); 616 ASSERT((class_header & kSmiTagMask) != kSmiTag);
617 intptr_t class_id = LookupInternalClass(class_header); 617 intptr_t class_id = LookupInternalClass(class_header);
618 switch (class_id) { 618 switch (class_id) {
619 #define SNAPSHOT_READ(clazz) \ 619 #define SNAPSHOT_READ(clazz) \
620 case clazz::kClassId: { \ 620 case clazz::kClassId: { \
621 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ 621 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_, false); \
622 break; \ 622 break; \
623 } 623 }
624 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) 624 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ)
625 #undef SNAPSHOT_READ 625 #undef SNAPSHOT_READ
626 #define SNAPSHOT_READ(clazz) \ 626 #define SNAPSHOT_READ(clazz) \
627 case kTypedData##clazz##Cid: \ 627 case kTypedData##clazz##Cid: \
628 628
629 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { 629 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
630 tags = RawObject::ClassIdTag::update(class_id, tags); 630 tags = RawObject::ClassIdTag::update(class_id, tags);
631 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_); 631 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_, false);
632 break; 632 break;
633 } 633 }
634 #undef SNAPSHOT_READ 634 #undef SNAPSHOT_READ
635 #define SNAPSHOT_READ(clazz) \ 635 #define SNAPSHOT_READ(clazz) \
636 case kExternalTypedData##clazz##Cid: \ 636 case kExternalTypedData##clazz##Cid: \
637 637
638 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { 638 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) {
639 tags = RawObject::ClassIdTag::update(class_id, tags); 639 tags = RawObject::ClassIdTag::update(class_id, tags);
640 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); 640 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_, false);
641 break; 641 break;
642 } 642 }
643 #undef SNAPSHOT_READ 643 #undef SNAPSHOT_READ
644 default: UNREACHABLE(); break; 644 default: UNREACHABLE(); break;
645 } 645 }
646 AddPatchRecord(object_id, patch_object_id, patch_offset); 646 AddPatchRecord(object_id, patch_object_id, patch_offset);
647 return pobj_.raw(); 647 return pobj_.raw();
648 } 648 }
649 649
650 650
(...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after
1703 V(OneByteString) \ 1703 V(OneByteString) \
1704 V(Mint) \ 1704 V(Mint) \
1705 V(Bigint) \ 1705 V(Bigint) \
1706 V(Double) \ 1706 V(Double) \
1707 V(ImmutableArray) \ 1707 V(ImmutableArray) \
1708 1708
1709 #define VM_OBJECT_WRITE(clazz) \ 1709 #define VM_OBJECT_WRITE(clazz) \
1710 case clazz::kClassId: { \ 1710 case clazz::kClassId: { \
1711 object_id = forward_list_->AddObject(rawobj, kIsSerialized); \ 1711 object_id = forward_list_->AddObject(rawobj, kIsSerialized); \
1712 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \ 1712 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \
1713 raw_obj->WriteTo(this, object_id, kind()); \ 1713 raw_obj->WriteTo(this, object_id, kind(), false); \
1714 return true; \ 1714 return true; \
1715 } \ 1715 } \
1716 1716
1717 #define WRITE_VM_SINGLETON_OBJ(obj, id) \ 1717 #define WRITE_VM_SINGLETON_OBJ(obj, id) \
1718 if (rawobj == obj) { \ 1718 if (rawobj == obj) { \
1719 WriteVMIsolateObject(id); \ 1719 WriteVMIsolateObject(id); \
1720 return true; \ 1720 return true; \
1721 } \ 1721 } \
1722 1722
1723 bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { 1723 bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1787 intptr_t object_id = forward_list_->FindObject(rawobj); 1787 intptr_t object_id = forward_list_->FindObject(rawobj);
1788 if (object_id != -1) { 1788 if (object_id != -1) {
1789 WriteIndexedObject(object_id); 1789 WriteIndexedObject(object_id);
1790 return true; 1790 return true;
1791 } else { 1791 } else {
1792 switch (id) { 1792 switch (id) {
1793 VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE) 1793 VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE)
1794 case kTypedDataUint32ArrayCid: { 1794 case kTypedDataUint32ArrayCid: {
1795 object_id = forward_list_->AddObject(rawobj, kIsSerialized); 1795 object_id = forward_list_->AddObject(rawobj, kIsSerialized);
1796 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj); 1796 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj);
1797 raw_obj->WriteTo(this, object_id, kind()); 1797 raw_obj->WriteTo(this, object_id, kind(), false);
1798 return true; 1798 return true;
1799 } 1799 }
1800 default: 1800 default:
1801 OS::Print("class id = %" Pd "\n", id); 1801 OS::Print("class id = %" Pd "\n", id);
1802 break; 1802 break;
1803 } 1803 }
1804 } 1804 }
1805 } 1805 }
1806 1806
1807 if (!vm_isolate_is_symbolic()) { 1807 if (!vm_isolate_is_symbolic()) {
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2061 uword tags = raw->ptr()->tags_; 2061 uword tags = raw->ptr()->tags_;
2062 if (SerializedHeaderTag::decode(tags) == kObjectId) { 2062 if (SerializedHeaderTag::decode(tags) == kObjectId) {
2063 intptr_t id = SerializedHeaderData::decode(tags); 2063 intptr_t id = SerializedHeaderData::decode(tags);
2064 return forward_list_->NodeForObjectId(id)->tags(); 2064 return forward_list_->NodeForObjectId(id)->tags();
2065 } else { 2065 } else {
2066 return tags; 2066 return tags;
2067 } 2067 }
2068 } 2068 }
2069 2069
2070 2070
2071 intptr_t SnapshotWriter::GetObjectId(RawObject* raw) {
2072 uword tags = raw->ptr()->tags_;
2073 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
2074 return SerializedHeaderData::decode(tags);
2075 }
2076
2077
2071 ForwardList::ForwardList(intptr_t first_object_id) 2078 ForwardList::ForwardList(intptr_t first_object_id)
2072 : first_object_id_(first_object_id), 2079 : first_object_id_(first_object_id),
2073 nodes_(), 2080 nodes_(),
2074 first_unprocessed_object_id_(first_object_id) { 2081 first_unprocessed_object_id_(first_object_id) {
2075 // The ForwardList encodes information in the header tag word. There cannot 2082 // The ForwardList encodes information in the header tag word. There cannot
2076 // be any concurrent GC tasks while it is in use. 2083 // be any concurrent GC tasks while it is in use.
2077 Thread* thread = Thread::Current(); 2084 Thread* thread = Thread::Current();
2078 Isolate* isolate = thread->isolate(); 2085 Isolate* isolate = thread->isolate();
2079 PageSpace* page_space = isolate->heap()->old_space(); 2086 PageSpace* page_space = isolate->heap()->old_space();
2080 MonitorLocker ml(page_space->tasks_lock()); 2087 MonitorLocker ml(page_space->tasks_lock());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2138 const Node* node = NodeForObjectId(id); 2145 const Node* node = NodeForObjectId(id);
2139 RawObject* raw = node->raw(); 2146 RawObject* raw = node->raw();
2140 if (SerializedHeaderTag::decode(raw->ptr()->tags_) == kObjectId) { 2147 if (SerializedHeaderTag::decode(raw->ptr()->tags_) == kObjectId) {
2141 raw->ptr()->tags_ = node->tags(); // Restore original tags. 2148 raw->ptr()->tags_ = node->tags(); // Restore original tags.
2142 } 2149 }
2143 } 2150 }
2144 Thread::Current()->DecrementNoSafepointScopeDepth(); 2151 Thread::Current()->DecrementNoSafepointScopeDepth();
2145 } 2152 }
2146 2153
2147 2154
2155 void ForwardList::SetState(RawObject* raw, SerializeState state) {
2156 uword tags = raw->ptr()->tags_;
2157 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
2158 intptr_t id = SerializedHeaderData::decode(tags);
2159 NodeForObjectId(id)->set_state(state);
2160 }
2161
2162
2148 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { 2163 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) {
2149 // Check if object can be written in one of the following ways: 2164 // Check if object can be written in one of the following ways:
2150 // - Smi: the Smi value is written as is (last bit is not tagged). 2165 // - Smi: the Smi value is written as is (last bit is not tagged).
2151 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) 2166 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3)
2152 // - Object that has already been written: (negative id in stream | 0x3) 2167 // - Object that has already been written: (negative id in stream | 0x3)
2153 2168
2154 NoSafepointScope no_safepoint; 2169 NoSafepointScope no_safepoint;
2155 2170
2156 // First check if it is a Smi (i.e not a heap object). 2171 // First check if it is a Smi (i.e not a heap object).
2157 if (!rawobj->IsHeapObject()) { 2172 if (!rawobj->IsHeapObject()) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 return false; 2232 return false;
2218 } 2233 }
2219 2234
2220 2235
2221 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { 2236 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) {
2222 // First check if object can be written as a simple predefined type. 2237 // First check if object can be written as a simple predefined type.
2223 if (CheckAndWritePredefinedObject(raw)) { 2238 if (CheckAndWritePredefinedObject(raw)) {
2224 return; 2239 return;
2225 } 2240 }
2226 2241
2227 // Objects are usually writen as references to avoid deep recursion, but in 2242 // When we know that we are dealing with leaf or shallow objects we write
2228 // some places we know we are dealing with leaf or shallow objects and write 2243 // these objects inline even when 'as_reference' is true.
2229 // them inline. 2244 bool write_as_reference = as_reference && !raw->IsCanonical();
2230 if (!as_reference || raw->IsCanonical()) { 2245 intptr_t tags = raw->ptr()->tags_;
2231 // Object is being serialized, add it to the forward ref list and mark 2246
2232 // it so that future references to this object in the snapshot will use 2247 // Add object to the forward ref list and mark it so that future references
2233 // an object id, instead of trying to serialize it again. 2248 // to this object in the snapshot will use this object id. Mark the
2249 // serialization state so that we do the right thing when we go through
2250 // the forward list.
2251 intptr_t class_id = raw->GetClassId();
2252 if (write_as_reference && IsSplitClassId(class_id)) {
2253 forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
2254 } else {
2234 forward_list_->MarkAndAddObject(raw, kIsSerialized); 2255 forward_list_->MarkAndAddObject(raw, kIsSerialized);
2235 2256 }
2236 WriteInlinedObject(raw); 2257 intptr_t object_id;
2258 if (write_as_reference || !IsSplitClassId(class_id)) {
2259 object_id = kOmittedObjectId;
2237 } else { 2260 } else {
2238 WriteObjectRef(raw); 2261 ASSERT(SerializedHeaderTag::decode(raw->ptr()->tags_) == kObjectId);
2262 object_id = SerializedHeaderData::decode(raw->ptr()->tags_);
2239 } 2263 }
2264 WriteMarkedObjectImpl(raw, tags, object_id, write_as_reference);
2240 } 2265 }
2241 2266
2242 2267
2243 void SnapshotWriter::WriteObjectRef(RawObject* raw) { 2268 void SnapshotWriter::WriteMarkedObjectImpl(RawObject* raw,
2269 intptr_t tags,
2270 intptr_t object_id,
2271 bool as_reference) {
2244 NoSafepointScope no_safepoint; 2272 NoSafepointScope no_safepoint;
2245 RawClass* cls = class_table_->At(raw->GetClassId()); 2273 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
2246 intptr_t class_id = cls->ptr()->id_; 2274 intptr_t class_id = cls->ptr()->id_;
2247 ASSERT(class_id == raw->GetClassId()); 2275 ASSERT(class_id == RawObject::ClassIdTag::decode(tags));
2248 if (class_id >= kNumPredefinedCids || 2276 if (class_id >= kNumPredefinedCids ||
2249 RawObject::IsImplicitFieldClassId(class_id)) { 2277 RawObject::IsImplicitFieldClassId(class_id)) {
2250 WriteInstanceRef(raw, cls); 2278 WriteInstance(raw, cls, tags, object_id, as_reference);
2251 return; 2279 return;
2252 } 2280 }
2253 if (class_id == kArrayCid || class_id == kImmutableArrayCid) {
2254 intptr_t tags = GetObjectTags(raw);
2255 2281
2256 // Object is being referenced, add it to the forward ref list and mark
2257 // it so that future references to this object in the snapshot will use
2258 // this object id. Mark it as not having been serialized yet so that we
2259 // will serialize the object when we go through the forward list.
2260 forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
2261
2262 RawArray* rawarray = reinterpret_cast<RawArray*>(raw);
2263
2264 // Write out the serialization header value for this object.
2265 WriteInlinedObjectHeader(kOmittedObjectId);
2266
2267 // Write out the class information.
2268 WriteIndexedObject(class_id);
2269 WriteTags(tags);
2270
2271 // Write out the length field.
2272 Write<RawObject*>(rawarray->ptr()->length_);
2273
2274 return;
2275 }
2276 if (class_id == kObjectPoolCid) {
2277 intptr_t tags = GetObjectTags(raw);
2278
2279 // Object is being referenced, add it to the forward ref list and mark
2280 // it so that future references to this object in the snapshot will use
2281 // this object id. Mark it as not having been serialized yet so that we
2282 // will serialize the object when we go through the forward list.
2283 forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
2284
2285 RawObjectPool* rawpool = reinterpret_cast<RawObjectPool*>(raw);
2286
2287 // Write out the serialization header value for this object.
2288 WriteInlinedObjectHeader(kOmittedObjectId);
2289
2290 // Write out the class information.
2291 WriteVMIsolateObject(kObjectPoolCid);
2292 WriteTags(tags);
2293
2294 // Write out the length field.
2295 Write<intptr_t>(rawpool->ptr()->length_);
2296
2297 return;
2298 }
2299 // Add object to the forward ref list and mark it so that future references
2300 // to this object in the snapshot will use this object id. Mark it as having
2301 // been serialized so that we do not serialize the object when we go through
2302 // the forward list.
2303 forward_list_->MarkAndAddObject(raw, kIsSerialized);
2304 switch (class_id) { 2282 switch (class_id) {
2305 #define SNAPSHOT_WRITE(clazz) \ 2283 #define SNAPSHOT_WRITE(clazz) \
2306 case clazz::kClassId: { \ 2284 case clazz::kClassId: { \
2307 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ 2285 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
2308 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ 2286 raw_obj->WriteTo(this, object_id, kind_, as_reference); \
2309 return; \ 2287 return; \
2310 } \ 2288 } \
2311 2289
2312 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
2313 #undef SNAPSHOT_WRITE
2314 #define SNAPSHOT_WRITE(clazz) \
2315 case kTypedData##clazz##Cid: \
2316
2317 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
2318 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);
2319 raw_obj->WriteTo(this, kOmittedObjectId, kind_);
2320 return;
2321 }
2322 #undef SNAPSHOT_WRITE
2323 #define SNAPSHOT_WRITE(clazz) \
2324 case kExternalTypedData##clazz##Cid: \
2325
2326 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
2327 RawExternalTypedData* raw_obj =
2328 reinterpret_cast<RawExternalTypedData*>(raw);
2329 raw_obj->WriteTo(this, kOmittedObjectId, kind_);
2330 return;
2331 }
2332 #undef SNAPSHOT_WRITE
2333 default: break;
2334 }
2335 UNREACHABLE();
2336 }
2337
2338
2339 void SnapshotWriter::WriteInlinedObject(RawObject* raw) {
2340 // Now write the object out inline in the stream as follows:
2341 // - Object is seen for the first time (inlined as follows):
2342 // (object size in multiples of kObjectAlignment | 0x1)
2343 // serialized fields of the object
2344 // ......
2345 NoSafepointScope no_safepoint;
2346 uword tags = raw->ptr()->tags_;
2347 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
2348 intptr_t object_id = SerializedHeaderData::decode(tags);
2349 tags = forward_list_->NodeForObjectId(object_id)->tags();
2350 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags));
2351 intptr_t class_id = cls->ptr()->id_;
2352
2353 if (!IsSplitClassId(class_id)) {
2354 object_id = kOmittedObjectId;
2355 }
2356
2357 if (class_id >= kNumPredefinedCids) {
2358 WriteInstance(object_id, raw, cls, tags);
2359 return;
2360 }
2361 switch (class_id) {
2362 #define SNAPSHOT_WRITE(clazz) \
2363 case clazz::kClassId: { \
2364 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \
2365 raw_obj->WriteTo(this, object_id, kind_); \
2366 return; \
2367 } \
2368
2369 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) 2290 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE)
2370 #undef SNAPSHOT_WRITE 2291 #undef SNAPSHOT_WRITE
2371 #define SNAPSHOT_WRITE(clazz) \ 2292 #define SNAPSHOT_WRITE(clazz) \
2372 case kTypedData##clazz##Cid: \ 2293 case kTypedData##clazz##Cid: \
2373 2294
2374 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { 2295 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
2375 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw); 2296 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(raw);
2376 raw_obj->WriteTo(this, object_id, kind_); 2297 raw_obj->WriteTo(this, object_id, kind_, as_reference);
2377 return; 2298 return;
2378 } 2299 }
2379 #undef SNAPSHOT_WRITE 2300 #undef SNAPSHOT_WRITE
2380 #define SNAPSHOT_WRITE(clazz) \ 2301 #define SNAPSHOT_WRITE(clazz) \
2381 case kExternalTypedData##clazz##Cid: \ 2302 case kExternalTypedData##clazz##Cid: \
2382 2303
2383 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) { 2304 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) {
2384 RawExternalTypedData* raw_obj = 2305 RawExternalTypedData* raw_obj =
2385 reinterpret_cast<RawExternalTypedData*>(raw); 2306 reinterpret_cast<RawExternalTypedData*>(raw);
2386 raw_obj->WriteTo(this, object_id, kind_); 2307 raw_obj->WriteTo(this, object_id, kind_, as_reference);
2387 return; 2308 return;
2388 } 2309 }
2389 #undef SNAPSHOT_WRITE 2310 #undef SNAPSHOT_WRITE
2390 #define SNAPSHOT_WRITE(clazz) \
2391 case kTypedData##clazz##ViewCid: \
2392
2393 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE)
2394 case kByteDataViewCid: {
2395 WriteInstance(object_id, raw, cls, tags);
2396 return;
2397 }
2398 #undef SNAPSHOT_WRITE
2399 default: break; 2311 default: break;
2400 } 2312 }
2401 2313
2402 const Object& obj = Object::Handle(raw); 2314 const Object& obj = Object::Handle(raw);
2403 FATAL1("Unexpected inlined object: %s\n", obj.ToCString()); 2315 FATAL1("Unexpected object: %s\n", obj.ToCString());
2404 } 2316 }
2405 2317
2406 2318
2407 class WriteInlinedObjectVisitor : public ObjectVisitor { 2319 class WriteInlinedObjectVisitor : public ObjectVisitor {
2408 public: 2320 public:
2409 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) 2321 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer)
2410 : ObjectVisitor(Isolate::Current()), writer_(writer) {} 2322 : ObjectVisitor(Isolate::Current()), writer_(writer) {}
2411 2323
2412 virtual void VisitObject(RawObject* obj) { 2324 virtual void VisitObject(RawObject* obj) {
2413 writer_->WriteInlinedObject(obj); 2325 intptr_t object_id = writer_->GetObjectId(obj);
2326 intptr_t tags = writer_->GetObjectTags(obj);
2327 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject);
2414 } 2328 }
2415 2329
2416 private: 2330 private:
2417 SnapshotWriter* writer_; 2331 SnapshotWriter* writer_;
2418 }; 2332 };
2419 2333
2420 2334
2421 void SnapshotWriter::WriteForwardedObjects() { 2335 void SnapshotWriter::WriteForwardedObjects() {
2422 WriteInlinedObjectVisitor visitor(this); 2336 WriteInlinedObjectVisitor visitor(this);
2423 forward_list_->SerializeAll(&visitor); 2337 forward_list_->SerializeAll(&visitor);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2501 WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject); 2415 WriteObjectImpl(cls->ptr()->name_, kAsInlinedObject);
2502 WriteObjectImpl(func->ptr()->name_, kAsInlinedObject); 2416 WriteObjectImpl(func->ptr()->name_, kAsInlinedObject);
2503 } 2417 }
2504 2418
2505 2419
2506 void SnapshotWriter::ArrayWriteTo(intptr_t object_id, 2420 void SnapshotWriter::ArrayWriteTo(intptr_t object_id,
2507 intptr_t array_kind, 2421 intptr_t array_kind,
2508 intptr_t tags, 2422 intptr_t tags,
2509 RawSmi* length, 2423 RawSmi* length,
2510 RawTypeArguments* type_arguments, 2424 RawTypeArguments* type_arguments,
2511 RawObject* data[]) { 2425 RawObject* data[],
2512 intptr_t len = Smi::Value(length); 2426 bool as_reference) {
2427 if (as_reference) {
2428 // Write out the serialization header value for this object.
2429 WriteInlinedObjectHeader(kOmittedObjectId);
2513 2430
2514 // Write out the serialization header value for this object. 2431 // Write out the class information.
2515 WriteInlinedObjectHeader(object_id); 2432 WriteIndexedObject(array_kind);
2433 WriteTags(tags);
2516 2434
2517 // Write out the class and tags information. 2435 // Write out the length field.
2518 WriteIndexedObject(array_kind); 2436 Write<RawObject*>(length);
2519 WriteTags(tags); 2437 } else {
2438 intptr_t len = Smi::Value(length);
2520 2439
2521 // Write out the length field. 2440 // Write out the serialization header value for this object.
2522 Write<RawObject*>(length); 2441 WriteInlinedObjectHeader(object_id);
2523 2442
2524 // Write out the type arguments. 2443 // Write out the class and tags information.
2525 WriteObjectImpl(type_arguments, kAsInlinedObject); 2444 WriteIndexedObject(array_kind);
2445 WriteTags(tags);
2526 2446
2527 // Write out the individual object ids. 2447 // Write out the length field.
2528 bool as_reference = RawObject::IsCanonical(tags) ? false : true; 2448 Write<RawObject*>(length);
2529 for (intptr_t i = 0; i < len; i++) { 2449
2530 WriteObjectImpl(data[i], as_reference); 2450 // Write out the type arguments.
2451 WriteObjectImpl(type_arguments, kAsInlinedObject);
2452
2453 // Write out the individual object ids.
2454 bool write_as_reference = RawObject::IsCanonical(tags) ? false : true;
2455 for (intptr_t i = 0; i < len; i++) {
2456 WriteObjectImpl(data[i], write_as_reference);
2457 }
2531 } 2458 }
2532 } 2459 }
2533 2460
2534 2461
2535 RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls, 2462 RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls,
2536 RawObject* obj) { 2463 RawObject* obj) {
2537 if (Class::IsSignatureClass(cls)) { 2464 if (Class::IsSignatureClass(cls)) {
2538 // 'obj' is a closure as its class is a signature class, extract 2465 // 'obj' is a closure as its class is a signature class, extract
2539 // the function object to check if this closure can be sent in an 2466 // the function object to check if this closure can be sent in an
2540 // isolate message. 2467 // isolate message.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2594 void SnapshotWriter::SetWriteException(Exceptions::ExceptionType type, 2521 void SnapshotWriter::SetWriteException(Exceptions::ExceptionType type,
2595 const char* msg) { 2522 const char* msg) {
2596 set_exception_type(type); 2523 set_exception_type(type);
2597 set_exception_msg(msg); 2524 set_exception_msg(msg);
2598 // The more specific error is set up in SnapshotWriter::ThrowException(). 2525 // The more specific error is set up in SnapshotWriter::ThrowException().
2599 thread()->long_jump_base()-> 2526 thread()->long_jump_base()->
2600 Jump(1, Object::snapshot_writer_error()); 2527 Jump(1, Object::snapshot_writer_error());
2601 } 2528 }
2602 2529
2603 2530
2604 void SnapshotWriter::WriteInstance(intptr_t object_id, 2531 void SnapshotWriter::WriteInstance(RawObject* raw,
2605 RawObject* raw,
2606 RawClass* cls, 2532 RawClass* cls,
2607 intptr_t tags) { 2533 intptr_t tags,
2534 intptr_t object_id,
2535 bool as_reference) {
2608 // Check if the instance has native fields and throw an exception if it does. 2536 // Check if the instance has native fields and throw an exception if it does.
2609 CheckForNativeFields(cls); 2537 CheckForNativeFields(cls);
2610 2538
2611 if ((kind() == Snapshot::kMessage) || (kind() == Snapshot::kScript)) { 2539 if ((kind() == Snapshot::kMessage) || (kind() == Snapshot::kScript)) {
2612 // Check if object is a closure that is serializable, if the object is a 2540 // Check if object is a closure that is serializable, if the object is a
2613 // closure that is not serializable this will throw an exception. 2541 // closure that is not serializable this will throw an exception.
2614 RawFunction* func = IsSerializableClosure(cls, raw); 2542 RawFunction* func = IsSerializableClosure(cls, raw);
2615 if (func != Function::null()) { 2543 if (func != Function::null()) {
2544 forward_list_->SetState(raw, kIsSerialized);
2616 WriteStaticImplicitClosure(object_id, func, tags); 2545 WriteStaticImplicitClosure(object_id, func, tags);
2617 return; 2546 return;
2618 } 2547 }
2619 } 2548 }
2620 2549
2621 // Object is regular dart instance. 2550 // Object is regular dart instance.
2622 intptr_t next_field_offset = Class::IsSignatureClass(cls) ? 2551 if (as_reference) {
2623 Closure::InstanceSize() : 2552 // Write out the serialization header value for this object.
2624 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; 2553 WriteInlinedObjectHeader(kOmittedObjectId);
2625 ASSERT(next_field_offset > 0);
2626 2554
2627 // Write out the serialization header value for this object. 2555 // Indicate this is an instance object.
2628 WriteInlinedObjectHeader(object_id); 2556 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId));
2557 WriteTags(tags);
2629 2558
2630 // Indicate this is an instance object. 2559 // Write out the class information for this object.
2631 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); 2560 WriteObjectImpl(cls, kAsInlinedObject);
2561 } else {
2562 ASSERT(SerializedHeaderTag::decode(raw->ptr()->tags_) == kObjectId);
2563 ASSERT(object_id == SerializedHeaderData::decode(raw->ptr()->tags_));
2564 intptr_t next_field_offset = Class::IsSignatureClass(cls) ?
2565 Closure::InstanceSize() :
2566 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2;
2567 ASSERT(next_field_offset > 0);
2632 2568
2633 // Write out the tags. 2569 // Write out the serialization header value for this object.
2634 WriteTags(tags); 2570 WriteInlinedObjectHeader(object_id);
2635 2571
2636 // Write out the class information for this object. 2572 // Indicate this is an instance object.
2637 WriteObjectImpl(cls, kAsInlinedObject); 2573 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId));
2638 2574
2639 // Write out all the fields for the object. 2575 // Write out the tags.
2640 // Instance::NextFieldOffset() returns the offset of the first field in 2576 WriteTags(tags);
2641 // a Dart object. 2577
2642 bool as_reference = RawObject::IsCanonical(tags) ? false : true; 2578 // Write out the class information for this object.
2643 intptr_t offset = Instance::NextFieldOffset(); 2579 WriteObjectImpl(cls, kAsInlinedObject);
2644 while (offset < next_field_offset) { 2580
2645 RawObject* raw_obj = *reinterpret_cast<RawObject**>( 2581 // Write out all the fields for the object.
2646 reinterpret_cast<uword>(raw->ptr()) + offset); 2582 // Instance::NextFieldOffset() returns the offset of the first field in
2647 WriteObjectImpl(raw_obj, as_reference); 2583 // a Dart object.
2648 offset += kWordSize; 2584 bool write_as_reference = RawObject::IsCanonical(tags) ? false : true;
2585 intptr_t offset = Instance::NextFieldOffset();
2586 while (offset < next_field_offset) {
2587 RawObject* raw_obj = *reinterpret_cast<RawObject**>(
2588 reinterpret_cast<uword>(raw->ptr()) + offset);
2589 WriteObjectImpl(raw_obj, write_as_reference);
2590 offset += kWordSize;
2591 }
2649 } 2592 }
2650 return; 2593 return;
2651 } 2594 }
2652 2595
2653 2596
2654 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) {
2655 // Check if the instance has native fields and throw an exception if it does.
2656 CheckForNativeFields(cls);
2657
2658 // Check if object is a closure that is serializable, if the object is a
2659 // closure that is not serializable this will throw an exception.
2660 RawFunction* func = IsSerializableClosure(cls, raw);
2661 if (func != Function::null()) {
2662 // Add object to the forward ref list and mark it so that future references
2663 // to this object in the snapshot will use this object id. Mark it as having
2664 // been serialized so that we do not serialize the object when we go through
2665 // the forward list.
2666 forward_list_->MarkAndAddObject(raw, kIsSerialized);
2667 uword tags = raw->ptr()->tags_;
2668 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
2669 intptr_t object_id = SerializedHeaderData::decode(tags);
2670 tags = forward_list_->NodeForObjectId(object_id)->tags();
2671 WriteStaticImplicitClosure(object_id, func, tags);
2672 return;
2673 }
2674
2675 // Object is being referenced, add it to the forward ref list and mark
2676 // it so that future references to this object in the snapshot will use
2677 // this object id. Mark it as not having been serialized yet so that we
2678 // will serialize the object when we go through the forward list.
2679 intptr_t tags = raw->ptr()->tags_;
2680 forward_list_->MarkAndAddObject(raw, kIsNotSerialized);
2681
2682 // Write out the serialization header value for this object.
2683 WriteInlinedObjectHeader(kOmittedObjectId);
2684
2685 // Indicate this is an instance object.
2686 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId));
2687 WriteTags(tags);
2688
2689 // Write out the class information for this object.
2690 WriteObjectImpl(cls, kAsInlinedObject);
2691 }
2692
2693
2694 bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) { 2597 bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) {
2695 return (library == object_store()->collection_library() || 2598 return (library == object_store()->collection_library() ||
2696 library == object_store()->core_library() || 2599 library == object_store()->core_library() ||
2697 library == object_store()->typed_data_library()); 2600 library == object_store()->typed_data_library());
2698 } 2601 }
2699 2602
2700 2603
2701 intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) { 2604 intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) {
2702 intptr_t length = Object::vm_isolate_snapshot_object_table().Length(); 2605 intptr_t length = Object::vm_isolate_snapshot_object_table().Length();
2703 for (intptr_t i = 0; i < length; i++) { 2606 for (intptr_t i = 0; i < length; i++) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
2825 NoSafepointScope no_safepoint; 2728 NoSafepointScope no_safepoint;
2826 WriteObject(obj.raw()); 2729 WriteObject(obj.raw());
2827 UnmarkAll(); 2730 UnmarkAll();
2828 } else { 2731 } else {
2829 ThrowException(exception_type(), exception_msg()); 2732 ThrowException(exception_type(), exception_msg());
2830 } 2733 }
2831 } 2734 }
2832 2735
2833 2736
2834 } // namespace dart 2737 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/snapshot.h ('k') | tests/isolate/isolate.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698