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" |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 }; | 405 }; |
406 | 406 |
407 | 407 |
408 RawApiError* SnapshotReader::ReadFullSnapshot() { | 408 RawApiError* SnapshotReader::ReadFullSnapshot() { |
409 ASSERT(kind_ == Snapshot::kFull); | 409 ASSERT(kind_ == Snapshot::kFull); |
410 Isolate* isolate = Isolate::Current(); | 410 Isolate* isolate = Isolate::Current(); |
411 ASSERT(isolate != NULL); | 411 ASSERT(isolate != NULL); |
412 ObjectStore* object_store = isolate->object_store(); | 412 ObjectStore* object_store = isolate->object_store(); |
413 ASSERT(object_store != NULL); | 413 ASSERT(object_store != NULL); |
414 | 414 |
| 415 // First read the version string, and check that it matches. |
| 416 RawApiError* error = VerifyVersion(); |
| 417 if (error != ApiError::null()) { |
| 418 return error; |
| 419 } |
| 420 |
| 421 // The version string matches. Read the rest of the snapshot. |
| 422 |
415 // TODO(asiva): Add a check here to ensure we have the right heap | 423 // TODO(asiva): Add a check here to ensure we have the right heap |
416 // size for the full snapshot being read. | 424 // size for the full snapshot being read. |
417 | |
418 { | 425 { |
419 NoGCScope no_gc; | 426 NoGCScope no_gc; |
420 HeapLocker hl(isolate, old_space()); | 427 HeapLocker hl(isolate, old_space()); |
421 | 428 |
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() || | |
428 !String::Cast(obj_).Equals(Version::SnapshotString())) { | |
429 const intptr_t kMessageBufferSize = 128; | |
430 char message_buffer[kMessageBufferSize]; | |
431 OS::SNPrint(message_buffer, | |
432 kMessageBufferSize, | |
433 "Wrong full snapshot version. Found %s expected %s", | |
434 obj_.ToCString(), | |
435 Version::SnapshotString()); | |
436 const String& msg = String::Handle(String::New(message_buffer)); | |
437 return ApiError::New(msg); | |
438 } | |
439 | |
440 // The version string matches. Read the rest of the snapshot. | |
441 | |
442 // Read in all the objects stored in the object store. | 429 // Read in all the objects stored in the object store. |
443 intptr_t num_flds = (object_store->to() - object_store->from()); | 430 intptr_t num_flds = (object_store->to() - object_store->from()); |
444 for (intptr_t i = 0; i <= num_flds; i++) { | 431 for (intptr_t i = 0; i <= num_flds; i++) { |
445 *(object_store->from() + i) = ReadObjectImpl(); | 432 *(object_store->from() + i) = ReadObjectImpl(); |
446 } | 433 } |
447 for (intptr_t i = 0; i < backward_references_.length(); i++) { | 434 for (intptr_t i = 0; i < backward_references_.length(); i++) { |
448 if (!backward_references_[i].is_deserialized()) { | 435 if (!backward_references_[i].is_deserialized()) { |
449 ReadObjectImpl(); | 436 ReadObjectImpl(); |
450 backward_references_[i].set_state(kIsDeserialized); | 437 backward_references_[i].set_state(kIsDeserialized); |
451 } | 438 } |
452 } | 439 } |
453 | 440 |
454 // Validate the class table. | 441 // Validate the class table. |
455 #if defined(DEBUG) | 442 #if defined(DEBUG) |
456 isolate->ValidateClassTable(); | 443 isolate->ValidateClassTable(); |
457 #endif | 444 #endif |
458 | 445 |
459 // Setup native resolver for bootstrap impl. | 446 // Setup native resolver for bootstrap impl. |
460 Bootstrap::SetupNativeResolver(); | 447 Bootstrap::SetupNativeResolver(); |
461 return ApiError::null(); | 448 return ApiError::null(); |
462 } | 449 } |
463 } | 450 } |
464 | 451 |
465 | 452 |
466 RawObject* SnapshotReader::ReadScriptSnapshot() { | 453 RawObject* SnapshotReader::ReadScriptSnapshot() { |
467 ASSERT(kind_ == Snapshot::kScript); | 454 ASSERT(kind_ == Snapshot::kScript); |
468 | 455 |
469 // First read the version string, and check that it matches. | 456 // First read the version string, and check that it matches. |
470 obj_ = ReadObject(); | 457 RawApiError* error = VerifyVersion(); |
471 | 458 if (error != ApiError::null()) { |
472 // If the version string doesn't match, return an error. | 459 return error; |
473 // NB: New things are allocated only if we're going to return an error. | |
474 if (!obj_.IsString() || | |
475 !String::Cast(obj_).Equals(Version::SnapshotString())) { | |
476 const intptr_t kMessageBufferSize = 256; | |
477 char message_buffer[kMessageBufferSize]; | |
478 OS::SNPrint(message_buffer, | |
479 kMessageBufferSize, | |
480 "Wrong script snapshot version. Found %s expected '%s'", | |
481 obj_.ToCString(), | |
482 Version::SnapshotString()); | |
483 const String& msg = String::Handle(String::New(message_buffer)); | |
484 return ApiError::New(msg); | |
485 } | 460 } |
486 | 461 |
487 // The version string matches. Read the rest of the snapshot. | 462 // The version string matches. Read the rest of the snapshot. |
488 obj_ = ReadObject(); | 463 obj_ = ReadObject(); |
489 if (!obj_.IsLibrary()) { | 464 if (!obj_.IsLibrary()) { |
490 if (!obj_.IsError()) { | 465 if (!obj_.IsError()) { |
491 const intptr_t kMessageBufferSize = 128; | 466 const intptr_t kMessageBufferSize = 128; |
492 char message_buffer[kMessageBufferSize]; | 467 char message_buffer[kMessageBufferSize]; |
493 OS::SNPrint(message_buffer, | 468 OS::SNPrint(message_buffer, |
494 kMessageBufferSize, | 469 kMessageBufferSize, |
495 "Invalid object %s found in script snapshot", | 470 "Invalid object %s found in script snapshot", |
496 obj_.ToCString()); | 471 obj_.ToCString()); |
497 const String& msg = String::Handle(String::New(message_buffer)); | 472 const String& msg = String::Handle(String::New(message_buffer)); |
498 obj_ = ApiError::New(msg); | 473 obj_ = ApiError::New(msg); |
499 } | 474 } |
500 } | 475 } |
501 return obj_.raw(); | 476 return obj_.raw(); |
502 } | 477 } |
503 | 478 |
504 | 479 |
| 480 RawApiError* SnapshotReader::VerifyVersion() { |
| 481 // If the version string doesn't match, return an error. |
| 482 // Note: New things are allocated only if we're going to return an error. |
| 483 |
| 484 const char* expected_version = Version::SnapshotString(); |
| 485 ASSERT(expected_version != NULL); |
| 486 const intptr_t version_len = strlen(expected_version); |
| 487 if (PendingBytes() < version_len) { |
| 488 const intptr_t kMessageBufferSize = 128; |
| 489 char message_buffer[kMessageBufferSize]; |
| 490 OS::SNPrint(message_buffer, |
| 491 kMessageBufferSize, |
| 492 "No full snapshot version found, expected '%s'", |
| 493 Version::SnapshotString()); |
| 494 const String& msg = String::Handle(String::New(message_buffer)); |
| 495 return ApiError::New(msg); |
| 496 } |
| 497 |
| 498 const char* version = reinterpret_cast<const char*>(CurrentBufferAddress()); |
| 499 ASSERT(version != NULL); |
| 500 if (strncmp(version, expected_version, version_len)) { |
| 501 const intptr_t kMessageBufferSize = 256; |
| 502 char message_buffer[kMessageBufferSize]; |
| 503 char* actual_version = strndup(version, version_len); |
| 504 OS::SNPrint(message_buffer, |
| 505 kMessageBufferSize, |
| 506 "Wrong full snapshot version, expected '%s' found '%s'", |
| 507 Version::SnapshotString(), |
| 508 actual_version); |
| 509 free(actual_version); |
| 510 const String& msg = String::Handle(String::New(message_buffer)); |
| 511 return ApiError::New(msg); |
| 512 } |
| 513 Advance(version_len); |
| 514 return ApiError::null(); |
| 515 } |
| 516 |
| 517 |
505 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ | 518 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ |
506 ASSERT(kind_ == Snapshot::kFull); \ | 519 ASSERT(kind_ == Snapshot::kFull); \ |
507 ASSERT(isolate()->no_gc_scope_depth() != 0); \ | 520 ASSERT(isolate()->no_gc_scope_depth() != 0); \ |
508 Raw##type* obj = reinterpret_cast<Raw##type*>( \ | 521 Raw##type* obj = reinterpret_cast<Raw##type*>( \ |
509 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ | 522 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ |
510 obj->ptr()->length_ = Smi::New(length); \ | 523 obj->ptr()->length_ = Smi::New(length); \ |
511 return obj; \ | 524 return obj; \ |
512 | 525 |
513 | 526 |
514 RawArray* SnapshotReader::NewArray(intptr_t len) { | 527 RawArray* SnapshotReader::NewArray(intptr_t len) { |
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 #endif | 1257 #endif |
1245 | 1258 |
1246 // Setup for long jump in case there is an exception while writing | 1259 // Setup for long jump in case there is an exception while writing |
1247 // the snapshot. | 1260 // the snapshot. |
1248 LongJumpScope jump; | 1261 LongJumpScope jump; |
1249 if (setjmp(*jump.Set()) == 0) { | 1262 if (setjmp(*jump.Set()) == 0) { |
1250 // Reserve space in the output buffer for a snapshot header. | 1263 // Reserve space in the output buffer for a snapshot header. |
1251 ReserveHeader(); | 1264 ReserveHeader(); |
1252 | 1265 |
1253 // Write out the version string. | 1266 // Write out the version string. |
1254 WriteObject(String::New(Version::SnapshotString())); | 1267 WriteVersion(); |
1255 | 1268 |
1256 // Write out the full snapshot. | 1269 // Write out the full snapshot. |
1257 { | 1270 { |
1258 NoGCScope no_gc; | 1271 NoGCScope no_gc; |
1259 | 1272 |
1260 // Write out all the objects in the object store of the isolate which | 1273 // Write out all the objects in the object store of the isolate which |
1261 // is the root set for all dart allocated objects at this point. | 1274 // is the root set for all dart allocated objects at this point. |
1262 SnapshotWriterVisitor visitor(this, false); | 1275 SnapshotWriterVisitor visitor(this, false); |
1263 object_store->VisitObjectPointers(&visitor); | 1276 object_store->VisitObjectPointers(&visitor); |
1264 | 1277 |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1666 const Array& args = Array::Handle(Array::New(1)); | 1679 const Array& args = Array::Handle(Array::New(1)); |
1667 args.SetAt(0, msg_obj); | 1680 args.SetAt(0, msg_obj); |
1668 Exceptions::ThrowByType(type, args); | 1681 Exceptions::ThrowByType(type, args); |
1669 } else { | 1682 } else { |
1670 Exceptions::ThrowByType(type, Object::empty_array()); | 1683 Exceptions::ThrowByType(type, Object::empty_array()); |
1671 } | 1684 } |
1672 UNREACHABLE(); | 1685 UNREACHABLE(); |
1673 } | 1686 } |
1674 | 1687 |
1675 | 1688 |
| 1689 void SnapshotWriter::WriteVersion() { |
| 1690 const char* expected_version = Version::SnapshotString(); |
| 1691 ASSERT(expected_version != NULL); |
| 1692 const intptr_t version_len = strlen(expected_version); |
| 1693 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len); |
| 1694 } |
| 1695 |
| 1696 |
1676 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 1697 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
1677 ASSERT(kind() == Snapshot::kScript); | 1698 ASSERT(kind() == Snapshot::kScript); |
1678 Isolate* isolate = Isolate::Current(); | 1699 Isolate* isolate = Isolate::Current(); |
1679 ASSERT(isolate != NULL); | 1700 ASSERT(isolate != NULL); |
1680 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1701 ASSERT(ClassFinalizer::AllClassesFinalized()); |
1681 | 1702 |
1682 // Setup for long jump in case there is an exception while writing | 1703 // Setup for long jump in case there is an exception while writing |
1683 // the snapshot. | 1704 // the snapshot. |
1684 LongJumpScope jump; | 1705 LongJumpScope jump; |
1685 if (setjmp(*jump.Set()) == 0) { | 1706 if (setjmp(*jump.Set()) == 0) { |
1686 // Reserve space in the output buffer for a snapshot header. | 1707 // Reserve space in the output buffer for a snapshot header. |
1687 ReserveHeader(); | 1708 ReserveHeader(); |
1688 | 1709 |
1689 // Write out the version string. | 1710 // Write out the version string. |
1690 WriteObject(String::New(Version::SnapshotString())); | 1711 WriteVersion(); |
1691 | 1712 |
1692 // Write out the library object. | 1713 // Write out the library object. |
1693 { | 1714 { |
1694 NoGCScope no_gc; | 1715 NoGCScope no_gc; |
1695 | 1716 |
1696 // Write out the library object. | 1717 // Write out the library object. |
1697 WriteObject(lib.raw()); | 1718 WriteObject(lib.raw()); |
1698 | 1719 |
1699 FillHeader(kind()); | 1720 FillHeader(kind()); |
1700 UnmarkAll(); | 1721 UnmarkAll(); |
(...skipping 28 matching lines...) Expand all Loading... |
1729 NoGCScope no_gc; | 1750 NoGCScope no_gc; |
1730 WriteObject(obj.raw()); | 1751 WriteObject(obj.raw()); |
1731 UnmarkAll(); | 1752 UnmarkAll(); |
1732 } else { | 1753 } else { |
1733 ThrowException(exception_type(), exception_msg()); | 1754 ThrowException(exception_type(), exception_msg()); |
1734 } | 1755 } |
1735 } | 1756 } |
1736 | 1757 |
1737 | 1758 |
1738 } // namespace dart | 1759 } // namespace dart |
OLD | NEW |