Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(402)

Side by Side Diff: runtime/vm/snapshot.cc

Issue 1318803002: Toward precompiled snapshots. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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()->no_safepoint_scope_depth() != 0) 27 ASSERT(thread()->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
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 Thread* thread) 178 Thread* thread)
177 : BaseReader(buffer, size), 179 : BaseReader(buffer, size),
180 instructions_buffer_(instructions_buffer),
178 kind_(kind), 181 kind_(kind),
179 snapshot_code_(false), 182 snapshot_code_(instructions_buffer != NULL),
180 thread_(thread), 183 thread_(thread),
181 zone_(thread->zone()), 184 zone_(thread->zone()),
182 heap_(isolate()->heap()), 185 heap_(isolate()->heap()),
183 old_space_(thread_->isolate()->heap()->old_space()), 186 old_space_(thread_->isolate()->heap()->old_space()),
184 cls_(Class::Handle(zone_)), 187 cls_(Class::Handle(zone_)),
185 obj_(Object::Handle(zone_)), 188 obj_(Object::Handle(zone_)),
186 pobj_(PassiveObject::Handle(zone_)), 189 pobj_(PassiveObject::Handle(zone_)),
187 array_(Array::Handle(zone_)), 190 array_(Array::Handle(zone_)),
188 field_(Field::Handle(zone_)), 191 field_(Field::Handle(zone_)),
189 str_(String::Handle(zone_)), 192 str_(String::Handle(zone_)),
190 library_(Library::Handle(zone_)), 193 library_(Library::Handle(zone_)),
191 type_(AbstractType::Handle(zone_)), 194 type_(AbstractType::Handle(zone_)),
192 type_arguments_(TypeArguments::Handle(zone_)), 195 type_arguments_(TypeArguments::Handle(zone_)),
193 tokens_(Array::Handle(zone_)), 196 tokens_(Array::Handle(zone_)),
194 stream_(TokenStream::Handle(zone_)), 197 stream_(TokenStream::Handle(zone_)),
195 data_(ExternalTypedData::Handle(zone_)), 198 data_(ExternalTypedData::Handle(zone_)),
196 typed_data_(TypedData::Handle(zone_)), 199 typed_data_(TypedData::Handle(zone_)),
200 code_(Code::Handle(zone_)),
197 error_(UnhandledException::Handle(zone_)), 201 error_(UnhandledException::Handle(zone_)),
198 max_vm_isolate_object_id_( 202 max_vm_isolate_object_id_(
199 (kind == Snapshot::kFull) ? 203 (kind == Snapshot::kFull) ?
200 Object::vm_isolate_snapshot_object_table().Length() : 0), 204 Object::vm_isolate_snapshot_object_table().Length() : 0),
201 backward_references_(backward_refs) { 205 backward_references_(backward_refs),
206 instructions_reader_(NULL) {
207 if (instructions_buffer != NULL) {
208 instructions_reader_ = new InstructionsReader(instructions_buffer);
209 }
202 } 210 }
203 211
204 212
205 RawObject* SnapshotReader::ReadObject() { 213 RawObject* SnapshotReader::ReadObject() {
206 // Setup for long jump in case there is an exception while reading. 214 // Setup for long jump in case there is an exception while reading.
207 LongJumpScope jump; 215 LongJumpScope jump;
208 if (setjmp(*jump.Set()) == 0) { 216 if (setjmp(*jump.Set()) == 0) {
209 PassiveObject& obj = 217 PassiveObject& obj =
210 PassiveObject::Handle(isolate(), ReadObjectImpl(kAsInlinedObject)); 218 PassiveObject::Handle(isolate(), ReadObjectImpl(kAsInlinedObject));
211 for (intptr_t i = 0; i < backward_references_->length(); i++) { 219 for (intptr_t i = 0; i < backward_references_->length(); i++) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 } else { 503 } else {
496 *result ^= Object::Allocate(cls_.id(), 504 *result ^= Object::Allocate(cls_.id(),
497 instance_size, 505 instance_size,
498 HEAP_SPACE(kind_)); 506 HEAP_SPACE(kind_));
499 } 507 }
500 } else { 508 } else {
501 cls_ ^= ReadObjectImpl(kAsInlinedObject); 509 cls_ ^= ReadObjectImpl(kAsInlinedObject);
502 ASSERT(!cls_.IsNull()); 510 ASSERT(!cls_.IsNull());
503 instance_size = cls_.instance_size(); 511 instance_size = cls_.instance_size();
504 } 512 }
505 intptr_t next_field_offset = cls_.next_field_offset(); 513 intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw())
514 ? Closure::InstanceSize() : cls_.next_field_offset();
515
506 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); 516 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset();
507 ASSERT(next_field_offset > 0); 517 ASSERT(next_field_offset > 0);
508 // Instance::NextFieldOffset() returns the offset of the first field in 518 // Instance::NextFieldOffset() returns the offset of the first field in
509 // a Dart object. 519 // a Dart object.
510 bool as_reference = RawObject::IsCanonical(tags) ? false : true; 520 bool as_reference = RawObject::IsCanonical(tags) ? false : true;
511 intptr_t offset = Instance::NextFieldOffset(); 521 intptr_t offset = Instance::NextFieldOffset();
512 intptr_t result_cid = result->GetClassId(); 522 intptr_t result_cid = result->GetClassId();
513 while (offset < next_field_offset) { 523 while (offset < next_field_offset) {
514 pobj_ = ReadObjectImpl(as_reference); 524 pobj_ = ReadObjectImpl(as_reference);
515 result->SetFieldAtOffset(offset, pobj_); 525 result->SetFieldAtOffset(offset, pobj_);
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 RawTwoByteString* SnapshotReader::NewTwoByteString(intptr_t len) { 778 RawTwoByteString* SnapshotReader::NewTwoByteString(intptr_t len) {
769 ALLOC_NEW_OBJECT_WITH_LEN(TwoByteString, len); 779 ALLOC_NEW_OBJECT_WITH_LEN(TwoByteString, len);
770 } 780 }
771 781
772 782
773 RawTypeArguments* SnapshotReader::NewTypeArguments(intptr_t len) { 783 RawTypeArguments* SnapshotReader::NewTypeArguments(intptr_t len) {
774 ALLOC_NEW_OBJECT_WITH_LEN(TypeArguments, len); 784 ALLOC_NEW_OBJECT_WITH_LEN(TypeArguments, len);
775 } 785 }
776 786
777 787
788 RawObjectPool* SnapshotReader::NewObjectPool(intptr_t len) {
789 ASSERT(kind_ == Snapshot::kFull);
790 ASSERT_NO_SAFEPOINT_SCOPE();
791 RawObjectPool* obj = reinterpret_cast<RawObjectPool*>(
792 AllocateUninitialized(kObjectPoolCid, ObjectPool::InstanceSize(len)));
793 obj->ptr()->length_ = len;
794 return obj;
795 }
796
797
798 RawLocalVarDescriptors* SnapshotReader::NewLocalVarDescriptors(
799 intptr_t num_entries) {
800 ASSERT(kind_ == Snapshot::kFull);
801 ASSERT_NO_SAFEPOINT_SCOPE();
802 RawLocalVarDescriptors* obj = reinterpret_cast<RawLocalVarDescriptors*>(
803 AllocateUninitialized(kLocalVarDescriptorsCid,
804 LocalVarDescriptors::InstanceSize(num_entries)));
805 obj->ptr()->num_entries_ = num_entries;
806 return obj;
807 }
808
809
810 RawExceptionHandlers* SnapshotReader::NewExceptionHandlers(
811 intptr_t num_entries) {
812 ASSERT(kind_ == Snapshot::kFull);
813 ASSERT_NO_SAFEPOINT_SCOPE();
814 RawExceptionHandlers* obj = reinterpret_cast<RawExceptionHandlers*>(
815 AllocateUninitialized(kExceptionHandlersCid,
816 ExceptionHandlers::InstanceSize(num_entries)));
817 obj->ptr()->num_entries_ = num_entries;
818 return obj;
819 }
820
821
822 RawPcDescriptors* SnapshotReader::NewPcDescriptors(intptr_t len) {
823 ASSERT(kind_ == Snapshot::kFull);
824 ASSERT_NO_SAFEPOINT_SCOPE();
825 RawPcDescriptors* obj = reinterpret_cast<RawPcDescriptors*>(
826 AllocateUninitialized(kPcDescriptorsCid,
827 PcDescriptors::InstanceSize(len)));
828 obj->ptr()->length_ = len;
829 return obj;
830 }
831
832
833 RawStackmap* SnapshotReader::NewStackmap(intptr_t len) {
834 ASSERT(kind_ == Snapshot::kFull);
835 ASSERT_NO_SAFEPOINT_SCOPE();
836 RawStackmap* obj = reinterpret_cast<RawStackmap*>(
837 AllocateUninitialized(kStackmapCid, Stackmap::InstanceSize(len)));
838 obj->ptr()->length_ = len;
839 return obj;
840 }
841
842
843 RawContextScope* SnapshotReader::NewContextScope(intptr_t num_variables) {
844 ASSERT(kind_ == Snapshot::kFull);
845 ASSERT_NO_SAFEPOINT_SCOPE();
846 RawContextScope* obj = reinterpret_cast<RawContextScope*>(
847 AllocateUninitialized(kContextScopeCid,
848 ContextScope::InstanceSize(num_variables)));
849 obj->ptr()->num_variables_ = num_variables;
850 return obj;
851 }
852
853
854 RawCode* SnapshotReader::NewCode(intptr_t pointer_offsets_length) {
855 ASSERT(pointer_offsets_length == 0);
856 ASSERT(kind_ == Snapshot::kFull);
857 ASSERT_NO_SAFEPOINT_SCOPE();
858 RawCode* obj = reinterpret_cast<RawCode*>(
859 AllocateUninitialized(kCodeCid, Code::InstanceSize(0)));
860 return obj;
861 }
862
863
778 RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) { 864 RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) {
779 ASSERT(kind_ == Snapshot::kFull); 865 ASSERT(kind_ == Snapshot::kFull);
780 ASSERT_NO_SAFEPOINT_SCOPE(); 866 ASSERT_NO_SAFEPOINT_SCOPE();
781 stream_ = reinterpret_cast<RawTokenStream*>( 867 stream_ = reinterpret_cast<RawTokenStream*>(
782 AllocateUninitialized(kTokenStreamCid, TokenStream::InstanceSize())); 868 AllocateUninitialized(kTokenStreamCid, TokenStream::InstanceSize()));
783 uint8_t* array = const_cast<uint8_t*>(CurrentBufferAddress()); 869 uint8_t* array = const_cast<uint8_t*>(CurrentBufferAddress());
784 ASSERT(array != NULL); 870 ASSERT(array != NULL);
785 Advance(len); 871 Advance(len);
786 data_ = reinterpret_cast<RawExternalTypedData*>( 872 data_ = reinterpret_cast<RawExternalTypedData*>(
787 AllocateUninitialized(kExternalTypedDataUint8ArrayCid, 873 AllocateUninitialized(kExternalTypedDataUint8ArrayCid,
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 RawRedirectionData* SnapshotReader::NewRedirectionData() { 1003 RawRedirectionData* SnapshotReader::NewRedirectionData() {
918 ALLOC_NEW_OBJECT(RedirectionData); 1004 ALLOC_NEW_OBJECT(RedirectionData);
919 } 1005 }
920 1006
921 1007
922 RawFunction* SnapshotReader::NewFunction() { 1008 RawFunction* SnapshotReader::NewFunction() {
923 ALLOC_NEW_OBJECT(Function); 1009 ALLOC_NEW_OBJECT(Function);
924 } 1010 }
925 1011
926 1012
927 RawCode* SnapshotReader::NewCode(intptr_t pointer_offsets_length) {
928 ASSERT(pointer_offsets_length == 0);
929 ALLOC_NEW_OBJECT(Code);
930 }
931
932
933 RawObjectPool* SnapshotReader::NewObjectPool(intptr_t length) {
934 ALLOC_NEW_OBJECT(ObjectPool);
935 }
936
937
938 RawICData* SnapshotReader::NewICData() { 1013 RawICData* SnapshotReader::NewICData() {
939 ALLOC_NEW_OBJECT(ICData); 1014 ALLOC_NEW_OBJECT(ICData);
940 } 1015 }
941 1016
942 1017
1018 RawLinkedHashMap* SnapshotReader::NewLinkedHashMap() {
1019 ALLOC_NEW_OBJECT(LinkedHashMap);
1020 }
1021
1022
943 RawMegamorphicCache* SnapshotReader::NewMegamorphicCache() { 1023 RawMegamorphicCache* SnapshotReader::NewMegamorphicCache() {
944 ALLOC_NEW_OBJECT(MegamorphicCache); 1024 ALLOC_NEW_OBJECT(MegamorphicCache);
945 } 1025 }
946 1026
947 1027
948 RawSubtypeTestCache* SnapshotReader::NewSubtypeTestCache() { 1028 RawSubtypeTestCache* SnapshotReader::NewSubtypeTestCache() {
949 ALLOC_NEW_OBJECT(SubtypeTestCache); 1029 ALLOC_NEW_OBJECT(SubtypeTestCache);
950 } 1030 }
951 1031
952 1032
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 } 1130 }
1051 return Mint::NewCanonical(value); 1131 return Mint::NewCanonical(value);
1052 } 1132 }
1053 1133
1054 1134
1055 RawStacktrace* SnapshotReader::NewStacktrace() { 1135 RawStacktrace* SnapshotReader::NewStacktrace() {
1056 ALLOC_NEW_OBJECT(Stacktrace); 1136 ALLOC_NEW_OBJECT(Stacktrace);
1057 } 1137 }
1058 1138
1059 1139
1060 RawInstructions* SnapshotReader::GetInstructionsById(int32_t id) { 1140 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) {
1061 // TODO(rmacnak): Read from shared library. 1141 // Instructions are allocated with the code alignment and we don't write
1142 // anything else in the text section.
1143 ASSERT(Utils::IsAligned(stream_.bytes_written(),
1144 OS::PreferredCodeAlignment()));
1145
1146 intptr_t offset = stream_.bytes_written();
1147 stream_.WriteBytes(reinterpret_cast<uint8_t*>(instructions) - kHeapObjectTag,
1148 instructions->Size());
1149 return offset;
1150 }
1151
1152
1153 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset,
1154 uword expected_tags) {
1155 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment()));
1156
1157 RawInstructions* result =
1158 reinterpret_cast<RawInstructions*>(
1159 reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag);
1160
1161 uword actual_tags = result->ptr()->tags_;
1162 if (actual_tags != expected_tags) {
1163 FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd,
1164 expected_tags,
1165 actual_tags);
1166 }
1167
1168 // TODO(rmacnak): The above contains stale pointers to a Code and an
1169 // ObjectPool. Return the actual result after calling convention change.
1062 return Instructions::null(); 1170 return Instructions::null();
1063 } 1171 }
1064 1172
1065 1173
1066 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { 1174 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) {
1067 // If the header is an object Id, lookup singleton VM classes or classes 1175 // If the header is an object Id, lookup singleton VM classes or classes
1068 // stored in the object store. 1176 // stored in the object store.
1069 if (IsVMIsolateObject(class_header)) { 1177 if (IsVMIsolateObject(class_header)) {
1070 intptr_t class_id = GetVMIsolateObjectId(class_header); 1178 intptr_t class_id = GetVMIsolateObjectId(class_header);
1071 ASSERT(IsSingletonClassId(class_id)); 1179 ASSERT(IsSingletonClassId(class_id));
1072 return class_id; 1180 return class_id;
1073 } 1181 }
1074 ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId); 1182 ASSERT(SerializedHeaderTag::decode(class_header) == kObjectId);
1075 intptr_t class_id = SerializedHeaderData::decode(class_header); 1183 intptr_t class_id = SerializedHeaderData::decode(class_header);
1076 ASSERT(IsObjectStoreClassId(class_id)); 1184 ASSERT(IsObjectStoreClassId(class_id) || IsSingletonClassId(class_id));
1077 return class_id; 1185 return class_id;
1078 } 1186 }
1079 1187
1080 1188
1081 RawObject* SnapshotReader::AllocateUninitialized(intptr_t class_id, 1189 RawObject* SnapshotReader::AllocateUninitialized(intptr_t class_id,
1082 intptr_t size) { 1190 intptr_t size) {
1083 ASSERT_NO_SAFEPOINT_SCOPE(); 1191 ASSERT_NO_SAFEPOINT_SCOPE();
1084 ASSERT(Utils::IsAligned(size, kObjectAlignment)); 1192 ASSERT(Utils::IsAligned(size, kObjectAlignment));
1085 1193
1086 // Allocate memory where all words look like smis. This is currently 1194 // Allocate memory where all words look like smis. This is currently
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 reinterpret_cast<RawObject**>(result.raw()->ptr()); 1372 reinterpret_cast<RawObject**>(result.raw()->ptr());
1265 for (intptr_t i = 0; i < len; i++) { 1373 for (intptr_t i = 0; i < len; i++) {
1266 *PassiveObjectHandle() = ReadObjectImpl(as_reference, 1374 *PassiveObjectHandle() = ReadObjectImpl(as_reference,
1267 object_id, 1375 object_id,
1268 (i + offset)); 1376 (i + offset));
1269 result.SetAt(i, *PassiveObjectHandle()); 1377 result.SetAt(i, *PassiveObjectHandle());
1270 } 1378 }
1271 } 1379 }
1272 1380
1273 1381
1274 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, 1382 VmIsolateSnapshotReader::VmIsolateSnapshotReader(
1275 intptr_t size, 1383 const uint8_t* buffer,
1276 Thread* thread) 1384 intptr_t size,
1277 : SnapshotReader(buffer, 1385 const uint8_t* instructions_buffer,
1278 size, 1386 Thread* thread)
1279 Snapshot::kFull, 1387 : SnapshotReader(buffer,
1280 new ZoneGrowableArray<BackRefNode>( 1388 size,
1281 kNumVmIsolateSnapshotReferences), 1389 instructions_buffer,
1282 thread) { 1390 Snapshot::kFull,
1391 new ZoneGrowableArray<BackRefNode>(
1392 kNumVmIsolateSnapshotReferences),
1393 thread) {
1283 } 1394 }
1284 1395
1285 1396
1286 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { 1397 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() {
1287 intptr_t len = GetBackwardReferenceTable()->length(); 1398 intptr_t len = GetBackwardReferenceTable()->length();
1288 Object::InitVmIsolateSnapshotObjectTable(len); 1399 Object::InitVmIsolateSnapshotObjectTable(len);
1289 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable(); 1400 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable();
1290 for (intptr_t i = 0; i < len; i++) { 1401 for (intptr_t i = 0; i < len; i++) {
1291 Object::vm_isolate_snapshot_object_table().SetAt( 1402 Object::vm_isolate_snapshot_object_table().SetAt(
1292 i, *(backrefs->At(i).reference())); 1403 i, *(backrefs->At(i).reference()));
1293 } 1404 }
1294 ResetBackwardReferenceTable(); 1405 ResetBackwardReferenceTable();
1406 Object::set_instructions_snapshot_buffer(instructions_buffer_);
1295 } 1407 }
1296 1408
1297 1409
1298 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { 1410 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() {
1299 ASSERT(kind() == Snapshot::kFull); 1411 ASSERT(kind() == Snapshot::kFull);
1300 Isolate* isolate = Isolate::Current(); 1412 Isolate* isolate = Isolate::Current();
1301 ASSERT(isolate != NULL); 1413 ASSERT(isolate != NULL);
1302 ASSERT(isolate == Dart::vm_isolate()); 1414 ASSERT(isolate == Dart::vm_isolate());
1303 ObjectStore* object_store = isolate->object_store(); 1415 ObjectStore* object_store = isolate->object_store();
1304 ASSERT(object_store != NULL); 1416 ASSERT(object_store != NULL);
(...skipping 13 matching lines...) Expand all
1318 // Read in the symbol table. 1430 // Read in the symbol table.
1319 object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject()); 1431 object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject());
1320 1432
1321 Symbols::InitOnceFromSnapshot(isolate); 1433 Symbols::InitOnceFromSnapshot(isolate);
1322 1434
1323 // Read in all the script objects and the accompanying token streams 1435 // Read in all the script objects and the accompanying token streams
1324 // for bootstrap libraries so that they are in the VM isolate's read 1436 // for bootstrap libraries so that they are in the VM isolate's read
1325 // only memory. 1437 // only memory.
1326 *(ArrayHandle()) ^= ReadObject(); 1438 *(ArrayHandle()) ^= ReadObject();
1327 1439
1440
1441 if (snapshot_code()) {
1442 for (intptr_t i = 0;
1443 i < ArgumentsDescriptor::kCachedDescriptorCount;
1444 i++) {
1445 *(ArrayHandle()) ^= ReadObject();
1446 // TODO(rmacnak):
1447 // ArgumentsDescriptor::InitOnceFromSnapshot(i, *(ArrayHandle()));
1448 }
1449
1450 ObjectPool::CheckedHandle(ReadObject()); // empty pool
1451 PcDescriptors::CheckedHandle(ReadObject()); // empty pc desc
1452 LocalVarDescriptors::CheckedHandle(ReadObject()); // empty var desc
1453 ExceptionHandlers::CheckedHandle(ReadObject()); // empty exc handlers
1454
1455 #define READ_STUB(name) \
1456 *(CodeHandle()) ^= ReadObject();
1457 // TODO(rmacnak):
1458 // StubCode::name##_entry()->InitOnceFromSnapshot(CodeHandle())
1459 VM_STUB_CODE_LIST(READ_STUB);
1460 #undef READ_STUB
1461 }
1462
1328 // Validate the class table. 1463 // Validate the class table.
1329 #if defined(DEBUG) 1464 #if defined(DEBUG)
1330 isolate->ValidateClassTable(); 1465 isolate->ValidateClassTable();
1331 #endif 1466 #endif
1332 1467
1333 return ApiError::null(); 1468 return ApiError::null();
1334 } 1469 }
1335 } 1470 }
1336 1471
1337 1472
1338 IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer, 1473 IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer,
1339 intptr_t size, 1474 intptr_t size,
1475 const uint8_t* instructions_buffer,
1340 Thread* thread) 1476 Thread* thread)
1341 : SnapshotReader(buffer, 1477 : SnapshotReader(buffer,
1342 size, 1478 size,
1479 instructions_buffer,
1343 Snapshot::kFull, 1480 Snapshot::kFull,
1344 new ZoneGrowableArray<BackRefNode>( 1481 new ZoneGrowableArray<BackRefNode>(
1345 kNumInitialReferencesInFullSnapshot), 1482 kNumInitialReferencesInFullSnapshot),
1346 thread) { 1483 thread) {
1347 } 1484 }
1348 1485
1349 1486
1350 IsolateSnapshotReader::~IsolateSnapshotReader() { 1487 IsolateSnapshotReader::~IsolateSnapshotReader() {
1351 ResetBackwardReferenceTable(); 1488 ResetBackwardReferenceTable();
1352 } 1489 }
1353 1490
1354 1491
1355 ScriptSnapshotReader::ScriptSnapshotReader(const uint8_t* buffer, 1492 ScriptSnapshotReader::ScriptSnapshotReader(const uint8_t* buffer,
1356 intptr_t size, 1493 intptr_t size,
1357 Thread* thread) 1494 Thread* thread)
1358 : SnapshotReader(buffer, 1495 : SnapshotReader(buffer,
1359 size, 1496 size,
1497 NULL, /* instructions_buffer */
1360 Snapshot::kScript, 1498 Snapshot::kScript,
1361 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), 1499 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences),
1362 thread) { 1500 thread) {
1363 } 1501 }
1364 1502
1365 1503
1366 ScriptSnapshotReader::~ScriptSnapshotReader() { 1504 ScriptSnapshotReader::~ScriptSnapshotReader() {
1367 ResetBackwardReferenceTable(); 1505 ResetBackwardReferenceTable();
1368 } 1506 }
1369 1507
1370 1508
1371 MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer, 1509 MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer,
1372 intptr_t size, 1510 intptr_t size,
1373 Thread* thread) 1511 Thread* thread)
1374 : SnapshotReader(buffer, 1512 : SnapshotReader(buffer,
1375 size, 1513 size,
1514 NULL, /* instructions_buffer */
1376 Snapshot::kMessage, 1515 Snapshot::kMessage,
1377 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), 1516 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences),
1378 thread) { 1517 thread) {
1379 } 1518 }
1380 1519
1381 1520
1382 MessageSnapshotReader::~MessageSnapshotReader() { 1521 MessageSnapshotReader::~MessageSnapshotReader() {
1383 ResetBackwardReferenceTable(); 1522 ResetBackwardReferenceTable();
1384 } 1523 }
1385 1524
1386 1525
1387 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, 1526 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind,
1388 uint8_t** buffer, 1527 uint8_t** buffer,
1389 ReAlloc alloc, 1528 ReAlloc alloc,
1390 intptr_t initial_size, 1529 intptr_t initial_size,
1391 ForwardList* forward_list, 1530 ForwardList* forward_list,
1531 InstructionsWriter* instructions_writer,
1392 bool can_send_any_object, 1532 bool can_send_any_object,
1393 bool snapshot_code) 1533 bool snapshot_code,
1534 bool vm_isolate_is_symbolic)
1394 : BaseWriter(buffer, alloc, initial_size), 1535 : BaseWriter(buffer, alloc, initial_size),
1395 kind_(kind), 1536 kind_(kind),
1396 thread_(Thread::Current()), 1537 thread_(Thread::Current()),
1397 object_store_(thread_->isolate()->object_store()), 1538 object_store_(thread_->isolate()->object_store()),
1398 class_table_(thread_->isolate()->class_table()), 1539 class_table_(thread_->isolate()->class_table()),
1399 forward_list_(forward_list), 1540 forward_list_(forward_list),
1541 instructions_writer_(instructions_writer),
1400 exception_type_(Exceptions::kNone), 1542 exception_type_(Exceptions::kNone),
1401 exception_msg_(NULL), 1543 exception_msg_(NULL),
1402 unmarked_objects_(false), 1544 unmarked_objects_(false),
1403 can_send_any_object_(can_send_any_object), 1545 can_send_any_object_(can_send_any_object),
1404 snapshot_code_(snapshot_code) { 1546 snapshot_code_(snapshot_code),
1547 vm_isolate_is_symbolic_(vm_isolate_is_symbolic) {
1405 ASSERT(forward_list_ != NULL); 1548 ASSERT(forward_list_ != NULL);
1406 } 1549 }
1407 1550
1408 1551
1409 void SnapshotWriter::WriteObject(RawObject* rawobj) { 1552 void SnapshotWriter::WriteObject(RawObject* rawobj) {
1410 WriteObjectImpl(rawobj, kAsInlinedObject); 1553 WriteObjectImpl(rawobj, kAsInlinedObject);
1411 WriteForwardedObjects(); 1554 WriteForwardedObjects();
1412 } 1555 }
1413 1556
1414 #define VM_OBJECT_CLASS_LIST(V) \ 1557 #define VM_OBJECT_CLASS_LIST(V) \
1415 V(OneByteString) \ 1558 V(OneByteString) \
1416 V(Mint) \ 1559 V(Mint) \
1417 V(Bigint) \ 1560 V(Bigint) \
1418 V(Double) \ 1561 V(Double) \
1419 V(ImmutableArray) \ 1562 V(ImmutableArray) \
1420 1563
1421 #define VM_OBJECT_WRITE(clazz) \ 1564 #define VM_OBJECT_WRITE(clazz) \
1422 case clazz::kClassId: { \ 1565 case clazz::kClassId: { \
1423 object_id = forward_list_->AddObject(rawobj, kIsSerialized); \ 1566 object_id = forward_list_->AddObject(rawobj, kIsSerialized); \
1424 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \ 1567 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \
1425 raw_obj->WriteTo(this, object_id, kind()); \ 1568 raw_obj->WriteTo(this, object_id, kind()); \
1426 return; \ 1569 return true; \
1427 } \ 1570 } \
1428 1571
1429 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { 1572 bool SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) {
1430 // Check if it is a singleton null object. 1573 // Check if it is a singleton null object.
1431 if (rawobj == Object::null()) { 1574 if (rawobj == Object::null()) {
1432 WriteVMIsolateObject(kNullObject); 1575 WriteVMIsolateObject(kNullObject);
1433 return; 1576 return true;
1434 } 1577 }
1435 1578
1436 // Check if it is a singleton sentinel object. 1579 // Check if it is a singleton sentinel object.
1437 if (rawobj == Object::sentinel().raw()) { 1580 if (rawobj == Object::sentinel().raw()) {
1438 WriteVMIsolateObject(kSentinelObject); 1581 WriteVMIsolateObject(kSentinelObject);
1439 return; 1582 return true;
1440 } 1583 }
1441 1584
1442 // Check if it is a singleton sentinel object. 1585 // Check if it is a singleton sentinel object.
1443 if (rawobj == Object::transition_sentinel().raw()) { 1586 if (rawobj == Object::transition_sentinel().raw()) {
1444 WriteVMIsolateObject(kTransitionSentinelObject); 1587 WriteVMIsolateObject(kTransitionSentinelObject);
1445 return; 1588 return true;
1446 } 1589 }
1447 1590
1448 // Check if it is a singleton empty array object. 1591 // Check if it is a singleton empty array object.
1449 if (rawobj == Object::empty_array().raw()) { 1592 if (rawobj == Object::empty_array().raw()) {
1450 WriteVMIsolateObject(kEmptyArrayObject); 1593 WriteVMIsolateObject(kEmptyArrayObject);
1451 return; 1594 return true;
1452 } 1595 }
1453 1596
1454 // Check if it is a singleton zero array object. 1597 // Check if it is a singleton zero array object.
1455 if (rawobj == Object::zero_array().raw()) { 1598 if (rawobj == Object::zero_array().raw()) {
1456 WriteVMIsolateObject(kZeroArrayObject); 1599 WriteVMIsolateObject(kZeroArrayObject);
1457 return; 1600 return true;
1458 } 1601 }
1459 1602
1460 // Check if it is a singleton dyanmic Type object. 1603 // Check if it is a singleton dyanmic Type object.
1461 if (rawobj == Object::dynamic_type()) { 1604 if (rawobj == Object::dynamic_type()) {
1462 WriteVMIsolateObject(kDynamicType); 1605 WriteVMIsolateObject(kDynamicType);
1463 return; 1606 return true;
1464 } 1607 }
1465 1608
1466 // Check if it is a singleton void Type object. 1609 // Check if it is a singleton void Type object.
1467 if (rawobj == Object::void_type()) { 1610 if (rawobj == Object::void_type()) {
1468 WriteVMIsolateObject(kVoidType); 1611 WriteVMIsolateObject(kVoidType);
1469 return; 1612 return true;
1470 } 1613 }
1471 1614
1472 // Check if it is a singleton boolean true object. 1615 // Check if it is a singleton boolean true object.
1473 if (rawobj == Bool::True().raw()) { 1616 if (rawobj == Bool::True().raw()) {
1474 WriteVMIsolateObject(kTrueValue); 1617 WriteVMIsolateObject(kTrueValue);
1475 return; 1618 return true;
1476 } 1619 }
1477 1620
1478 // Check if it is a singleton boolean false object. 1621 // Check if it is a singleton boolean false object.
1479 if (rawobj == Bool::False().raw()) { 1622 if (rawobj == Bool::False().raw()) {
1480 WriteVMIsolateObject(kFalseValue); 1623 WriteVMIsolateObject(kFalseValue);
1481 return; 1624 return true;
1482 } 1625 }
1483 1626
1484 // Check if it is a singleton extractor parameter types array. 1627 // Check if it is a singleton extractor parameter types array.
1485 if (rawobj == Object::extractor_parameter_types().raw()) { 1628 if (rawobj == Object::extractor_parameter_types().raw()) {
1486 WriteVMIsolateObject(kExtractorParameterTypes); 1629 WriteVMIsolateObject(kExtractorParameterTypes);
1487 return; 1630 return true;
1488 } 1631 }
1489 1632
1490 // Check if it is a singleton extractor parameter names array. 1633 // Check if it is a singleton extractor parameter names array.
1491 if (rawobj == Object::extractor_parameter_names().raw()) { 1634 if (rawobj == Object::extractor_parameter_names().raw()) {
1492 WriteVMIsolateObject(kExtractorParameterNames); 1635 WriteVMIsolateObject(kExtractorParameterNames);
1493 return; 1636 return true;
1494 } 1637 }
1495 1638
1496 // Check if it is a singleton empty context scope object. 1639 // Check if it is a singleton empty context scope object.
1497 if (rawobj == Object::empty_context_scope().raw()) { 1640 if (rawobj == Object::empty_context_scope().raw()) {
1498 WriteVMIsolateObject(kEmptyContextScopeObject); 1641 WriteVMIsolateObject(kEmptyContextScopeObject);
1499 return; 1642 return true;
1500 } 1643 }
1501 1644
1502 // Check if it is a singleton class object which is shared by 1645 // Check if it is a singleton class object which is shared by
1503 // all isolates. 1646 // all isolates.
1504 intptr_t id = rawobj->GetClassId(); 1647 intptr_t id = rawobj->GetClassId();
1505 if (id == kClassCid) { 1648 if (id == kClassCid) {
1506 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); 1649 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj);
1507 intptr_t class_id = raw_class->ptr()->id_; 1650 intptr_t class_id = raw_class->ptr()->id_;
1508 if (IsSingletonClassId(class_id)) { 1651 if (IsSingletonClassId(class_id)) {
1509 intptr_t object_id = ObjectIdFromClassId(class_id); 1652 intptr_t object_id = ObjectIdFromClassId(class_id);
1510 WriteVMIsolateObject(object_id); 1653 WriteVMIsolateObject(object_id);
1511 return; 1654 return true;
1512 } 1655 }
1513 } 1656 }
1514 1657
1515 if (kind() == Snapshot::kFull) { 1658 if (kind() == Snapshot::kFull) {
1516 // Check it is a predefined symbol in the VM isolate. 1659 // Check it is a predefined symbol in the VM isolate.
1517 id = Symbols::LookupVMSymbol(rawobj); 1660 id = Symbols::LookupVMSymbol(rawobj);
1518 if (id != kInvalidIndex) { 1661 if (id != kInvalidIndex) {
1519 WriteVMIsolateObject(id); 1662 WriteVMIsolateObject(id);
1520 return; 1663 return true;
1521 } 1664 }
1522 1665
1523 // Check if it is an object from the vm isolate snapshot object table. 1666 // Check if it is an object from the vm isolate snapshot object table.
1524 id = FindVmSnapshotObject(rawobj); 1667 id = FindVmSnapshotObject(rawobj);
1525 if (id != kInvalidIndex) { 1668 if (id != kInvalidIndex) {
1526 WriteIndexedObject(id); 1669 WriteIndexedObject(id);
1527 return; 1670 return true;
1528 } 1671 }
1529 } else { 1672 } else {
1530 // In the case of script snapshots or for messages we do not use 1673 // In the case of script snapshots or for messages we do not use
1531 // the index into the vm isolate snapshot object table, instead we 1674 // the index into the vm isolate snapshot object table, instead we
1532 // explicitly write the object out. 1675 // explicitly write the object out.
1533 intptr_t object_id = forward_list_->FindObject(rawobj); 1676 intptr_t object_id = forward_list_->FindObject(rawobj);
1534 if (object_id != -1) { 1677 if (object_id != -1) {
1535 WriteIndexedObject(object_id); 1678 WriteIndexedObject(object_id);
1536 return; 1679 return true;
1537 } else { 1680 } else {
1538 switch (id) { 1681 switch (id) {
1539 VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE) 1682 VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE)
1540 case kTypedDataUint32ArrayCid: { 1683 case kTypedDataUint32ArrayCid: {
1541 object_id = forward_list_->AddObject(rawobj, kIsSerialized); 1684 object_id = forward_list_->AddObject(rawobj, kIsSerialized);
1542 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj); 1685 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj);
1543 raw_obj->WriteTo(this, object_id, kind()); 1686 raw_obj->WriteTo(this, object_id, kind());
1544 return; 1687 return true;
1545 } 1688 }
1546 default: 1689 default:
1547 OS::Print("class id = %" Pd "\n", id); 1690 OS::Print("class id = %" Pd "\n", id);
1548 break; 1691 break;
1549 } 1692 }
1550 } 1693 }
1551 } 1694 }
1552 1695
1696 if (!vm_isolate_is_symbolic()) {
1697 return false;
1698 }
1699
1553 const Object& obj = Object::Handle(rawobj); 1700 const Object& obj = Object::Handle(rawobj);
1554 FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString()); 1701 FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString());
1702 return false;
1555 } 1703 }
1556 1704
1557 #undef VM_OBJECT_WRITE 1705 #undef VM_OBJECT_WRITE
1558 1706
1559 1707
1560 // An object visitor which will iterate over all the script objects in the heap 1708 // An object visitor which will iterate over all the script objects in the heap
1561 // and either count them or collect them into an array. This is used during 1709 // and either count them or collect them into an array. This is used during
1562 // full snapshot generation of the VM isolate to write out all script 1710 // full snapshot generation of the VM isolate to write out all script
1563 // objects and their accompanying token streams. 1711 // objects and their accompanying token streams.
1564 class ScriptVisitor : public ObjectVisitor { 1712 class ScriptVisitor : public ObjectVisitor {
(...skipping 24 matching lines...) Expand all
1589 1737
1590 private: 1738 private:
1591 Object& objHandle_; 1739 Object& objHandle_;
1592 intptr_t count_; 1740 intptr_t count_;
1593 const Array* scripts_; 1741 const Array* scripts_;
1594 }; 1742 };
1595 1743
1596 1744
1597 FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, 1745 FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer,
1598 uint8_t** isolate_snapshot_buffer, 1746 uint8_t** isolate_snapshot_buffer,
1747 uint8_t** instructions_snapshot_buffer,
1599 ReAlloc alloc, 1748 ReAlloc alloc,
1600 bool snapshot_code) 1749 bool snapshot_code,
1750 bool vm_isolate_is_symbolic)
1601 : isolate_(Isolate::Current()), 1751 : isolate_(Isolate::Current()),
1602 vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer), 1752 vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer),
1603 isolate_snapshot_buffer_(isolate_snapshot_buffer), 1753 isolate_snapshot_buffer_(isolate_snapshot_buffer),
1754 instructions_snapshot_buffer_(instructions_snapshot_buffer),
1604 alloc_(alloc), 1755 alloc_(alloc),
1605 vm_isolate_snapshot_size_(0), 1756 vm_isolate_snapshot_size_(0),
1606 isolate_snapshot_size_(0), 1757 isolate_snapshot_size_(0),
1758 instructions_snapshot_size_(0),
1607 forward_list_(NULL), 1759 forward_list_(NULL),
1760 instructions_writer_(NULL),
1608 scripts_(Array::Handle(isolate_)), 1761 scripts_(Array::Handle(isolate_)),
1609 symbol_table_(Array::Handle(isolate_)), 1762 symbol_table_(Array::Handle(isolate_)),
1610 snapshot_code_(snapshot_code) { 1763 snapshot_code_(snapshot_code),
1764 vm_isolate_is_symbolic_(vm_isolate_is_symbolic) {
1611 ASSERT(isolate_snapshot_buffer_ != NULL); 1765 ASSERT(isolate_snapshot_buffer_ != NULL);
1612 ASSERT(alloc_ != NULL); 1766 ASSERT(alloc_ != NULL);
1613 ASSERT(isolate_ != NULL); 1767 ASSERT(isolate_ != NULL);
1614 ASSERT(ClassFinalizer::AllClassesFinalized()); 1768 ASSERT(ClassFinalizer::AllClassesFinalized());
1615 ObjectStore* object_store = isolate_->object_store(); 1769 ObjectStore* object_store = isolate_->object_store();
1616 ASSERT(object_store != NULL); 1770 ASSERT(object_store != NULL);
1617 Heap* heap = isolate_->heap(); 1771 Heap* heap = isolate_->heap();
1618 ASSERT(heap != NULL); 1772 ASSERT(heap != NULL);
1619 // Ensure the class table is valid. 1773 // Ensure the class table is valid.
1620 #if defined(DEBUG) 1774 #if defined(DEBUG)
(...skipping 13 matching lines...) Expand all
1634 heap->IterateOldObjects(&script_visitor); 1788 heap->IterateOldObjects(&script_visitor);
1635 1789
1636 // Stash the symbol table away for writing and reading into the vm isolate, 1790 // Stash the symbol table away for writing and reading into the vm isolate,
1637 // and reset the symbol table for the regular isolate so that we do not 1791 // and reset the symbol table for the regular isolate so that we do not
1638 // write these symbols into the snapshot of a regular dart isolate. 1792 // write these symbols into the snapshot of a regular dart isolate.
1639 symbol_table_ = object_store->symbol_table(); 1793 symbol_table_ = object_store->symbol_table();
1640 Symbols::SetupSymbolTable(isolate_); 1794 Symbols::SetupSymbolTable(isolate_);
1641 1795
1642 forward_list_ = new ForwardList(SnapshotWriter::FirstObjectId()); 1796 forward_list_ = new ForwardList(SnapshotWriter::FirstObjectId());
1643 ASSERT(forward_list_ != NULL); 1797 ASSERT(forward_list_ != NULL);
1798
1799 if (instructions_snapshot_buffer != NULL) {
1800 instructions_writer_ = new InstructionsWriter(instructions_snapshot_buffer,
1801 alloc,
1802 kInitialSize);
1803 }
1644 } 1804 }
1645 1805
1646 1806
1647 FullSnapshotWriter::~FullSnapshotWriter() { 1807 FullSnapshotWriter::~FullSnapshotWriter() {
1648 delete forward_list_; 1808 delete forward_list_;
1649 symbol_table_ = Array::null(); 1809 symbol_table_ = Array::null();
1650 scripts_ = Array::null(); 1810 scripts_ = Array::null();
1651 } 1811 }
1652 1812
1653 1813
1654 void FullSnapshotWriter::WriteVmIsolateSnapshot() { 1814 void FullSnapshotWriter::WriteVmIsolateSnapshot() {
1655 ASSERT(vm_isolate_snapshot_buffer_ != NULL); 1815 ASSERT(vm_isolate_snapshot_buffer_ != NULL);
1656 SnapshotWriter writer(Snapshot::kFull, 1816 SnapshotWriter writer(Snapshot::kFull,
1657 vm_isolate_snapshot_buffer_, 1817 vm_isolate_snapshot_buffer_,
1658 alloc_, 1818 alloc_,
1659 kInitialSize, 1819 kInitialSize,
1660 forward_list_, 1820 forward_list_,
1821 instructions_writer_,
1661 true, /* can_send_any_object */ 1822 true, /* can_send_any_object */
1662 snapshot_code_); 1823 snapshot_code_,
1824 vm_isolate_is_symbolic_);
1663 // Write full snapshot for the VM isolate. 1825 // Write full snapshot for the VM isolate.
1664 // Setup for long jump in case there is an exception while writing 1826 // Setup for long jump in case there is an exception while writing
1665 // the snapshot. 1827 // the snapshot.
1666 LongJumpScope jump; 1828 LongJumpScope jump;
1667 if (setjmp(*jump.Set()) == 0) { 1829 if (setjmp(*jump.Set()) == 0) {
1668 // Reserve space in the output buffer for a snapshot header. 1830 // Reserve space in the output buffer for a snapshot header.
1669 writer.ReserveHeader(); 1831 writer.ReserveHeader();
1670 1832
1671 // Write out the version string. 1833 // Write out the version string.
1672 writer.WriteVersion(); 1834 writer.WriteVersion();
1673 1835
1674 /* 1836 /*
1675 * Now Write out the following 1837 * Now Write out the following
1676 * - the symbol table 1838 * - the symbol table
1677 * - all the scripts and token streams for these scripts 1839 * - all the scripts and token streams for these scripts
1678 * 1840 *
1679 **/ 1841 **/
1680 // Write out the symbol table. 1842 // Write out the symbol table.
1681 writer.WriteObject(symbol_table_.raw()); 1843 writer.WriteObject(symbol_table_.raw());
1682 1844
1683 // Write out all the script objects and the accompanying token streams 1845 // Write out all the script objects and the accompanying token streams
1684 // for the bootstrap libraries so that they are in the VM isolate 1846 // for the bootstrap libraries so that they are in the VM isolate
1685 // read only memory. 1847 // read only memory.
1686 writer.WriteObject(scripts_.raw()); 1848 writer.WriteObject(scripts_.raw());
1687 1849
1688 // Write out all forwarded objects. 1850 if (snapshot_code_) {
1689 writer.WriteForwardedObjects(); 1851 ASSERT(!vm_isolate_is_symbolic_);
1852
1853 for (intptr_t i = 0;
1854 i < ArgumentsDescriptor::kCachedDescriptorCount;
1855 i++) {
1856 writer.WriteObject(ArgumentsDescriptor::cached_args_descriptors_[i]);
1857 }
1858
1859 writer.WriteObject(Object::empty_object_pool().raw());
1860 writer.WriteObject(Object::empty_descriptors().raw());
1861 writer.WriteObject(Object::empty_var_descriptors().raw());
1862 writer.WriteObject(Object::empty_exception_handlers().raw());
1863
1864 #define WRITE_STUB(name) \
1865 writer.WriteObject(StubCode::name##_entry()->code());
1866 VM_STUB_CODE_LIST(WRITE_STUB);
1867 #undef WRITE_STUB
1868 }
1869
1690 1870
1691 writer.FillHeader(writer.kind()); 1871 writer.FillHeader(writer.kind());
1692 1872
1693 vm_isolate_snapshot_size_ = writer.BytesWritten(); 1873 vm_isolate_snapshot_size_ = writer.BytesWritten();
1694 } else { 1874 } else {
1695 writer.ThrowException(writer.exception_type(), writer.exception_msg()); 1875 writer.ThrowException(writer.exception_type(), writer.exception_msg());
1696 } 1876 }
1697 } 1877 }
1698 1878
1699 1879
1700 void FullSnapshotWriter::WriteIsolateFullSnapshot() { 1880 void FullSnapshotWriter::WriteIsolateFullSnapshot() {
1701 SnapshotWriter writer(Snapshot::kFull, 1881 SnapshotWriter writer(Snapshot::kFull,
1702 isolate_snapshot_buffer_, 1882 isolate_snapshot_buffer_,
1703 alloc_, 1883 alloc_,
1704 kInitialSize, 1884 kInitialSize,
1705 forward_list_, 1885 forward_list_,
1886 instructions_writer_,
1706 true, /* can_send_any_object */ 1887 true, /* can_send_any_object */
1707 snapshot_code_); 1888 snapshot_code_,
1889 true /* vm_isolate_is_symbolic */);
1708 ObjectStore* object_store = isolate_->object_store(); 1890 ObjectStore* object_store = isolate_->object_store();
1709 ASSERT(object_store != NULL); 1891 ASSERT(object_store != NULL);
1710 1892
1711 // Write full snapshot for a regular isolate. 1893 // Write full snapshot for a regular isolate.
1712 // Setup for long jump in case there is an exception while writing 1894 // Setup for long jump in case there is an exception while writing
1713 // the snapshot. 1895 // the snapshot.
1714 LongJumpScope jump; 1896 LongJumpScope jump;
1715 if (setjmp(*jump.Set()) == 0) { 1897 if (setjmp(*jump.Set()) == 0) {
1716 // Reserve space in the output buffer for a snapshot header. 1898 // Reserve space in the output buffer for a snapshot header.
1717 writer.ReserveHeader(); 1899 writer.ReserveHeader();
(...skipping 14 matching lines...) Expand all
1732 writer.FillHeader(writer.kind()); 1914 writer.FillHeader(writer.kind());
1733 writer.UnmarkAll(); 1915 writer.UnmarkAll();
1734 1916
1735 isolate_snapshot_size_ = writer.BytesWritten(); 1917 isolate_snapshot_size_ = writer.BytesWritten();
1736 } else { 1918 } else {
1737 writer.ThrowException(writer.exception_type(), writer.exception_msg()); 1919 writer.ThrowException(writer.exception_type(), writer.exception_msg());
1738 } 1920 }
1739 } 1921 }
1740 1922
1741 1923
1924 class WritableVMIsolateScope : StackResource {
1925 public:
1926 explicit WritableVMIsolateScope(Thread* thread) : StackResource(thread) {
1927 Dart::vm_isolate()->heap()->WriteProtect(false);
1928 }
1929
1930 ~WritableVMIsolateScope() {
1931 ASSERT(Dart::vm_isolate()->heap()->UsedInWords(Heap::kNew) == 0);
1932 Dart::vm_isolate()->heap()->WriteProtect(true);
1933 }
1934 };
1935
1936
1742 void FullSnapshotWriter::WriteFullSnapshot() { 1937 void FullSnapshotWriter::WriteFullSnapshot() {
1743 if (vm_isolate_snapshot_buffer() != NULL) { 1938 if (!vm_isolate_is_symbolic_) {
1744 WriteVmIsolateSnapshot(); 1939 // TODO(asiva): Don't mutate object headers during serialization.
1940 WritableVMIsolateScope scope(Thread::Current());
1941
1942 if (vm_isolate_snapshot_buffer() != NULL) {
1943 WriteVmIsolateSnapshot();
1944 }
1945 WriteIsolateFullSnapshot();
1946
1947 instructions_snapshot_size_ = instructions_writer_->BytesWritten();
1948 } else {
1949 if (vm_isolate_snapshot_buffer() != NULL) {
1950 WriteVmIsolateSnapshot();
1951 }
1952 WriteIsolateFullSnapshot();
1745 } 1953 }
1746 WriteIsolateFullSnapshot();
1747 } 1954 }
1748 1955
1749 1956
1750 PrecompiledSnapshotWriter::PrecompiledSnapshotWriter( 1957 PrecompiledSnapshotWriter::PrecompiledSnapshotWriter(
1751 uint8_t** vm_isolate_snapshot_buffer, 1958 uint8_t** vm_isolate_snapshot_buffer,
1752 uint8_t** isolate_snapshot_buffer, 1959 uint8_t** isolate_snapshot_buffer,
1960 uint8_t** instructions_snapshot_buffer,
1753 ReAlloc alloc) 1961 ReAlloc alloc)
1754 : FullSnapshotWriter(vm_isolate_snapshot_buffer, 1962 : FullSnapshotWriter(vm_isolate_snapshot_buffer,
1755 isolate_snapshot_buffer, 1963 isolate_snapshot_buffer,
1964 instructions_snapshot_buffer,
1756 alloc, 1965 alloc,
1757 true /* snapshot_code */) { 1966 true, /* snapshot_code */
1967 false /* vm_isolate_is_symbolic */) {
1758 } 1968 }
1759 1969
1760 1970
1761 PrecompiledSnapshotWriter::~PrecompiledSnapshotWriter() {} 1971 PrecompiledSnapshotWriter::~PrecompiledSnapshotWriter() {}
1762 1972
1763 1973
1764 uword SnapshotWriter::GetObjectTags(RawObject* raw) { 1974 uword SnapshotWriter::GetObjectTags(RawObject* raw) {
1765 uword tags = raw->ptr()->tags_; 1975 uword tags = raw->ptr()->tags_;
1766 if (SerializedHeaderTag::decode(tags) == kObjectId) { 1976 if (SerializedHeaderTag::decode(tags) == kObjectId) {
1767 intptr_t id = SerializedHeaderData::decode(tags); 1977 intptr_t id = SerializedHeaderData::decode(tags);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1877 uword tags = rawobj->ptr()->tags_; 2087 uword tags = rawobj->ptr()->tags_;
1878 if (SerializedHeaderTag::decode(tags) == kObjectId) { 2088 if (SerializedHeaderTag::decode(tags) == kObjectId) {
1879 intptr_t id = SerializedHeaderData::decode(tags); 2089 intptr_t id = SerializedHeaderData::decode(tags);
1880 WriteIndexedObject(id); 2090 WriteIndexedObject(id);
1881 return true; 2091 return true;
1882 } 2092 }
1883 2093
1884 // Now check if it is an object from the VM isolate (NOTE: premarked objects 2094 // Now check if it is an object from the VM isolate (NOTE: premarked objects
1885 // are considered to be objects in the VM isolate). These objects are shared 2095 // are considered to be objects in the VM isolate). These objects are shared
1886 // by all isolates. 2096 // by all isolates.
1887 if (rawobj->IsVMHeapObject()) { 2097 if (rawobj->IsVMHeapObject() && HandleVMIsolateObject(rawobj)) {
1888 HandleVMIsolateObject(rawobj);
1889 return true; 2098 return true;
1890 } 2099 }
1891 2100
1892 // Check if it is a code object in that case just write a Null object 2101 // Check if it is a code object in that case just write a Null object
1893 // as we do not want code objects in the snapshot. 2102 // as we do not want code objects in the snapshot.
1894 if (cid == kCodeCid && !snapshot_code()) { 2103 if (cid == kCodeCid && !snapshot_code()) {
1895 WriteVMIsolateObject(kNullObject); 2104 WriteVMIsolateObject(kNullObject);
1896 return true; 2105 return true;
1897 } 2106 }
1898 2107
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2070 case kTypedData##clazz##ViewCid: \ 2279 case kTypedData##clazz##ViewCid: \
2071 2280
2072 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE) 2281 CLASS_LIST_TYPED_DATA(SNAPSHOT_WRITE)
2073 case kByteDataViewCid: { 2282 case kByteDataViewCid: {
2074 WriteInstance(object_id, raw, cls, tags); 2283 WriteInstance(object_id, raw, cls, tags);
2075 return; 2284 return;
2076 } 2285 }
2077 #undef SNAPSHOT_WRITE 2286 #undef SNAPSHOT_WRITE
2078 default: break; 2287 default: break;
2079 } 2288 }
2080 UNREACHABLE(); 2289
2290 const Object& obj = Object::Handle(raw);
2291 FATAL1("Unexpected inlined object: %s\n", obj.ToCString());
2081 } 2292 }
2082 2293
2083 2294
2084 class WriteInlinedObjectVisitor : public ObjectVisitor { 2295 class WriteInlinedObjectVisitor : public ObjectVisitor {
2085 public: 2296 public:
2086 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) 2297 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer)
2087 : ObjectVisitor(Isolate::Current()), writer_(writer) {} 2298 : ObjectVisitor(Isolate::Current()), writer_(writer) {}
2088 2299
2089 virtual void VisitObject(RawObject* obj) { 2300 virtual void VisitObject(RawObject* obj) {
2090 writer_->WriteInlinedObject(obj); 2301 writer_->WriteInlinedObject(obj);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2266 } 2477 }
2267 2478
2268 2479
2269 void SnapshotWriter::WriteInstance(intptr_t object_id, 2480 void SnapshotWriter::WriteInstance(intptr_t object_id,
2270 RawObject* raw, 2481 RawObject* raw,
2271 RawClass* cls, 2482 RawClass* cls,
2272 intptr_t tags) { 2483 intptr_t tags) {
2273 // Check if the instance has native fields and throw an exception if it does. 2484 // Check if the instance has native fields and throw an exception if it does.
2274 CheckForNativeFields(cls); 2485 CheckForNativeFields(cls);
2275 2486
2276 // Check if object is a closure that is serializable, if the object is a 2487 if ((kind() == Snapshot::kMessage) || (kind() == Snapshot::kScript)) {
2277 // closure that is not serializable this will throw an exception. 2488 // Check if object is a closure that is serializable, if the object is a
2278 RawFunction* func = IsSerializableClosure(cls, raw); 2489 // closure that is not serializable this will throw an exception.
2279 if (func != Function::null()) { 2490 RawFunction* func = IsSerializableClosure(cls, raw);
2280 WriteStaticImplicitClosure(object_id, func, tags); 2491 if (func != Function::null()) {
2281 return; 2492 WriteStaticImplicitClosure(object_id, func, tags);
2493 return;
2494 }
2282 } 2495 }
2283 2496
2284 // Object is regular dart instance. 2497 // Object is regular dart instance.
2285 intptr_t next_field_offset = Class::IsSignatureClass(cls) ? 2498 intptr_t next_field_offset = Class::IsSignatureClass(cls) ?
2286 Closure::InstanceSize() : 2499 Closure::InstanceSize() :
2287 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; 2500 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2;
2288 ASSERT(next_field_offset > 0); 2501 ASSERT(next_field_offset > 0);
2289 2502
2290 // Write out the serialization header value for this object. 2503 // Write out the serialization header value for this object.
2291 WriteInlinedObjectHeader(object_id); 2504 WriteInlinedObjectHeader(object_id);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2401 } 2614 }
2402 2615
2403 2616
2404 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, 2617 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer,
2405 ReAlloc alloc) 2618 ReAlloc alloc)
2406 : SnapshotWriter(Snapshot::kScript, 2619 : SnapshotWriter(Snapshot::kScript,
2407 buffer, 2620 buffer,
2408 alloc, 2621 alloc,
2409 kInitialSize, 2622 kInitialSize,
2410 &forward_list_, 2623 &forward_list_,
2624 NULL, /* instructions_writer */
2411 true, /* can_send_any_object */ 2625 true, /* can_send_any_object */
2412 false /* snapshot_code */), 2626 false, /* snapshot_code */
2627 true /* vm_isolate_is_symbolic */),
2413 forward_list_(kMaxPredefinedObjectIds) { 2628 forward_list_(kMaxPredefinedObjectIds) {
2414 ASSERT(buffer != NULL); 2629 ASSERT(buffer != NULL);
2415 ASSERT(alloc != NULL); 2630 ASSERT(alloc != NULL);
2416 } 2631 }
2417 2632
2418 2633
2419 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { 2634 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) {
2420 ASSERT(kind() == Snapshot::kScript); 2635 ASSERT(kind() == Snapshot::kScript);
2421 ASSERT(isolate() != NULL); 2636 ASSERT(isolate() != NULL);
2422 ASSERT(ClassFinalizer::AllClassesFinalized()); 2637 ASSERT(ClassFinalizer::AllClassesFinalized());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 2671
2457 2672
2458 MessageWriter::MessageWriter(uint8_t** buffer, 2673 MessageWriter::MessageWriter(uint8_t** buffer,
2459 ReAlloc alloc, 2674 ReAlloc alloc,
2460 bool can_send_any_object) 2675 bool can_send_any_object)
2461 : SnapshotWriter(Snapshot::kMessage, 2676 : SnapshotWriter(Snapshot::kMessage,
2462 buffer, 2677 buffer,
2463 alloc, 2678 alloc,
2464 kInitialSize, 2679 kInitialSize,
2465 &forward_list_, 2680 &forward_list_,
2681 NULL, /* instructions_writer */
2466 can_send_any_object, 2682 can_send_any_object,
2467 false /* snapshot_code */), 2683 false, /* snapshot_code */
2684 true /* vm_isolate_is_symbolic */),
2468 forward_list_(kMaxPredefinedObjectIds) { 2685 forward_list_(kMaxPredefinedObjectIds) {
2469 ASSERT(buffer != NULL); 2686 ASSERT(buffer != NULL);
2470 ASSERT(alloc != NULL); 2687 ASSERT(alloc != NULL);
2471 } 2688 }
2472 2689
2473 2690
2474 void MessageWriter::WriteMessage(const Object& obj) { 2691 void MessageWriter::WriteMessage(const Object& obj) {
2475 ASSERT(kind() == Snapshot::kMessage); 2692 ASSERT(kind() == Snapshot::kMessage);
2476 ASSERT(isolate() != NULL); 2693 ASSERT(isolate() != NULL);
2477 2694
2478 // Setup for long jump in case there is an exception while writing 2695 // Setup for long jump in case there is an exception while writing
2479 // the message. 2696 // the message.
2480 LongJumpScope jump; 2697 LongJumpScope jump;
2481 if (setjmp(*jump.Set()) == 0) { 2698 if (setjmp(*jump.Set()) == 0) {
2482 NoSafepointScope no_safepoint; 2699 NoSafepointScope no_safepoint;
2483 WriteObject(obj.raw()); 2700 WriteObject(obj.raw());
2484 UnmarkAll(); 2701 UnmarkAll();
2485 } else { 2702 } else {
2486 ThrowException(exception_type(), exception_msg()); 2703 ThrowException(exception_type(), exception_msg());
2487 } 2704 }
2488 } 2705 }
2489 2706
2490 2707
2491 } // namespace dart 2708 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/snapshot.h ('k') | runtime/vm/snapshot_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698