| 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" |
| 11 #include "vm/heap.h" | 11 #include "vm/heap.h" |
| 12 #include "vm/longjump.h" |
| 12 #include "vm/object.h" | 13 #include "vm/object.h" |
| 13 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
| 14 #include "vm/snapshot_ids.h" | 15 #include "vm/snapshot_ids.h" |
| 15 #include "vm/symbols.h" | 16 #include "vm/symbols.h" |
| 16 | 17 |
| 17 namespace dart { | 18 namespace dart { |
| 18 | 19 |
| 19 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; | 20 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; |
| 20 static const int kNumInitialReferences = 4; | 21 static const int kNumInitialReferences = 4; |
| 21 | 22 |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 733 *TypeArgumentsHandle() ^= ReadObjectImpl(); | 734 *TypeArgumentsHandle() ^= ReadObjectImpl(); |
| 734 result.SetTypeArguments(*TypeArgumentsHandle()); | 735 result.SetTypeArguments(*TypeArgumentsHandle()); |
| 735 | 736 |
| 736 for (intptr_t i = 0; i < len; i++) { | 737 for (intptr_t i = 0; i < len; i++) { |
| 737 *ObjectHandle() = ReadObjectRef(); | 738 *ObjectHandle() = ReadObjectRef(); |
| 738 result.SetAt(i, *ObjectHandle()); | 739 result.SetAt(i, *ObjectHandle()); |
| 739 } | 740 } |
| 740 } | 741 } |
| 741 | 742 |
| 742 | 743 |
| 744 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, |
| 745 uint8_t** buffer, |
| 746 ReAlloc alloc, |
| 747 intptr_t increment_size) |
| 748 : BaseWriter(buffer, alloc, increment_size), |
| 749 kind_(kind), |
| 750 object_store_(Isolate::Current()->object_store()), |
| 751 class_table_(Isolate::Current()->class_table()), |
| 752 forward_list_(), |
| 753 exception_type_(Exceptions::kNone), |
| 754 exception_msg_(NULL), |
| 755 error_(LanguageError::Handle()) { |
| 756 } |
| 757 |
| 758 |
| 743 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 759 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
| 744 WriteObjectImpl(rawobj); | 760 WriteObjectImpl(rawobj); |
| 745 WriteForwardedObjects(); | 761 WriteForwardedObjects(); |
| 746 } | 762 } |
| 747 | 763 |
| 748 | 764 |
| 749 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { | 765 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
| 750 // Check if it is a singleton null object. | 766 // Check if it is a singleton null object. |
| 751 if (rawobj == Object::null()) { | 767 if (rawobj == Object::null()) { |
| 752 WriteVMIsolateObject(kNullObject); | 768 WriteVMIsolateObject(kNullObject); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 // First check if object can be written as a simple predefined type. | 809 // First check if object can be written as a simple predefined type. |
| 794 if (CheckAndWritePredefinedObject(raw)) { | 810 if (CheckAndWritePredefinedObject(raw)) { |
| 795 return; | 811 return; |
| 796 } | 812 } |
| 797 | 813 |
| 798 NoGCScope no_gc; | 814 NoGCScope no_gc; |
| 799 RawClass* cls = class_table_->At(raw->GetClassId()); | 815 RawClass* cls = class_table_->At(raw->GetClassId()); |
| 800 intptr_t class_id = cls->ptr()->id_; | 816 intptr_t class_id = cls->ptr()->id_; |
| 801 ASSERT(class_id == raw->GetClassId()); | 817 ASSERT(class_id == raw->GetClassId()); |
| 802 if (class_id >= kNumPredefinedCids) { | 818 if (class_id >= kNumPredefinedCids) { |
| 803 ASSERT(!Class::IsSignatureClass(cls)); | 819 if (Class::IsSignatureClass(cls)) { |
| 820 // We do not allow closure objects in an isolate message. |
| 821 set_exception_type(Exceptions::kArgumentError); |
| 822 // TODO(asiva): Allocate these constant strings once in the VM isolate. |
| 823 set_exception_msg("Illegal argument in isolate message" |
| 824 " : (object is a closure)"); |
| 825 Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
| 826 } |
| 804 // Object is being referenced, add it to the forward ref list and mark | 827 // 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 | 828 // 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 | 829 // 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. | 830 // will serialize the object when we go through the forward list. |
| 808 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 831 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
| 809 | 832 |
| 810 // Write out the serialization header value for this object. | 833 // Write out the serialization header value for this object. |
| 811 WriteInlinedObjectHeader(object_id); | 834 WriteInlinedObjectHeader(object_id); |
| 812 | 835 |
| 813 // Indicate this is an instance object. | 836 // Indicate this is an instance object. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 UNREACHABLE(); | 901 UNREACHABLE(); |
| 879 } | 902 } |
| 880 | 903 |
| 881 | 904 |
| 882 void FullSnapshotWriter::WriteFullSnapshot() { | 905 void FullSnapshotWriter::WriteFullSnapshot() { |
| 883 Isolate* isolate = Isolate::Current(); | 906 Isolate* isolate = Isolate::Current(); |
| 884 ASSERT(isolate != NULL); | 907 ASSERT(isolate != NULL); |
| 885 ObjectStore* object_store = isolate->object_store(); | 908 ObjectStore* object_store = isolate->object_store(); |
| 886 ASSERT(object_store != NULL); | 909 ASSERT(object_store != NULL); |
| 887 | 910 |
| 888 // Reserve space in the output buffer for a snapshot header. | 911 // Setup for long jump in case there is an exception while writing |
| 889 ReserveHeader(); | 912 // the snapshot. |
| 913 LongJump* base = isolate->long_jump_base(); |
| 914 LongJump jump; |
| 915 isolate->set_long_jump_base(&jump); |
| 916 // TODO(asiva): Allocate these constant strings once in the VM isolate. |
| 917 *ErrorHandle() = LanguageError::New( |
| 918 String::Handle(String::New("Error while writing full snapshot"))); |
| 919 if (setjmp(*jump.Set()) == 0) { |
| 920 NoGCScope no_gc; |
| 890 | 921 |
| 891 // Write out all the objects in the object store of the isolate which | 922 // Reserve space in the output buffer for a snapshot header. |
| 892 // is the root set for all dart allocated objects at this point. | 923 ReserveHeader(); |
| 893 SnapshotWriterVisitor visitor(this, false); | |
| 894 object_store->VisitObjectPointers(&visitor); | |
| 895 | 924 |
| 896 // Write out all forwarded objects. | 925 // Write out all the objects in the object store of the isolate which |
| 897 WriteForwardedObjects(); | 926 // is the root set for all dart allocated objects at this point. |
| 927 SnapshotWriterVisitor visitor(this, false); |
| 928 object_store->VisitObjectPointers(&visitor); |
| 898 | 929 |
| 899 FillHeader(kind()); | 930 // Write out all forwarded objects. |
| 900 UnmarkAll(); | 931 WriteForwardedObjects(); |
| 932 |
| 933 FillHeader(kind()); |
| 934 UnmarkAll(); |
| 935 |
| 936 isolate->set_long_jump_base(base); |
| 937 } else { |
| 938 isolate->set_long_jump_base(base); |
| 939 ThrowException(exception_type(), exception_msg()); |
| 940 } |
| 901 } | 941 } |
| 902 | 942 |
| 903 | 943 |
| 904 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 944 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
| 905 uword tags = raw->ptr()->tags_; | 945 uword tags = raw->ptr()->tags_; |
| 906 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 946 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
| 907 intptr_t id = SerializedHeaderData::decode(tags); | 947 intptr_t id = SerializedHeaderData::decode(tags); |
| 908 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); | 948 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); |
| 909 } else { | 949 } else { |
| 910 return tags; | 950 return tags; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1024 // ...... | 1064 // ...... |
| 1025 NoGCScope no_gc; | 1065 NoGCScope no_gc; |
| 1026 uword tags = raw->ptr()->tags_; | 1066 uword tags = raw->ptr()->tags_; |
| 1027 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 1067 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
| 1028 intptr_t object_id = SerializedHeaderData::decode(tags); | 1068 intptr_t object_id = SerializedHeaderData::decode(tags); |
| 1029 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); | 1069 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); |
| 1030 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 1070 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
| 1031 intptr_t class_id = cls->ptr()->id_; | 1071 intptr_t class_id = cls->ptr()->id_; |
| 1032 | 1072 |
| 1033 if (class_id >= kNumPredefinedCids) { | 1073 if (class_id >= kNumPredefinedCids) { |
| 1034 ASSERT(!Class::IsSignatureClass(cls)); | 1074 if (Class::IsSignatureClass(cls)) { |
| 1075 // We do not allow closure objects in an isolate message. |
| 1076 set_exception_type(Exceptions::kArgumentError); |
| 1077 // TODO(asiva): Allocate these constant strings once in the VM isolate. |
| 1078 set_exception_msg("Illegal argument in isolate message" |
| 1079 " : (object is a closure)"); |
| 1080 Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
| 1081 } |
| 1082 if (cls->ptr()->num_native_fields_ != 0) { |
| 1083 // We do not allow objects with native fields in an isolate message. |
| 1084 set_exception_type(Exceptions::kArgumentError); |
| 1085 // TODO(asiva): Allocate these constant strings once in the VM isolate. |
| 1086 set_exception_msg("Illegal argument in isolate message" |
| 1087 " : (object extends NativeWrapper)"); |
| 1088 |
| 1089 Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
| 1090 } |
| 1035 // Object is regular dart instance. | 1091 // 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_; | 1092 intptr_t instance_size = cls->ptr()->instance_size_; |
| 1040 ASSERT(instance_size != 0); | 1093 ASSERT(instance_size != 0); |
| 1041 | 1094 |
| 1042 // Write out the serialization header value for this object. | 1095 // Write out the serialization header value for this object. |
| 1043 WriteInlinedObjectHeader(object_id); | 1096 WriteInlinedObjectHeader(object_id); |
| 1044 | 1097 |
| 1045 // Indicate this is an instance object. | 1098 // Indicate this is an instance object. |
| 1046 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); | 1099 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
| 1047 | 1100 |
| 1048 // Write out the tags. | 1101 // Write out the tags. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1141 // Write out the type arguments. | 1194 // Write out the type arguments. |
| 1142 WriteObjectImpl(type_arguments); | 1195 WriteObjectImpl(type_arguments); |
| 1143 | 1196 |
| 1144 // Write out the individual object ids. | 1197 // Write out the individual object ids. |
| 1145 for (intptr_t i = 0; i < len; i++) { | 1198 for (intptr_t i = 0; i < len; i++) { |
| 1146 WriteObjectRef(data[i]); | 1199 WriteObjectRef(data[i]); |
| 1147 } | 1200 } |
| 1148 } | 1201 } |
| 1149 | 1202 |
| 1150 | 1203 |
| 1204 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, |
| 1205 const char* msg) { |
| 1206 Isolate::Current()->object_store()->clear_sticky_error(); |
| 1207 UnmarkAll(); |
| 1208 const String& msg_obj = String::Handle(String::New(msg)); |
| 1209 GrowableArray<const Object*> args(1); |
| 1210 args.Add(&msg_obj); |
| 1211 Exceptions::ThrowByType(type, args); |
| 1212 UNREACHABLE(); |
| 1213 } |
| 1214 |
| 1215 |
| 1151 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 1216 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
| 1152 ASSERT(kind() == Snapshot::kScript); | 1217 ASSERT(kind() == Snapshot::kScript); |
| 1218 Isolate* isolate = Isolate::Current(); |
| 1219 ASSERT(isolate != NULL); |
| 1153 | 1220 |
| 1154 // Write out the library object. | 1221 // Setup for long jump in case there is an exception while writing |
| 1155 ReserveHeader(); | 1222 // the snapshot. |
| 1156 WriteObject(lib.raw()); | 1223 LongJump* base = isolate->long_jump_base(); |
| 1157 FillHeader(kind()); | 1224 LongJump jump; |
| 1158 UnmarkAll(); | 1225 isolate->set_long_jump_base(&jump); |
| 1226 *ErrorHandle() = LanguageError::New( |
| 1227 String::Handle(String::New("Error while writing script snapshot"))); |
| 1228 if (setjmp(*jump.Set()) == 0) { |
| 1229 // Write out the library object. |
| 1230 NoGCScope no_gc; |
| 1231 ReserveHeader(); |
| 1232 WriteObject(lib.raw()); |
| 1233 FillHeader(kind()); |
| 1234 UnmarkAll(); |
| 1235 isolate->set_long_jump_base(base); |
| 1236 } else { |
| 1237 isolate->set_long_jump_base(base); |
| 1238 ThrowException(exception_type(), exception_msg()); |
| 1239 } |
| 1159 } | 1240 } |
| 1160 | 1241 |
| 1161 | 1242 |
| 1162 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 1243 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 1163 for (RawObject** current = first; current <= last; current++) { | 1244 for (RawObject** current = first; current <= last; current++) { |
| 1164 RawObject* raw_obj = *current; | 1245 RawObject* raw_obj = *current; |
| 1165 if (as_references_) { | 1246 if (as_references_) { |
| 1166 writer_->WriteObjectRef(raw_obj); | 1247 writer_->WriteObjectRef(raw_obj); |
| 1167 } else { | 1248 } else { |
| 1168 writer_->WriteObjectImpl(raw_obj); | 1249 writer_->WriteObjectImpl(raw_obj); |
| 1169 } | 1250 } |
| 1170 } | 1251 } |
| 1171 } | 1252 } |
| 1172 | 1253 |
| 1173 | 1254 |
| 1174 void MessageWriter::WriteMessage(const Object& obj) { | 1255 void MessageWriter::WriteMessage(const Object& obj) { |
| 1175 ASSERT(kind() == Snapshot::kMessage); | 1256 ASSERT(kind() == Snapshot::kMessage); |
| 1176 WriteObject(obj.raw()); | 1257 Isolate* isolate = Isolate::Current(); |
| 1177 UnmarkAll(); | 1258 ASSERT(isolate != NULL); |
| 1259 |
| 1260 // Setup for long jump in case there is an exception while writing |
| 1261 // the message. |
| 1262 LongJump* base = isolate->long_jump_base(); |
| 1263 LongJump jump; |
| 1264 isolate->set_long_jump_base(&jump); |
| 1265 *ErrorHandle() = LanguageError::New( |
| 1266 String::Handle(String::New("Error while writing message"))); |
| 1267 if (setjmp(*jump.Set()) == 0) { |
| 1268 NoGCScope no_gc; |
| 1269 WriteObject(obj.raw()); |
| 1270 UnmarkAll(); |
| 1271 isolate->set_long_jump_base(base); |
| 1272 } else { |
| 1273 isolate->set_long_jump_base(base); |
| 1274 ThrowException(exception_type(), exception_msg()); |
| 1275 } |
| 1178 } | 1276 } |
| 1179 | 1277 |
| 1180 | 1278 |
| 1181 } // namespace dart | 1279 } // namespace dart |
| OLD | NEW |