| 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 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1135 return Mint::NewCanonical(value); | 1135 return Mint::NewCanonical(value); |
| 1136 } | 1136 } |
| 1137 | 1137 |
| 1138 | 1138 |
| 1139 RawStacktrace* SnapshotReader::NewStacktrace() { | 1139 RawStacktrace* SnapshotReader::NewStacktrace() { |
| 1140 ALLOC_NEW_OBJECT(Stacktrace); | 1140 ALLOC_NEW_OBJECT(Stacktrace); |
| 1141 } | 1141 } |
| 1142 | 1142 |
| 1143 | 1143 |
| 1144 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) { | 1144 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) { |
| 1145 // Can't use instructions->Size() because the header was mutated by the |
| 1146 // snapshot writer. |
| 1147 intptr_t heap_size = |
| 1148 Instructions::InstanceSize(instructions->ptr()->size_); |
| 1145 intptr_t offset = next_offset_; | 1149 intptr_t offset = next_offset_; |
| 1146 next_offset_ += instructions->Size(); | 1150 next_offset_ += heap_size; |
| 1147 instructions_.Add(InstructionsData(instructions)); | 1151 instructions_.Add(InstructionsData(instructions)); |
| 1148 return offset; | 1152 return offset; |
| 1149 } | 1153 } |
| 1150 | 1154 |
| 1151 | 1155 |
| 1152 static void EnsureIdentifier(char* label) { | 1156 static void EnsureIdentifier(char* label) { |
| 1153 for (char c = *label; c != '\0'; c = *++label) { | 1157 for (char c = *label; c != '\0'; c = *++label) { |
| 1154 if (((c >= 'a') && (c <= 'z')) || | 1158 if (((c >= 'a') && (c <= 'z')) || |
| 1155 ((c >= 'A') && (c <= 'Z')) || | 1159 ((c >= 'A') && (c <= 'Z')) || |
| 1156 ((c >= '0') && (c <= '9'))) { | 1160 ((c >= '0') && (c <= '9'))) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1168 // will allocate on the Dart heap. | 1172 // will allocate on the Dart heap. |
| 1169 for (intptr_t i = 0; i < instructions_.length(); i++) { | 1173 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 1170 InstructionsData& data = instructions_[i]; | 1174 InstructionsData& data = instructions_[i]; |
| 1171 data.insns_ = &Instructions::Handle(Z, data.raw_insns_); | 1175 data.insns_ = &Instructions::Handle(Z, data.raw_insns_); |
| 1172 ASSERT(data.raw_code_ != NULL); | 1176 ASSERT(data.raw_code_ != NULL); |
| 1173 data.code_ = &Code::Handle(Z, data.raw_code_); | 1177 data.code_ = &Code::Handle(Z, data.raw_code_); |
| 1174 } | 1178 } |
| 1175 | 1179 |
| 1176 stream_.Print(".text\n"); | 1180 stream_.Print(".text\n"); |
| 1177 stream_.Print(".globl _kInstructionsSnapshot\n"); | 1181 stream_.Print(".globl _kInstructionsSnapshot\n"); |
| 1178 stream_.Print(".balign %" Pd ", 0\n", OS::PreferredCodeAlignment()); | 1182 stream_.Print(".balign %" Pd ", 0\n", OS::kMaxPreferredCodeAlignment); |
| 1179 stream_.Print("_kInstructionsSnapshot:\n"); | 1183 stream_.Print("_kInstructionsSnapshot:\n"); |
| 1180 | 1184 |
| 1185 // This head also provides the gap to make the instructions snapshot |
| 1186 // look like a HeapPage. |
| 1187 intptr_t instructions_length = next_offset_; |
| 1188 WriteWordLiteral(instructions_length); |
| 1189 intptr_t header_words = InstructionsSnapshot::kHeaderSize / sizeof(uword); |
| 1190 for (intptr_t i = 1; i < header_words; i++) { |
| 1191 WriteWordLiteral(0); |
| 1192 } |
| 1193 |
| 1181 Object& owner = Object::Handle(Z); | 1194 Object& owner = Object::Handle(Z); |
| 1182 String& str = String::Handle(Z); | 1195 String& str = String::Handle(Z); |
| 1183 | 1196 |
| 1184 for (intptr_t i = 0; i < instructions_.length(); i++) { | 1197 for (intptr_t i = 0; i < instructions_.length(); i++) { |
| 1185 const Instructions& insns = *instructions_[i].insns_; | 1198 const Instructions& insns = *instructions_[i].insns_; |
| 1186 const Code& code = *instructions_[i].code_; | 1199 const Code& code = *instructions_[i].code_; |
| 1187 | 1200 |
| 1188 ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0); | 1201 ASSERT(insns.raw()->Size() % sizeof(uint64_t) == 0); |
| 1189 | 1202 |
| 1190 { | 1203 { |
| 1191 // 1. Write from the header to the entry point. | 1204 // 1. Write from the header to the entry point. |
| 1192 NoSafepointScope no_safepoint; | 1205 NoSafepointScope no_safepoint; |
| 1193 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; | 1206 |
| 1207 uword beginning = reinterpret_cast<uword>(insns.raw_ptr()); |
| 1194 uword entry = beginning + Instructions::HeaderSize(); | 1208 uword entry = beginning + Instructions::HeaderSize(); |
| 1195 | 1209 |
| 1196 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); | 1210 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 1197 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); | 1211 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 1198 | 1212 |
| 1199 for (uint64_t* cursor = reinterpret_cast<uint64_t*>(beginning); | 1213 // Write Instructions with the mark and VM heap bits set. |
| 1200 cursor < reinterpret_cast<uint64_t*>(entry); | 1214 uword marked_tags = insns.raw_ptr()->tags_; |
| 1215 marked_tags = RawObject::VMHeapObjectTag::update(true, marked_tags); |
| 1216 marked_tags = RawObject::MarkBit::update(true, marked_tags); |
| 1217 |
| 1218 WriteWordLiteral(marked_tags); |
| 1219 beginning += sizeof(uword); |
| 1220 |
| 1221 for (uword* cursor = reinterpret_cast<uword*>(beginning); |
| 1222 cursor < reinterpret_cast<uword*>(entry); |
| 1201 cursor++) { | 1223 cursor++) { |
| 1202 stream_.Print(".quad 0x%0.16" Px64 "\n", *cursor); | 1224 WriteWordLiteral(*cursor); |
| 1203 } | 1225 } |
| 1204 } | 1226 } |
| 1205 | 1227 |
| 1206 // 2. Write a label at the entry point. | 1228 // 2. Write a label at the entry point. |
| 1207 owner = code.owner(); | 1229 owner = code.owner(); |
| 1208 if (owner.IsNull()) { | 1230 if (owner.IsNull()) { |
| 1209 const char* name = StubCode::NameOfStub(insns.EntryPoint()); | 1231 const char* name = StubCode::NameOfStub(insns.EntryPoint()); |
| 1210 stream_.Print("Precompiled_Stub_%s:\n", name); | 1232 stream_.Print("Precompiled_Stub_%s:\n", name); |
| 1211 } else if (owner.IsClass()) { | 1233 } else if (owner.IsClass()) { |
| 1212 str = Class::Cast(owner).Name(); | 1234 str = Class::Cast(owner).Name(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1225 // 3. Write from the entry point to the end. | 1247 // 3. Write from the entry point to the end. |
| 1226 NoSafepointScope no_safepoint; | 1248 NoSafepointScope no_safepoint; |
| 1227 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; | 1249 uword beginning = reinterpret_cast<uword>(insns.raw()) - kHeapObjectTag; |
| 1228 uword entry = beginning + Instructions::HeaderSize(); | 1250 uword entry = beginning + Instructions::HeaderSize(); |
| 1229 uword end = beginning + insns.raw()->Size(); | 1251 uword end = beginning + insns.raw()->Size(); |
| 1230 | 1252 |
| 1231 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); | 1253 ASSERT(Utils::IsAligned(beginning, sizeof(uint64_t))); |
| 1232 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); | 1254 ASSERT(Utils::IsAligned(entry, sizeof(uint64_t))); |
| 1233 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); | 1255 ASSERT(Utils::IsAligned(end, sizeof(uint64_t))); |
| 1234 | 1256 |
| 1235 for (uint64_t* cursor = reinterpret_cast<uint64_t*>(entry); | 1257 for (uword* cursor = reinterpret_cast<uword*>(entry); |
| 1236 cursor < reinterpret_cast<uint64_t*>(end); | 1258 cursor < reinterpret_cast<uword*>(end); |
| 1237 cursor++) { | 1259 cursor++) { |
| 1238 stream_.Print(".quad 0x%0.16" Px64 "\n", *cursor); | 1260 WriteWordLiteral(*cursor); |
| 1239 } | 1261 } |
| 1240 } | 1262 } |
| 1241 } | 1263 } |
| 1242 } | 1264 } |
| 1243 | 1265 |
| 1244 | 1266 |
| 1245 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset, | 1267 RawInstructions* InstructionsReader::GetInstructionsAt(int32_t offset, |
| 1246 uword expected_tags) { | 1268 uword expected_tags) { |
| 1247 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); | 1269 ASSERT(Utils::IsAligned(offset, OS::PreferredCodeAlignment())); |
| 1248 | 1270 |
| 1249 RawInstructions* result = | 1271 RawInstructions* result = |
| 1250 reinterpret_cast<RawInstructions*>( | 1272 reinterpret_cast<RawInstructions*>( |
| 1251 reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); | 1273 reinterpret_cast<uword>(buffer_) + offset + kHeapObjectTag); |
| 1252 | 1274 |
| 1253 uword actual_tags = result->ptr()->tags_; | 1275 uword actual_tags = result->ptr()->tags_; |
| 1254 if (actual_tags != expected_tags) { | 1276 if (actual_tags != expected_tags) { |
| 1255 FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, | 1277 FATAL2("Instructions tag mismatch: expected %" Pd ", saw %" Pd, |
| 1256 expected_tags, | 1278 expected_tags, |
| 1257 actual_tags); | 1279 actual_tags); |
| 1258 } | 1280 } |
| 1259 | 1281 |
| 1260 // TODO(rmacnak): The above contains stale pointers to a Code and an | 1282 ASSERT(result->IsMarked()); |
| 1261 // ObjectPool. Return the actual result after calling convention change. | 1283 |
| 1262 return Instructions::null(); | 1284 return result; |
| 1263 } | 1285 } |
| 1264 | 1286 |
| 1265 | 1287 |
| 1266 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { | 1288 intptr_t SnapshotReader::LookupInternalClass(intptr_t class_header) { |
| 1267 // If the header is an object Id, lookup singleton VM classes or classes | 1289 // If the header is an object Id, lookup singleton VM classes or classes |
| 1268 // stored in the object store. | 1290 // stored in the object store. |
| 1269 if (IsVMIsolateObject(class_header)) { | 1291 if (IsVMIsolateObject(class_header)) { |
| 1270 intptr_t class_id = GetVMIsolateObjectId(class_header); | 1292 intptr_t class_id = GetVMIsolateObjectId(class_header); |
| 1271 ASSERT(IsSingletonClassId(class_id)); | 1293 ASSERT(IsSingletonClassId(class_id)); |
| 1272 return class_id; | 1294 return class_id; |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1488 | 1510 |
| 1489 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { | 1511 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { |
| 1490 intptr_t len = GetBackwardReferenceTable()->length(); | 1512 intptr_t len = GetBackwardReferenceTable()->length(); |
| 1491 Object::InitVmIsolateSnapshotObjectTable(len); | 1513 Object::InitVmIsolateSnapshotObjectTable(len); |
| 1492 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable(); | 1514 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable(); |
| 1493 for (intptr_t i = 0; i < len; i++) { | 1515 for (intptr_t i = 0; i < len; i++) { |
| 1494 Object::vm_isolate_snapshot_object_table().SetAt( | 1516 Object::vm_isolate_snapshot_object_table().SetAt( |
| 1495 i, *(backrefs->At(i).reference())); | 1517 i, *(backrefs->At(i).reference())); |
| 1496 } | 1518 } |
| 1497 ResetBackwardReferenceTable(); | 1519 ResetBackwardReferenceTable(); |
| 1498 Object::set_instructions_snapshot_buffer(instructions_buffer_); | 1520 Dart::set_instructions_snapshot_buffer(instructions_buffer_); |
| 1499 } | 1521 } |
| 1500 | 1522 |
| 1501 | 1523 |
| 1502 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { | 1524 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
| 1503 ASSERT(kind() == Snapshot::kFull); | 1525 ASSERT(kind() == Snapshot::kFull); |
| 1504 Isolate* isolate = Isolate::Current(); | 1526 Isolate* isolate = Isolate::Current(); |
| 1505 ASSERT(isolate != NULL); | 1527 ASSERT(isolate != NULL); |
| 1506 ASSERT(isolate == Dart::vm_isolate()); | 1528 ASSERT(isolate == Dart::vm_isolate()); |
| 1507 ObjectStore* object_store = isolate->object_store(); | 1529 ObjectStore* object_store = isolate->object_store(); |
| 1508 ASSERT(object_store != NULL); | 1530 ASSERT(object_store != NULL); |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2783 NoSafepointScope no_safepoint; | 2805 NoSafepointScope no_safepoint; |
| 2784 WriteObject(obj.raw()); | 2806 WriteObject(obj.raw()); |
| 2785 UnmarkAll(); | 2807 UnmarkAll(); |
| 2786 } else { | 2808 } else { |
| 2787 ThrowException(exception_type(), exception_msg()); | 2809 ThrowException(exception_type(), exception_msg()); |
| 2788 } | 2810 } |
| 2789 } | 2811 } |
| 2790 | 2812 |
| 2791 | 2813 |
| 2792 } // namespace dart | 2814 } // namespace dart |
| OLD | NEW |