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

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
« runtime/vm/snapshot.h ('K') | « 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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 Isolate* isolate = thread->isolate(); 596 Isolate* isolate = thread->isolate();
597 ASSERT(isolate != NULL); 597 ASSERT(isolate != NULL);
598 ObjectStore* object_store = isolate->object_store(); 598 ObjectStore* object_store = isolate->object_store();
599 ASSERT(object_store != NULL); 599 ASSERT(object_store != NULL);
600 600
601 // First read the version string, and check that it matches. 601 // First read the version string, and check that it matches.
602 RawApiError* error = VerifyVersion(); 602 RawApiError* error = VerifyVersion();
603 if (error != ApiError::null()) { 603 if (error != ApiError::null()) {
604 return error; 604 return error;
605 } 605 }
606 error = VerifyFeatures();
607 if (error != ApiError::null()) {
608 return error;
609 }
606 610
607 // The version string matches. Read the rest of the snapshot. 611 // The version string matches. Read the rest of the snapshot.
608 612
609 // TODO(asiva): Add a check here to ensure we have the right heap 613 // TODO(asiva): Add a check here to ensure we have the right heap
610 // size for the full snapshot being read. 614 // size for the full snapshot being read.
611 { 615 {
612 NoSafepointScope no_safepoint; 616 NoSafepointScope no_safepoint;
613 HeapLocker hl(thread, old_space()); 617 HeapLocker hl(thread, old_space());
614 618
615 // Read in all the objects stored in the object store. 619 // Read in all the objects stored in the object store.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 671
668 672
669 RawObject* SnapshotReader::ReadScriptSnapshot() { 673 RawObject* SnapshotReader::ReadScriptSnapshot() {
670 ASSERT(kind_ == Snapshot::kScript); 674 ASSERT(kind_ == Snapshot::kScript);
671 675
672 // First read the version string, and check that it matches. 676 // First read the version string, and check that it matches.
673 RawApiError* error = VerifyVersion(); 677 RawApiError* error = VerifyVersion();
674 if (error != ApiError::null()) { 678 if (error != ApiError::null()) {
675 return error; 679 return error;
676 } 680 }
681 error = VerifyFeatures();
682 if (error != ApiError::null()) {
683 return error;
684 }
677 685
678 // The version string matches. Read the rest of the snapshot. 686 // The version string matches. Read the rest of the snapshot.
679 obj_ = ReadObject(); 687 obj_ = ReadObject();
680 if (!obj_.IsLibrary()) { 688 if (!obj_.IsLibrary()) {
681 if (!obj_.IsError()) { 689 if (!obj_.IsError()) {
682 const intptr_t kMessageBufferSize = 128; 690 const intptr_t kMessageBufferSize = 128;
683 char message_buffer[kMessageBufferSize]; 691 char message_buffer[kMessageBufferSize];
684 OS::SNPrint(message_buffer, 692 OS::SNPrint(message_buffer,
685 kMessageBufferSize, 693 kMessageBufferSize,
686 "Invalid object %s found in script snapshot", 694 "Invalid object %s found in script snapshot",
(...skipping 12 matching lines...) Expand all
699 707
700 const char* expected_version = Version::SnapshotString(); 708 const char* expected_version = Version::SnapshotString();
701 ASSERT(expected_version != NULL); 709 ASSERT(expected_version != NULL);
702 const intptr_t version_len = strlen(expected_version); 710 const intptr_t version_len = strlen(expected_version);
703 if (PendingBytes() < version_len) { 711 if (PendingBytes() < version_len) {
704 const intptr_t kMessageBufferSize = 128; 712 const intptr_t kMessageBufferSize = 128;
705 char message_buffer[kMessageBufferSize]; 713 char message_buffer[kMessageBufferSize];
706 OS::SNPrint(message_buffer, 714 OS::SNPrint(message_buffer,
707 kMessageBufferSize, 715 kMessageBufferSize,
708 "No full snapshot version found, expected '%s'", 716 "No full snapshot version found, expected '%s'",
709 Version::SnapshotString()); 717 expected_version);
710 // This can also fail while bringing up the VM isolate, so make sure to 718 // This can also fail while bringing up the VM isolate, so make sure to
711 // allocate the error message in old space. 719 // allocate the error message in old space.
712 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); 720 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
713 return ApiError::New(msg, Heap::kOld); 721 return ApiError::New(msg, Heap::kOld);
714 } 722 }
715 723
716 const char* version = reinterpret_cast<const char*>(CurrentBufferAddress()); 724 const char* version = reinterpret_cast<const char*>(CurrentBufferAddress());
717 ASSERT(version != NULL); 725 ASSERT(version != NULL);
718 if (strncmp(version, expected_version, version_len)) { 726 if (strncmp(version, expected_version, version_len)) {
719 const intptr_t kMessageBufferSize = 256; 727 const intptr_t kMessageBufferSize = 256;
720 char message_buffer[kMessageBufferSize]; 728 char message_buffer[kMessageBufferSize];
721 char* actual_version = OS::StrNDup(version, version_len); 729 char* actual_version = OS::StrNDup(version, version_len);
722 OS::SNPrint(message_buffer, 730 OS::SNPrint(message_buffer,
723 kMessageBufferSize, 731 kMessageBufferSize,
724 "Wrong %s snapshot version, expected '%s' found '%s'", 732 "Wrong %s snapshot version, expected '%s' found '%s'",
725 (Snapshot::IsFull(kind_)) ? "full" : "script", 733 (Snapshot::IsFull(kind_)) ? "full" : "script",
726 Version::SnapshotString(), 734 expected_version,
727 actual_version); 735 actual_version);
728 free(actual_version); 736 free(actual_version);
729 // This can also fail while bringing up the VM isolate, so make sure to 737 // This can also fail while bringing up the VM isolate, so make sure to
730 // allocate the error message in old space. 738 // allocate the error message in old space.
731 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld)); 739 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
732 return ApiError::New(msg, Heap::kOld); 740 return ApiError::New(msg, Heap::kOld);
733 } 741 }
734 Advance(version_len); 742 Advance(version_len);
735 return ApiError::null(); 743 return ApiError::null();
736 } 744 }
737 745
738 746
747 RawApiError* SnapshotReader::VerifyFeatures() {
748 // If the features string doesn't match, return an error.
749 // Note: New things are allocated only if we're going to return an error.
750
751 const char* expected_features = Dart::FeaturesString(kind_);
752 ASSERT(expected_features != NULL);
753 const intptr_t expected_len = strlen(expected_features);
754
755 const char* features = reinterpret_cast<const char*>(CurrentBufferAddress());
756 ASSERT(features != NULL);
757 intptr_t buffer_len = strnlen(features, PendingBytes());
758 if (strncmp(features, expected_features,
759 expected_len < buffer_len ? expected_len : buffer_len)) {
siva 2016/05/16 16:48:00 why not write this as if ((expected_len > buffer_
rmacnak 2016/05/16 20:59:56 Done.
760 const intptr_t kMessageBufferSize = 256;
761 char message_buffer[kMessageBufferSize];
762 char* actual_features = OS::StrNDup(features, buffer_len < 128 ? buffer_len
763 : 128);
764 OS::SNPrint(message_buffer,
765 kMessageBufferSize,
766 "Wrong features in snapshot, expected '%s' found '%s'",
767 expected_features,
768 actual_features);
769 free(const_cast<char*>(expected_features));
770 free(actual_features);
771 // This can also fail while bringing up the VM isolate, so make sure to
772 // allocate the error message in old space.
773 const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
774 return ApiError::New(msg, Heap::kOld);
775 }
776 free(const_cast<char*>(expected_features));
777 Advance(expected_len + 1);
778 return ApiError::null();
779 }
780
781
739 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \ 782 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length) \
740 ASSERT(Snapshot::IsFull(kind_)); \ 783 ASSERT(Snapshot::IsFull(kind_)); \
741 ASSERT_NO_SAFEPOINT_SCOPE(); \ 784 ASSERT_NO_SAFEPOINT_SCOPE(); \
742 Raw##type* obj = reinterpret_cast<Raw##type*>( \ 785 Raw##type* obj = reinterpret_cast<Raw##type*>( \
743 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \ 786 AllocateUninitialized(k##type##Cid, type::InstanceSize(length))); \
744 obj->StoreSmi(&(obj->ptr()->length_), Smi::New(length)); \ 787 obj->StoreSmi(&(obj->ptr()->length_), Smi::New(length)); \
745 return obj; \ 788 return obj; \
746 789
747 790
748 RawArray* SnapshotReader::NewArray(intptr_t len) { 791 RawArray* SnapshotReader::NewArray(intptr_t len) {
(...skipping 963 matching lines...) Expand 10 before | Expand all | Expand 10 after
1712 ASSERT(isolate != NULL); 1755 ASSERT(isolate != NULL);
1713 ASSERT(isolate == Dart::vm_isolate()); 1756 ASSERT(isolate == Dart::vm_isolate());
1714 ObjectStore* object_store = isolate->object_store(); 1757 ObjectStore* object_store = isolate->object_store();
1715 ASSERT(object_store != NULL); 1758 ASSERT(object_store != NULL);
1716 1759
1717 // First read the version string, and check that it matches. 1760 // First read the version string, and check that it matches.
1718 RawApiError* error = VerifyVersion(); 1761 RawApiError* error = VerifyVersion();
1719 if (error != ApiError::null()) { 1762 if (error != ApiError::null()) {
1720 return error; 1763 return error;
1721 } 1764 }
1765 error = VerifyFeatures();
1766 if (error != ApiError::null()) {
1767 return error;
1768 }
1722 1769
1723 // The version string matches. Read the rest of the snapshot. 1770 // The version string matches. Read the rest of the snapshot.
1724 1771
1725 { 1772 {
1726 NoSafepointScope no_safepoint; 1773 NoSafepointScope no_safepoint;
1727 HeapLocker hl(thread, old_space()); 1774 HeapLocker hl(thread, old_space());
1728 1775
1729 // Read in the symbol table. 1776 // Read in the symbol table.
1730 object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject()); 1777 object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject());
1731 1778
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 // Write full snapshot for the VM isolate. 2154 // Write full snapshot for the VM isolate.
2108 // Setup for long jump in case there is an exception while writing 2155 // Setup for long jump in case there is an exception while writing
2109 // the snapshot. 2156 // the snapshot.
2110 LongJumpScope jump; 2157 LongJumpScope jump;
2111 if (setjmp(*jump.Set()) == 0) { 2158 if (setjmp(*jump.Set()) == 0) {
2112 // Reserve space in the output buffer for a snapshot header. 2159 // Reserve space in the output buffer for a snapshot header.
2113 writer.ReserveHeader(); 2160 writer.ReserveHeader();
2114 2161
2115 // Write out the version string. 2162 // Write out the version string.
2116 writer.WriteVersion(); 2163 writer.WriteVersion();
2164 writer.WriteFeatures();
2117 2165
2118 /* 2166 /*
2119 * Now Write out the following 2167 * Now Write out the following
2120 * - the symbol table 2168 * - the symbol table
2121 * - all the scripts and token streams for these scripts 2169 * - all the scripts and token streams for these scripts
2122 * - the stub code (precompiled snapshots only) 2170 * - the stub code (precompiled snapshots only)
2123 **/ 2171 **/
2124 // Write out the symbol table. 2172 // Write out the symbol table.
2125 writer.WriteObject(new_vm_symbol_table_.raw()); 2173 writer.WriteObject(new_vm_symbol_table_.raw());
2126 2174
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2158 // Write full snapshot for a regular isolate. 2206 // Write full snapshot for a regular isolate.
2159 // Setup for long jump in case there is an exception while writing 2207 // Setup for long jump in case there is an exception while writing
2160 // the snapshot. 2208 // the snapshot.
2161 LongJumpScope jump; 2209 LongJumpScope jump;
2162 if (setjmp(*jump.Set()) == 0) { 2210 if (setjmp(*jump.Set()) == 0) {
2163 // Reserve space in the output buffer for a snapshot header. 2211 // Reserve space in the output buffer for a snapshot header.
2164 writer.ReserveHeader(); 2212 writer.ReserveHeader();
2165 2213
2166 // Write out the version string. 2214 // Write out the version string.
2167 writer.WriteVersion(); 2215 writer.WriteVersion();
2216 writer.WriteFeatures();
2168 2217
2169 // Write out the full snapshot. 2218 // Write out the full snapshot.
2170 2219
2171 // Write out all the objects in the object store of the isolate which 2220 // Write out all the objects in the object store of the isolate which
2172 // is the root set for all dart allocated objects at this point. 2221 // is the root set for all dart allocated objects at this point.
2173 SnapshotWriterVisitor visitor(&writer, false); 2222 SnapshotWriterVisitor visitor(&writer, false);
2174 visitor.VisitPointers(object_store->from(), 2223 visitor.VisitPointers(object_store->from(),
2175 object_store->to_snapshot(kind_)); 2224 object_store->to_snapshot(kind_));
2176 2225
2177 // Write out all forwarded objects. 2226 // Write out all forwarded objects.
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
2689 2738
2690 2739
2691 void SnapshotWriter::WriteVersion() { 2740 void SnapshotWriter::WriteVersion() {
2692 const char* expected_version = Version::SnapshotString(); 2741 const char* expected_version = Version::SnapshotString();
2693 ASSERT(expected_version != NULL); 2742 ASSERT(expected_version != NULL);
2694 const intptr_t version_len = strlen(expected_version); 2743 const intptr_t version_len = strlen(expected_version);
2695 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len); 2744 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len);
2696 } 2745 }
2697 2746
2698 2747
2748 void SnapshotWriter::WriteFeatures() {
2749 const char* expected_features = Dart::FeaturesString(kind_);
2750 ASSERT(expected_features != NULL);
2751 const intptr_t features_len = strlen(expected_features);
2752 WriteBytes(reinterpret_cast<const uint8_t*>(expected_features),
2753 features_len + 1);
2754 free(const_cast<char*>(expected_features));
2755 }
2756
2757
2699 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, 2758 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer,
2700 ReAlloc alloc) 2759 ReAlloc alloc)
2701 : SnapshotWriter(Thread::Current(), 2760 : SnapshotWriter(Thread::Current(),
2702 Snapshot::kScript, 2761 Snapshot::kScript,
2703 buffer, 2762 buffer,
2704 alloc, 2763 alloc,
2705 kInitialSize, 2764 kInitialSize,
2706 &forward_list_, 2765 &forward_list_,
2707 NULL, /* instructions_writer */ 2766 NULL, /* instructions_writer */
2708 true, /* can_send_any_object */ 2767 true, /* can_send_any_object */
(...skipping 11 matching lines...) Expand all
2720 2779
2721 // Setup for long jump in case there is an exception while writing 2780 // Setup for long jump in case there is an exception while writing
2722 // the snapshot. 2781 // the snapshot.
2723 LongJumpScope jump; 2782 LongJumpScope jump;
2724 if (setjmp(*jump.Set()) == 0) { 2783 if (setjmp(*jump.Set()) == 0) {
2725 // Reserve space in the output buffer for a snapshot header. 2784 // Reserve space in the output buffer for a snapshot header.
2726 ReserveHeader(); 2785 ReserveHeader();
2727 2786
2728 // Write out the version string. 2787 // Write out the version string.
2729 WriteVersion(); 2788 WriteVersion();
2789 WriteFeatures();
2730 2790
2731 // Write out the library object. 2791 // Write out the library object.
2732 { 2792 {
2733 NoSafepointScope no_safepoint; 2793 NoSafepointScope no_safepoint;
2734 2794
2735 // Write out the library object. 2795 // Write out the library object.
2736 WriteObject(lib.raw()); 2796 WriteObject(lib.raw());
2737 2797
2738 FillHeader(kind()); 2798 FillHeader(kind());
2739 } 2799 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2779 if (setjmp(*jump.Set()) == 0) { 2839 if (setjmp(*jump.Set()) == 0) {
2780 NoSafepointScope no_safepoint; 2840 NoSafepointScope no_safepoint;
2781 WriteObject(obj.raw()); 2841 WriteObject(obj.raw());
2782 } else { 2842 } else {
2783 ThrowException(exception_type(), exception_msg()); 2843 ThrowException(exception_type(), exception_msg());
2784 } 2844 }
2785 } 2845 }
2786 2846
2787 2847
2788 } // namespace dart 2848 } // namespace dart
OLDNEW
« runtime/vm/snapshot.h ('K') | « runtime/vm/snapshot.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698