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

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

Issue 1975423002: Check snapshots for feature compatibility. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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') | no next file » | 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 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/snapshot.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698