| 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 |