| 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/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 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 | 593 |
| 594 RawApiError* SnapshotReader::ReadFullSnapshot() { | 594 RawApiError* SnapshotReader::ReadFullSnapshot() { |
| 595 ASSERT(Snapshot::IsFull(kind_)); | 595 ASSERT(Snapshot::IsFull(kind_)); |
| 596 Thread* thread = Thread::Current(); | 596 Thread* thread = Thread::Current(); |
| 597 Isolate* isolate = thread->isolate(); | 597 Isolate* isolate = thread->isolate(); |
| 598 ASSERT(isolate != NULL); | 598 ASSERT(isolate != NULL); |
| 599 ObjectStore* object_store = isolate->object_store(); | 599 ObjectStore* object_store = isolate->object_store(); |
| 600 ASSERT(object_store != NULL); | 600 ASSERT(object_store != NULL); |
| 601 | 601 |
| 602 // First read the version string, and check that it matches. | 602 // First read the version string, and check that it matches. |
| 603 RawApiError* error = VerifyVersion(); | 603 RawApiError* error = VerifyVersionAndFeatures(); |
| 604 if (error != ApiError::null()) { | 604 if (error != ApiError::null()) { |
| 605 return error; | 605 return error; |
| 606 } | 606 } |
| 607 | 607 |
| 608 // The version string matches. Read the rest of the snapshot. | 608 // The version string matches. Read the rest of the snapshot. |
| 609 | 609 |
| 610 // TODO(asiva): Add a check here to ensure we have the right heap | 610 // TODO(asiva): Add a check here to ensure we have the right heap |
| 611 // size for the full snapshot being read. | 611 // size for the full snapshot being read. |
| 612 { | 612 { |
| 613 NoSafepointScope no_safepoint; | 613 NoSafepointScope no_safepoint; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 } | 664 } |
| 665 | 665 |
| 666 return ApiError::null(); | 666 return ApiError::null(); |
| 667 } | 667 } |
| 668 | 668 |
| 669 | 669 |
| 670 RawObject* SnapshotReader::ReadScriptSnapshot() { | 670 RawObject* SnapshotReader::ReadScriptSnapshot() { |
| 671 ASSERT(kind_ == Snapshot::kScript); | 671 ASSERT(kind_ == Snapshot::kScript); |
| 672 | 672 |
| 673 // First read the version string, and check that it matches. | 673 // First read the version string, and check that it matches. |
| 674 RawApiError* error = VerifyVersion(); | 674 RawApiError* error = VerifyVersionAndFeatures(); |
| 675 if (error != ApiError::null()) { | 675 if (error != ApiError::null()) { |
| 676 return error; | 676 return error; |
| 677 } | 677 } |
| 678 | 678 |
| 679 // The version string matches. Read the rest of the snapshot. | 679 // The version string matches. Read the rest of the snapshot. |
| 680 obj_ = ReadObject(); | 680 obj_ = ReadObject(); |
| 681 if (!obj_.IsLibrary()) { | 681 if (!obj_.IsLibrary()) { |
| 682 if (!obj_.IsError()) { | 682 if (!obj_.IsError()) { |
| 683 const intptr_t kMessageBufferSize = 128; | 683 const intptr_t kMessageBufferSize = 128; |
| 684 char message_buffer[kMessageBufferSize]; | 684 char message_buffer[kMessageBufferSize]; |
| 685 OS::SNPrint(message_buffer, | 685 OS::SNPrint(message_buffer, |
| 686 kMessageBufferSize, | 686 kMessageBufferSize, |
| 687 "Invalid object %s found in script snapshot", | 687 "Invalid object %s found in script snapshot", |
| 688 obj_.ToCString()); | 688 obj_.ToCString()); |
| 689 const String& msg = String::Handle(String::New(message_buffer)); | 689 const String& msg = String::Handle(String::New(message_buffer)); |
| 690 obj_ = ApiError::New(msg); | 690 obj_ = ApiError::New(msg); |
| 691 } | 691 } |
| 692 } | 692 } |
| 693 return obj_.raw(); | 693 return obj_.raw(); |
| 694 } | 694 } |
| 695 | 695 |
| 696 | 696 |
| 697 RawApiError* SnapshotReader::VerifyVersion() { | 697 RawApiError* SnapshotReader::VerifyVersionAndFeatures() { |
| 698 // If the version string doesn't match, return an error. | 698 // If the version string doesn't match, return an error. |
| 699 // Note: New things are allocated only if we're going to return an error. | 699 // Note: New things are allocated only if we're going to return an error. |
| 700 | 700 |
| 701 const char* expected_version = Version::SnapshotString(); | 701 const char* expected_version = Version::SnapshotString(); |
| 702 ASSERT(expected_version != NULL); | 702 ASSERT(expected_version != NULL); |
| 703 const intptr_t version_len = strlen(expected_version); | 703 const intptr_t version_len = strlen(expected_version); |
| 704 if (PendingBytes() < version_len) { | 704 if (PendingBytes() < version_len) { |
| 705 const intptr_t kMessageBufferSize = 128; | 705 const intptr_t kMessageBufferSize = 128; |
| 706 char message_buffer[kMessageBufferSize]; | 706 char message_buffer[kMessageBufferSize]; |
| 707 OS::SNPrint(message_buffer, | 707 OS::SNPrint(message_buffer, |
| 708 kMessageBufferSize, | 708 kMessageBufferSize, |
| 709 "No full snapshot version found, expected '%s'", | 709 "No full snapshot version found, expected '%s'", |
| 710 Version::SnapshotString()); | 710 expected_version); |
| 711 // This can also fail while bringing up the VM isolate, so make sure to | 711 // This can also fail while bringing up the VM isolate, so make sure to |
| 712 // allocate the error message in old space. | 712 // allocate the error message in old space. |
| 713 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); | 713 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); |
| 714 return ApiError::New(msg, Heap::kOld); | 714 return ApiError::New(msg, Heap::kOld); |
| 715 } | 715 } |
| 716 | 716 |
| 717 const char* version = reinterpret_cast<const char*>(CurrentBufferAddress()); | 717 const char* version = reinterpret_cast<const char*>(CurrentBufferAddress()); |
| 718 ASSERT(version != NULL); | 718 ASSERT(version != NULL); |
| 719 if (strncmp(version, expected_version, version_len)) { | 719 if (strncmp(version, expected_version, version_len)) { |
| 720 const intptr_t kMessageBufferSize = 256; | 720 const intptr_t kMessageBufferSize = 256; |
| 721 char message_buffer[kMessageBufferSize]; | 721 char message_buffer[kMessageBufferSize]; |
| 722 char* actual_version = OS::StrNDup(version, version_len); | 722 char* actual_version = OS::StrNDup(version, version_len); |
| 723 OS::SNPrint(message_buffer, | 723 OS::SNPrint(message_buffer, |
| 724 kMessageBufferSize, | 724 kMessageBufferSize, |
| 725 "Wrong %s snapshot version, expected '%s' found '%s'", | 725 "Wrong %s snapshot version, expected '%s' found '%s'", |
| 726 (Snapshot::IsFull(kind_)) ? "full" : "script", | 726 (Snapshot::IsFull(kind_)) ? "full" : "script", |
| 727 Version::SnapshotString(), | 727 expected_version, |
| 728 actual_version); | 728 actual_version); |
| 729 free(actual_version); | 729 free(actual_version); |
| 730 // This can also fail while bringing up the VM isolate, so make sure to | 730 // This can also fail while bringing up the VM isolate, so make sure to |
| 731 // allocate the error message in old space. | 731 // allocate the error message in old space. |
| 732 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); | 732 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); |
| 733 return ApiError::New(msg, Heap::kOld); | 733 return ApiError::New(msg, Heap::kOld); |
| 734 } | 734 } |
| 735 Advance(version_len); | 735 Advance(version_len); |
| 736 |
| 737 const char* expected_features = Dart::FeaturesString(kind_); |
| 738 ASSERT(expected_features != NULL); |
| 739 const intptr_t expected_len = strlen(expected_features); |
| 740 |
| 741 const char* features = reinterpret_cast<const char*>(CurrentBufferAddress()); |
| 742 ASSERT(features != NULL); |
| 743 intptr_t buffer_len = strnlen(features, PendingBytes()); |
| 744 if ((buffer_len != expected_len) || |
| 745 strncmp(features, expected_features, expected_len)) { |
| 746 const intptr_t kMessageBufferSize = 256; |
| 747 char message_buffer[kMessageBufferSize]; |
| 748 char* actual_features = OS::StrNDup(features, buffer_len < 128 ? buffer_len |
| 749 : 128); |
| 750 OS::SNPrint(message_buffer, |
| 751 kMessageBufferSize, |
| 752 "Wrong features in snapshot, expected '%s' found '%s'", |
| 753 expected_features, |
| 754 actual_features); |
| 755 free(const_cast<char*>(expected_features)); |
| 756 free(actual_features); |
| 757 // This can also fail while bringing up the VM isolate, so make sure to |
| 758 // allocate the error message in old space. |
| 759 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); |
| 760 return ApiError::New(msg, Heap::kOld); |
| 761 } |
| 762 free(const_cast<char*>(expected_features)); |
| 763 Advance(expected_len + 1); |
| 736 return ApiError::null(); | 764 return ApiError::null(); |
| 737 } | 765 } |
| 738 | 766 |
| 739 | 767 |
| 740 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ | 768 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ |
| 741 ASSERT(Snapshot::IsFull(kind_)); \ | 769 ASSERT(Snapshot::IsFull(kind_)); \ |
| 742 ASSERT_NO_SAFEPOINT_SCOPE(); \ | 770 ASSERT_NO_SAFEPOINT_SCOPE(); \ |
| 743 Raw##type* obj = reinterpret_cast<Raw##type*>( \ | 771 Raw##type* obj = reinterpret_cast<Raw##type*>( \ |
| 744 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ | 772 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ |
| 745 obj->StoreSmi(&(obj->ptr()->length_), Smi::New(length)); \ | 773 obj->StoreSmi(&(obj->ptr()->length_), Smi::New(length)); \ |
| (...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1715 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { | 1743 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
| 1716 ASSERT(Snapshot::IsFull(kind())); | 1744 ASSERT(Snapshot::IsFull(kind())); |
| 1717 Thread* thread = Thread::Current(); | 1745 Thread* thread = Thread::Current(); |
| 1718 Isolate* isolate = thread->isolate(); | 1746 Isolate* isolate = thread->isolate(); |
| 1719 ASSERT(isolate != NULL); | 1747 ASSERT(isolate != NULL); |
| 1720 ASSERT(isolate == Dart::vm_isolate()); | 1748 ASSERT(isolate == Dart::vm_isolate()); |
| 1721 ObjectStore* object_store = isolate->object_store(); | 1749 ObjectStore* object_store = isolate->object_store(); |
| 1722 ASSERT(object_store != NULL); | 1750 ASSERT(object_store != NULL); |
| 1723 | 1751 |
| 1724 // First read the version string, and check that it matches. | 1752 // First read the version string, and check that it matches. |
| 1725 RawApiError* error = VerifyVersion(); | 1753 RawApiError* error = VerifyVersionAndFeatures(); |
| 1726 if (error != ApiError::null()) { | 1754 if (error != ApiError::null()) { |
| 1727 return error; | 1755 return error; |
| 1728 } | 1756 } |
| 1729 | 1757 |
| 1730 // The version string matches. Read the rest of the snapshot. | 1758 // The version string matches. Read the rest of the snapshot. |
| 1731 | 1759 |
| 1732 { | 1760 { |
| 1733 NoSafepointScope no_safepoint; | 1761 NoSafepointScope no_safepoint; |
| 1734 HeapLocker hl(thread, old_space()); | 1762 HeapLocker hl(thread, old_space()); |
| 1735 | 1763 |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2119 true /* writing_vm_isolate */); | 2147 true /* writing_vm_isolate */); |
| 2120 // Write full snapshot for the VM isolate. | 2148 // Write full snapshot for the VM isolate. |
| 2121 // Setup for long jump in case there is an exception while writing | 2149 // Setup for long jump in case there is an exception while writing |
| 2122 // the snapshot. | 2150 // the snapshot. |
| 2123 LongJumpScope jump; | 2151 LongJumpScope jump; |
| 2124 if (setjmp(*jump.Set()) == 0) { | 2152 if (setjmp(*jump.Set()) == 0) { |
| 2125 // Reserve space in the output buffer for a snapshot header. | 2153 // Reserve space in the output buffer for a snapshot header. |
| 2126 writer.ReserveHeader(); | 2154 writer.ReserveHeader(); |
| 2127 | 2155 |
| 2128 // Write out the version string. | 2156 // Write out the version string. |
| 2129 writer.WriteVersion(); | 2157 writer.WriteVersionAndFeatures(); |
| 2130 | 2158 |
| 2131 /* | 2159 /* |
| 2132 * Now Write out the following | 2160 * Now Write out the following |
| 2133 * - the symbol table | 2161 * - the symbol table |
| 2134 * - all the scripts and token streams for these scripts | 2162 * - all the scripts and token streams for these scripts |
| 2135 * - the stub code (precompiled snapshots only) | 2163 * - the stub code (precompiled snapshots only) |
| 2136 **/ | 2164 **/ |
| 2137 // Write out the symbol table. | 2165 // Write out the symbol table. |
| 2138 writer.WriteObject(new_vm_symbol_table_.raw()); | 2166 writer.WriteObject(new_vm_symbol_table_.raw()); |
| 2139 | 2167 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2173 | 2201 |
| 2174 // Write full snapshot for a regular isolate. | 2202 // Write full snapshot for a regular isolate. |
| 2175 // Setup for long jump in case there is an exception while writing | 2203 // Setup for long jump in case there is an exception while writing |
| 2176 // the snapshot. | 2204 // the snapshot. |
| 2177 LongJumpScope jump; | 2205 LongJumpScope jump; |
| 2178 if (setjmp(*jump.Set()) == 0) { | 2206 if (setjmp(*jump.Set()) == 0) { |
| 2179 // Reserve space in the output buffer for a snapshot header. | 2207 // Reserve space in the output buffer for a snapshot header. |
| 2180 writer.ReserveHeader(); | 2208 writer.ReserveHeader(); |
| 2181 | 2209 |
| 2182 // Write out the version string. | 2210 // Write out the version string. |
| 2183 writer.WriteVersion(); | 2211 writer.WriteVersionAndFeatures(); |
| 2184 | 2212 |
| 2185 // Write out the full snapshot. | 2213 // Write out the full snapshot. |
| 2186 | 2214 |
| 2187 // Write out all the objects in the object store of the isolate which | 2215 // Write out all the objects in the object store of the isolate which |
| 2188 // is the root set for all dart allocated objects at this point. | 2216 // is the root set for all dart allocated objects at this point. |
| 2189 SnapshotWriterVisitor visitor(&writer, false); | 2217 SnapshotWriterVisitor visitor(&writer, false); |
| 2190 visitor.VisitPointers(object_store->from(), | 2218 visitor.VisitPointers(object_store->from(), |
| 2191 object_store->to_snapshot(kind_)); | 2219 object_store->to_snapshot(kind_)); |
| 2192 | 2220 |
| 2193 // Write out all forwarded objects. | 2221 // Write out all forwarded objects. |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2697 const Array& args = Array::Handle(Array::New(1)); | 2725 const Array& args = Array::Handle(Array::New(1)); |
| 2698 args.SetAt(0, msg_obj); | 2726 args.SetAt(0, msg_obj); |
| 2699 Exceptions::ThrowByType(type, args); | 2727 Exceptions::ThrowByType(type, args); |
| 2700 } else { | 2728 } else { |
| 2701 Exceptions::ThrowByType(type, Object::empty_array()); | 2729 Exceptions::ThrowByType(type, Object::empty_array()); |
| 2702 } | 2730 } |
| 2703 UNREACHABLE(); | 2731 UNREACHABLE(); |
| 2704 } | 2732 } |
| 2705 | 2733 |
| 2706 | 2734 |
| 2707 void SnapshotWriter::WriteVersion() { | 2735 void SnapshotWriter::WriteVersionAndFeatures() { |
| 2708 const char* expected_version = Version::SnapshotString(); | 2736 const char* expected_version = Version::SnapshotString(); |
| 2709 ASSERT(expected_version != NULL); | 2737 ASSERT(expected_version != NULL); |
| 2710 const intptr_t version_len = strlen(expected_version); | 2738 const intptr_t version_len = strlen(expected_version); |
| 2711 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len); | 2739 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len); |
| 2740 |
| 2741 const char* expected_features = Dart::FeaturesString(kind_); |
| 2742 ASSERT(expected_features != NULL); |
| 2743 const intptr_t features_len = strlen(expected_features); |
| 2744 WriteBytes(reinterpret_cast<const uint8_t*>(expected_features), |
| 2745 features_len + 1); |
| 2746 free(const_cast<char*>(expected_features)); |
| 2712 } | 2747 } |
| 2713 | 2748 |
| 2714 | 2749 |
| 2715 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, | 2750 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, |
| 2716 ReAlloc alloc) | 2751 ReAlloc alloc) |
| 2717 : SnapshotWriter(Thread::Current(), | 2752 : SnapshotWriter(Thread::Current(), |
| 2718 Snapshot::kScript, | 2753 Snapshot::kScript, |
| 2719 buffer, | 2754 buffer, |
| 2720 alloc, | 2755 alloc, |
| 2721 kInitialSize, | 2756 kInitialSize, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2735 ASSERT(ClassFinalizer::AllClassesFinalized()); | 2770 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 2736 | 2771 |
| 2737 // Setup for long jump in case there is an exception while writing | 2772 // Setup for long jump in case there is an exception while writing |
| 2738 // the snapshot. | 2773 // the snapshot. |
| 2739 LongJumpScope jump; | 2774 LongJumpScope jump; |
| 2740 if (setjmp(*jump.Set()) == 0) { | 2775 if (setjmp(*jump.Set()) == 0) { |
| 2741 // Reserve space in the output buffer for a snapshot header. | 2776 // Reserve space in the output buffer for a snapshot header. |
| 2742 ReserveHeader(); | 2777 ReserveHeader(); |
| 2743 | 2778 |
| 2744 // Write out the version string. | 2779 // Write out the version string. |
| 2745 WriteVersion(); | 2780 WriteVersionAndFeatures(); |
| 2746 | 2781 |
| 2747 // Write out the library object. | 2782 // Write out the library object. |
| 2748 { | 2783 { |
| 2749 NoSafepointScope no_safepoint; | 2784 NoSafepointScope no_safepoint; |
| 2750 | 2785 |
| 2751 // Write out the library object. | 2786 // Write out the library object. |
| 2752 WriteObject(lib.raw()); | 2787 WriteObject(lib.raw()); |
| 2753 | 2788 |
| 2754 FillHeader(kind()); | 2789 FillHeader(kind()); |
| 2755 } | 2790 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2795 if (setjmp(*jump.Set()) == 0) { | 2830 if (setjmp(*jump.Set()) == 0) { |
| 2796 NoSafepointScope no_safepoint; | 2831 NoSafepointScope no_safepoint; |
| 2797 WriteObject(obj.raw()); | 2832 WriteObject(obj.raw()); |
| 2798 } else { | 2833 } else { |
| 2799 ThrowException(exception_type(), exception_msg()); | 2834 ThrowException(exception_type(), exception_msg()); |
| 2800 } | 2835 } |
| 2801 } | 2836 } |
| 2802 | 2837 |
| 2803 | 2838 |
| 2804 } // namespace dart | 2839 } // namespace dart |
| OLD | NEW |