Chromium Code Reviews| 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/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| 11 #include "vm/exceptions.h" | 11 #include "vm/exceptions.h" |
| 12 #include "vm/heap.h" | 12 #include "vm/heap.h" |
| 13 #include "vm/longjump.h" | 13 #include "vm/longjump.h" |
| 14 #include "vm/object.h" | 14 #include "vm/object.h" |
| 15 #include "vm/object_store.h" | 15 #include "vm/object_store.h" |
| 16 #include "vm/snapshot_ids.h" | 16 #include "vm/snapshot_ids.h" |
| 17 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
| 18 #include "vm/version.h" | |
| 18 | 19 |
| 19 namespace dart { | 20 namespace dart { |
| 20 | 21 |
| 21 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; | 22 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; |
| 22 static const int kNumInitialReferences = 64; | 23 static const int kNumInitialReferences = 64; |
| 23 | 24 |
| 24 | 25 |
| 25 static bool IsSingletonClassId(intptr_t class_id) { | 26 static bool IsSingletonClassId(intptr_t class_id) { |
| 26 // Check if this is a singleton object class which is shared by all isolates. | 27 // Check if this is a singleton object class which is shared by all isolates. |
| 27 return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) || | 28 return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) || |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 } | 397 } |
| 397 ~HeapLocker() { | 398 ~HeapLocker() { |
| 398 page_space_->ReleaseDataLock(); | 399 page_space_->ReleaseDataLock(); |
| 399 } | 400 } |
| 400 | 401 |
| 401 private: | 402 private: |
| 402 PageSpace* page_space_; | 403 PageSpace* page_space_; |
| 403 }; | 404 }; |
| 404 | 405 |
| 405 | 406 |
| 406 void SnapshotReader::ReadFullSnapshot() { | 407 RawApiError* SnapshotReader::ReadFullSnapshot() { |
| 407 ASSERT(kind_ == Snapshot::kFull); | 408 ASSERT(kind_ == Snapshot::kFull); |
| 408 Isolate* isolate = Isolate::Current(); | 409 Isolate* isolate = Isolate::Current(); |
| 409 ASSERT(isolate != NULL); | 410 ASSERT(isolate != NULL); |
| 410 ObjectStore* object_store = isolate->object_store(); | 411 ObjectStore* object_store = isolate->object_store(); |
| 411 ASSERT(object_store != NULL); | 412 ASSERT(object_store != NULL); |
| 412 NoGCScope no_gc; | |
| 413 | 413 |
| 414 // TODO(asiva): Add a check here to ensure we have the right heap | 414 // TODO(asiva): Add a check here to ensure we have the right heap |
| 415 // size for the full snapshot being read. | 415 // size for the full snapshot being read. |
| 416 | 416 |
| 417 { | 417 { |
| 418 NoGCScope no_gc; | |
| 418 HeapLocker hl(isolate, old_space()); | 419 HeapLocker hl(isolate, old_space()); |
| 420 | |
| 421 // First read the version string, and check that it matches. | |
| 422 obj_ = ReadObject(); | |
| 423 | |
| 424 // If the version string doesn't match, return an error. | |
| 425 // NB: New things are allocated only if we're going to return an error. | |
| 426 if (!obj_.IsString() || !String::Cast(obj_).Equals(Version::String())) { | |
| 427 const intptr_t kMessageBufferSize = 128; | |
| 428 char message_buffer[kMessageBufferSize]; | |
| 429 OS::SNPrint(message_buffer, | |
| 430 kMessageBufferSize, | |
| 431 "Wrong full snapshot version. Found %s Expected %s", | |
|
Ivan Posva
2014/08/26 23:52:43
Strange capitalization of Expected.
siva
2014/08/27 18:25:08
Fixed.
| |
| 432 obj_.ToCString(), | |
| 433 Version::String()); | |
| 434 const String& msg = String::Handle(String::New(message_buffer)); | |
| 435 return ApiError::New(msg); | |
| 436 } | |
| 437 | |
| 438 // The version string matches. Read the rest of the snapshot. | |
| 439 | |
| 419 // Read in all the objects stored in the object store. | 440 // Read in all the objects stored in the object store. |
| 420 intptr_t num_flds = (object_store->to() - object_store->from()); | 441 intptr_t num_flds = (object_store->to() - object_store->from()); |
| 421 for (intptr_t i = 0; i <= num_flds; i++) { | 442 for (intptr_t i = 0; i <= num_flds; i++) { |
| 422 *(object_store->from() + i) = ReadObjectImpl(); | 443 *(object_store->from() + i) = ReadObjectImpl(); |
| 423 } | 444 } |
| 424 for (intptr_t i = 0; i < backward_references_.length(); i++) { | 445 for (intptr_t i = 0; i < backward_references_.length(); i++) { |
| 425 if (!backward_references_[i].is_deserialized()) { | 446 if (!backward_references_[i].is_deserialized()) { |
| 426 ReadObjectImpl(); | 447 ReadObjectImpl(); |
| 427 backward_references_[i].set_state(kIsDeserialized); | 448 backward_references_[i].set_state(kIsDeserialized); |
| 428 } | 449 } |
| 429 } | 450 } |
| 451 | |
| 452 // Validate the class table. | |
| 453 #if defined(DEBUG) | |
| 454 isolate->ValidateClassTable(); | |
| 455 #endif | |
| 456 | |
| 457 // Setup native resolver for bootstrap impl. | |
| 458 Bootstrap::SetupNativeResolver(); | |
| 459 return ApiError::null(); | |
| 460 } | |
| 461 } | |
| 462 | |
| 463 | |
| 464 RawObject* SnapshotReader::ReadScriptSnapshot() { | |
| 465 ASSERT(kind_ == Snapshot::kScript); | |
| 466 | |
| 467 // First read the version string, and check that it matches. | |
| 468 obj_ = ReadObject(); | |
| 469 | |
| 470 // If the version string doesn't match, return an error. | |
| 471 // NB: New things are allocated only if we're going to return an error. | |
| 472 if (!obj_.IsString() || !String::Cast(obj_).Equals(Version::String())) { | |
| 473 const intptr_t kMessageBufferSize = 128; | |
| 474 char message_buffer[kMessageBufferSize]; | |
| 475 OS::SNPrint(message_buffer, | |
| 476 kMessageBufferSize, | |
| 477 "Wrong script snapshot version. Found %s Expected %s", | |
| 478 obj_.ToCString(), | |
| 479 Version::String()); | |
| 480 const String& msg = String::Handle(String::New(message_buffer)); | |
| 481 return ApiError::New(msg); | |
| 430 } | 482 } |
| 431 | 483 |
| 432 // Validate the class table. | 484 // The version string matches. Read the rest of the snapshot. |
| 433 #if defined(DEBUG) | 485 return ReadObject(); |
|
Ivan Posva
2014/08/26 23:52:43
Alternatively you could do the test for library in
siva
2014/08/27 18:25:07
Done.
| |
| 434 isolate->ValidateClassTable(); | |
| 435 #endif | |
| 436 | |
| 437 // Setup native resolver for bootstrap impl. | |
| 438 Bootstrap::SetupNativeResolver(); | |
| 439 } | 486 } |
| 440 | 487 |
| 441 | 488 |
| 442 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ | 489 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ |
| 443 ASSERT(kind_ == Snapshot::kFull); \ | 490 ASSERT(kind_ == Snapshot::kFull); \ |
| 444 ASSERT(isolate()->no_gc_scope_depth() != 0); \ | 491 ASSERT(isolate()->no_gc_scope_depth() != 0); \ |
| 445 Raw##type* obj = reinterpret_cast<Raw##type*>( \ | 492 Raw##type* obj = reinterpret_cast<Raw##type*>( \ |
| 446 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ | 493 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ |
| 447 obj->ptr()->length_ = Smi::New(length); \ | 494 obj->ptr()->length_ = Smi::New(length); \ |
| 448 return obj; \ | 495 return obj; \ |
| (...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1172 ASSERT(isolate != NULL); | 1219 ASSERT(isolate != NULL); |
| 1173 ObjectStore* object_store = isolate->object_store(); | 1220 ObjectStore* object_store = isolate->object_store(); |
| 1174 ASSERT(object_store != NULL); | 1221 ASSERT(object_store != NULL); |
| 1175 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1222 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 1176 | 1223 |
| 1177 // Ensure the class table is valid. | 1224 // Ensure the class table is valid. |
| 1178 #if defined(DEBUG) | 1225 #if defined(DEBUG) |
| 1179 isolate->ValidateClassTable(); | 1226 isolate->ValidateClassTable(); |
| 1180 #endif | 1227 #endif |
| 1181 | 1228 |
| 1182 | |
| 1183 // Setup for long jump in case there is an exception while writing | 1229 // Setup for long jump in case there is an exception while writing |
| 1184 // the snapshot. | 1230 // the snapshot. |
| 1185 LongJumpScope jump; | 1231 LongJumpScope jump; |
| 1186 if (setjmp(*jump.Set()) == 0) { | 1232 if (setjmp(*jump.Set()) == 0) { |
| 1187 NoGCScope no_gc; | |
| 1188 | |
| 1189 // Reserve space in the output buffer for a snapshot header. | 1233 // Reserve space in the output buffer for a snapshot header. |
| 1190 ReserveHeader(); | 1234 ReserveHeader(); |
| 1191 | 1235 |
| 1192 // Write out all the objects in the object store of the isolate which | 1236 // Write out the version string. |
| 1193 // is the root set for all dart allocated objects at this point. | 1237 WriteObject(String::New(Version::String())); |
| 1194 SnapshotWriterVisitor visitor(this, false); | |
| 1195 object_store->VisitObjectPointers(&visitor); | |
| 1196 | 1238 |
| 1197 // Write out all forwarded objects. | 1239 // Write out the full snapshot. |
| 1198 WriteForwardedObjects(); | 1240 { |
| 1241 NoGCScope no_gc; | |
| 1199 | 1242 |
| 1200 FillHeader(kind()); | 1243 // Write out all the objects in the object store of the isolate which |
| 1201 UnmarkAll(); | 1244 // is the root set for all dart allocated objects at this point. |
| 1245 SnapshotWriterVisitor visitor(this, false); | |
| 1246 object_store->VisitObjectPointers(&visitor); | |
| 1247 | |
| 1248 // Write out all forwarded objects. | |
| 1249 WriteForwardedObjects(); | |
| 1250 | |
| 1251 FillHeader(kind()); | |
| 1252 UnmarkAll(); | |
| 1253 } | |
| 1202 } else { | 1254 } else { |
| 1203 ThrowException(exception_type(), exception_msg()); | 1255 ThrowException(exception_type(), exception_msg()); |
| 1204 } | 1256 } |
| 1205 } | 1257 } |
| 1206 | 1258 |
| 1207 | 1259 |
| 1208 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 1260 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
| 1209 uword tags = raw->ptr()->tags_; | 1261 uword tags = raw->ptr()->tags_; |
| 1210 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 1262 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
| 1211 intptr_t id = SerializedHeaderData::decode(tags); | 1263 intptr_t id = SerializedHeaderData::decode(tags); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1607 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 1659 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
| 1608 ASSERT(kind() == Snapshot::kScript); | 1660 ASSERT(kind() == Snapshot::kScript); |
| 1609 Isolate* isolate = Isolate::Current(); | 1661 Isolate* isolate = Isolate::Current(); |
| 1610 ASSERT(isolate != NULL); | 1662 ASSERT(isolate != NULL); |
| 1611 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1663 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 1612 | 1664 |
| 1613 // Setup for long jump in case there is an exception while writing | 1665 // Setup for long jump in case there is an exception while writing |
| 1614 // the snapshot. | 1666 // the snapshot. |
| 1615 LongJumpScope jump; | 1667 LongJumpScope jump; |
| 1616 if (setjmp(*jump.Set()) == 0) { | 1668 if (setjmp(*jump.Set()) == 0) { |
| 1669 // Reserve space in the output buffer for a snapshot header. | |
| 1670 ReserveHeader(); | |
| 1671 | |
| 1672 // Write out the version string. | |
| 1673 WriteObject(String::New(Version::String())); | |
| 1674 | |
| 1617 // Write out the library object. | 1675 // Write out the library object. |
| 1618 NoGCScope no_gc; | 1676 { |
| 1619 ReserveHeader(); | 1677 NoGCScope no_gc; |
| 1620 WriteObject(lib.raw()); | 1678 |
| 1621 FillHeader(kind()); | 1679 // Write out the library object. |
| 1622 UnmarkAll(); | 1680 WriteObject(lib.raw()); |
| 1681 | |
| 1682 FillHeader(kind()); | |
| 1683 UnmarkAll(); | |
| 1684 } | |
| 1623 } else { | 1685 } else { |
| 1624 ThrowException(exception_type(), exception_msg()); | 1686 ThrowException(exception_type(), exception_msg()); |
| 1625 } | 1687 } |
| 1626 } | 1688 } |
| 1627 | 1689 |
| 1628 | 1690 |
| 1629 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 1691 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 1630 for (RawObject** current = first; current <= last; current++) { | 1692 for (RawObject** current = first; current <= last; current++) { |
| 1631 RawObject* raw_obj = *current; | 1693 RawObject* raw_obj = *current; |
| 1632 if (as_references_) { | 1694 if (as_references_) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1650 NoGCScope no_gc; | 1712 NoGCScope no_gc; |
| 1651 WriteObject(obj.raw()); | 1713 WriteObject(obj.raw()); |
| 1652 UnmarkAll(); | 1714 UnmarkAll(); |
| 1653 } else { | 1715 } else { |
| 1654 ThrowException(exception_type(), exception_msg()); | 1716 ThrowException(exception_type(), exception_msg()); |
| 1655 } | 1717 } |
| 1656 } | 1718 } |
| 1657 | 1719 |
| 1658 | 1720 |
| 1659 } // namespace dart | 1721 } // namespace dart |
| OLD | NEW |