Chromium Code Reviews| 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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |