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::kIllegalArgument); | |
822 set_exception_msg("Illegal argument in isolate message" | |
823 " : (object is a closure)"); | |
824 Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); | |
825 } | |
804 // Object is being referenced, add it to the forward ref list and mark | 826 // 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 | 827 // 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 | 828 // 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. | 829 // will serialize the object when we go through the forward list. |
808 intptr_t object_id = MarkObject(raw, kIsNotSerialized); | 830 intptr_t object_id = MarkObject(raw, kIsNotSerialized); |
809 | 831 |
810 // Write out the serialization header value for this object. | 832 // Write out the serialization header value for this object. |
811 WriteInlinedObjectHeader(object_id); | 833 WriteInlinedObjectHeader(object_id); |
812 | 834 |
813 // Indicate this is an instance object. | 835 // Indicate this is an instance object. |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 UNREACHABLE(); | 900 UNREACHABLE(); |
879 } | 901 } |
880 | 902 |
881 | 903 |
882 void FullSnapshotWriter::WriteFullSnapshot() { | 904 void FullSnapshotWriter::WriteFullSnapshot() { |
883 Isolate* isolate = Isolate::Current(); | 905 Isolate* isolate = Isolate::Current(); |
884 ASSERT(isolate != NULL); | 906 ASSERT(isolate != NULL); |
885 ObjectStore* object_store = isolate->object_store(); | 907 ObjectStore* object_store = isolate->object_store(); |
886 ASSERT(object_store != NULL); | 908 ASSERT(object_store != NULL); |
887 | 909 |
888 // Reserve space in the output buffer for a snapshot header. | 910 // Setup for long jump in case there is an exception while writing |
889 ReserveHeader(); | 911 // the snapshot. |
912 LongJump* base = isolate->long_jump_base(); | |
913 LongJump jump; | |
914 isolate->set_long_jump_base(&jump); | |
915 *ErrorHandle() = LanguageError::New( | |
916 String::Handle(String::New("Error while writing full snapshot"))); | |
917 if (setjmp(*jump.Set()) == 0) { | |
918 NoGCScope no_gc; | |
890 | 919 |
891 // Write out all the objects in the object store of the isolate which | 920 // Reserve space in the output buffer for a snapshot header. |
892 // is the root set for all dart allocated objects at this point. | 921 ReserveHeader(); |
893 SnapshotWriterVisitor visitor(this, false); | |
894 object_store->VisitObjectPointers(&visitor); | |
895 | 922 |
896 // Write out all forwarded objects. | 923 // Write out all the objects in the object store of the isolate which |
897 WriteForwardedObjects(); | 924 // is the root set for all dart allocated objects at this point. |
925 SnapshotWriterVisitor visitor(this, false); | |
926 object_store->VisitObjectPointers(&visitor); | |
898 | 927 |
899 FillHeader(kind()); | 928 // Write out all forwarded objects. |
900 UnmarkAll(); | 929 WriteForwardedObjects(); |
930 | |
931 FillHeader(kind()); | |
932 UnmarkAll(); | |
933 | |
934 isolate->set_long_jump_base(base); | |
935 } else { | |
936 ThrowException(exception_type(), exception_msg()); | |
937 } | |
901 } | 938 } |
902 | 939 |
903 | 940 |
904 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 941 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
905 uword tags = raw->ptr()->tags_; | 942 uword tags = raw->ptr()->tags_; |
906 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 943 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
907 intptr_t id = SerializedHeaderData::decode(tags); | 944 intptr_t id = SerializedHeaderData::decode(tags); |
908 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); | 945 return forward_list_[id - kMaxPredefinedObjectIds]->tags(); |
909 } else { | 946 } else { |
910 return tags; | 947 return tags; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1024 // ...... | 1061 // ...... |
1025 NoGCScope no_gc; | 1062 NoGCScope no_gc; |
1026 uword tags = raw->ptr()->tags_; | 1063 uword tags = raw->ptr()->tags_; |
1027 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 1064 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
1028 intptr_t object_id = SerializedHeaderData::decode(tags); | 1065 intptr_t object_id = SerializedHeaderData::decode(tags); |
1029 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); | 1066 tags = forward_list_[object_id - kMaxPredefinedObjectIds]->tags(); |
1030 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 1067 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
1031 intptr_t class_id = cls->ptr()->id_; | 1068 intptr_t class_id = cls->ptr()->id_; |
1032 | 1069 |
1033 if (class_id >= kNumPredefinedCids) { | 1070 if (class_id >= kNumPredefinedCids) { |
1034 ASSERT(!Class::IsSignatureClass(cls)); | 1071 if (Class::IsSignatureClass(cls)) { |
1072 // We do not allow closure objects in an isolate message. | |
1073 set_exception_type(Exceptions::kIllegalArgument); | |
1074 set_exception_msg("Illegal argument in isolate message" | |
1075 " : (object is a closure)"); | |
1076 Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); | |
1077 } | |
1078 if (cls->ptr()->num_native_fields_ != 0) { | |
1079 // We do not allow objects with native fields in an isolate message. | |
1080 set_exception_type(Exceptions::kIllegalArgument); | |
1081 set_exception_msg("Illegal argument in isolate message" | |
1082 " : (object extends NativeWrapper)"); | |
1083 | |
1084 Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); | |
1085 } | |
1035 // Object is regular dart instance. | 1086 // 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_; | 1087 intptr_t instance_size = cls->ptr()->instance_size_; |
1040 ASSERT(instance_size != 0); | 1088 ASSERT(instance_size != 0); |
1041 | 1089 |
1042 // Write out the serialization header value for this object. | 1090 // Write out the serialization header value for this object. |
1043 WriteInlinedObjectHeader(object_id); | 1091 WriteInlinedObjectHeader(object_id); |
1044 | 1092 |
1045 // Indicate this is an instance object. | 1093 // Indicate this is an instance object. |
1046 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); | 1094 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
1047 | 1095 |
1048 // Write out the tags. | 1096 // Write out the tags. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1141 // Write out the type arguments. | 1189 // Write out the type arguments. |
1142 WriteObjectImpl(type_arguments); | 1190 WriteObjectImpl(type_arguments); |
1143 | 1191 |
1144 // Write out the individual object ids. | 1192 // Write out the individual object ids. |
1145 for (intptr_t i = 0; i < len; i++) { | 1193 for (intptr_t i = 0; i < len; i++) { |
1146 WriteObjectRef(data[i]); | 1194 WriteObjectRef(data[i]); |
1147 } | 1195 } |
1148 } | 1196 } |
1149 | 1197 |
1150 | 1198 |
1199 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, | |
1200 const char* msg) { | |
1201 Isolate::Current()->object_store()->clear_sticky_error(); | |
1202 UnmarkAll(); | |
1203 const String& msg_obj = String::Handle(String::New(msg)); | |
1204 GrowableArray<const Object*> args(1); | |
1205 args.Add(&msg_obj); | |
1206 Exceptions::ThrowByType(type, args); | |
1207 UNREACHABLE(); | |
1208 } | |
1209 | |
1210 | |
1151 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 1211 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
1152 ASSERT(kind() == Snapshot::kScript); | 1212 ASSERT(kind() == Snapshot::kScript); |
1213 Isolate* isolate = Isolate::Current(); | |
1214 ASSERT(isolate != NULL); | |
1153 | 1215 |
1154 // Write out the library object. | 1216 // Setup for long jump in case there is an exception while writing |
1155 ReserveHeader(); | 1217 // the snapshot. |
1156 WriteObject(lib.raw()); | 1218 LongJump* base = isolate->long_jump_base(); |
1157 FillHeader(kind()); | 1219 LongJump jump; |
1158 UnmarkAll(); | 1220 isolate->set_long_jump_base(&jump); |
1221 *ErrorHandle() = LanguageError::New( | |
1222 String::Handle(String::New("Error while writing script snapshot"))); | |
Ivan Posva
2012/11/14 05:12:15
Can these strings be in the shared symbol table to
siva
2012/11/14 18:26:38
Instead of using the symbol table we should probab
| |
1223 if (setjmp(*jump.Set()) == 0) { | |
1224 // Write out the library object. | |
1225 NoGCScope no_gc; | |
1226 ReserveHeader(); | |
1227 WriteObject(lib.raw()); | |
1228 FillHeader(kind()); | |
1229 UnmarkAll(); | |
1230 isolate->set_long_jump_base(base); | |
1231 } else { | |
1232 ThrowException(exception_type(), exception_msg()); | |
Ivan Posva
2012/11/14 05:12:15
What happens to the long jump base in case we are
siva
2012/11/14 18:26:38
Good point, reset base back before throwing the ex
| |
1233 } | |
1159 } | 1234 } |
1160 | 1235 |
1161 | 1236 |
1162 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 1237 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
1163 for (RawObject** current = first; current <= last; current++) { | 1238 for (RawObject** current = first; current <= last; current++) { |
1164 RawObject* raw_obj = *current; | 1239 RawObject* raw_obj = *current; |
1165 if (as_references_) { | 1240 if (as_references_) { |
1166 writer_->WriteObjectRef(raw_obj); | 1241 writer_->WriteObjectRef(raw_obj); |
1167 } else { | 1242 } else { |
1168 writer_->WriteObjectImpl(raw_obj); | 1243 writer_->WriteObjectImpl(raw_obj); |
1169 } | 1244 } |
1170 } | 1245 } |
1171 } | 1246 } |
1172 | 1247 |
1173 | 1248 |
1174 void MessageWriter::WriteMessage(const Object& obj) { | 1249 void MessageWriter::WriteMessage(const Object& obj) { |
1175 ASSERT(kind() == Snapshot::kMessage); | 1250 ASSERT(kind() == Snapshot::kMessage); |
1176 WriteObject(obj.raw()); | 1251 Isolate* isolate = Isolate::Current(); |
1177 UnmarkAll(); | 1252 ASSERT(isolate != NULL); |
1253 | |
1254 // Setup for long jump in case there is an exception while writing | |
1255 // the message. | |
1256 LongJump* base = isolate->long_jump_base(); | |
1257 LongJump jump; | |
1258 isolate->set_long_jump_base(&jump); | |
1259 *ErrorHandle() = LanguageError::New( | |
1260 String::Handle(String::New("Error while writing message"))); | |
1261 if (setjmp(*jump.Set()) == 0) { | |
1262 NoGCScope no_gc; | |
1263 WriteObject(obj.raw()); | |
1264 UnmarkAll(); | |
1265 isolate->set_long_jump_base(base); | |
1266 } else { | |
1267 ThrowException(exception_type(), exception_msg()); | |
1268 } | |
1178 } | 1269 } |
1179 | 1270 |
1180 | 1271 |
1181 } // namespace dart | 1272 } // namespace dart |
OLD | NEW |