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/exceptions.h" | 10 #include "vm/exceptions.h" |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 UNREACHABLE(); | 788 UNREACHABLE(); |
789 } | 789 } |
790 | 790 |
791 | 791 |
792 void SnapshotWriter::WriteObjectRef(RawObject* raw) { | 792 void SnapshotWriter::WriteObjectRef(RawObject* raw) { |
793 // First check if object can be written as a simple predefined type. | 793 // First check if object can be written as a simple predefined type. |
794 if (CheckAndWritePredefinedObject(raw)) { | 794 if (CheckAndWritePredefinedObject(raw)) { |
795 return; | 795 return; |
796 } | 796 } |
797 | 797 |
798 NoGCScope no_gc; | 798 NoGCDuringSnapshotWriteScope no_gc; |
799 RawClass* cls = class_table_->At(raw->GetClassId()); | 799 RawClass* cls = class_table_->At(raw->GetClassId()); |
800 intptr_t class_id = cls->ptr()->id_; | 800 intptr_t class_id = cls->ptr()->id_; |
801 ASSERT(class_id == raw->GetClassId()); | 801 ASSERT(class_id == raw->GetClassId()); |
802 if (class_id >= kNumPredefinedCids) { | 802 if (class_id >= kNumPredefinedCids) { |
803 ASSERT(!Class::IsSignatureClass(cls)); | 803 if (Class::IsSignatureClass(cls)) { |
| 804 // We do not allow closure objects in an isolate message. |
| 805 ThrowIllegalArgException(no_gc, |
| 806 "Illegal argument in isolate message" |
| 807 " : (object is a closure)"); |
| 808 } |
804 // Object is being referenced, add it to the forward ref list and mark | 809 // Object is being referenced, add it to the forward ref list and mark |
805 // it so that future references to this object in the snapshot will use | 810 // it so that future references to this object in the snapshot will use |
806 // this object id. Mark it as not having been serialized yet so that we | 811 // this object id. Mark it as not having been serialized yet so that we |
807 // will serialize the object when we go through the forward list. | 812 // will serialize the object when we go through the forward list. |
808 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 813 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
809 | 814 |
810 // Write out the serialization header value for this object. | 815 // Write out the serialization header value for this object. |
811 WriteInlinedObjectHeader(object_id); | 816 WriteInlinedObjectHeader(object_id); |
812 | 817 |
813 // Indicate this is an instance object. | 818 // Indicate this is an instance object. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
906 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 911 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
907 intptr_t id = SerializedHeaderData::decode(tags); | 912 intptr_t id = SerializedHeaderData::decode(tags); |
908 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); | 913 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); |
909 } else { | 914 } else { |
910 return tags; | 915 return tags; |
911 } | 916 } |
912 } | 917 } |
913 | 918 |
914 | 919 |
915 intptr_t SnapshotWriter::MarkObject(RawObject* raw, SerializeState state) { | 920 intptr_t SnapshotWriter::MarkObject(RawObject* raw, SerializeState state) { |
916 NoGCScope no_gc; | 921 NoGCDuringSnapshotWriteScope no_gc; |
917 intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds; | 922 intptr_t object_id = forward_list_.length() + kMaxPredefinedObjectIds; |
918 ASSERT(object_id <= kMaxObjectId); | 923 ASSERT(object_id <= kMaxObjectId); |
919 uword value = 0; | 924 uword value = 0; |
920 value = SerializedHeaderTag::update(kObjectId, value); | 925 value = SerializedHeaderTag::update(kObjectId, value); |
921 value = SerializedHeaderData::update(object_id, value); | 926 value = SerializedHeaderData::update(object_id, value); |
922 uword tags = raw->ptr()->tags_; | 927 uword tags = raw->ptr()->tags_; |
923 raw->ptr()->tags_ = value; | 928 raw->ptr()->tags_ = value; |
924 ForwardObjectNode* node = new ForwardObjectNode(raw, tags, state); | 929 ForwardObjectNode* node = new ForwardObjectNode(raw, tags, state); |
925 ASSERT(node != NULL); | 930 ASSERT(node != NULL); |
926 forward_list_.Add(node); | 931 forward_list_.Add(node); |
927 return object_id; | 932 return object_id; |
928 } | 933 } |
929 | 934 |
930 | 935 |
931 void SnapshotWriter::UnmarkAll() { | 936 void SnapshotWriter::UnmarkAll() { |
932 NoGCScope no_gc; | 937 NoGCDuringSnapshotWriteScope no_gc; |
933 for (intptr_t i = 0; i < forward_list_.length(); i++) { | 938 for (intptr_t i = 0; i < forward_list_.length(); i++) { |
934 RawObject* raw = forward_list_[i]->raw(); | 939 RawObject* raw = forward_list_[i]->raw(); |
935 raw->ptr()->tags_ = forward_list_[i]->tags(); // Restore original tags. | 940 raw->ptr()->tags_ = forward_list_[i]->tags(); // Restore original tags. |
936 } | 941 } |
937 } | 942 } |
938 | 943 |
939 | 944 |
940 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { | 945 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { |
941 // Check if object can be written in one of the following ways: | 946 // Check if object can be written in one of the following ways: |
942 // - Smi: the Smi value is written as is (last bit is not tagged). | 947 // - Smi: the Smi value is written as is (last bit is not tagged). |
943 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) | 948 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) |
944 // - Object that has already been written: (negative id in stream | 0x3) | 949 // - Object that has already been written: (negative id in stream | 0x3) |
945 | 950 |
946 NoGCScope no_gc; | 951 NoGCDuringSnapshotWriteScope no_gc; |
947 | 952 |
948 // First check if it is a Smi (i.e not a heap object). | 953 // First check if it is a Smi (i.e not a heap object). |
949 if (!rawobj->IsHeapObject()) { | 954 if (!rawobj->IsHeapObject()) { |
950 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj)); | 955 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj)); |
951 return true; | 956 return true; |
952 } | 957 } |
953 | 958 |
954 // Check if object has already been serialized, in that case just write | 959 // Check if object has already been serialized, in that case just write |
955 // the object id out. | 960 // the object id out. |
956 uword tags = rawobj->ptr()->tags_; | 961 uword tags = rawobj->ptr()->tags_; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 WriteInlinedObject(raw); | 1020 WriteInlinedObject(raw); |
1016 } | 1021 } |
1017 | 1022 |
1018 | 1023 |
1019 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { | 1024 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { |
1020 // Now write the object out inline in the stream as follows: | 1025 // Now write the object out inline in the stream as follows: |
1021 // - Object is seen for the first time (inlined as follows): | 1026 // - Object is seen for the first time (inlined as follows): |
1022 // (object size in multiples of kObjectAlignment | 0x1) | 1027 // (object size in multiples of kObjectAlignment | 0x1) |
1023 // serialized fields of the object | 1028 // serialized fields of the object |
1024 // ...... | 1029 // ...... |
1025 NoGCScope no_gc; | 1030 NoGCDuringSnapshotWriteScope no_gc; |
1026 uword tags = raw->ptr()->tags_; | 1031 uword tags = raw->ptr()->tags_; |
1027 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 1032 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
1028 intptr_t object_id = SerializedHeaderData::decode(tags); | 1033 intptr_t object_id = SerializedHeaderData::decode(tags); |
1029 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); | 1034 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); |
1030 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 1035 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
1031 intptr_t class_id = cls->ptr()->id_; | 1036 intptr_t class_id = cls->ptr()->id_; |
1032 | 1037 |
1033 if (class_id >= kNumPredefinedCids) { | 1038 if (class_id >= kNumPredefinedCids) { |
1034 ASSERT(!Class::IsSignatureClass(cls)); | 1039 if (Class::IsSignatureClass(cls)) { |
| 1040 // We do not allow closure objects in an isolate message. |
| 1041 ThrowIllegalArgException(no_gc, |
| 1042 "Illegal argument in isolate message" |
| 1043 " : (object is a closure)"); |
| 1044 } |
| 1045 if (cls->ptr()->num_native_fields_ != 0) { |
| 1046 // We do not allow objects with native fields in an isolate message. |
| 1047 ThrowIllegalArgException(no_gc, |
| 1048 "Illegal argument in isolate message" |
| 1049 " : (object extends NativeWrapper)"); |
| 1050 } |
1035 // Object is regular dart instance. | 1051 // Object is regular dart instance. |
1036 // TODO(5411462): figure out what we need to do if an object with native | |
1037 // fields is serialized (throw exception or serialize a null object). | |
1038 ASSERT(cls->ptr()->num_native_fields_ == 0); | |
1039 intptr_t instance_size = cls->ptr()->instance_size_; | 1052 intptr_t instance_size = cls->ptr()->instance_size_; |
1040 ASSERT(instance_size != 0); | 1053 ASSERT(instance_size != 0); |
1041 | 1054 |
1042 // Write out the serialization header value for this object. | 1055 // Write out the serialization header value for this object. |
1043 WriteInlinedObjectHeader(object_id); | 1056 WriteInlinedObjectHeader(object_id); |
1044 | 1057 |
1045 // Indicate this is an instance object. | 1058 // Indicate this is an instance object. |
1046 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); | 1059 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
1047 | 1060 |
1048 // Write out the tags. | 1061 // Write out the tags. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 // Write out the type arguments. | 1154 // Write out the type arguments. |
1142 WriteObjectImpl(type_arguments); | 1155 WriteObjectImpl(type_arguments); |
1143 | 1156 |
1144 // Write out the individual object ids. | 1157 // Write out the individual object ids. |
1145 for (intptr_t i = 0; i < len; i++) { | 1158 for (intptr_t i = 0; i < len; i++) { |
1146 WriteObjectRef(data[i]); | 1159 WriteObjectRef(data[i]); |
1147 } | 1160 } |
1148 } | 1161 } |
1149 | 1162 |
1150 | 1163 |
| 1164 void SnapshotWriter::ThrowIllegalArgException( |
| 1165 const NoGCDuringSnapshotWriteScope& no_gc, const char* msg) { |
| 1166 UnmarkAll(); |
| 1167 no_gc.Reset(); |
| 1168 const String& msg_obj = String::Handle(String::New(msg)); |
| 1169 GrowableArray<const Object*> args(1); |
| 1170 args.Add(&msg_obj); |
| 1171 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args); |
| 1172 UNREACHABLE(); |
| 1173 } |
| 1174 |
| 1175 |
1151 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 1176 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
1152 ASSERT(kind() == Snapshot::kScript); | 1177 ASSERT(kind() == Snapshot::kScript); |
1153 | 1178 |
1154 // Write out the library object. | 1179 // Write out the library object. |
1155 ReserveHeader(); | 1180 ReserveHeader(); |
1156 WriteObject(lib.raw()); | 1181 WriteObject(lib.raw()); |
1157 FillHeader(kind()); | 1182 FillHeader(kind()); |
1158 UnmarkAll(); | 1183 UnmarkAll(); |
1159 } | 1184 } |
1160 | 1185 |
(...skipping 11 matching lines...) Expand all Loading... |
1172 | 1197 |
1173 | 1198 |
1174 void MessageWriter::WriteMessage(const Object& obj) { | 1199 void MessageWriter::WriteMessage(const Object& obj) { |
1175 ASSERT(kind() == Snapshot::kMessage); | 1200 ASSERT(kind() == Snapshot::kMessage); |
1176 WriteObject(obj.raw()); | 1201 WriteObject(obj.raw()); |
1177 UnmarkAll(); | 1202 UnmarkAll(); |
1178 } | 1203 } |
1179 | 1204 |
1180 | 1205 |
1181 } // namespace dart | 1206 } // namespace dart |
OLD | NEW |