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 |