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/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| 11 #include "vm/exceptions.h" | 11 #include "vm/exceptions.h" |
| 12 #include "vm/heap.h" | 12 #include "vm/heap.h" |
| 13 #include "vm/lockers.h" | |
| 13 #include "vm/longjump.h" | 14 #include "vm/longjump.h" |
| 14 #include "vm/object.h" | 15 #include "vm/object.h" |
| 15 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
| 16 #include "vm/snapshot_ids.h" | 17 #include "vm/snapshot_ids.h" |
| 17 #include "vm/symbols.h" | 18 #include "vm/symbols.h" |
| 18 #include "vm/version.h" | 19 #include "vm/version.h" |
| 19 | 20 |
| 20 namespace dart { | 21 namespace dart { |
| 21 | 22 |
| 22 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; | 23 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; |
| (...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1051 } | 1052 } |
| 1052 } | 1053 } |
| 1053 | 1054 |
| 1054 | 1055 |
| 1055 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, | 1056 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, |
| 1056 uint8_t** buffer, | 1057 uint8_t** buffer, |
| 1057 ReAlloc alloc, | 1058 ReAlloc alloc, |
| 1058 intptr_t initial_size) | 1059 intptr_t initial_size) |
| 1059 : BaseWriter(buffer, alloc, initial_size), | 1060 : BaseWriter(buffer, alloc, initial_size), |
| 1060 kind_(kind), | 1061 kind_(kind), |
| 1061 object_store_(Isolate::Current()->object_store()), | 1062 isolate_(Isolate::Current()), |
| 1062 class_table_(Isolate::Current()->class_table()), | 1063 object_store_(isolate_->object_store()), |
| 1064 class_table_(isolate_->class_table()), | |
| 1063 forward_list_(kMaxPredefinedObjectIds), | 1065 forward_list_(kMaxPredefinedObjectIds), |
| 1064 exception_type_(Exceptions::kNone), | 1066 exception_type_(Exceptions::kNone), |
| 1065 exception_msg_(NULL) { | 1067 exception_msg_(NULL) { |
| 1066 } | 1068 } |
| 1067 | 1069 |
| 1068 | 1070 |
| 1069 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1071 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
| 1070 WriteObjectImpl(rawobj); | 1072 WriteObjectImpl(rawobj); |
| 1071 WriteForwardedObjects(); | 1073 WriteForwardedObjects(); |
| 1072 } | 1074 } |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1238 return; | 1240 return; |
| 1239 } | 1241 } |
| 1240 #undef SNAPSHOT_WRITE | 1242 #undef SNAPSHOT_WRITE |
| 1241 default: break; | 1243 default: break; |
| 1242 } | 1244 } |
| 1243 UNREACHABLE(); | 1245 UNREACHABLE(); |
| 1244 } | 1246 } |
| 1245 | 1247 |
| 1246 | 1248 |
| 1247 void FullSnapshotWriter::WriteFullSnapshot() { | 1249 void FullSnapshotWriter::WriteFullSnapshot() { |
| 1248 Isolate* isolate = Isolate::Current(); | 1250 ASSERT(isolate() != NULL); |
| 1249 ASSERT(isolate != NULL); | 1251 ObjectStore* object_store = isolate()->object_store(); |
| 1250 ObjectStore* object_store = isolate->object_store(); | |
| 1251 ASSERT(object_store != NULL); | 1252 ASSERT(object_store != NULL); |
| 1252 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1253 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 1253 | 1254 |
| 1254 // Ensure the class table is valid. | 1255 // Ensure the class table is valid. |
| 1255 #if defined(DEBUG) | 1256 #if defined(DEBUG) |
| 1256 isolate->ValidateClassTable(); | 1257 isolate()->ValidateClassTable(); |
| 1257 #endif | 1258 #endif |
| 1258 | 1259 |
| 1259 // Setup for long jump in case there is an exception while writing | 1260 // Setup for long jump in case there is an exception while writing |
| 1260 // the snapshot. | 1261 // the snapshot. |
| 1261 LongJumpScope jump; | 1262 LongJumpScope jump; |
| 1262 if (setjmp(*jump.Set()) == 0) { | 1263 if (setjmp(*jump.Set()) == 0) { |
| 1263 // Reserve space in the output buffer for a snapshot header. | 1264 // Reserve space in the output buffer for a snapshot header. |
| 1264 ReserveHeader(); | 1265 ReserveHeader(); |
| 1265 | 1266 |
| 1266 // Write out the version string. | 1267 // Write out the version string. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1291 uword tags = raw->ptr()->tags_; | 1292 uword tags = raw->ptr()->tags_; |
| 1292 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 1293 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
| 1293 intptr_t id = SerializedHeaderData::decode(tags); | 1294 intptr_t id = SerializedHeaderData::decode(tags); |
| 1294 return forward_list_.NodeForObjectId(id)->tags(); | 1295 return forward_list_.NodeForObjectId(id)->tags(); |
| 1295 } else { | 1296 } else { |
| 1296 return tags; | 1297 return tags; |
| 1297 } | 1298 } |
| 1298 } | 1299 } |
| 1299 | 1300 |
| 1300 | 1301 |
| 1302 ForwardList::ForwardList(intptr_t first_object_id) | |
| 1303 : first_object_id_(first_object_id), | |
| 1304 nodes_(), | |
| 1305 first_unprocessed_object_id_(first_object_id) { | |
| 1306 // The ForwardList encodes information in the header tag word. There cannot | |
|
koda
2014/09/02 04:18:31
cannot -> must not?
I.e., are you saying that thi
| |
| 1307 // be any concurrent GC tasks while it is in use. | |
| 1308 PageSpace* page_space = Isolate::Current()->heap()->old_space(); | |
| 1309 MonitorLocker ml(page_space->tasks_lock()); | |
| 1310 while (page_space->tasks() > 0) { | |
| 1311 ml.Wait(); | |
| 1312 } | |
| 1313 page_space->set_tasks(1); | |
|
koda
2014/09/02 04:18:31
Do you consider this an actual "task", or are you
| |
| 1314 } | |
| 1315 | |
| 1316 | |
| 1317 ForwardList::~ForwardList() { | |
| 1318 PageSpace* page_space = Isolate::Current()->heap()->old_space(); | |
| 1319 MonitorLocker ml(page_space->tasks_lock()); | |
| 1320 ASSERT(page_space->tasks() == 1); | |
| 1321 page_space->set_tasks(0); | |
| 1322 ml.Notify(); | |
| 1323 } | |
| 1324 | |
| 1325 | |
| 1301 intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) { | 1326 intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) { |
| 1302 NoGCScope no_gc; | 1327 NoGCScope no_gc; |
| 1303 intptr_t object_id = next_object_id(); | 1328 intptr_t object_id = next_object_id(); |
| 1304 ASSERT(object_id <= kMaxObjectId); | 1329 ASSERT(object_id <= kMaxObjectId); |
| 1305 uword value = 0; | 1330 uword value = 0; |
| 1306 value = SerializedHeaderTag::update(kObjectId, value); | 1331 value = SerializedHeaderTag::update(kObjectId, value); |
| 1307 value = SerializedHeaderData::update(object_id, value); | 1332 value = SerializedHeaderData::update(object_id, value); |
| 1308 uword tags = raw->ptr()->tags_; | 1333 uword tags = raw->ptr()->tags_; |
| 1309 ASSERT(SerializedHeaderTag::decode(tags) != kObjectId); | 1334 ASSERT(SerializedHeaderTag::decode(tags) != kObjectId); |
| 1310 raw->ptr()->tags_ = value; | 1335 raw->ptr()->tags_ = value; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1600 " : (object extends NativeWrapper)"); | 1625 " : (object extends NativeWrapper)"); |
| 1601 } | 1626 } |
| 1602 } | 1627 } |
| 1603 | 1628 |
| 1604 | 1629 |
| 1605 void SnapshotWriter::SetWriteException(Exceptions::ExceptionType type, | 1630 void SnapshotWriter::SetWriteException(Exceptions::ExceptionType type, |
| 1606 const char* msg) { | 1631 const char* msg) { |
| 1607 set_exception_type(type); | 1632 set_exception_type(type); |
| 1608 set_exception_msg(msg); | 1633 set_exception_msg(msg); |
| 1609 // The more specific error is set up in SnapshotWriter::ThrowException(). | 1634 // The more specific error is set up in SnapshotWriter::ThrowException(). |
| 1610 Isolate::Current()->long_jump_base()-> | 1635 isolate()->long_jump_base()-> |
| 1611 Jump(1, Object::snapshot_writer_error()); | 1636 Jump(1, Object::snapshot_writer_error()); |
| 1612 } | 1637 } |
| 1613 | 1638 |
| 1614 | 1639 |
| 1615 void SnapshotWriter::WriteInstance(intptr_t object_id, | 1640 void SnapshotWriter::WriteInstance(intptr_t object_id, |
| 1616 RawObject* raw, | 1641 RawObject* raw, |
| 1617 RawClass* cls, | 1642 RawClass* cls, |
| 1618 intptr_t tags) { | 1643 intptr_t tags) { |
| 1619 // First check if object is a closure or has native fields. | 1644 // First check if object is a closure or has native fields. |
| 1620 CheckIfSerializable(cls); | 1645 CheckIfSerializable(cls); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1665 // Indicate this is an instance object. | 1690 // Indicate this is an instance object. |
| 1666 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); | 1691 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
| 1667 | 1692 |
| 1668 // Write out the class information for this object. | 1693 // Write out the class information for this object. |
| 1669 WriteObjectImpl(cls); | 1694 WriteObjectImpl(cls); |
| 1670 } | 1695 } |
| 1671 | 1696 |
| 1672 | 1697 |
| 1673 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, | 1698 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, |
| 1674 const char* msg) { | 1699 const char* msg) { |
| 1675 Isolate::Current()->object_store()->clear_sticky_error(); | 1700 isolate()->object_store()->clear_sticky_error(); |
| 1676 UnmarkAll(); | 1701 UnmarkAll(); |
| 1677 if (msg != NULL) { | 1702 if (msg != NULL) { |
| 1678 const String& msg_obj = String::Handle(String::New(msg)); | 1703 const String& msg_obj = String::Handle(String::New(msg)); |
| 1679 const Array& args = Array::Handle(Array::New(1)); | 1704 const Array& args = Array::Handle(Array::New(1)); |
| 1680 args.SetAt(0, msg_obj); | 1705 args.SetAt(0, msg_obj); |
| 1681 Exceptions::ThrowByType(type, args); | 1706 Exceptions::ThrowByType(type, args); |
| 1682 } else { | 1707 } else { |
| 1683 Exceptions::ThrowByType(type, Object::empty_array()); | 1708 Exceptions::ThrowByType(type, Object::empty_array()); |
| 1684 } | 1709 } |
| 1685 UNREACHABLE(); | 1710 UNREACHABLE(); |
| 1686 } | 1711 } |
| 1687 | 1712 |
| 1688 | 1713 |
| 1689 void SnapshotWriter::WriteVersion() { | 1714 void SnapshotWriter::WriteVersion() { |
| 1690 const char* expected_version = Version::SnapshotString(); | 1715 const char* expected_version = Version::SnapshotString(); |
| 1691 ASSERT(expected_version != NULL); | 1716 ASSERT(expected_version != NULL); |
| 1692 const intptr_t version_len = strlen(expected_version); | 1717 const intptr_t version_len = strlen(expected_version); |
| 1693 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len); | 1718 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len); |
| 1694 } | 1719 } |
| 1695 | 1720 |
| 1696 | 1721 |
| 1697 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 1722 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
| 1698 ASSERT(kind() == Snapshot::kScript); | 1723 ASSERT(kind() == Snapshot::kScript); |
| 1699 Isolate* isolate = Isolate::Current(); | 1724 ASSERT(isolate() != NULL); |
| 1700 ASSERT(isolate != NULL); | |
| 1701 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1725 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 1702 | 1726 |
| 1703 // Setup for long jump in case there is an exception while writing | 1727 // Setup for long jump in case there is an exception while writing |
| 1704 // the snapshot. | 1728 // the snapshot. |
| 1705 LongJumpScope jump; | 1729 LongJumpScope jump; |
| 1706 if (setjmp(*jump.Set()) == 0) { | 1730 if (setjmp(*jump.Set()) == 0) { |
| 1707 // Reserve space in the output buffer for a snapshot header. | 1731 // Reserve space in the output buffer for a snapshot header. |
| 1708 ReserveHeader(); | 1732 ReserveHeader(); |
| 1709 | 1733 |
| 1710 // Write out the version string. | 1734 // Write out the version string. |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1733 writer_->WriteObjectRef(raw_obj); | 1757 writer_->WriteObjectRef(raw_obj); |
| 1734 } else { | 1758 } else { |
| 1735 writer_->WriteObjectImpl(raw_obj); | 1759 writer_->WriteObjectImpl(raw_obj); |
| 1736 } | 1760 } |
| 1737 } | 1761 } |
| 1738 } | 1762 } |
| 1739 | 1763 |
| 1740 | 1764 |
| 1741 void MessageWriter::WriteMessage(const Object& obj) { | 1765 void MessageWriter::WriteMessage(const Object& obj) { |
| 1742 ASSERT(kind() == Snapshot::kMessage); | 1766 ASSERT(kind() == Snapshot::kMessage); |
| 1743 Isolate* isolate = Isolate::Current(); | 1767 ASSERT(isolate() != NULL); |
| 1744 ASSERT(isolate != NULL); | |
| 1745 | 1768 |
| 1746 // Setup for long jump in case there is an exception while writing | 1769 // Setup for long jump in case there is an exception while writing |
| 1747 // the message. | 1770 // the message. |
| 1748 LongJumpScope jump; | 1771 LongJumpScope jump; |
| 1749 if (setjmp(*jump.Set()) == 0) { | 1772 if (setjmp(*jump.Set()) == 0) { |
| 1750 NoGCScope no_gc; | 1773 NoGCScope no_gc; |
| 1751 WriteObject(obj.raw()); | 1774 WriteObject(obj.raw()); |
| 1752 UnmarkAll(); | 1775 UnmarkAll(); |
| 1753 } else { | 1776 } else { |
| 1754 ThrowException(exception_type(), exception_msg()); | 1777 ThrowException(exception_type(), exception_msg()); |
| 1755 } | 1778 } |
| 1756 } | 1779 } |
| 1757 | 1780 |
| 1758 | 1781 |
| 1759 } // namespace dart | 1782 } // namespace dart |
| OLD | NEW |