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/bootstrap.h" | 8 #include "vm/bootstrap.h" |
9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
10 #include "vm/dart.h" | 10 #include "vm/dart.h" |
11 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
12 #include "vm/exceptions.h" | 12 #include "vm/exceptions.h" |
13 #include "vm/heap.h" | 13 #include "vm/heap.h" |
14 #include "vm/lockers.h" | 14 #include "vm/lockers.h" |
15 #include "vm/longjump.h" | 15 #include "vm/longjump.h" |
16 #include "vm/object.h" | 16 #include "vm/object.h" |
17 #include "vm/object_store.h" | 17 #include "vm/object_store.h" |
18 #include "vm/snapshot_ids.h" | 18 #include "vm/snapshot_ids.h" |
19 #include "vm/stub_code.h" | |
19 #include "vm/symbols.h" | 20 #include "vm/symbols.h" |
20 #include "vm/verified_memory.h" | 21 #include "vm/verified_memory.h" |
21 #include "vm/version.h" | 22 #include "vm/version.h" |
22 | 23 |
23 // We currently only expect the Dart mutator to read snapshots. | 24 // We currently only expect the Dart mutator to read snapshots. |
24 #define ASSERT_NO_SAFEPOINT_SCOPE() \ | 25 #define ASSERT_NO_SAFEPOINT_SCOPE() \ |
25 isolate()->AssertCurrentThreadIsMutator(); \ | 26 isolate()->AssertCurrentThreadIsMutator(); \ |
26 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0) | 27 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0) |
27 | 28 |
28 namespace dart { | 29 namespace dart { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
164 | 165 |
165 | 166 |
166 intptr_t BaseReader::ReadSmiValue() { | 167 intptr_t BaseReader::ReadSmiValue() { |
167 return Smi::Value(ReadAsSmi()); | 168 return Smi::Value(ReadAsSmi()); |
168 } | 169 } |
169 | 170 |
170 | 171 |
171 SnapshotReader::SnapshotReader( | 172 SnapshotReader::SnapshotReader( |
172 const uint8_t* buffer, | 173 const uint8_t* buffer, |
173 intptr_t size, | 174 intptr_t size, |
175 const uint8_t* instructions_buffer, | |
174 Snapshot::Kind kind, | 176 Snapshot::Kind kind, |
175 ZoneGrowableArray<BackRefNode>* backward_refs, | 177 ZoneGrowableArray<BackRefNode>* backward_refs, |
176 Isolate* isolate, | 178 Isolate* isolate, |
177 Zone* zone) | 179 Zone* zone) |
178 : BaseReader(buffer, size), | 180 : BaseReader(buffer, size), |
181 instructions_buffer_(instructions_buffer), | |
179 kind_(kind), | 182 kind_(kind), |
180 snapshot_code_(false), | 183 snapshot_code_(instructions_buffer != NULL), |
181 isolate_(isolate), | 184 isolate_(isolate), |
182 zone_(zone), | 185 zone_(zone), |
183 heap_(isolate->heap()), | 186 heap_(isolate->heap()), |
184 old_space_(isolate->heap()->old_space()), | 187 old_space_(isolate->heap()->old_space()), |
185 cls_(Class::Handle(isolate)), | 188 cls_(Class::Handle(isolate)), |
186 obj_(Object::Handle(isolate)), | 189 obj_(Object::Handle(isolate)), |
187 pobj_(PassiveObject::Handle(isolate)), | 190 pobj_(PassiveObject::Handle(isolate)), |
188 array_(Array::Handle(isolate)), | 191 array_(Array::Handle(isolate)), |
189 field_(Field::Handle(isolate)), | 192 field_(Field::Handle(isolate)), |
190 str_(String::Handle(isolate)), | 193 str_(String::Handle(isolate)), |
191 library_(Library::Handle(isolate)), | 194 library_(Library::Handle(isolate)), |
192 type_(AbstractType::Handle(isolate)), | 195 type_(AbstractType::Handle(isolate)), |
193 type_arguments_(TypeArguments::Handle(isolate)), | 196 type_arguments_(TypeArguments::Handle(isolate)), |
194 tokens_(Array::Handle(isolate)), | 197 tokens_(Array::Handle(isolate)), |
195 stream_(TokenStream::Handle(isolate)), | 198 stream_(TokenStream::Handle(isolate)), |
196 data_(ExternalTypedData::Handle(isolate)), | 199 data_(ExternalTypedData::Handle(isolate)), |
197 typed_data_(TypedData::Handle(isolate)), | 200 typed_data_(TypedData::Handle(isolate)), |
201 code_(Code::Handle(isolate)), | |
198 error_(UnhandledException::Handle(isolate)), | 202 error_(UnhandledException::Handle(isolate)), |
199 max_vm_isolate_object_id_( | 203 max_vm_isolate_object_id_( |
200 (kind == Snapshot::kFull) ? | 204 (kind == Snapshot::kFull) ? |
201 Object::vm_isolate_snapshot_object_table().Length() : 0), | 205 Object::vm_isolate_snapshot_object_table().Length() : 0), |
202 backward_references_(backward_refs) { | 206 backward_references_(backward_refs), |
207 instructions_reader_(NULL) { | |
208 if (instructions_buffer != NULL) { | |
209 instructions_reader_ = new InstructionsReader(instructions_buffer); | |
210 } | |
203 } | 211 } |
204 | 212 |
205 | 213 |
206 RawObject* SnapshotReader::ReadObject() { | 214 RawObject* SnapshotReader::ReadObject() { |
207 // Setup for long jump in case there is an exception while reading. | 215 // Setup for long jump in case there is an exception while reading. |
208 LongJumpScope jump; | 216 LongJumpScope jump; |
209 if (setjmp(*jump.Set()) == 0) { | 217 if (setjmp(*jump.Set()) == 0) { |
210 PassiveObject& obj = | 218 PassiveObject& obj = |
211 PassiveObject::Handle(isolate(), ReadObjectImpl(kAsInlinedObject)); | 219 PassiveObject::Handle(isolate(), ReadObjectImpl(kAsInlinedObject)); |
212 for (intptr_t i = 0; i < backward_references_->length(); i++) { | 220 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
498 } else { | 506 } else { |
499 *result ^= Object::Allocate(cls_.id(), | 507 *result ^= Object::Allocate(cls_.id(), |
500 instance_size, | 508 instance_size, |
501 HEAP_SPACE(kind_)); | 509 HEAP_SPACE(kind_)); |
502 } | 510 } |
503 } else { | 511 } else { |
504 cls_ ^= ReadObjectImpl(kAsInlinedObject); | 512 cls_ ^= ReadObjectImpl(kAsInlinedObject); |
505 ASSERT(!cls_.IsNull()); | 513 ASSERT(!cls_.IsNull()); |
506 instance_size = cls_.instance_size(); | 514 instance_size = cls_.instance_size(); |
507 } | 515 } |
508 intptr_t next_field_offset = cls_.next_field_offset(); | 516 intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw()) |
517 ? Closure::InstanceSize() : cls_.next_field_offset(); | |
518 | |
509 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); | 519 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
510 ASSERT(next_field_offset > 0); | 520 ASSERT(next_field_offset > 0); |
511 // Instance::NextFieldOffset() returns the offset of the first field in | 521 // Instance::NextFieldOffset() returns the offset of the first field in |
512 // a Dart object. | 522 // a Dart object. |
513 bool as_reference = RawObject::IsCanonical(tags) ? false : true; | 523 bool as_reference = RawObject::IsCanonical(tags) ? false : true; |
514 intptr_t offset = Instance::NextFieldOffset(); | 524 intptr_t offset = Instance::NextFieldOffset(); |
515 intptr_t result_cid = result->GetClassId(); | 525 intptr_t result_cid = result->GetClassId(); |
516 while (offset < next_field_offset) { | 526 while (offset < next_field_offset) { |
517 pobj_ = ReadObjectImpl(as_reference); | 527 pobj_ = ReadObjectImpl(as_reference); |
518 result->SetFieldAtOffset(offset, pobj_); | 528 result->SetFieldAtOffset(offset, pobj_); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
771 RawTwoByteString* SnapshotReader::NewTwoByteString(intptr_t len) { | 781 RawTwoByteString* SnapshotReader::NewTwoByteString(intptr_t len) { |
772 ALLOC_NEW_OBJECT_WITH_LEN(TwoByteString, len); | 782 ALLOC_NEW_OBJECT_WITH_LEN(TwoByteString, len); |
773 } | 783 } |
774 | 784 |
775 | 785 |
776 RawTypeArguments* SnapshotReader::NewTypeArguments(intptr_t len) { | 786 RawTypeArguments* SnapshotReader::NewTypeArguments(intptr_t len) { |
777 ALLOC_NEW_OBJECT_WITH_LEN(TypeArguments, len); | 787 ALLOC_NEW_OBJECT_WITH_LEN(TypeArguments, len); |
778 } | 788 } |
779 | 789 |
780 | 790 |
791 RawObjectPool* SnapshotReader::NewObjectPool(intptr_t len) { | |
792 ASSERT(kind_ == Snapshot::kFull); | |
793 ASSERT_NO_SAFEPOINT_SCOPE(); | |
794 RawObjectPool* obj = reinterpret_cast<RawObjectPool*>( | |
795 AllocateUninitialized(kObjectPoolCid, ObjectPool::InstanceSize(len))); | |
796 obj->ptr()->length_ = len; | |
797 return obj; | |
798 } | |
799 | |
800 | |
801 RawLocalVarDescriptors* SnapshotReader::NewLocalVarDescriptors( | |
802 intptr_t num_entries) { | |
803 ASSERT(kind_ == Snapshot::kFull); | |
804 ASSERT_NO_SAFEPOINT_SCOPE(); | |
805 RawLocalVarDescriptors* obj = reinterpret_cast<RawLocalVarDescriptors*>( | |
806 AllocateUninitialized(kLocalVarDescriptorsCid, | |
807 LocalVarDescriptors::InstanceSize(num_entries))); | |
808 obj->ptr()->num_entries_ = num_entries; | |
809 return obj; | |
810 } | |
811 | |
812 | |
813 RawExceptionHandlers* SnapshotReader::NewExceptionHandlers( | |
814 intptr_t num_entries) { | |
815 ASSERT(kind_ == Snapshot::kFull); | |
816 ASSERT_NO_SAFEPOINT_SCOPE(); | |
817 RawExceptionHandlers* obj = reinterpret_cast<RawExceptionHandlers*>( | |
818 AllocateUninitialized(kExceptionHandlersCid, | |
819 ExceptionHandlers::InstanceSize(num_entries))); | |
820 obj->ptr()->num_entries_ = num_entries; | |
821 return obj; | |
822 } | |
823 | |
824 | |
825 RawPcDescriptors* SnapshotReader::NewPcDescriptors(intptr_t len) { | |
826 ASSERT(kind_ == Snapshot::kFull); | |
827 ASSERT_NO_SAFEPOINT_SCOPE(); | |
828 RawPcDescriptors* obj = reinterpret_cast<RawPcDescriptors*>( | |
829 AllocateUninitialized(kPcDescriptorsCid, | |
830 PcDescriptors::InstanceSize(len))); | |
831 obj->ptr()->length_ = len; | |
832 return obj; | |
833 } | |
834 | |
835 | |
836 RawStackmap* SnapshotReader::NewStackmap(intptr_t len) { | |
837 ASSERT(kind_ == Snapshot::kFull); | |
838 ASSERT_NO_SAFEPOINT_SCOPE(); | |
839 RawStackmap* obj = reinterpret_cast<RawStackmap*>( | |
840 AllocateUninitialized(kStackmapCid, Stackmap::InstanceSize(len))); | |
841 obj->ptr()->length_ = len; | |
842 return obj; | |
843 } | |
844 | |
845 | |
846 RawCode* SnapshotReader::NewCode(intptr_t pointer_offsets_length) { | |
847 ASSERT(pointer_offsets_length == 0); | |
848 ASSERT(kind_ == Snapshot::kFull); | |
849 ASSERT_NO_SAFEPOINT_SCOPE(); | |
850 RawCode* obj = reinterpret_cast<RawCode*>( | |
851 AllocateUninitialized(kCodeCid, Code::InstanceSize(0))); | |
852 return obj; | |
853 } | |
854 | |
855 | |
781 RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) { | 856 RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) { |
782 ASSERT(kind_ == Snapshot::kFull); | 857 ASSERT(kind_ == Snapshot::kFull); |
783 ASSERT_NO_SAFEPOINT_SCOPE(); | 858 ASSERT_NO_SAFEPOINT_SCOPE(); |
784 stream_ = reinterpret_cast<RawTokenStream*>( | 859 stream_ = reinterpret_cast<RawTokenStream*>( |
785 AllocateUninitialized(kTokenStreamCid, TokenStream::InstanceSize())); | 860 AllocateUninitialized(kTokenStreamCid, TokenStream::InstanceSize())); |
786 uint8_t* array = const_cast<uint8_t*>(CurrentBufferAddress()); | 861 uint8_t* array = const_cast<uint8_t*>(CurrentBufferAddress()); |
787 ASSERT(array != NULL); | 862 ASSERT(array != NULL); |
788 Advance(len); | 863 Advance(len); |
789 data_ = reinterpret_cast<RawExternalTypedData*>( | 864 data_ = reinterpret_cast<RawExternalTypedData*>( |
790 AllocateUninitialized(kExternalTypedDataUint8ArrayCid, | 865 AllocateUninitialized(kExternalTypedDataUint8ArrayCid, |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
920 RawRedirectionData* SnapshotReader::NewRedirectionData() { | 995 RawRedirectionData* SnapshotReader::NewRedirectionData() { |
921 ALLOC_NEW_OBJECT(RedirectionData); | 996 ALLOC_NEW_OBJECT(RedirectionData); |
922 } | 997 } |
923 | 998 |
924 | 999 |
925 RawFunction* SnapshotReader::NewFunction() { | 1000 RawFunction* SnapshotReader::NewFunction() { |
926 ALLOC_NEW_OBJECT(Function); | 1001 ALLOC_NEW_OBJECT(Function); |
927 } | 1002 } |
928 | 1003 |
929 | 1004 |
930 RawCode* SnapshotReader::NewCode(intptr_t pointer_offsets_length) { | |
931 ASSERT(pointer_offsets_length == 0); | |
932 ALLOC_NEW_OBJECT(Code); | |
933 } | |
934 | |
935 | |
936 RawObjectPool* SnapshotReader::NewObjectPool(intptr_t length) { | |
937 ALLOC_NEW_OBJECT(ObjectPool); | |
938 } | |
939 | |
940 | |
941 RawICData* SnapshotReader::NewICData() { | 1005 RawICData* SnapshotReader::NewICData() { |
942 ALLOC_NEW_OBJECT(ICData); | 1006 ALLOC_NEW_OBJECT(ICData); |
943 } | 1007 } |
944 | 1008 |
945 | 1009 |
1010 RawLinkedHashMap* SnapshotReader::NewLinkedHashMap() { | |
1011 ALLOC_NEW_OBJECT(LinkedHashMap); | |
1012 } | |
1013 | |
1014 | |
946 RawMegamorphicCache* SnapshotReader::NewMegamorphicCache() { | 1015 RawMegamorphicCache* SnapshotReader::NewMegamorphicCache() { |
947 ALLOC_NEW_OBJECT(MegamorphicCache); | 1016 ALLOC_NEW_OBJECT(MegamorphicCache); |
948 } | 1017 } |
949 | 1018 |
950 | 1019 |
951 RawSubtypeTestCache* SnapshotReader::NewSubtypeTestCache() { | 1020 RawSubtypeTestCache* SnapshotReader::NewSubtypeTestCache() { |
952 ALLOC_NEW_OBJECT(SubtypeTestCache); | 1021 ALLOC_NEW_OBJECT(SubtypeTestCache); |
953 } | 1022 } |
954 | 1023 |
955 | 1024 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1053 } | 1122 } |
1054 return Mint::NewCanonical(value); | 1123 return Mint::NewCanonical(value); |
1055 } | 1124 } |
1056 | 1125 |
1057 | 1126 |
1058 RawStacktrace* SnapshotReader::NewStacktrace() { | 1127 RawStacktrace* SnapshotReader::NewStacktrace() { |
1059 ALLOC_NEW_OBJECT(Stacktrace); | 1128 ALLOC_NEW_OBJECT(Stacktrace); |
1060 } | 1129 } |
1061 | 1130 |
1062 | 1131 |
1063 RawInstructions* SnapshotReader::GetInstructionsById(int32_t id) { | 1132 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) { |
1064 // TODO(rmacnak): Read from shared library. | 1133 // Instructions are allocated with the code alignment and we don't write |
1134 // anything else in the text section. | |
1135 ASSERT(Utils::IsAligned(stream_.bytes_written(), | |
1136 OS::PreferredCodeAlignment())); | |
1137 | |
1138 intptr_t offset = stream_.bytes_written(); | |
1139 stream_.WriteBytes(reinterpret_cast<uint8_t*>(instructions) - kHeapObjectTag, | |
1140 instructions->Size()); | |
1141 return offset; | |
1142 } | |
1143 | |
1144 | |
1145 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset, | |
1146 uword expected_tags) { | |
1147 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); | |
1148 | |
1149 RawInstructions* result = | |
1150 reinterpret_cast<RawInstructions*>( | |
1151 reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); | |
1152 | |
1153 uword actual_tags = result->ptr()->tags_; | |
1154 if (actual_tags != expected_tags) { | |
1155 FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, | |
1156 expected_tags, | |
1157 actual_tags); | |
1158 } | |
1159 | |
1160 // TODO(rmacnak): The above contains stale pointers to a Code and an | |
1161 // ObjectPool. Return the actual result after calling convention change. | |
1065 return Instructions::null(); | 1162 return Instructions::null(); |
1066 } | 1163 } |
1067 | 1164 |
1068 | 1165 |
1069 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { | 1166 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { |
1070 // If the header is an object Id, lookup singleton VM classes or classes | 1167 // If the header is an object Id, lookup singleton VM classes or classes |
1071 // stored in the object store. | 1168 // stored in the object store. |
1072 if (IsVMIsolateObject(class_header)) { | 1169 if (IsVMIsolateObject(class_header)) { |
1073 intptr_t class_id = GetVMIsolateObjectId(class_header); | 1170 intptr_t class_id = GetVMIsolateObjectId(class_header); |
1074 ASSERT(IsSingletonClassId(class_id)); | 1171 ASSERT(IsSingletonClassId(class_id)); |
1075 return class_id; | 1172 return class_id; |
1076 } | 1173 } |
1077 ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId); | 1174 ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId); |
1078 intptr_t class_id = SerializedHeaderData::decode(class_header); | 1175 intptr_t class_id = SerializedHeaderData::decode(class_header); |
1079 ASSERT(IsObjectStoreClassId(class_id)); | 1176 ASSERT(IsObjectStoreClassId(class_id) || IsSingletonClassId(class_id)); |
1080 return class_id; | 1177 return class_id; |
1081 } | 1178 } |
1082 | 1179 |
1083 | 1180 |
1084 RawObject* SnapshotReader::AllocateUninitialized(intptr_t class_id, | 1181 RawObject* SnapshotReader::AllocateUninitialized(intptr_t class_id, |
1085 intptr_t size) { | 1182 intptr_t size) { |
1086 ASSERT_NO_SAFEPOINT_SCOPE(); | 1183 ASSERT_NO_SAFEPOINT_SCOPE(); |
1087 ASSERT(Utils::IsAligned(size, kObjectAlignment)); | 1184 ASSERT(Utils::IsAligned(size, kObjectAlignment)); |
1088 | 1185 |
1089 // Allocate memory where all words look like smis. This is currently | 1186 // Allocate memory where all words look like smis. This is currently |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1258 reinterpret_cast<RawObject**>(result.raw()->ptr()); | 1355 reinterpret_cast<RawObject**>(result.raw()->ptr()); |
1259 for (intptr_t i = 0; i < len; i++) { | 1356 for (intptr_t i = 0; i < len; i++) { |
1260 *PassiveObjectHandle() = ReadObjectImpl(as_reference, | 1357 *PassiveObjectHandle() = ReadObjectImpl(as_reference, |
1261 object_id, | 1358 object_id, |
1262 (i + offset)); | 1359 (i + offset)); |
1263 result.SetAt(i, *PassiveObjectHandle()); | 1360 result.SetAt(i, *PassiveObjectHandle()); |
1264 } | 1361 } |
1265 } | 1362 } |
1266 | 1363 |
1267 | 1364 |
1268 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, | 1365 VmIsolateSnapshotReader::VmIsolateSnapshotReader( |
1269 intptr_t size, | 1366 const uint8_t* buffer, |
1270 Zone* zone) | 1367 intptr_t size, |
1271 : SnapshotReader(buffer, | 1368 const uint8_t* instructions_buffer, |
1272 size, | 1369 Zone* zone) |
1273 Snapshot::kFull, | 1370 : SnapshotReader(buffer, |
1274 new ZoneGrowableArray<BackRefNode>( | 1371 size, |
1275 kNumVmIsolateSnapshotReferences), | 1372 instructions_buffer, |
1276 Dart::vm_isolate(), | 1373 Snapshot::kFull, |
1277 zone) { | 1374 new ZoneGrowableArray<BackRefNode>( |
1375 kNumVmIsolateSnapshotReferences), | |
1376 Dart::vm_isolate(), | |
1377 zone) { | |
1278 } | 1378 } |
1279 | 1379 |
1280 | 1380 |
1281 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { | 1381 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { |
1282 intptr_t len = GetBackwardReferenceTable()->length(); | 1382 intptr_t len = GetBackwardReferenceTable()->length(); |
1283 Object::InitVmIsolateSnapshotObjectTable(len); | 1383 Object::InitVmIsolateSnapshotObjectTable(len); |
1284 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable(); | 1384 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable(); |
1285 for (intptr_t i = 0; i < len; i++) { | 1385 for (intptr_t i = 0; i < len; i++) { |
1286 Object::vm_isolate_snapshot_object_table().SetAt( | 1386 Object::vm_isolate_snapshot_object_table().SetAt( |
1287 i, *(backrefs->At(i).reference())); | 1387 i, *(backrefs->At(i).reference())); |
1288 } | 1388 } |
1289 ResetBackwardReferenceTable(); | 1389 ResetBackwardReferenceTable(); |
1390 Object::set_instructions_snapshot_buffer(instructions_buffer_); | |
1290 } | 1391 } |
1291 | 1392 |
1292 | 1393 |
1293 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { | 1394 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
1294 ASSERT(kind() == Snapshot::kFull); | 1395 ASSERT(kind() == Snapshot::kFull); |
1295 Isolate* isolate = Isolate::Current(); | 1396 Isolate* isolate = Isolate::Current(); |
1296 ASSERT(isolate != NULL); | 1397 ASSERT(isolate != NULL); |
1297 ASSERT(isolate == Dart::vm_isolate()); | 1398 ASSERT(isolate == Dart::vm_isolate()); |
1298 ObjectStore* object_store = isolate->object_store(); | 1399 ObjectStore* object_store = isolate->object_store(); |
1299 ASSERT(object_store != NULL); | 1400 ASSERT(object_store != NULL); |
(...skipping 13 matching lines...) Expand all Loading... | |
1313 // Read in the symbol table. | 1414 // Read in the symbol table. |
1314 object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject()); | 1415 object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject()); |
1315 | 1416 |
1316 Symbols::InitOnceFromSnapshot(isolate); | 1417 Symbols::InitOnceFromSnapshot(isolate); |
1317 | 1418 |
1318 // Read in all the script objects and the accompanying token streams | 1419 // Read in all the script objects and the accompanying token streams |
1319 // for bootstrap libraries so that they are in the VM isolate's read | 1420 // for bootstrap libraries so that they are in the VM isolate's read |
1320 // only memory. | 1421 // only memory. |
1321 *(ArrayHandle()) ^= ReadObject(); | 1422 *(ArrayHandle()) ^= ReadObject(); |
1322 | 1423 |
1424 | |
1425 if (snapshot_code()) { | |
1426 for (intptr_t i = 0; | |
1427 i < ArgumentsDescriptor::kCachedDescriptorCount; | |
1428 i++) { | |
1429 *(ArrayHandle()) ^= ReadObject(); | |
1430 // TODO(rmacnak): | |
1431 // ArgumentsDescriptor::InitOnceFromSnapshot(i, *(ArrayHandle())); | |
1432 } | |
1433 | |
1434 ObjectPool::CheckedHandle(ReadObject()); // empty pool | |
1435 PcDescriptors::CheckedHandle(ReadObject()); // empty pc desc | |
1436 LocalVarDescriptors::CheckedHandle(ReadObject()); // empty var desc | |
1437 ExceptionHandlers::CheckedHandle(ReadObject()); // empty exc handlers | |
1438 | |
1439 #define READ_STUB(name) \ | |
1440 *(CodeHandle()) ^= ReadObject(); | |
1441 // TODO(rmacnak): | |
1442 // StubCode::name##_entry()->InitOnceFromSnapshot(CodeHandle()) | |
1443 VM_STUB_CODE_LIST(READ_STUB); | |
1444 #undef READ_STUB | |
1445 } | |
1446 | |
1323 // Validate the class table. | 1447 // Validate the class table. |
1324 #if defined(DEBUG) | 1448 #if defined(DEBUG) |
1325 isolate->ValidateClassTable(); | 1449 isolate->ValidateClassTable(); |
1326 #endif | 1450 #endif |
1327 | 1451 |
1328 return ApiError::null(); | 1452 return ApiError::null(); |
1329 } | 1453 } |
1330 } | 1454 } |
1331 | 1455 |
1332 | 1456 |
1333 IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer, | 1457 IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer, |
1334 intptr_t size, | 1458 intptr_t size, |
1459 const uint8_t* instructions_buffer, | |
1335 Isolate* isolate, | 1460 Isolate* isolate, |
1336 Zone* zone) | 1461 Zone* zone) |
1337 : SnapshotReader(buffer, | 1462 : SnapshotReader(buffer, |
1338 size, | 1463 size, |
1464 instructions_buffer, | |
1339 Snapshot::kFull, | 1465 Snapshot::kFull, |
1340 new ZoneGrowableArray<BackRefNode>( | 1466 new ZoneGrowableArray<BackRefNode>( |
1341 kNumInitialReferencesInFullSnapshot), | 1467 kNumInitialReferencesInFullSnapshot), |
1342 isolate, | 1468 isolate, |
1343 zone) { | 1469 zone) { |
1344 } | 1470 } |
1345 | 1471 |
1346 | 1472 |
1347 IsolateSnapshotReader::~IsolateSnapshotReader() { | 1473 IsolateSnapshotReader::~IsolateSnapshotReader() { |
1348 ResetBackwardReferenceTable(); | 1474 ResetBackwardReferenceTable(); |
1349 } | 1475 } |
1350 | 1476 |
1351 | 1477 |
1352 ScriptSnapshotReader::ScriptSnapshotReader(const uint8_t* buffer, | 1478 ScriptSnapshotReader::ScriptSnapshotReader(const uint8_t* buffer, |
1353 intptr_t size, | 1479 intptr_t size, |
1354 Isolate* isolate, | 1480 Isolate* isolate, |
1355 Zone* zone) | 1481 Zone* zone) |
1356 : SnapshotReader(buffer, | 1482 : SnapshotReader(buffer, |
1357 size, | 1483 size, |
1484 NULL, /* instructions_buffer */ | |
1358 Snapshot::kScript, | 1485 Snapshot::kScript, |
1359 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), | 1486 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), |
1360 isolate, | 1487 isolate, |
1361 zone) { | 1488 zone) { |
1362 } | 1489 } |
1363 | 1490 |
1364 | 1491 |
1365 ScriptSnapshotReader::~ScriptSnapshotReader() { | 1492 ScriptSnapshotReader::~ScriptSnapshotReader() { |
1366 ResetBackwardReferenceTable(); | 1493 ResetBackwardReferenceTable(); |
1367 } | 1494 } |
1368 | 1495 |
1369 | 1496 |
1370 MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer, | 1497 MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer, |
1371 intptr_t size, | 1498 intptr_t size, |
1372 Isolate* isolate, | 1499 Isolate* isolate, |
1373 Zone* zone) | 1500 Zone* zone) |
1374 : SnapshotReader(buffer, | 1501 : SnapshotReader(buffer, |
1375 size, | 1502 size, |
1503 NULL, /* instructions_buffer */ | |
1376 Snapshot::kMessage, | 1504 Snapshot::kMessage, |
1377 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), | 1505 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), |
1378 isolate, | 1506 isolate, |
1379 zone) { | 1507 zone) { |
1380 } | 1508 } |
1381 | 1509 |
1382 | 1510 |
1383 MessageSnapshotReader::~MessageSnapshotReader() { | 1511 MessageSnapshotReader::~MessageSnapshotReader() { |
1384 ResetBackwardReferenceTable(); | 1512 ResetBackwardReferenceTable(); |
1385 } | 1513 } |
1386 | 1514 |
1387 | 1515 |
1388 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, | 1516 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, |
1389 uint8_t** buffer, | 1517 uint8_t** buffer, |
1390 ReAlloc alloc, | 1518 ReAlloc alloc, |
1391 intptr_t initial_size, | 1519 intptr_t initial_size, |
1392 ForwardList* forward_list, | 1520 ForwardList* forward_list, |
1521 InstructionsWriter* instructions_writer, | |
1393 bool can_send_any_object, | 1522 bool can_send_any_object, |
1394 bool snapshot_code) | 1523 bool snapshot_code, |
1524 bool vm_isolate_is_symbolic) | |
1395 : BaseWriter(buffer, alloc, initial_size), | 1525 : BaseWriter(buffer, alloc, initial_size), |
1396 kind_(kind), | 1526 kind_(kind), |
1397 isolate_(Isolate::Current()), | 1527 isolate_(Isolate::Current()), |
1398 object_store_(isolate_->object_store()), | 1528 object_store_(isolate_->object_store()), |
1399 class_table_(isolate_->class_table()), | 1529 class_table_(isolate_->class_table()), |
1400 forward_list_(forward_list), | 1530 forward_list_(forward_list), |
1531 instructions_writer_(instructions_writer), | |
1401 exception_type_(Exceptions::kNone), | 1532 exception_type_(Exceptions::kNone), |
1402 exception_msg_(NULL), | 1533 exception_msg_(NULL), |
1403 unmarked_objects_(false), | 1534 unmarked_objects_(false), |
1404 can_send_any_object_(can_send_any_object), | 1535 can_send_any_object_(can_send_any_object), |
1405 snapshot_code_(snapshot_code) { | 1536 snapshot_code_(snapshot_code), |
1537 vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { | |
1406 ASSERT(forward_list_ != NULL); | 1538 ASSERT(forward_list_ != NULL); |
1407 } | 1539 } |
1408 | 1540 |
1409 | 1541 |
1410 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1542 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
1411 WriteObjectImpl(rawobj, kAsInlinedObject); | 1543 WriteObjectImpl(rawobj, kAsInlinedObject); |
1412 WriteForwardedObjects(); | 1544 WriteForwardedObjects(); |
1413 } | 1545 } |
1414 | 1546 |
1415 #define VM_OBJECT_CLASS_LIST(V) \ | 1547 #define VM_OBJECT_CLASS_LIST(V) \ |
1416 V(OneByteString) \ | 1548 V(OneByteString) \ |
1417 V(Mint) \ | 1549 V(Mint) \ |
1418 V(Bigint) \ | 1550 V(Bigint) \ |
1419 V(Double) \ | 1551 V(Double) \ |
1420 | 1552 |
1421 #define VM_OBJECT_WRITE(clazz) \ | 1553 #define VM_OBJECT_WRITE(clazz) \ |
1422 case clazz::kClassId: { \ | 1554 case clazz::kClassId: { \ |
1423 object_id = forward_list_->AddObject(rawobj, kIsSerialized); \ | 1555 object_id = forward_list_->AddObject(rawobj, kIsSerialized); \ |
1424 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \ | 1556 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \ |
1425 raw_obj->WriteTo(this, object_id, kind()); \ | 1557 raw_obj->WriteTo(this, object_id, kind()); \ |
1426 return; \ | 1558 return true; \ |
1427 } \ | 1559 } \ |
1428 | 1560 |
1429 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { | 1561 bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
1430 // Check if it is a singleton null object. | 1562 // Check if it is a singleton null object. |
1431 if (rawobj == Object::null()) { | 1563 if (rawobj == Object::null()) { |
1432 WriteVMIsolateObject(kNullObject); | 1564 WriteVMIsolateObject(kNullObject); |
1433 return; | 1565 return true; |
1434 } | 1566 } |
1435 | 1567 |
1436 // Check if it is a singleton sentinel object. | 1568 // Check if it is a singleton sentinel object. |
1437 if (rawobj == Object::sentinel().raw()) { | 1569 if (rawobj == Object::sentinel().raw()) { |
1438 WriteVMIsolateObject(kSentinelObject); | 1570 WriteVMIsolateObject(kSentinelObject); |
1439 return; | 1571 return true; |
1440 } | 1572 } |
1441 | 1573 |
1442 // Check if it is a singleton sentinel object. | 1574 // Check if it is a singleton sentinel object. |
1443 if (rawobj == Object::transition_sentinel().raw()) { | 1575 if (rawobj == Object::transition_sentinel().raw()) { |
1444 WriteVMIsolateObject(kTransitionSentinelObject); | 1576 WriteVMIsolateObject(kTransitionSentinelObject); |
1445 return; | 1577 return true; |
1446 } | 1578 } |
1447 | 1579 |
1448 // Check if it is a singleton empty array object. | 1580 // Check if it is a singleton empty array object. |
1449 if (rawobj == Object::empty_array().raw()) { | 1581 if (rawobj == Object::empty_array().raw()) { |
1450 WriteVMIsolateObject(kEmptyArrayObject); | 1582 WriteVMIsolateObject(kEmptyArrayObject); |
1451 return; | 1583 return true; |
1452 } | 1584 } |
1453 | 1585 |
1454 // Check if it is a singleton zero array object. | 1586 // Check if it is a singleton zero array object. |
1455 if (rawobj == Object::zero_array().raw()) { | 1587 if (rawobj == Object::zero_array().raw()) { |
1456 WriteVMIsolateObject(kZeroArrayObject); | 1588 WriteVMIsolateObject(kZeroArrayObject); |
1457 return; | 1589 return true; |
1458 } | 1590 } |
1459 | 1591 |
1460 // Check if it is a singleton dyanmic Type object. | 1592 // Check if it is a singleton dyanmic Type object. |
1461 if (rawobj == Object::dynamic_type()) { | 1593 if (rawobj == Object::dynamic_type()) { |
1462 WriteVMIsolateObject(kDynamicType); | 1594 WriteVMIsolateObject(kDynamicType); |
1463 return; | 1595 return true; |
1464 } | 1596 } |
1465 | 1597 |
1466 // Check if it is a singleton void Type object. | 1598 // Check if it is a singleton void Type object. |
1467 if (rawobj == Object::void_type()) { | 1599 if (rawobj == Object::void_type()) { |
1468 WriteVMIsolateObject(kVoidType); | 1600 WriteVMIsolateObject(kVoidType); |
1469 return; | 1601 return true; |
1470 } | 1602 } |
1471 | 1603 |
1472 // Check if it is a singleton boolean true object. | 1604 // Check if it is a singleton boolean true object. |
1473 if (rawobj == Bool::True().raw()) { | 1605 if (rawobj == Bool::True().raw()) { |
1474 WriteVMIsolateObject(kTrueValue); | 1606 WriteVMIsolateObject(kTrueValue); |
1475 return; | 1607 return true; |
1476 } | 1608 } |
1477 | 1609 |
1478 // Check if it is a singleton boolean false object. | 1610 // Check if it is a singleton boolean false object. |
1479 if (rawobj == Bool::False().raw()) { | 1611 if (rawobj == Bool::False().raw()) { |
1480 WriteVMIsolateObject(kFalseValue); | 1612 WriteVMIsolateObject(kFalseValue); |
1481 return; | 1613 return true; |
1482 } | 1614 } |
1483 | 1615 |
1484 // Check if it is a singleton class object which is shared by | 1616 // Check if it is a singleton class object which is shared by |
1485 // all isolates. | 1617 // all isolates. |
1486 intptr_t id = rawobj->GetClassId(); | 1618 intptr_t id = rawobj->GetClassId(); |
1487 if (id == kClassCid) { | 1619 if (id == kClassCid) { |
1488 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); | 1620 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); |
1489 intptr_t class_id = raw_class->ptr()->id_; | 1621 intptr_t class_id = raw_class->ptr()->id_; |
1490 if (IsSingletonClassId(class_id)) { | 1622 if (IsSingletonClassId(class_id)) { |
1491 intptr_t object_id = ObjectIdFromClassId(class_id); | 1623 intptr_t object_id = ObjectIdFromClassId(class_id); |
1492 WriteVMIsolateObject(object_id); | 1624 WriteVMIsolateObject(object_id); |
1493 return; | 1625 return true; |
1494 } | 1626 } |
1495 } | 1627 } |
1496 | 1628 |
1629 if (!vm_isolate_is_symbolic()) { | |
1630 return false; | |
1631 } | |
siva
2015/09/01 20:58:49
Maybe move this down to the end as discussed offli
rmacnak
2015/09/01 23:43:48
Done.
| |
1632 | |
1497 if (kind() == Snapshot::kFull) { | 1633 if (kind() == Snapshot::kFull) { |
1498 // Check it is a predefined symbol in the VM isolate. | 1634 // Check it is a predefined symbol in the VM isolate. |
1499 id = Symbols::LookupVMSymbol(rawobj); | 1635 id = Symbols::LookupVMSymbol(rawobj); |
1500 if (id != kInvalidIndex) { | 1636 if (id != kInvalidIndex) { |
1501 WriteVMIsolateObject(id); | 1637 WriteVMIsolateObject(id); |
1502 return; | 1638 return true; |
1503 } | 1639 } |
1504 | 1640 |
1505 // Check if it is an object from the vm isolate snapshot object table. | 1641 // Check if it is an object from the vm isolate snapshot object table. |
1506 id = FindVmSnapshotObject(rawobj); | 1642 id = FindVmSnapshotObject(rawobj); |
1507 if (id != kInvalidIndex) { | 1643 if (id != kInvalidIndex) { |
1508 WriteIndexedObject(id); | 1644 WriteIndexedObject(id); |
1509 return; | 1645 return true; |
1510 } | 1646 } |
1511 } else { | 1647 } else { |
1512 // In the case of script snapshots or for messages we do not use | 1648 // In the case of script snapshots or for messages we do not use |
1513 // the index into the vm isolate snapshot object table, instead we | 1649 // the index into the vm isolate snapshot object table, instead we |
1514 // explicitly write the object out. | 1650 // explicitly write the object out. |
1515 intptr_t object_id = forward_list_->FindObject(rawobj); | 1651 intptr_t object_id = forward_list_->FindObject(rawobj); |
1516 if (object_id != -1) { | 1652 if (object_id != -1) { |
1517 WriteIndexedObject(object_id); | 1653 WriteIndexedObject(object_id); |
1518 return; | 1654 return true; |
1519 } else { | 1655 } else { |
1520 switch (id) { | 1656 switch (id) { |
1521 VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE) | 1657 VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE) |
1522 case kTypedDataUint32ArrayCid: { | 1658 case kTypedDataUint32ArrayCid: { |
1523 object_id = forward_list_->AddObject(rawobj, kIsSerialized); | 1659 object_id = forward_list_->AddObject(rawobj, kIsSerialized); |
1524 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj); | 1660 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj); |
1525 raw_obj->WriteTo(this, object_id, kind()); | 1661 raw_obj->WriteTo(this, object_id, kind()); |
1526 return; | 1662 return true; |
1527 } | 1663 } |
1528 default: | 1664 default: |
1529 OS::Print("class id = %" Pd "\n", id); | 1665 OS::Print("class id = %" Pd "\n", id); |
1530 break; | 1666 break; |
1531 } | 1667 } |
1532 } | 1668 } |
1533 } | 1669 } |
1534 | 1670 |
1535 const Object& obj = Object::Handle(rawobj); | 1671 const Object& obj = Object::Handle(rawobj); |
1536 FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString()); | 1672 FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString()); |
1673 return false; | |
1537 } | 1674 } |
1538 | 1675 |
1539 #undef VM_OBJECT_WRITE | 1676 #undef VM_OBJECT_WRITE |
1540 | 1677 |
1541 | 1678 |
1542 // An object visitor which will iterate over all the script objects in the heap | 1679 // An object visitor which will iterate over all the script objects in the heap |
1543 // and either count them or collect them into an array. This is used during | 1680 // and either count them or collect them into an array. This is used during |
1544 // full snapshot generation of the VM isolate to write out all script | 1681 // full snapshot generation of the VM isolate to write out all script |
1545 // objects and their accompanying token streams. | 1682 // objects and their accompanying token streams. |
1546 class ScriptVisitor : public ObjectVisitor { | 1683 class ScriptVisitor : public ObjectVisitor { |
(...skipping 24 matching lines...) Expand all Loading... | |
1571 | 1708 |
1572 private: | 1709 private: |
1573 Object& objHandle_; | 1710 Object& objHandle_; |
1574 intptr_t count_; | 1711 intptr_t count_; |
1575 const Array* scripts_; | 1712 const Array* scripts_; |
1576 }; | 1713 }; |
1577 | 1714 |
1578 | 1715 |
1579 FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, | 1716 FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, |
1580 uint8_t** isolate_snapshot_buffer, | 1717 uint8_t** isolate_snapshot_buffer, |
1718 uint8_t** instructions_snapshot_buffer, | |
1581 ReAlloc alloc, | 1719 ReAlloc alloc, |
1582 bool snapshot_code) | 1720 bool snapshot_code, |
1721 bool vm_isolate_is_symbolic) | |
1583 : isolate_(Isolate::Current()), | 1722 : isolate_(Isolate::Current()), |
1584 vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer), | 1723 vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer), |
1585 isolate_snapshot_buffer_(isolate_snapshot_buffer), | 1724 isolate_snapshot_buffer_(isolate_snapshot_buffer), |
1725 instructions_snapshot_buffer_(instructions_snapshot_buffer), | |
1586 alloc_(alloc), | 1726 alloc_(alloc), |
1587 vm_isolate_snapshot_size_(0), | 1727 vm_isolate_snapshot_size_(0), |
1588 isolate_snapshot_size_(0), | 1728 isolate_snapshot_size_(0), |
1729 instructions_snapshot_size_(0), | |
1589 forward_list_(NULL), | 1730 forward_list_(NULL), |
1731 instructions_writer_(NULL), | |
1590 scripts_(Array::Handle(isolate_)), | 1732 scripts_(Array::Handle(isolate_)), |
1591 symbol_table_(Array::Handle(isolate_)), | 1733 symbol_table_(Array::Handle(isolate_)), |
1592 snapshot_code_(snapshot_code) { | 1734 snapshot_code_(snapshot_code), |
1735 vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { | |
1593 ASSERT(isolate_snapshot_buffer_ != NULL); | 1736 ASSERT(isolate_snapshot_buffer_ != NULL); |
1594 ASSERT(alloc_ != NULL); | 1737 ASSERT(alloc_ != NULL); |
1595 ASSERT(isolate_ != NULL); | 1738 ASSERT(isolate_ != NULL); |
1596 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1739 ASSERT(ClassFinalizer::AllClassesFinalized()); |
1597 ObjectStore* object_store = isolate_->object_store(); | 1740 ObjectStore* object_store = isolate_->object_store(); |
1598 ASSERT(object_store != NULL); | 1741 ASSERT(object_store != NULL); |
1599 Heap* heap = isolate_->heap(); | 1742 Heap* heap = isolate_->heap(); |
1600 ASSERT(heap != NULL); | 1743 ASSERT(heap != NULL); |
1601 // Ensure the class table is valid. | 1744 // Ensure the class table is valid. |
1602 #if defined(DEBUG) | 1745 #if defined(DEBUG) |
(...skipping 13 matching lines...) Expand all Loading... | |
1616 heap->IterateOldObjects(&script_visitor); | 1759 heap->IterateOldObjects(&script_visitor); |
1617 | 1760 |
1618 // Stash the symbol table away for writing and reading into the vm isolate, | 1761 // Stash the symbol table away for writing and reading into the vm isolate, |
1619 // and reset the symbol table for the regular isolate so that we do not | 1762 // and reset the symbol table for the regular isolate so that we do not |
1620 // write these symbols into the snapshot of a regular dart isolate. | 1763 // write these symbols into the snapshot of a regular dart isolate. |
1621 symbol_table_ = object_store->symbol_table(); | 1764 symbol_table_ = object_store->symbol_table(); |
1622 Symbols::SetupSymbolTable(isolate_); | 1765 Symbols::SetupSymbolTable(isolate_); |
1623 | 1766 |
1624 forward_list_ = new ForwardList(SnapshotWriter::FirstObjectId()); | 1767 forward_list_ = new ForwardList(SnapshotWriter::FirstObjectId()); |
1625 ASSERT(forward_list_ != NULL); | 1768 ASSERT(forward_list_ != NULL); |
1769 | |
1770 if (instructions_snapshot_buffer != NULL) { | |
1771 instructions_writer_ = new InstructionsWriter(instructions_snapshot_buffer, | |
1772 alloc, | |
1773 kInitialSize); | |
1774 } | |
1626 } | 1775 } |
1627 | 1776 |
1628 | 1777 |
1629 FullSnapshotWriter::~FullSnapshotWriter() { | 1778 FullSnapshotWriter::~FullSnapshotWriter() { |
1630 delete forward_list_; | 1779 delete forward_list_; |
1631 symbol_table_ = Array::null(); | 1780 symbol_table_ = Array::null(); |
1632 scripts_ = Array::null(); | 1781 scripts_ = Array::null(); |
1633 } | 1782 } |
1634 | 1783 |
1635 | 1784 |
1636 void FullSnapshotWriter::WriteVmIsolateSnapshot() { | 1785 void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
1637 ASSERT(vm_isolate_snapshot_buffer_ != NULL); | 1786 ASSERT(vm_isolate_snapshot_buffer_ != NULL); |
1638 SnapshotWriter writer(Snapshot::kFull, | 1787 SnapshotWriter writer(Snapshot::kFull, |
1639 vm_isolate_snapshot_buffer_, | 1788 vm_isolate_snapshot_buffer_, |
1640 alloc_, | 1789 alloc_, |
1641 kInitialSize, | 1790 kInitialSize, |
1642 forward_list_, | 1791 forward_list_, |
1792 instructions_writer_, | |
1643 true, /* can_send_any_object */ | 1793 true, /* can_send_any_object */ |
1644 snapshot_code_); | 1794 snapshot_code_, |
1795 vm_isolate_is_symbolic_); | |
1645 // Write full snapshot for the VM isolate. | 1796 // Write full snapshot for the VM isolate. |
1646 // Setup for long jump in case there is an exception while writing | 1797 // Setup for long jump in case there is an exception while writing |
1647 // the snapshot. | 1798 // the snapshot. |
1648 LongJumpScope jump; | 1799 LongJumpScope jump; |
1649 if (setjmp(*jump.Set()) == 0) { | 1800 if (setjmp(*jump.Set()) == 0) { |
1650 // Reserve space in the output buffer for a snapshot header. | 1801 // Reserve space in the output buffer for a snapshot header. |
1651 writer.ReserveHeader(); | 1802 writer.ReserveHeader(); |
1652 | 1803 |
1653 // Write out the version string. | 1804 // Write out the version string. |
1654 writer.WriteVersion(); | 1805 writer.WriteVersion(); |
1655 | 1806 |
1656 /* | 1807 /* |
1657 * Now Write out the following | 1808 * Now Write out the following |
1658 * - the symbol table | 1809 * - the symbol table |
1659 * - all the scripts and token streams for these scripts | 1810 * - all the scripts and token streams for these scripts |
1660 * | 1811 * |
1661 **/ | 1812 **/ |
1662 // Write out the symbol table. | 1813 // Write out the symbol table. |
1663 writer.WriteObject(symbol_table_.raw()); | 1814 writer.WriteObject(symbol_table_.raw()); |
1664 | 1815 |
1665 // Write out all the script objects and the accompanying token streams | 1816 // Write out all the script objects and the accompanying token streams |
1666 // for the bootstrap libraries so that they are in the VM isolate | 1817 // for the bootstrap libraries so that they are in the VM isolate |
1667 // read only memory. | 1818 // read only memory. |
1668 writer.WriteObject(scripts_.raw()); | 1819 writer.WriteObject(scripts_.raw()); |
1669 | 1820 |
1670 // Write out all forwarded objects. | 1821 if (snapshot_code_) { |
1671 writer.WriteForwardedObjects(); | 1822 ASSERT(!vm_isolate_is_symbolic_); |
1823 | |
1824 for (intptr_t i = 0; | |
1825 i < ArgumentsDescriptor::kCachedDescriptorCount; | |
1826 i++) { | |
1827 writer.WriteObject(ArgumentsDescriptor::cached_args_descriptors_[i]); | |
1828 } | |
1829 | |
1830 writer.WriteObject(Object::empty_object_pool().raw()); | |
1831 writer.WriteObject(Object::empty_descriptors().raw()); | |
1832 writer.WriteObject(Object::empty_var_descriptors().raw()); | |
1833 writer.WriteObject(Object::empty_exception_handlers().raw()); | |
1834 | |
1835 #define WRITE_STUB(name) \ | |
1836 writer.WriteObject(StubCode::name##_entry()->code()); | |
1837 VM_STUB_CODE_LIST(WRITE_STUB); | |
1838 #undef WRITE_STUB | |
1839 } | |
1840 | |
1672 | 1841 |
1673 writer.FillHeader(writer.kind()); | 1842 writer.FillHeader(writer.kind()); |
1674 | 1843 |
1675 vm_isolate_snapshot_size_ = writer.BytesWritten(); | 1844 vm_isolate_snapshot_size_ = writer.BytesWritten(); |
1676 } else { | 1845 } else { |
1677 writer.ThrowException(writer.exception_type(), writer.exception_msg()); | 1846 writer.ThrowException(writer.exception_type(), writer.exception_msg()); |
1678 } | 1847 } |
1679 } | 1848 } |
1680 | 1849 |
1681 | 1850 |
1682 void FullSnapshotWriter::WriteIsolateFullSnapshot() { | 1851 void FullSnapshotWriter::WriteIsolateFullSnapshot() { |
1683 SnapshotWriter writer(Snapshot::kFull, | 1852 SnapshotWriter writer(Snapshot::kFull, |
1684 isolate_snapshot_buffer_, | 1853 isolate_snapshot_buffer_, |
1685 alloc_, | 1854 alloc_, |
1686 kInitialSize, | 1855 kInitialSize, |
1687 forward_list_, | 1856 forward_list_, |
1857 instructions_writer_, | |
1688 true, /* can_send_any_object */ | 1858 true, /* can_send_any_object */ |
1689 snapshot_code_); | 1859 snapshot_code_, |
1860 true /* vm_isolate_is_symbolic */); | |
1690 ObjectStore* object_store = isolate_->object_store(); | 1861 ObjectStore* object_store = isolate_->object_store(); |
1691 ASSERT(object_store != NULL); | 1862 ASSERT(object_store != NULL); |
1692 | 1863 |
1693 // Write full snapshot for a regular isolate. | 1864 // Write full snapshot for a regular isolate. |
1694 // Setup for long jump in case there is an exception while writing | 1865 // Setup for long jump in case there is an exception while writing |
1695 // the snapshot. | 1866 // the snapshot. |
1696 LongJumpScope jump; | 1867 LongJumpScope jump; |
1697 if (setjmp(*jump.Set()) == 0) { | 1868 if (setjmp(*jump.Set()) == 0) { |
1698 // Reserve space in the output buffer for a snapshot header. | 1869 // Reserve space in the output buffer for a snapshot header. |
1699 writer.ReserveHeader(); | 1870 writer.ReserveHeader(); |
(...skipping 14 matching lines...) Expand all Loading... | |
1714 writer.FillHeader(writer.kind()); | 1885 writer.FillHeader(writer.kind()); |
1715 writer.UnmarkAll(); | 1886 writer.UnmarkAll(); |
1716 | 1887 |
1717 isolate_snapshot_size_ = writer.BytesWritten(); | 1888 isolate_snapshot_size_ = writer.BytesWritten(); |
1718 } else { | 1889 } else { |
1719 writer.ThrowException(writer.exception_type(), writer.exception_msg()); | 1890 writer.ThrowException(writer.exception_type(), writer.exception_msg()); |
1720 } | 1891 } |
1721 } | 1892 } |
1722 | 1893 |
1723 | 1894 |
1895 class WritableVMIsolateScope : StackResource { | |
1896 public: | |
1897 explicit WritableVMIsolateScope(Thread* thread) : StackResource(thread) { | |
1898 Dart::vm_isolate()->heap()->WriteProtect(false); | |
1899 } | |
1900 | |
1901 ~WritableVMIsolateScope() { | |
1902 ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0); | |
1903 Dart::vm_isolate()->heap()->WriteProtect(true); | |
1904 } | |
1905 }; | |
1906 | |
1907 | |
1724 void FullSnapshotWriter::WriteFullSnapshot() { | 1908 void FullSnapshotWriter::WriteFullSnapshot() { |
1725 if (vm_isolate_snapshot_buffer() != NULL) { | 1909 if (!vm_isolate_is_symbolic_) { |
1726 WriteVmIsolateSnapshot(); | 1910 // TODO(asiva): Don't mutate object headers during serialization. |
1911 WritableVMIsolateScope scope(Thread::Current()); | |
1912 | |
1913 if (vm_isolate_snapshot_buffer() != NULL) { | |
1914 WriteVmIsolateSnapshot(); | |
1915 } | |
1916 WriteIsolateFullSnapshot(); | |
1917 | |
1918 instructions_snapshot_size_ = instructions_writer_->BytesWritten(); | |
1919 } else { | |
1920 if (vm_isolate_snapshot_buffer() != NULL) { | |
1921 WriteVmIsolateSnapshot(); | |
1922 } | |
1923 WriteIsolateFullSnapshot(); | |
1727 } | 1924 } |
1728 WriteIsolateFullSnapshot(); | |
1729 } | 1925 } |
1730 | 1926 |
1731 | 1927 |
1732 PrecompiledSnapshotWriter::PrecompiledSnapshotWriter( | 1928 PrecompiledSnapshotWriter::PrecompiledSnapshotWriter( |
1733 uint8_t** vm_isolate_snapshot_buffer, | 1929 uint8_t** vm_isolate_snapshot_buffer, |
1734 uint8_t** isolate_snapshot_buffer, | 1930 uint8_t** isolate_snapshot_buffer, |
1931 uint8_t** instructions_snapshot_buffer, | |
1735 ReAlloc alloc) | 1932 ReAlloc alloc) |
1736 : FullSnapshotWriter(vm_isolate_snapshot_buffer, | 1933 : FullSnapshotWriter(vm_isolate_snapshot_buffer, |
1737 isolate_snapshot_buffer, | 1934 isolate_snapshot_buffer, |
1935 instructions_snapshot_buffer, | |
1738 alloc, | 1936 alloc, |
1739 true /* snapshot_code */) { | 1937 true, /* snapshot_code */ |
1938 false /* vm_isolate_is_symbolic */) { | |
1740 } | 1939 } |
1741 | 1940 |
1742 | 1941 |
1743 PrecompiledSnapshotWriter::~PrecompiledSnapshotWriter() {} | 1942 PrecompiledSnapshotWriter::~PrecompiledSnapshotWriter() {} |
1744 | 1943 |
1745 | 1944 |
1746 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 1945 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
1747 uword tags = raw->ptr()->tags_; | 1946 uword tags = raw->ptr()->tags_; |
1748 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 1947 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
1749 intptr_t id = SerializedHeaderData::decode(tags); | 1948 intptr_t id = SerializedHeaderData::decode(tags); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1859 uword tags = rawobj->ptr()->tags_; | 2058 uword tags = rawobj->ptr()->tags_; |
1860 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 2059 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
1861 intptr_t id = SerializedHeaderData::decode(tags); | 2060 intptr_t id = SerializedHeaderData::decode(tags); |
1862 WriteIndexedObject(id); | 2061 WriteIndexedObject(id); |
1863 return true; | 2062 return true; |
1864 } | 2063 } |
1865 | 2064 |
1866 // Now check if it is an object from the VM isolate (NOTE: premarked objects | 2065 // Now check if it is an object from the VM isolate (NOTE: premarked objects |
1867 // are considered to be objects in the VM isolate). These objects are shared | 2066 // are considered to be objects in the VM isolate). These objects are shared |
1868 // by all isolates. | 2067 // by all isolates. |
1869 if (rawobj->IsVMHeapObject()) { | 2068 if (rawobj->IsVMHeapObject() && HandleVMIsolateObject(rawobj)) { |
1870 HandleVMIsolateObject(rawobj); | |
1871 return true; | 2069 return true; |
1872 } | 2070 } |
1873 | 2071 |
1874 // Check if it is a code object in that case just write a Null object | 2072 // Check if it is a code object in that case just write a Null object |
1875 // as we do not want code objects in the snapshot. | 2073 // as we do not want code objects in the snapshot. |
1876 if (cid == kCodeCid && !snapshot_code()) { | 2074 if (cid == kCodeCid && !snapshot_code()) { |
1877 WriteVMIsolateObject(kNullObject); | 2075 WriteVMIsolateObject(kNullObject); |
1878 return true; | 2076 return true; |
1879 } | 2077 } |
1880 | 2078 |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2052 case kTypedData##clazz##ViewCid: \ | 2250 case kTypedData##clazz##ViewCid: \ |
2053 | 2251 |
2054 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) | 2252 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) |
2055 case kByteDataViewCid: { | 2253 case kByteDataViewCid: { |
2056 WriteInstance(object_id, raw, cls, tags); | 2254 WriteInstance(object_id, raw, cls, tags); |
2057 return; | 2255 return; |
2058 } | 2256 } |
2059 #undef SNAPSHOT_WRITE | 2257 #undef SNAPSHOT_WRITE |
2060 default: break; | 2258 default: break; |
2061 } | 2259 } |
2062 UNREACHABLE(); | 2260 |
2261 | |
2262 const Object& obj = Object::Handle(raw); | |
2263 FATAL1("Unexpected inlined object: %s\n", obj.ToCString()); | |
2063 } | 2264 } |
2064 | 2265 |
2065 | 2266 |
2066 class WriteInlinedObjectVisitor : public ObjectVisitor { | 2267 class WriteInlinedObjectVisitor : public ObjectVisitor { |
2067 public: | 2268 public: |
2068 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) | 2269 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) |
2069 : ObjectVisitor(Isolate::Current()), writer_(writer) {} | 2270 : ObjectVisitor(Isolate::Current()), writer_(writer) {} |
2070 | 2271 |
2071 virtual void VisitObject(RawObject* obj) { | 2272 virtual void VisitObject(RawObject* obj) { |
2072 writer_->WriteInlinedObject(obj); | 2273 writer_->WriteInlinedObject(obj); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2248 } | 2449 } |
2249 | 2450 |
2250 | 2451 |
2251 void SnapshotWriter::WriteInstance(intptr_t object_id, | 2452 void SnapshotWriter::WriteInstance(intptr_t object_id, |
2252 RawObject* raw, | 2453 RawObject* raw, |
2253 RawClass* cls, | 2454 RawClass* cls, |
2254 intptr_t tags) { | 2455 intptr_t tags) { |
2255 // Check if the instance has native fields and throw an exception if it does. | 2456 // Check if the instance has native fields and throw an exception if it does. |
2256 CheckForNativeFields(cls); | 2457 CheckForNativeFields(cls); |
2257 | 2458 |
2258 // Check if object is a closure that is serializable, if the object is a | 2459 if (kind() == Snapshot::kMessage) { |
siva
2015/09/01 20:58:49
|| kind() == Snapshot::kScript)
rmacnak
2015/09/01 23:43:48
Done.
| |
2259 // closure that is not serializable this will throw an exception. | 2460 // Check if object is a closure that is serializable, if the object is a |
2260 RawFunction* func = IsSerializableClosure(cls, raw); | 2461 // closure that is not serializable this will throw an exception. |
2261 if (func != Function::null()) { | 2462 RawFunction* func = IsSerializableClosure(cls, raw); |
2262 WriteStaticImplicitClosure(object_id, func, tags); | 2463 if (func != Function::null()) { |
2263 return; | 2464 WriteStaticImplicitClosure(object_id, func, tags); |
2465 return; | |
2466 } | |
2264 } | 2467 } |
2265 | 2468 |
2266 // Object is regular dart instance. | 2469 // Object is regular dart instance. |
2267 intptr_t next_field_offset = Class::IsSignatureClass(cls) ? | 2470 intptr_t next_field_offset = Class::IsSignatureClass(cls) ? |
2268 Closure::InstanceSize() : | 2471 Closure::InstanceSize() : |
2269 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; | 2472 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; |
2270 ASSERT(next_field_offset > 0); | 2473 ASSERT(next_field_offset > 0); |
2271 | 2474 |
2272 // Write out the serialization header value for this object. | 2475 // Write out the serialization header value for this object. |
2273 WriteInlinedObjectHeader(object_id); | 2476 WriteInlinedObjectHeader(object_id); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2383 } | 2586 } |
2384 | 2587 |
2385 | 2588 |
2386 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, | 2589 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, |
2387 ReAlloc alloc) | 2590 ReAlloc alloc) |
2388 : SnapshotWriter(Snapshot::kScript, | 2591 : SnapshotWriter(Snapshot::kScript, |
2389 buffer, | 2592 buffer, |
2390 alloc, | 2593 alloc, |
2391 kInitialSize, | 2594 kInitialSize, |
2392 &forward_list_, | 2595 &forward_list_, |
2596 NULL, /* instructions_writer */ | |
2393 true, /* can_send_any_object */ | 2597 true, /* can_send_any_object */ |
2394 false /* snapshot_code */), | 2598 false, /* snapshot_code */ |
2599 true /* vm_isolate_is_symbolic */), | |
2395 forward_list_(kMaxPredefinedObjectIds) { | 2600 forward_list_(kMaxPredefinedObjectIds) { |
2396 ASSERT(buffer != NULL); | 2601 ASSERT(buffer != NULL); |
2397 ASSERT(alloc != NULL); | 2602 ASSERT(alloc != NULL); |
2398 } | 2603 } |
2399 | 2604 |
2400 | 2605 |
2401 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 2606 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
2402 ASSERT(kind() == Snapshot::kScript); | 2607 ASSERT(kind() == Snapshot::kScript); |
2403 ASSERT(isolate() != NULL); | 2608 ASSERT(isolate() != NULL); |
2404 ASSERT(ClassFinalizer::AllClassesFinalized()); | 2609 ASSERT(ClassFinalizer::AllClassesFinalized()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2438 | 2643 |
2439 | 2644 |
2440 MessageWriter::MessageWriter(uint8_t** buffer, | 2645 MessageWriter::MessageWriter(uint8_t** buffer, |
2441 ReAlloc alloc, | 2646 ReAlloc alloc, |
2442 bool can_send_any_object) | 2647 bool can_send_any_object) |
2443 : SnapshotWriter(Snapshot::kMessage, | 2648 : SnapshotWriter(Snapshot::kMessage, |
2444 buffer, | 2649 buffer, |
2445 alloc, | 2650 alloc, |
2446 kInitialSize, | 2651 kInitialSize, |
2447 &forward_list_, | 2652 &forward_list_, |
2653 NULL, /* instructions_writer */ | |
2448 can_send_any_object, | 2654 can_send_any_object, |
2449 false /* snapshot_code */), | 2655 false, /* snapshot_code */ |
2656 true /* vm_isolate_is_symbolic */), | |
2450 forward_list_(kMaxPredefinedObjectIds) { | 2657 forward_list_(kMaxPredefinedObjectIds) { |
2451 ASSERT(buffer != NULL); | 2658 ASSERT(buffer != NULL); |
2452 ASSERT(alloc != NULL); | 2659 ASSERT(alloc != NULL); |
2453 } | 2660 } |
2454 | 2661 |
2455 | 2662 |
2456 void MessageWriter::WriteMessage(const Object& obj) { | 2663 void MessageWriter::WriteMessage(const Object& obj) { |
2457 ASSERT(kind() == Snapshot::kMessage); | 2664 ASSERT(kind() == Snapshot::kMessage); |
2458 ASSERT(isolate() != NULL); | 2665 ASSERT(isolate() != NULL); |
2459 | 2666 |
2460 // Setup for long jump in case there is an exception while writing | 2667 // Setup for long jump in case there is an exception while writing |
2461 // the message. | 2668 // the message. |
2462 LongJumpScope jump; | 2669 LongJumpScope jump; |
2463 if (setjmp(*jump.Set()) == 0) { | 2670 if (setjmp(*jump.Set()) == 0) { |
2464 NoSafepointScope no_safepoint; | 2671 NoSafepointScope no_safepoint; |
2465 WriteObject(obj.raw()); | 2672 WriteObject(obj.raw()); |
2466 UnmarkAll(); | 2673 UnmarkAll(); |
2467 } else { | 2674 } else { |
2468 ThrowException(exception_type(), exception_msg()); | 2675 ThrowException(exception_type(), exception_msg()); |
2469 } | 2676 } |
2470 } | 2677 } |
2471 | 2678 |
2472 | 2679 |
2473 } // namespace dart | 2680 } // namespace dart |
OLD | NEW |