| 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 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 return Mint::NewCanonical(value); | 1172 return Mint::NewCanonical(value); |
| 1173 } | 1173 } |
| 1174 | 1174 |
| 1175 | 1175 |
| 1176 RawStacktrace* SnapshotReader::NewStacktrace() { | 1176 RawStacktrace* SnapshotReader::NewStacktrace() { |
| 1177 ALLOC_NEW_OBJECT(Stacktrace); | 1177 ALLOC_NEW_OBJECT(Stacktrace); |
| 1178 } | 1178 } |
| 1179 | 1179 |
| 1180 | 1180 |
| 1181 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) { | 1181 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) { |
| 1182 // Can't use instructions->Size() because the header was mutated by the |
| 1183 // snapshot writer. |
| 1184 intptr_t heap_size = |
| 1185 Instructions::InstanceSize(instructions->ptr()->size_); |
| 1182 intptr_t offset = next_offset_; | 1186 intptr_t offset = next_offset_; |
| 1183 next_offset_ += instructions->Size(); | 1187 next_offset_ += heap_size; |
| 1184 instructions_.Add(InstructionsData(instructions)); | 1188 instructions_.Add(InstructionsData(instructions)); |
| 1185 return offset; | 1189 return offset; |
| 1186 } | 1190 } |
| 1187 | 1191 |
| 1188 | 1192 |
| 1189 static void EnsureIdentifier(char* label) { | 1193 static void EnsureIdentifier(char* label) { |
| 1190 for (char c = *label; c != '\0'; c = *++label) { | 1194 for (char c = *label; c != '\0'; c = *++label) { |
| 1191 if (((c >= 'a') && (c <= 'z')) || | 1195 if (((c >= 'a') && (c <= 'z')) || |
| 1192 ((c >= 'A') && (c <= 'Z')) || | 1196 ((c >= 'A') && (c <= 'Z')) || |
| 1193 ((c >= '0') && (c <= '9'))) { | 1197 ((c >= '0') && (c <= '9'))) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1205 // will allocate on the Dart heap. | 1209 // will allocate on the Dart heap. |
| 1206 for (intptr_t i = 0; i < instructions_.length(); i++) { | 1210 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 1207 InstructionsData& data = instructions_[i]; | 1211 InstructionsData& data = instructions_[i]; |
| 1208 data.insns_ = &Instructions::Handle(Z, data.raw_insns_); | 1212 data.insns_ = &Instructions::Handle(Z, data.raw_insns_); |
| 1209 ASSERT(data.raw_code_ != NULL); | 1213 ASSERT(data.raw_code_ != NULL); |
| 1210 data.code_ = &Code::Handle(Z, data.raw_code_); | 1214 data.code_ = &Code::Handle(Z, data.raw_code_); |
| 1211 } | 1215 } |
| 1212 | 1216 |
| 1213 stream_.Print(".text\n"); | 1217 stream_.Print(".text\n"); |
| 1214 stream_.Print(".globl _kInstructionsSnapshot\n"); | 1218 stream_.Print(".globl _kInstructionsSnapshot\n"); |
| 1215 stream_.Print(".balign %" Pd ", 0\n", OS::PreferredCodeAlignment()); | 1219 stream_.Print(".balign %" Pd ", 0\n", OS::kMaxPreferredCodeAlignment); |
| 1216 stream_.Print("_kInstructionsSnapshot:\n"); | 1220 stream_.Print("_kInstructionsSnapshot:\n"); |
| 1217 | 1221 |
| 1222 // This head also provides the gap to make the instructions snapshot |
| 1223 // look like a HeapPage. |
| 1224 intptr_t instructions_length = next_offset_; |
| 1225 WriteWordLiteral(instructions_length); |
| 1226 intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword); |
| 1227 for (intptr_t i = 1; i < header_words; i++) { |
| 1228 WriteWordLiteral(0); |
| 1229 } |
| 1230 |
| 1218 Object& owner = Object::Handle(Z); | 1231 Object& owner = Object::Handle(Z); |
| 1219 String& str = String::Handle(Z); | 1232 String& str = String::Handle(Z); |
| 1220 | 1233 |
| 1221 for (intptr_t i = 0; i < instructions_.length(); i++) { | 1234 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 1222 const Instructions& insns = *instructions_[i].insns_; | 1235 const Instructions& insns = *instructions_[i].insns_; |
| 1223 const Code& code = *instructions_[i].code_; | 1236 const Code& code = *instructions_[i].code_; |
| 1224 | 1237 |
| 1225 ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0); | 1238 ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0); |
| 1226 | 1239 |
| 1227 { | 1240 { |
| 1228 // 1. Write from the header to the entry point. | 1241 // 1. Write from the header to the entry point. |
| 1229 NoSafepointScope no_safepoint; | 1242 NoSafepointScope no_safepoint; |
| 1230 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; | 1243 |
| 1244 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); |
| 1231 uword entry = beginning + Instructions::HeaderSize(); | 1245 uword entry = beginning + Instructions::HeaderSize(); |
| 1232 | 1246 |
| 1233 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); | 1247 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 1234 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); | 1248 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 1235 | 1249 |
| 1236 for (uint64_t* cursor = reinterpret_cast<uint64_t*>(beginning); | 1250 // Write Instructions with the mark and VM heap bits set. |
| 1237 cursor < reinterpret_cast<uint64_t*>(entry); | 1251 uword marked_tags = insns.raw_ptr()->tags_; |
| 1252 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
| 1253 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
| 1254 |
| 1255 WriteWordLiteral(marked_tags); |
| 1256 beginning += sizeof(uword); |
| 1257 |
| 1258 for (uword* cursor = reinterpret_cast<uword*>(beginning); |
| 1259 cursor < reinterpret_cast<uword*>(entry); |
| 1238 cursor++) { | 1260 cursor++) { |
| 1239 stream_.Print(".quad 0x%0.16" Px64 "\n", *cursor); | 1261 WriteWordLiteral(*cursor); |
| 1240 } | 1262 } |
| 1241 } | 1263 } |
| 1242 | 1264 |
| 1243 // 2. Write a label at the entry point. | 1265 // 2. Write a label at the entry point. |
| 1244 owner = code.owner(); | 1266 owner = code.owner(); |
| 1245 if (owner.IsNull()) { | 1267 if (owner.IsNull()) { |
| 1246 const char* name = StubCode::NameOfStub(insns.EntryPoint()); | 1268 const char* name = StubCode::NameOfStub(insns.EntryPoint()); |
| 1247 stream_.Print("Precompiled_Stub_%s:\n", name); | 1269 stream_.Print("Precompiled_Stub_%s:\n", name); |
| 1248 } else if (owner.IsClass()) { | 1270 } else if (owner.IsClass()) { |
| 1249 str = Class::Cast(owner).Name(); | 1271 str = Class::Cast(owner).Name(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1262 // 3. Write from the entry point to the end. | 1284 // 3. Write from the entry point to the end. |
| 1263 NoSafepointScope no_safepoint; | 1285 NoSafepointScope no_safepoint; |
| 1264 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; | 1286 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; |
| 1265 uword entry = beginning + Instructions::HeaderSize(); | 1287 uword entry = beginning + Instructions::HeaderSize(); |
| 1266 uword end = beginning + insns.raw()->Size(); | 1288 uword end = beginning + insns.raw()->Size(); |
| 1267 | 1289 |
| 1268 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); | 1290 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 1269 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); | 1291 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 1270 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); | 1292 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); |
| 1271 | 1293 |
| 1272 for (uint64_t* cursor = reinterpret_cast<uint64_t*>(entry); | 1294 for (uword* cursor = reinterpret_cast<uword*>(entry); |
| 1273 cursor < reinterpret_cast<uint64_t*>(end); | 1295 cursor < reinterpret_cast<uword*>(end); |
| 1274 cursor++) { | 1296 cursor++) { |
| 1275 stream_.Print(".quad 0x%0.16" Px64 "\n", *cursor); | 1297 WriteWordLiteral(*cursor); |
| 1276 } | 1298 } |
| 1277 } | 1299 } |
| 1278 } | 1300 } |
| 1279 } | 1301 } |
| 1280 | 1302 |
| 1281 | 1303 |
| 1282 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset, | 1304 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset, |
| 1283 uword expected_tags) { | 1305 uword expected_tags) { |
| 1284 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); | 1306 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); |
| 1285 | 1307 |
| 1286 RawInstructions* result = | 1308 RawInstructions* result = |
| 1287 reinterpret_cast<RawInstructions*>( | 1309 reinterpret_cast<RawInstructions*>( |
| 1288 reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); | 1310 reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); |
| 1289 | 1311 |
| 1290 uword actual_tags = result->ptr()->tags_; | 1312 uword actual_tags = result->ptr()->tags_; |
| 1291 if (actual_tags != expected_tags) { | 1313 if (actual_tags != expected_tags) { |
| 1292 FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, | 1314 FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, |
| 1293 expected_tags, | 1315 expected_tags, |
| 1294 actual_tags); | 1316 actual_tags); |
| 1295 } | 1317 } |
| 1296 | 1318 |
| 1297 // TODO(rmacnak): The above contains stale pointers to a Code and an | 1319 ASSERT(result->IsMarked()); |
| 1298 // ObjectPool. Return the actual result after calling convention change. | 1320 |
| 1299 return Instructions::null(); | 1321 return result; |
| 1300 } | 1322 } |
| 1301 | 1323 |
| 1302 | 1324 |
| 1303 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { | 1325 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { |
| 1304 // If the header is an object Id, lookup singleton VM classes or classes | 1326 // If the header is an object Id, lookup singleton VM classes or classes |
| 1305 // stored in the object store. | 1327 // stored in the object store. |
| 1306 if (IsVMIsolateObject(class_header)) { | 1328 if (IsVMIsolateObject(class_header)) { |
| 1307 intptr_t class_id = GetVMIsolateObjectId(class_header); | 1329 intptr_t class_id = GetVMIsolateObjectId(class_header); |
| 1308 ASSERT(IsSingletonClassId(class_id)); | 1330 ASSERT(IsSingletonClassId(class_id)); |
| 1309 return class_id; | 1331 return class_id; |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1526 | 1548 |
| 1527 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { | 1549 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { |
| 1528 intptr_t len = GetBackwardReferenceTable()->length(); | 1550 intptr_t len = GetBackwardReferenceTable()->length(); |
| 1529 Object::InitVmIsolateSnapshotObjectTable(len); | 1551 Object::InitVmIsolateSnapshotObjectTable(len); |
| 1530 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable(); | 1552 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable(); |
| 1531 for (intptr_t i = 0; i < len; i++) { | 1553 for (intptr_t i = 0; i < len; i++) { |
| 1532 Object::vm_isolate_snapshot_object_table().SetAt( | 1554 Object::vm_isolate_snapshot_object_table().SetAt( |
| 1533 i, *(backrefs->At(i).reference())); | 1555 i, *(backrefs->At(i).reference())); |
| 1534 } | 1556 } |
| 1535 ResetBackwardReferenceTable(); | 1557 ResetBackwardReferenceTable(); |
| 1536 Object::set_instructions_snapshot_buffer(instructions_buffer_); | 1558 Dart::set_instructions_snapshot_buffer(instructions_buffer_); |
| 1537 } | 1559 } |
| 1538 | 1560 |
| 1539 | 1561 |
| 1540 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { | 1562 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
| 1541 ASSERT(kind() == Snapshot::kFull); | 1563 ASSERT(kind() == Snapshot::kFull); |
| 1542 Isolate* isolate = Isolate::Current(); | 1564 Isolate* isolate = Isolate::Current(); |
| 1543 ASSERT(isolate != NULL); | 1565 ASSERT(isolate != NULL); |
| 1544 ASSERT(isolate == Dart::vm_isolate()); | 1566 ASSERT(isolate == Dart::vm_isolate()); |
| 1545 ObjectStore* object_store = isolate->object_store(); | 1567 ObjectStore* object_store = isolate->object_store(); |
| 1546 ASSERT(object_store != NULL); | 1568 ASSERT(object_store != NULL); |
| (...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2777 NoSafepointScope no_safepoint; | 2799 NoSafepointScope no_safepoint; |
| 2778 WriteObject(obj.raw()); | 2800 WriteObject(obj.raw()); |
| 2779 UnmarkAll(); | 2801 UnmarkAll(); |
| 2780 } else { | 2802 } else { |
| 2781 ThrowException(exception_type(), exception_msg()); | 2803 ThrowException(exception_type(), exception_msg()); |
| 2782 } | 2804 } |
| 2783 } | 2805 } |
| 2784 | 2806 |
| 2785 | 2807 |
| 2786 } // namespace dart | 2808 } // namespace dart |
| OLD | NEW |