Chromium Code Reviews| 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" |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 field_(Field::Handle(zone_)), | 191 field_(Field::Handle(zone_)), |
| 192 str_(String::Handle(zone_)), | 192 str_(String::Handle(zone_)), |
| 193 library_(Library::Handle(zone_)), | 193 library_(Library::Handle(zone_)), |
| 194 type_(AbstractType::Handle(zone_)), | 194 type_(AbstractType::Handle(zone_)), |
| 195 type_arguments_(TypeArguments::Handle(zone_)), | 195 type_arguments_(TypeArguments::Handle(zone_)), |
| 196 tokens_(Array::Handle(zone_)), | 196 tokens_(Array::Handle(zone_)), |
| 197 stream_(TokenStream::Handle(zone_)), | 197 stream_(TokenStream::Handle(zone_)), |
| 198 data_(ExternalTypedData::Handle(zone_)), | 198 data_(ExternalTypedData::Handle(zone_)), |
| 199 typed_data_(TypedData::Handle(zone_)), | 199 typed_data_(TypedData::Handle(zone_)), |
| 200 code_(Code::Handle(zone_)), | 200 code_(Code::Handle(zone_)), |
| 201 function_(Function::Handle(zone_)), | |
| 202 megamorphic_cache_(MegamorphicCache::Handle(zone_)), | |
| 201 error_(UnhandledException::Handle(zone_)), | 203 error_(UnhandledException::Handle(zone_)), |
| 202 max_vm_isolate_object_id_( | 204 max_vm_isolate_object_id_( |
| 203 (kind == Snapshot::kFull) ? | 205 (kind == Snapshot::kFull) ? |
| 204 Object::vm_isolate_snapshot_object_table().Length() : 0), | 206 Object::vm_isolate_snapshot_object_table().Length() : 0), |
| 205 backward_references_(backward_refs), | 207 backward_references_(backward_refs), |
| 206 instructions_reader_(NULL) { | 208 instructions_reader_(NULL) { |
| 207 if (instructions_buffer != NULL) { | 209 if (instructions_buffer != NULL) { |
| 208 instructions_reader_ = new InstructionsReader(instructions_buffer); | 210 instructions_reader_ = new InstructionsReader(instructions_buffer); |
| 209 } | 211 } |
| 210 } | 212 } |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 // size for the full snapshot being read. | 659 // size for the full snapshot being read. |
| 658 { | 660 { |
| 659 NoSafepointScope no_safepoint; | 661 NoSafepointScope no_safepoint; |
| 660 HeapLocker hl(isolate, old_space()); | 662 HeapLocker hl(isolate, old_space()); |
| 661 | 663 |
| 662 // Read in all the objects stored in the object store. | 664 // Read in all the objects stored in the object store. |
| 663 intptr_t num_flds = (object_store->to() - object_store->from()); | 665 intptr_t num_flds = (object_store->to() - object_store->from()); |
| 664 for (intptr_t i = 0; i <= num_flds; i++) { | 666 for (intptr_t i = 0; i <= num_flds; i++) { |
| 665 *(object_store->from() + i) = ReadObjectImpl(kAsInlinedObject); | 667 *(object_store->from() + i) = ReadObjectImpl(kAsInlinedObject); |
| 666 } | 668 } |
| 669 if (snapshot_code_) { | |
| 670 isolate->megamorphic_cache_table()->ReadFrom(this); | |
| 671 } | |
| 667 for (intptr_t i = 0; i < backward_references_->length(); i++) { | 672 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
| 668 if (!(*backward_references_)[i].is_deserialized()) { | 673 if (!(*backward_references_)[i].is_deserialized()) { |
| 669 ReadObjectImpl(kAsInlinedObject); | 674 ReadObjectImpl(kAsInlinedObject); |
| 670 (*backward_references_)[i].set_state(kIsDeserialized); | 675 (*backward_references_)[i].set_state(kIsDeserialized); |
| 671 } | 676 } |
| 672 } | 677 } |
| 673 | 678 |
| 674 // Validate the class table. | 679 // Validate the class table. |
| 675 #if defined(DEBUG) | 680 #if defined(DEBUG) |
| 676 isolate->ValidateClassTable(); | 681 isolate->ValidateClassTable(); |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1164 // will allocate on the Dart heap. | 1169 // will allocate on the Dart heap. |
| 1165 for (intptr_t i = 0; i < instructions_.length(); i++) { | 1170 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 1166 InstructionsData& data = instructions_[i]; | 1171 InstructionsData& data = instructions_[i]; |
| 1167 data.insns_ = &Instructions::Handle(Z, data.raw_insns_); | 1172 data.insns_ = &Instructions::Handle(Z, data.raw_insns_); |
| 1168 ASSERT(data.raw_code_ != NULL); | 1173 ASSERT(data.raw_code_ != NULL); |
| 1169 data.code_ = &Code::Handle(Z, data.raw_code_); | 1174 data.code_ = &Code::Handle(Z, data.raw_code_); |
| 1170 } | 1175 } |
| 1171 | 1176 |
| 1172 stream_.Print(".text\n"); | 1177 stream_.Print(".text\n"); |
| 1173 stream_.Print(".globl _kInstructionsSnapshot\n"); | 1178 stream_.Print(".globl _kInstructionsSnapshot\n"); |
| 1174 stream_.Print(".balign %" Pd ", 0\n", OS::PreferredCodeAlignment()); | 1179 stream_.Print(".balign %" Pd ", 0\n", OS::kMaxPreferredCodeAlignment); |
| 1175 stream_.Print("_kInstructionsSnapshot:\n"); | 1180 stream_.Print("_kInstructionsSnapshot:\n"); |
| 1176 | 1181 |
| 1182 // This head also provides the gap to make the instructions snapshot | |
| 1183 // look like a HeapPage. | |
| 1184 intptr_t instructions_length = next_offset_; | |
| 1185 stream_.Print(".quad 0x%0.16" Px64 "\n", instructions_length); | |
| 1186 intptr_t header_quads = HeaderSize() / sizeof(uint64_t); | |
| 1187 for (intptr_t i = 1; i < header_quads; i++) { | |
| 1188 stream_.Print(".quad 0\n"); | |
| 1189 } | |
| 1190 | |
| 1177 Object& owner = Object::Handle(Z); | 1191 Object& owner = Object::Handle(Z); |
| 1178 String& str = String::Handle(Z); | 1192 String& str = String::Handle(Z); |
| 1179 | 1193 |
| 1180 for (intptr_t i = 0; i < instructions_.length(); i++) { | 1194 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 1181 const Instructions& insns = *instructions_[i].insns_; | 1195 const Instructions& insns = *instructions_[i].insns_; |
| 1182 const Code& code = *instructions_[i].code_; | 1196 const Code& code = *instructions_[i].code_; |
| 1183 | 1197 |
| 1184 ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0); | 1198 ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0); |
| 1185 | 1199 |
| 1186 { | 1200 { |
| 1187 // 1. Write from the header to the entry point. | 1201 // 1. Write from the header to the entry point. |
| 1188 NoSafepointScope no_safepoint; | 1202 NoSafepointScope no_safepoint; |
| 1203 | |
| 1204 bool was_marked = insns.raw()->IsMarked(); | |
| 1205 bool was_vmheap = insns.raw()->IsVMHeapObject(); | |
| 1206 | |
| 1207 if (!was_marked) { | |
| 1208 insns.raw()->SetMarkBit(); | |
| 1209 } | |
| 1210 if (!was_vmheap) { | |
| 1211 insns.raw()->SetVMHeapObject(); | |
| 1212 } | |
| 1213 | |
| 1214 // Write Instructions with the mark and VM heap bits set. | |
| 1215 ASSERT(insns.raw()->IsMarked()); | |
| 1216 ASSERT(insns.raw()->IsVMHeapObject()); | |
| 1217 | |
| 1189 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; | 1218 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; |
| 1190 uword entry = beginning + Instructions::HeaderSize(); | 1219 uword entry = beginning + Instructions::HeaderSize(); |
| 1191 | 1220 |
| 1192 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); | 1221 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 1193 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); | 1222 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 1194 | 1223 |
| 1195 for (uint64_t* cursor = reinterpret_cast<uint64_t*>(beginning); | 1224 for (uint64_t* cursor = reinterpret_cast<uint64_t*>(beginning); |
| 1196 cursor < reinterpret_cast<uint64_t*>(entry); | 1225 cursor < reinterpret_cast<uint64_t*>(entry); |
| 1197 cursor++) { | 1226 cursor++) { |
| 1198 stream_.Print(".quad 0x%0.16" Px64 "\n", *cursor); | 1227 stream_.Print(".quad 0x%0.16" Px64 "\n", *cursor); |
| 1199 } | 1228 } |
| 1229 | |
| 1230 if (!was_vmheap) { | |
| 1231 insns.raw()->ClearVMHeapObject(); | |
| 1232 } | |
| 1233 if (!was_marked) { | |
| 1234 insns.raw()->ClearMarkBit(); | |
| 1235 } | |
|
siva
2015/09/14 21:29:34
This style of setting and unsetting the mark bit a
rmacnak
2015/09/15 20:07:45
Done.
| |
| 1200 } | 1236 } |
| 1201 | 1237 |
| 1202 // 2. Write a label at the entry point. | 1238 // 2. Write a label at the entry point. |
| 1203 owner = code.owner(); | 1239 owner = code.owner(); |
| 1204 if (owner.IsNull()) { | 1240 if (owner.IsNull()) { |
| 1205 const char* name = StubCode::NameOfStub(insns.EntryPoint()); | 1241 const char* name = StubCode::NameOfStub(insns.EntryPoint()); |
| 1206 stream_.Print("Precompiled_Stub_%s:\n", name); | 1242 stream_.Print("Precompiled_Stub_%s:\n", name); |
| 1207 } else if (owner.IsClass()) { | 1243 } else if (owner.IsClass()) { |
| 1208 str = Class::Cast(owner).Name(); | 1244 str = Class::Cast(owner).Name(); |
| 1209 const char* name = str.ToCString(); | 1245 const char* name = str.ToCString(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1246 reinterpret_cast<RawInstructions*>( | 1282 reinterpret_cast<RawInstructions*>( |
| 1247 reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); | 1283 reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); |
| 1248 | 1284 |
| 1249 uword actual_tags = result->ptr()->tags_; | 1285 uword actual_tags = result->ptr()->tags_; |
| 1250 if (actual_tags != expected_tags) { | 1286 if (actual_tags != expected_tags) { |
| 1251 FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, | 1287 FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, |
| 1252 expected_tags, | 1288 expected_tags, |
| 1253 actual_tags); | 1289 actual_tags); |
| 1254 } | 1290 } |
| 1255 | 1291 |
| 1256 // TODO(rmacnak): The above contains stale pointers to a Code and an | 1292 ASSERT(result->IsMarked()); |
| 1257 // ObjectPool. Return the actual result after calling convention change. | 1293 |
| 1258 return Instructions::null(); | 1294 return result; |
| 1259 } | 1295 } |
| 1260 | 1296 |
| 1261 | 1297 |
| 1262 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { | 1298 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { |
| 1263 // If the header is an object Id, lookup singleton VM classes or classes | 1299 // If the header is an object Id, lookup singleton VM classes or classes |
| 1264 // stored in the object store. | 1300 // stored in the object store. |
| 1265 if (IsVMIsolateObject(class_header)) { | 1301 if (IsVMIsolateObject(class_header)) { |
| 1266 intptr_t class_id = GetVMIsolateObjectId(class_header); | 1302 intptr_t class_id = GetVMIsolateObjectId(class_header); |
| 1267 ASSERT(IsSingletonClassId(class_id)); | 1303 ASSERT(IsSingletonClassId(class_id)); |
| 1268 return class_id; | 1304 return class_id; |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1989 // Write out the version string. | 2025 // Write out the version string. |
| 1990 writer.WriteVersion(); | 2026 writer.WriteVersion(); |
| 1991 | 2027 |
| 1992 // Write out the full snapshot. | 2028 // Write out the full snapshot. |
| 1993 | 2029 |
| 1994 // Write out all the objects in the object store of the isolate which | 2030 // Write out all the objects in the object store of the isolate which |
| 1995 // is the root set for all dart allocated objects at this point. | 2031 // is the root set for all dart allocated objects at this point. |
| 1996 SnapshotWriterVisitor visitor(&writer, false); | 2032 SnapshotWriterVisitor visitor(&writer, false); |
| 1997 object_store->VisitObjectPointers(&visitor); | 2033 object_store->VisitObjectPointers(&visitor); |
| 1998 | 2034 |
| 2035 if (snapshot_code_) { | |
| 2036 isolate_->megamorphic_cache_table()->WriteTo(&writer); | |
| 2037 } | |
| 2038 | |
| 1999 // Write out all forwarded objects. | 2039 // Write out all forwarded objects. |
| 2000 writer.WriteForwardedObjects(); | 2040 writer.WriteForwardedObjects(); |
| 2001 | 2041 |
| 2002 writer.FillHeader(writer.kind()); | 2042 writer.FillHeader(writer.kind()); |
| 2003 writer.UnmarkAll(); | 2043 writer.UnmarkAll(); |
| 2004 | 2044 |
| 2005 isolate_snapshot_size_ = writer.BytesWritten(); | 2045 isolate_snapshot_size_ = writer.BytesWritten(); |
| 2006 } else { | 2046 } else { |
| 2007 writer.ThrowException(writer.exception_type(), writer.exception_msg()); | 2047 writer.ThrowException(writer.exception_type(), writer.exception_msg()); |
| 2008 } | 2048 } |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2784 NoSafepointScope no_safepoint; | 2824 NoSafepointScope no_safepoint; |
| 2785 WriteObject(obj.raw()); | 2825 WriteObject(obj.raw()); |
| 2786 UnmarkAll(); | 2826 UnmarkAll(); |
| 2787 } else { | 2827 } else { |
| 2788 ThrowException(exception_type(), exception_msg()); | 2828 ThrowException(exception_type(), exception_msg()); |
| 2789 } | 2829 } |
| 2790 } | 2830 } |
| 2791 | 2831 |
| 2792 | 2832 |
| 2793 } // namespace dart | 2833 } // namespace dart |
| OLD | NEW |