| 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 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 } | 398 } |
| 398 ~HeapLocker() { | 399 ~HeapLocker() { |
| 399 page_space_->ReleaseDataLock(); | 400 page_space_->ReleaseDataLock(); |
| 400 } | 401 } |
| 401 | 402 |
| 402 private: | 403 private: |
| 403 PageSpace* page_space_; | 404 PageSpace* page_space_; |
| 404 }; | 405 }; |
| 405 | 406 |
| 406 | 407 |
| 407 void SnapshotReader::ReadFullSnapshot() { | 408 RawApiError* SnapshotReader::ReadFullSnapshot() { |
| 408 ASSERT(kind_ == Snapshot::kFull); | 409 ASSERT(kind_ == Snapshot::kFull); |
| 409 Isolate* isolate = Isolate::Current(); | 410 Isolate* isolate = Isolate::Current(); |
| 410 ASSERT(isolate != NULL); | 411 ASSERT(isolate != NULL); |
| 411 ObjectStore* object_store = isolate->object_store(); | 412 ObjectStore* object_store = isolate->object_store(); |
| 412 ASSERT(object_store != NULL); | 413 ASSERT(object_store != NULL); |
| 413 NoGCScope no_gc; | |
| 414 | 414 |
| 415 // TODO(asiva): Add a check here to ensure we have the right heap | 415 // TODO(asiva): Add a check here to ensure we have the right heap |
| 416 // size for the full snapshot being read. | 416 // size for the full snapshot being read. |
| 417 | 417 |
| 418 { | 418 { |
| 419 NoGCScope no_gc; |
| 419 HeapLocker hl(isolate, old_space()); | 420 HeapLocker hl(isolate, old_space()); |
| 421 |
| 422 // First read the version string, and check that it matches. |
| 423 obj_ = ReadObject(); |
| 424 |
| 425 // If the version string doesn't match, return an error. |
| 426 // NB: New things are allocated only if we're going to return an error. |
| 427 if (!obj_.IsString() || !String::Cast(obj_).Equals(Version::String())) { |
| 428 const intptr_t kMessageBufferSize = 128; |
| 429 char message_buffer[kMessageBufferSize]; |
| 430 OS::SNPrint(message_buffer, |
| 431 kMessageBufferSize, |
| 432 "Wrong full snapshot version. Found %s expected %s", |
| 433 obj_.ToCString(), |
| 434 Version::String()); |
| 435 const String& msg = String::Handle(String::New(message_buffer)); |
| 436 return ApiError::New(msg); |
| 437 } |
| 438 |
| 439 // The version string matches. Read the rest of the snapshot. |
| 440 |
| 420 // Read in all the objects stored in the object store. | 441 // Read in all the objects stored in the object store. |
| 421 intptr_t num_flds = (object_store->to() - object_store->from()); | 442 intptr_t num_flds = (object_store->to() - object_store->from()); |
| 422 for (intptr_t i = 0; i <= num_flds; i++) { | 443 for (intptr_t i = 0; i <= num_flds; i++) { |
| 423 *(object_store->from() + i) = ReadObjectImpl(); | 444 *(object_store->from() + i) = ReadObjectImpl(); |
| 424 } | 445 } |
| 425 for (intptr_t i = 0; i < backward_references_.length(); i++) { | 446 for (intptr_t i = 0; i < backward_references_.length(); i++) { |
| 426 if (!backward_references_[i].is_deserialized()) { | 447 if (!backward_references_[i].is_deserialized()) { |
| 427 ReadObjectImpl(); | 448 ReadObjectImpl(); |
| 428 backward_references_[i].set_state(kIsDeserialized); | 449 backward_references_[i].set_state(kIsDeserialized); |
| 429 } | 450 } |
| 430 } | 451 } |
| 452 |
| 453 // Validate the class table. |
| 454 #if defined(DEBUG) |
| 455 isolate->ValidateClassTable(); |
| 456 #endif |
| 457 |
| 458 // Setup native resolver for bootstrap impl. |
| 459 Bootstrap::SetupNativeResolver(); |
| 460 return ApiError::null(); |
| 461 } |
| 462 } |
| 463 |
| 464 |
| 465 RawObject* SnapshotReader::ReadScriptSnapshot() { |
| 466 ASSERT(kind_ == Snapshot::kScript); |
| 467 |
| 468 // First read the version string, and check that it matches. |
| 469 obj_ = ReadObject(); |
| 470 |
| 471 // If the version string doesn't match, return an error. |
| 472 // NB: New things are allocated only if we're going to return an error. |
| 473 if (!obj_.IsString() || !String::Cast(obj_).Equals(Version::String())) { |
| 474 const intptr_t kMessageBufferSize = 256; |
| 475 char message_buffer[kMessageBufferSize]; |
| 476 OS::SNPrint(message_buffer, |
| 477 kMessageBufferSize, |
| 478 "Wrong script snapshot version. Found %s expected '%s'", |
| 479 obj_.ToCString(), |
| 480 Version::String()); |
| 481 const String& msg = String::Handle(String::New(message_buffer)); |
| 482 return ApiError::New(msg); |
| 431 } | 483 } |
| 432 | 484 |
| 433 // Validate the class table. | 485 // The version string matches. Read the rest of the snapshot. |
| 434 #if defined(DEBUG) | 486 obj_ = ReadObject(); |
| 435 isolate->ValidateClassTable(); | 487 if (!obj_.IsLibrary()) { |
| 436 #endif | 488 if (!obj_.IsError()) { |
| 437 | 489 const intptr_t kMessageBufferSize = 128; |
| 438 // Setup native resolver for bootstrap impl. | 490 char message_buffer[kMessageBufferSize]; |
| 439 Bootstrap::SetupNativeResolver(); | 491 OS::SNPrint(message_buffer, |
| 492 kMessageBufferSize, |
| 493 "Invalid object %s found in script snapshot", |
| 494 obj_.ToCString()); |
| 495 const String& msg = String::Handle(String::New(message_buffer)); |
| 496 obj_ = ApiError::New(msg); |
| 497 } |
| 498 } |
| 499 return obj_.raw(); |
| 440 } | 500 } |
| 441 | 501 |
| 442 | 502 |
| 443 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ | 503 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ |
| 444 ASSERT(kind_ == Snapshot::kFull); \ | 504 ASSERT(kind_ == Snapshot::kFull); \ |
| 445 ASSERT(isolate()->no_gc_scope_depth() != 0); \ | 505 ASSERT(isolate()->no_gc_scope_depth() != 0); \ |
| 446 Raw##type* obj = reinterpret_cast<Raw##type*>( \ | 506 Raw##type* obj = reinterpret_cast<Raw##type*>( \ |
| 447 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ | 507 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ |
| 448 obj->ptr()->length_ = Smi::New(length); \ | 508 obj->ptr()->length_ = Smi::New(length); \ |
| 449 return obj; \ | 509 return obj; \ |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1174 ASSERT(isolate != NULL); | 1234 ASSERT(isolate != NULL); |
| 1175 ObjectStore* object_store = isolate->object_store(); | 1235 ObjectStore* object_store = isolate->object_store(); |
| 1176 ASSERT(object_store != NULL); | 1236 ASSERT(object_store != NULL); |
| 1177 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1237 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 1178 | 1238 |
| 1179 // Ensure the class table is valid. | 1239 // Ensure the class table is valid. |
| 1180 #if defined(DEBUG) | 1240 #if defined(DEBUG) |
| 1181 isolate->ValidateClassTable(); | 1241 isolate->ValidateClassTable(); |
| 1182 #endif | 1242 #endif |
| 1183 | 1243 |
| 1184 | |
| 1185 // Setup for long jump in case there is an exception while writing | 1244 // Setup for long jump in case there is an exception while writing |
| 1186 // the snapshot. | 1245 // the snapshot. |
| 1187 LongJumpScope jump; | 1246 LongJumpScope jump; |
| 1188 if (setjmp(*jump.Set()) == 0) { | 1247 if (setjmp(*jump.Set()) == 0) { |
| 1189 NoGCScope no_gc; | |
| 1190 | |
| 1191 // Reserve space in the output buffer for a snapshot header. | 1248 // Reserve space in the output buffer for a snapshot header. |
| 1192 ReserveHeader(); | 1249 ReserveHeader(); |
| 1193 | 1250 |
| 1194 // Write out all the objects in the object store of the isolate which | 1251 // Write out the version string. |
| 1195 // is the root set for all dart allocated objects at this point. | 1252 WriteObject(String::New(Version::String())); |
| 1196 SnapshotWriterVisitor visitor(this, false); | |
| 1197 object_store->VisitObjectPointers(&visitor); | |
| 1198 | 1253 |
| 1199 // Write out all forwarded objects. | 1254 // Write out the full snapshot. |
| 1200 WriteForwardedObjects(); | 1255 { |
| 1256 NoGCScope no_gc; |
| 1201 | 1257 |
| 1202 FillHeader(kind()); | 1258 // Write out all the objects in the object store of the isolate which |
| 1203 UnmarkAll(); | 1259 // is the root set for all dart allocated objects at this point. |
| 1260 SnapshotWriterVisitor visitor(this, false); |
| 1261 object_store->VisitObjectPointers(&visitor); |
| 1262 |
| 1263 // Write out all forwarded objects. |
| 1264 WriteForwardedObjects(); |
| 1265 |
| 1266 FillHeader(kind()); |
| 1267 UnmarkAll(); |
| 1268 } |
| 1204 } else { | 1269 } else { |
| 1205 ThrowException(exception_type(), exception_msg()); | 1270 ThrowException(exception_type(), exception_msg()); |
| 1206 } | 1271 } |
| 1207 } | 1272 } |
| 1208 | 1273 |
| 1209 | 1274 |
| 1210 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 1275 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
| 1211 uword tags = raw->ptr()->tags_; | 1276 uword tags = raw->ptr()->tags_; |
| 1212 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 1277 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
| 1213 intptr_t id = SerializedHeaderData::decode(tags); | 1278 intptr_t id = SerializedHeaderData::decode(tags); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1609 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 1674 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
| 1610 ASSERT(kind() == Snapshot::kScript); | 1675 ASSERT(kind() == Snapshot::kScript); |
| 1611 Isolate* isolate = Isolate::Current(); | 1676 Isolate* isolate = Isolate::Current(); |
| 1612 ASSERT(isolate != NULL); | 1677 ASSERT(isolate != NULL); |
| 1613 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1678 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 1614 | 1679 |
| 1615 // Setup for long jump in case there is an exception while writing | 1680 // Setup for long jump in case there is an exception while writing |
| 1616 // the snapshot. | 1681 // the snapshot. |
| 1617 LongJumpScope jump; | 1682 LongJumpScope jump; |
| 1618 if (setjmp(*jump.Set()) == 0) { | 1683 if (setjmp(*jump.Set()) == 0) { |
| 1684 // Reserve space in the output buffer for a snapshot header. |
| 1685 ReserveHeader(); |
| 1686 |
| 1687 // Write out the version string. |
| 1688 WriteObject(String::New(Version::String())); |
| 1689 |
| 1619 // Write out the library object. | 1690 // Write out the library object. |
| 1620 NoGCScope no_gc; | 1691 { |
| 1621 ReserveHeader(); | 1692 NoGCScope no_gc; |
| 1622 WriteObject(lib.raw()); | 1693 |
| 1623 FillHeader(kind()); | 1694 // Write out the library object. |
| 1624 UnmarkAll(); | 1695 WriteObject(lib.raw()); |
| 1696 |
| 1697 FillHeader(kind()); |
| 1698 UnmarkAll(); |
| 1699 } |
| 1625 } else { | 1700 } else { |
| 1626 ThrowException(exception_type(), exception_msg()); | 1701 ThrowException(exception_type(), exception_msg()); |
| 1627 } | 1702 } |
| 1628 } | 1703 } |
| 1629 | 1704 |
| 1630 | 1705 |
| 1631 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 1706 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 1632 for (RawObject** current = first; current <= last; current++) { | 1707 for (RawObject** current = first; current <= last; current++) { |
| 1633 RawObject* raw_obj = *current; | 1708 RawObject* raw_obj = *current; |
| 1634 if (as_references_) { | 1709 if (as_references_) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1652 NoGCScope no_gc; | 1727 NoGCScope no_gc; |
| 1653 WriteObject(obj.raw()); | 1728 WriteObject(obj.raw()); |
| 1654 UnmarkAll(); | 1729 UnmarkAll(); |
| 1655 } else { | 1730 } else { |
| 1656 ThrowException(exception_type(), exception_msg()); | 1731 ThrowException(exception_type(), exception_msg()); |
| 1657 } | 1732 } |
| 1658 } | 1733 } |
| 1659 | 1734 |
| 1660 | 1735 |
| 1661 } // namespace dart | 1736 } // namespace dart |
| OLD | NEW |