| 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 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 return Mint::NewCanonical(value); | 1183 return Mint::NewCanonical(value); |
| 1184 } | 1184 } |
| 1185 | 1185 |
| 1186 | 1186 |
| 1187 RawStacktrace* SnapshotReader::NewStacktrace() { | 1187 RawStacktrace* SnapshotReader::NewStacktrace() { |
| 1188 ALLOC_NEW_OBJECT(Stacktrace); | 1188 ALLOC_NEW_OBJECT(Stacktrace); |
| 1189 } | 1189 } |
| 1190 | 1190 |
| 1191 | 1191 |
| 1192 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) { | 1192 int32_t InstructionsWriter::GetOffsetFor(RawInstructions* instructions) { |
| 1193 // Can't use instructions->Size() because the header was mutated by the | 1193 intptr_t heap_size = instructions->Size(); |
| 1194 // snapshot writer. | |
| 1195 intptr_t heap_size = | |
| 1196 Instructions::InstanceSize(instructions->ptr()->size_); | |
| 1197 intptr_t offset = next_offset_; | 1194 intptr_t offset = next_offset_; |
| 1198 next_offset_ += heap_size; | 1195 next_offset_ += heap_size; |
| 1199 instructions_.Add(InstructionsData(instructions)); | 1196 instructions_.Add(InstructionsData(instructions)); |
| 1200 return offset; | 1197 return offset; |
| 1201 } | 1198 } |
| 1202 | 1199 |
| 1203 | 1200 |
| 1204 static void EnsureIdentifier(char* label) { | 1201 static void EnsureIdentifier(char* label) { |
| 1205 for (char c = *label; c != '\0'; c = *++label) { | 1202 for (char c = *label; c != '\0'; c = *++label) { |
| 1206 if (((c >= 'a') && (c <= 'z')) || | 1203 if (((c >= 'a') && (c <= 'z')) || |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1662 thread) { | 1659 thread) { |
| 1663 } | 1660 } |
| 1664 | 1661 |
| 1665 | 1662 |
| 1666 MessageSnapshotReader::~MessageSnapshotReader() { | 1663 MessageSnapshotReader::~MessageSnapshotReader() { |
| 1667 ResetBackwardReferenceTable(); | 1664 ResetBackwardReferenceTable(); |
| 1668 } | 1665 } |
| 1669 | 1666 |
| 1670 | 1667 |
| 1671 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, | 1668 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, |
| 1669 Thread* thread, |
| 1672 uint8_t** buffer, | 1670 uint8_t** buffer, |
| 1673 ReAlloc alloc, | 1671 ReAlloc alloc, |
| 1674 intptr_t initial_size, | 1672 intptr_t initial_size, |
| 1675 ForwardList* forward_list, | 1673 ForwardList* forward_list, |
| 1676 InstructionsWriter* instructions_writer, | 1674 InstructionsWriter* instructions_writer, |
| 1677 bool can_send_any_object, | 1675 bool can_send_any_object, |
| 1678 bool snapshot_code, | 1676 bool snapshot_code, |
| 1679 bool vm_isolate_is_symbolic) | 1677 bool vm_isolate_is_symbolic) |
| 1680 : BaseWriter(buffer, alloc, initial_size), | 1678 : BaseWriter(buffer, alloc, initial_size), |
| 1681 kind_(kind), | 1679 kind_(kind), |
| 1682 thread_(Thread::Current()), | 1680 thread_(thread), |
| 1683 object_store_(thread_->isolate()->object_store()), | 1681 object_store_(isolate()->object_store()), |
| 1684 class_table_(thread_->isolate()->class_table()), | 1682 class_table_(isolate()->class_table()), |
| 1685 forward_list_(forward_list), | 1683 forward_list_(forward_list), |
| 1686 instructions_writer_(instructions_writer), | 1684 instructions_writer_(instructions_writer), |
| 1687 exception_type_(Exceptions::kNone), | 1685 exception_type_(Exceptions::kNone), |
| 1688 exception_msg_(NULL), | 1686 exception_msg_(NULL), |
| 1689 unmarked_objects_(false), | 1687 unmarked_objects_(false), |
| 1690 can_send_any_object_(can_send_any_object), | 1688 can_send_any_object_(can_send_any_object), |
| 1691 snapshot_code_(snapshot_code), | 1689 snapshot_code_(snapshot_code), |
| 1692 vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { | 1690 vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { |
| 1693 ASSERT(forward_list_ != NULL); | 1691 ASSERT(forward_list_ != NULL); |
| 1694 } | 1692 } |
| 1695 | 1693 |
| 1696 | 1694 |
| 1697 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1695 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
| 1698 WriteObjectImpl(rawobj, kAsInlinedObject); | 1696 WriteObjectImpl(rawobj, kAsInlinedObject); |
| 1699 WriteForwardedObjects(); | 1697 WriteForwardedObjects(); |
| 1700 } | 1698 } |
| 1701 | 1699 |
| 1700 |
| 1701 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
| 1702 return raw->ptr()->tags_; |
| 1703 } |
| 1704 |
| 1705 |
| 1702 #define VM_OBJECT_CLASS_LIST(V) \ | 1706 #define VM_OBJECT_CLASS_LIST(V) \ |
| 1703 V(OneByteString) \ | 1707 V(OneByteString) \ |
| 1704 V(Mint) \ | 1708 V(Mint) \ |
| 1705 V(Bigint) \ | 1709 V(Bigint) \ |
| 1706 V(Double) \ | 1710 V(Double) \ |
| 1707 V(ImmutableArray) \ | 1711 V(ImmutableArray) \ |
| 1708 | 1712 |
| 1709 #define VM_OBJECT_WRITE(clazz) \ | 1713 #define VM_OBJECT_WRITE(clazz) \ |
| 1710 case clazz::kClassId: { \ | 1714 case clazz::kClassId: { \ |
| 1711 object_id = forward_list_->AddObject(rawobj, kIsSerialized); \ | 1715 object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized); \ |
| 1712 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \ | 1716 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(rawobj); \ |
| 1713 raw_obj->WriteTo(this, object_id, kind(), false); \ | 1717 raw_obj->WriteTo(this, object_id, kind(), false); \ |
| 1714 return true; \ | 1718 return true; \ |
| 1715 } \ | 1719 } \ |
| 1716 | 1720 |
| 1717 #define WRITE_VM_SINGLETON_OBJ(obj, id) \ | 1721 #define WRITE_VM_SINGLETON_OBJ(obj, id) \ |
| 1718 if (rawobj == obj) { \ | 1722 if (rawobj == obj) { \ |
| 1719 WriteVMIsolateObject(id); \ | 1723 WriteVMIsolateObject(id); \ |
| 1720 return true; \ | 1724 return true; \ |
| 1721 } \ | 1725 } \ |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1785 // the index into the vm isolate snapshot object table, instead we | 1789 // the index into the vm isolate snapshot object table, instead we |
| 1786 // explicitly write the object out. | 1790 // explicitly write the object out. |
| 1787 intptr_t object_id = forward_list_->FindObject(rawobj); | 1791 intptr_t object_id = forward_list_->FindObject(rawobj); |
| 1788 if (object_id != -1) { | 1792 if (object_id != -1) { |
| 1789 WriteIndexedObject(object_id); | 1793 WriteIndexedObject(object_id); |
| 1790 return true; | 1794 return true; |
| 1791 } else { | 1795 } else { |
| 1792 switch (id) { | 1796 switch (id) { |
| 1793 VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE) | 1797 VM_OBJECT_CLASS_LIST(VM_OBJECT_WRITE) |
| 1794 case kTypedDataUint32ArrayCid: { | 1798 case kTypedDataUint32ArrayCid: { |
| 1795 object_id = forward_list_->AddObject(rawobj, kIsSerialized); | 1799 object_id = forward_list_->AddObject(zone(), rawobj, kIsSerialized); |
| 1796 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj); | 1800 RawTypedData* raw_obj = reinterpret_cast<RawTypedData*>(rawobj); |
| 1797 raw_obj->WriteTo(this, object_id, kind(), false); | 1801 raw_obj->WriteTo(this, object_id, kind(), false); |
| 1798 return true; | 1802 return true; |
| 1799 } | 1803 } |
| 1800 default: | 1804 default: |
| 1801 OS::Print("class id = %" Pd "\n", id); | 1805 OS::Print("class id = %" Pd "\n", id); |
| 1802 break; | 1806 break; |
| 1803 } | 1807 } |
| 1804 } | 1808 } |
| 1805 } | 1809 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1852 const Array* scripts_; | 1856 const Array* scripts_; |
| 1853 }; | 1857 }; |
| 1854 | 1858 |
| 1855 | 1859 |
| 1856 FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, | 1860 FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, |
| 1857 uint8_t** isolate_snapshot_buffer, | 1861 uint8_t** isolate_snapshot_buffer, |
| 1858 uint8_t** instructions_snapshot_buffer, | 1862 uint8_t** instructions_snapshot_buffer, |
| 1859 ReAlloc alloc, | 1863 ReAlloc alloc, |
| 1860 bool snapshot_code, | 1864 bool snapshot_code, |
| 1861 bool vm_isolate_is_symbolic) | 1865 bool vm_isolate_is_symbolic) |
| 1862 : isolate_(Isolate::Current()), | 1866 : thread_(Thread::Current()), |
| 1863 vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer), | 1867 vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer), |
| 1864 isolate_snapshot_buffer_(isolate_snapshot_buffer), | 1868 isolate_snapshot_buffer_(isolate_snapshot_buffer), |
| 1865 instructions_snapshot_buffer_(instructions_snapshot_buffer), | 1869 instructions_snapshot_buffer_(instructions_snapshot_buffer), |
| 1866 alloc_(alloc), | 1870 alloc_(alloc), |
| 1867 vm_isolate_snapshot_size_(0), | 1871 vm_isolate_snapshot_size_(0), |
| 1868 isolate_snapshot_size_(0), | 1872 isolate_snapshot_size_(0), |
| 1869 instructions_snapshot_size_(0), | 1873 instructions_snapshot_size_(0), |
| 1870 forward_list_(NULL), | 1874 forward_list_(NULL), |
| 1871 instructions_writer_(NULL), | 1875 instructions_writer_(NULL), |
| 1872 scripts_(Array::Handle(isolate_->current_zone())), | 1876 scripts_(Array::Handle(zone())), |
| 1873 symbol_table_(Array::Handle(isolate_->current_zone())), | 1877 symbol_table_(Array::Handle(zone())), |
| 1874 snapshot_code_(snapshot_code), | 1878 snapshot_code_(snapshot_code), |
| 1875 vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { | 1879 vm_isolate_is_symbolic_(vm_isolate_is_symbolic) { |
| 1876 ASSERT(isolate_snapshot_buffer_ != NULL); | 1880 ASSERT(isolate_snapshot_buffer_ != NULL); |
| 1877 ASSERT(alloc_ != NULL); | 1881 ASSERT(alloc_ != NULL); |
| 1878 ASSERT(isolate_ != NULL); | 1882 ASSERT(isolate() != NULL); |
| 1879 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1883 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 1880 ObjectStore* object_store = isolate_->object_store(); | 1884 ASSERT(isolate() != NULL); |
| 1885 ASSERT(heap() != NULL); |
| 1886 ObjectStore* object_store = isolate()->object_store(); |
| 1881 ASSERT(object_store != NULL); | 1887 ASSERT(object_store != NULL); |
| 1882 Heap* heap = isolate_->heap(); | |
| 1883 ASSERT(heap != NULL); | |
| 1884 // Ensure the class table is valid. | 1888 // Ensure the class table is valid. |
| 1885 #if defined(DEBUG) | 1889 #if defined(DEBUG) |
| 1886 isolate_->ValidateClassTable(); | 1890 isolate()->ValidateClassTable(); |
| 1887 #endif | 1891 #endif |
| 1888 | 1892 |
| 1889 // Collect all the script objects and their accompanying token stream objects | 1893 // Collect all the script objects and their accompanying token stream objects |
| 1890 // into an array so that we can write it out as part of the VM isolate | 1894 // into an array so that we can write it out as part of the VM isolate |
| 1891 // snapshot. We first count the number of script objects, allocate an array | 1895 // snapshot. We first count the number of script objects, allocate an array |
| 1892 // and then fill it up with the script objects. | 1896 // and then fill it up with the script objects. |
| 1893 ASSERT(isolate_ != NULL); | 1897 ScriptVisitor scripts_counter(isolate()); |
| 1894 ScriptVisitor scripts_counter(isolate_); | 1898 heap()->IterateOldObjects(&scripts_counter); |
| 1895 heap->IterateOldObjects(&scripts_counter); | |
| 1896 intptr_t count = scripts_counter.count(); | 1899 intptr_t count = scripts_counter.count(); |
| 1897 scripts_ = Array::New(count, Heap::kOld); | 1900 scripts_ = Array::New(count, Heap::kOld); |
| 1898 ScriptVisitor script_visitor(isolate_, &scripts_); | 1901 ScriptVisitor script_visitor(isolate(), &scripts_); |
| 1899 heap->IterateOldObjects(&script_visitor); | 1902 heap()->IterateOldObjects(&script_visitor); |
| 1900 | 1903 |
| 1901 // Stash the symbol table away for writing and reading into the vm isolate, | 1904 // Stash the symbol table away for writing and reading into the vm isolate, |
| 1902 // and reset the symbol table for the regular isolate so that we do not | 1905 // and reset the symbol table for the regular isolate so that we do not |
| 1903 // write these symbols into the snapshot of a regular dart isolate. | 1906 // write these symbols into the snapshot of a regular dart isolate. |
| 1904 symbol_table_ = object_store->symbol_table(); | 1907 symbol_table_ = object_store->symbol_table(); |
| 1905 Symbols::SetupSymbolTable(isolate_); | 1908 Symbols::SetupSymbolTable(isolate()); |
| 1906 | 1909 |
| 1907 forward_list_ = new ForwardList(SnapshotWriter::FirstObjectId()); | 1910 forward_list_ = new ForwardList(thread(), SnapshotWriter::FirstObjectId()); |
| 1908 ASSERT(forward_list_ != NULL); | 1911 ASSERT(forward_list_ != NULL); |
| 1909 | 1912 |
| 1910 if (instructions_snapshot_buffer != NULL) { | 1913 if (instructions_snapshot_buffer != NULL) { |
| 1911 instructions_writer_ = new InstructionsWriter(instructions_snapshot_buffer, | 1914 instructions_writer_ = new InstructionsWriter(instructions_snapshot_buffer, |
| 1912 alloc, | 1915 alloc, |
| 1913 kInitialSize); | 1916 kInitialSize); |
| 1914 } | 1917 } |
| 1915 } | 1918 } |
| 1916 | 1919 |
| 1917 | 1920 |
| 1918 FullSnapshotWriter::~FullSnapshotWriter() { | 1921 FullSnapshotWriter::~FullSnapshotWriter() { |
| 1919 delete forward_list_; | 1922 delete forward_list_; |
| 1920 symbol_table_ = Array::null(); | 1923 symbol_table_ = Array::null(); |
| 1921 scripts_ = Array::null(); | 1924 scripts_ = Array::null(); |
| 1922 } | 1925 } |
| 1923 | 1926 |
| 1924 | 1927 |
| 1925 void FullSnapshotWriter::WriteVmIsolateSnapshot() { | 1928 void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
| 1926 ASSERT(vm_isolate_snapshot_buffer_ != NULL); | 1929 ASSERT(vm_isolate_snapshot_buffer_ != NULL); |
| 1927 SnapshotWriter writer(Snapshot::kFull, | 1930 SnapshotWriter writer(Snapshot::kFull, |
| 1931 thread(), |
| 1928 vm_isolate_snapshot_buffer_, | 1932 vm_isolate_snapshot_buffer_, |
| 1929 alloc_, | 1933 alloc_, |
| 1930 kInitialSize, | 1934 kInitialSize, |
| 1931 forward_list_, | 1935 forward_list_, |
| 1932 instructions_writer_, | 1936 instructions_writer_, |
| 1933 true, /* can_send_any_object */ | 1937 true, /* can_send_any_object */ |
| 1934 snapshot_code_, | 1938 snapshot_code_, |
| 1935 vm_isolate_is_symbolic_); | 1939 vm_isolate_is_symbolic_); |
| 1936 // Write full snapshot for the VM isolate. | 1940 // Write full snapshot for the VM isolate. |
| 1937 // Setup for long jump in case there is an exception while writing | 1941 // Setup for long jump in case there is an exception while writing |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1968 | 1972 |
| 1969 vm_isolate_snapshot_size_ = writer.BytesWritten(); | 1973 vm_isolate_snapshot_size_ = writer.BytesWritten(); |
| 1970 } else { | 1974 } else { |
| 1971 writer.ThrowException(writer.exception_type(), writer.exception_msg()); | 1975 writer.ThrowException(writer.exception_type(), writer.exception_msg()); |
| 1972 } | 1976 } |
| 1973 } | 1977 } |
| 1974 | 1978 |
| 1975 | 1979 |
| 1976 void FullSnapshotWriter::WriteIsolateFullSnapshot() { | 1980 void FullSnapshotWriter::WriteIsolateFullSnapshot() { |
| 1977 SnapshotWriter writer(Snapshot::kFull, | 1981 SnapshotWriter writer(Snapshot::kFull, |
| 1982 thread(), |
| 1978 isolate_snapshot_buffer_, | 1983 isolate_snapshot_buffer_, |
| 1979 alloc_, | 1984 alloc_, |
| 1980 kInitialSize, | 1985 kInitialSize, |
| 1981 forward_list_, | 1986 forward_list_, |
| 1982 instructions_writer_, | 1987 instructions_writer_, |
| 1983 true, /* can_send_any_object */ | 1988 true, /* can_send_any_object */ |
| 1984 snapshot_code_, | 1989 snapshot_code_, |
| 1985 true /* vm_isolate_is_symbolic */); | 1990 true /* vm_isolate_is_symbolic */); |
| 1986 ObjectStore* object_store = isolate_->object_store(); | 1991 ObjectStore* object_store = isolate()->object_store(); |
| 1987 ASSERT(object_store != NULL); | 1992 ASSERT(object_store != NULL); |
| 1988 | 1993 |
| 1989 // Write full snapshot for a regular isolate. | 1994 // Write full snapshot for a regular isolate. |
| 1990 // Setup for long jump in case there is an exception while writing | 1995 // Setup for long jump in case there is an exception while writing |
| 1991 // the snapshot. | 1996 // the snapshot. |
| 1992 LongJumpScope jump; | 1997 LongJumpScope jump; |
| 1993 if (setjmp(*jump.Set()) == 0) { | 1998 if (setjmp(*jump.Set()) == 0) { |
| 1994 // Reserve space in the output buffer for a snapshot header. | 1999 // Reserve space in the output buffer for a snapshot header. |
| 1995 writer.ReserveHeader(); | 2000 writer.ReserveHeader(); |
| 1996 | 2001 |
| 1997 // Write out the version string. | 2002 // Write out the version string. |
| 1998 writer.WriteVersion(); | 2003 writer.WriteVersion(); |
| 1999 | 2004 |
| 2000 // Write out the full snapshot. | 2005 // Write out the full snapshot. |
| 2001 | 2006 |
| 2002 // Write out all the objects in the object store of the isolate which | 2007 // Write out all the objects in the object store of the isolate which |
| 2003 // is the root set for all dart allocated objects at this point. | 2008 // is the root set for all dart allocated objects at this point. |
| 2004 SnapshotWriterVisitor visitor(&writer, false); | 2009 SnapshotWriterVisitor visitor(&writer, false); |
| 2005 visitor.VisitPointers(object_store->from(), | 2010 visitor.VisitPointers(object_store->from(), |
| 2006 snapshot_code_ ? object_store->to() | 2011 snapshot_code_ ? object_store->to() |
| 2007 : object_store->to_snapshot()); | 2012 : object_store->to_snapshot()); |
| 2008 | 2013 |
| 2009 // Write out all forwarded objects. | 2014 // Write out all forwarded objects. |
| 2010 writer.WriteForwardedObjects(); | 2015 writer.WriteForwardedObjects(); |
| 2011 | 2016 |
| 2012 writer.FillHeader(writer.kind()); | 2017 writer.FillHeader(writer.kind()); |
| 2013 writer.UnmarkAll(); | |
| 2014 | 2018 |
| 2015 isolate_snapshot_size_ = writer.BytesWritten(); | 2019 isolate_snapshot_size_ = writer.BytesWritten(); |
| 2016 } else { | 2020 } else { |
| 2017 writer.ThrowException(writer.exception_type(), writer.exception_msg()); | 2021 writer.ThrowException(writer.exception_type(), writer.exception_msg()); |
| 2018 } | 2022 } |
| 2019 } | 2023 } |
| 2020 | 2024 |
| 2021 | 2025 |
| 2022 void FullSnapshotWriter::WriteFullSnapshot() { | 2026 void FullSnapshotWriter::WriteFullSnapshot() { |
| 2023 if (!vm_isolate_is_symbolic_) { | 2027 if (vm_isolate_snapshot_buffer() != NULL) { |
| 2024 // TODO(asiva): Don't mutate object headers during serialization. | 2028 WriteVmIsolateSnapshot(); |
| 2025 WritableVMIsolateScope scope(Thread::Current()); | 2029 } |
| 2026 | 2030 WriteIsolateFullSnapshot(); |
| 2027 if (vm_isolate_snapshot_buffer() != NULL) { | 2031 if (snapshot_code_) { |
| 2028 WriteVmIsolateSnapshot(); | |
| 2029 } | |
| 2030 WriteIsolateFullSnapshot(); | |
| 2031 | |
| 2032 instructions_writer_->WriteAssembly(); | 2032 instructions_writer_->WriteAssembly(); |
| 2033 instructions_snapshot_size_ = instructions_writer_->BytesWritten(); | 2033 instructions_snapshot_size_ = instructions_writer_->BytesWritten(); |
| 2034 } else { | |
| 2035 if (vm_isolate_snapshot_buffer() != NULL) { | |
| 2036 WriteVmIsolateSnapshot(); | |
| 2037 } | |
| 2038 WriteIsolateFullSnapshot(); | |
| 2039 } | 2034 } |
| 2040 } | 2035 } |
| 2041 | 2036 |
| 2042 | 2037 |
| 2043 PrecompiledSnapshotWriter::PrecompiledSnapshotWriter( | 2038 PrecompiledSnapshotWriter::PrecompiledSnapshotWriter( |
| 2044 uint8_t** vm_isolate_snapshot_buffer, | 2039 uint8_t** vm_isolate_snapshot_buffer, |
| 2045 uint8_t** isolate_snapshot_buffer, | 2040 uint8_t** isolate_snapshot_buffer, |
| 2046 uint8_t** instructions_snapshot_buffer, | 2041 uint8_t** instructions_snapshot_buffer, |
| 2047 ReAlloc alloc) | 2042 ReAlloc alloc) |
| 2048 : FullSnapshotWriter(vm_isolate_snapshot_buffer, | 2043 : FullSnapshotWriter(vm_isolate_snapshot_buffer, |
| 2049 isolate_snapshot_buffer, | 2044 isolate_snapshot_buffer, |
| 2050 instructions_snapshot_buffer, | 2045 instructions_snapshot_buffer, |
| 2051 alloc, | 2046 alloc, |
| 2052 true, /* snapshot_code */ | 2047 true, /* snapshot_code */ |
| 2053 false /* vm_isolate_is_symbolic */) { | 2048 false /* vm_isolate_is_symbolic */) { |
| 2054 } | 2049 } |
| 2055 | 2050 |
| 2056 | 2051 |
| 2057 PrecompiledSnapshotWriter::~PrecompiledSnapshotWriter() {} | 2052 PrecompiledSnapshotWriter::~PrecompiledSnapshotWriter() {} |
| 2058 | 2053 |
| 2059 | 2054 |
| 2060 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 2055 ForwardList::ForwardList(Thread* thread, intptr_t first_object_id) |
| 2061 uword tags = raw->ptr()->tags_; | 2056 : thread_(thread), |
| 2062 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 2057 first_object_id_(first_object_id), |
| 2063 intptr_t id = SerializedHeaderData::decode(tags); | |
| 2064 return forward_list_->NodeForObjectId(id)->tags(); | |
| 2065 } else { | |
| 2066 return tags; | |
| 2067 } | |
| 2068 } | |
| 2069 | |
| 2070 | |
| 2071 intptr_t SnapshotWriter::GetObjectId(RawObject* raw) { | |
| 2072 uword tags = raw->ptr()->tags_; | |
| 2073 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | |
| 2074 return SerializedHeaderData::decode(tags); | |
| 2075 } | |
| 2076 | |
| 2077 | |
| 2078 ForwardList::ForwardList(intptr_t first_object_id) | |
| 2079 : first_object_id_(first_object_id), | |
| 2080 nodes_(), | 2058 nodes_(), |
| 2081 first_unprocessed_object_id_(first_object_id) { | 2059 first_unprocessed_object_id_(first_object_id) { |
| 2082 // The ForwardList encodes information in the header tag word. There cannot | |
| 2083 // be any concurrent GC tasks while it is in use. | |
| 2084 Thread* thread = Thread::Current(); | |
| 2085 Isolate* isolate = thread->isolate(); | |
| 2086 PageSpace* page_space = isolate->heap()->old_space(); | |
| 2087 MonitorLocker ml(page_space->tasks_lock()); | |
| 2088 while (page_space->tasks() > 0) { | |
| 2089 ml.Wait(); | |
| 2090 } | |
| 2091 // Ensure that no GC happens while we are writing out the full snapshot. | |
| 2092 thread->IncrementNoSafepointScopeDepth(); | |
| 2093 } | 2060 } |
| 2094 | 2061 |
| 2095 | 2062 |
| 2096 ForwardList::~ForwardList() { | 2063 ForwardList::~ForwardList() { |
| 2064 heap()->ResetObjectIdTable(); |
| 2097 } | 2065 } |
| 2098 | 2066 |
| 2099 | 2067 |
| 2100 intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) { | 2068 intptr_t ForwardList::AddObject(Zone* zone, |
| 2069 RawObject* raw, |
| 2070 SerializeState state) { |
| 2101 NoSafepointScope no_safepoint; | 2071 NoSafepointScope no_safepoint; |
| 2102 intptr_t object_id = next_object_id(); | 2072 intptr_t object_id = next_object_id(); |
| 2103 ASSERT(object_id > 0 && object_id <= kMaxObjectId); | 2073 ASSERT(object_id > 0 && object_id <= kMaxObjectId); |
| 2104 uword value = 0; | 2074 const Object& obj = Object::ZoneHandle(zone, raw); |
| 2105 value = SerializedHeaderTag::update(kObjectId, value); | 2075 Node* node = new Node(&obj, state); |
| 2106 value = SerializedHeaderData::update(object_id, value); | |
| 2107 uword tags = raw->ptr()->tags_; | |
| 2108 ASSERT(SerializedHeaderTag::decode(tags) != kObjectId); | |
| 2109 raw->ptr()->tags_ = value; | |
| 2110 Node* node = new Node(raw, tags, state); | |
| 2111 ASSERT(node != NULL); | 2076 ASSERT(node != NULL); |
| 2112 nodes_.Add(node); | 2077 nodes_.Add(node); |
| 2113 return object_id; | 2078 ASSERT(SnapshotWriter::FirstObjectId() > 0); |
| 2114 } | 2079 ASSERT(object_id != 0); |
| 2115 | 2080 heap()->SetObjectId(raw, object_id); |
| 2116 | |
| 2117 intptr_t ForwardList::AddObject(RawObject* raw, SerializeState state) { | |
| 2118 NoSafepointScope no_safepoint; | |
| 2119 intptr_t object_id = next_object_id(); | |
| 2120 ASSERT(object_id > 0 && object_id <= kMaxObjectId); | |
| 2121 uword tags = raw->ptr()->tags_; | |
| 2122 ASSERT(SerializedHeaderTag::decode(tags) != kObjectId); | |
| 2123 Node* node = new Node(raw, tags, state); | |
| 2124 ASSERT(node != NULL); | |
| 2125 nodes_.Add(node); | |
| 2126 return object_id; | 2081 return object_id; |
| 2127 } | 2082 } |
| 2128 | 2083 |
| 2129 | 2084 |
| 2130 intptr_t ForwardList::FindObject(RawObject* raw) { | 2085 intptr_t ForwardList::FindObject(RawObject* raw) { |
| 2131 NoSafepointScope no_safepoint; | 2086 NoSafepointScope no_safepoint; |
| 2132 intptr_t id; | 2087 ASSERT(SnapshotWriter::FirstObjectId() > 0); |
| 2133 for (id = first_object_id(); id < next_object_id(); ++id) { | 2088 intptr_t id = heap()->GetObjectId(raw); |
| 2134 const Node* node = NodeForObjectId(id); | 2089 ASSERT(id == 0 || NodeForObjectId(id)->obj()->raw() == raw); |
| 2135 if (raw == node->raw()) { | 2090 return (id == 0) ? kInvalidIndex : id; |
| 2136 return id; | |
| 2137 } | |
| 2138 } | |
| 2139 return kInvalidIndex; | |
| 2140 } | 2091 } |
| 2141 | 2092 |
| 2142 | 2093 |
| 2143 void ForwardList::UnmarkAll() const { | |
| 2144 for (intptr_t id = first_object_id(); id < next_object_id(); ++id) { | |
| 2145 const Node* node = NodeForObjectId(id); | |
| 2146 RawObject* raw = node->raw(); | |
| 2147 if (SerializedHeaderTag::decode(raw->ptr()->tags_) == kObjectId) { | |
| 2148 raw->ptr()->tags_ = node->tags(); // Restore original tags. | |
| 2149 } | |
| 2150 } | |
| 2151 Thread::Current()->DecrementNoSafepointScopeDepth(); | |
| 2152 } | |
| 2153 | |
| 2154 | |
| 2155 void ForwardList::SetState(RawObject* raw, SerializeState state) { | |
| 2156 uword tags = raw->ptr()->tags_; | |
| 2157 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | |
| 2158 intptr_t id = SerializedHeaderData::decode(tags); | |
| 2159 NodeForObjectId(id)->set_state(state); | |
| 2160 } | |
| 2161 | |
| 2162 | |
| 2163 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { | 2094 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { |
| 2164 // Check if object can be written in one of the following ways: | 2095 // Check if object can be written in one of the following ways: |
| 2165 // - Smi: the Smi value is written as is (last bit is not tagged). | 2096 // - Smi: the Smi value is written as is (last bit is not tagged). |
| 2166 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) | 2097 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) |
| 2167 // - Object that has already been written: (negative id in stream | 0x3) | 2098 // - Object that has already been written: (negative id in stream | 0x3) |
| 2168 | 2099 |
| 2169 NoSafepointScope no_safepoint; | 2100 NoSafepointScope no_safepoint; |
| 2170 | 2101 |
| 2171 // First check if it is a Smi (i.e not a heap object). | 2102 // First check if it is a Smi (i.e not a heap object). |
| 2172 if (!rawobj->IsHeapObject()) { | 2103 if (!rawobj->IsHeapObject()) { |
| 2173 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj)); | 2104 Write<int64_t>(reinterpret_cast<intptr_t>(rawobj)); |
| 2174 return true; | 2105 return true; |
| 2175 } | 2106 } |
| 2176 | 2107 |
| 2177 intptr_t cid = rawobj->GetClassId(); | 2108 intptr_t cid = rawobj->GetClassId(); |
| 2178 | 2109 |
| 2179 if ((kind_ == Snapshot::kMessage) && (cid == kDoubleCid)) { | 2110 if ((kind_ == Snapshot::kMessage) && (cid == kDoubleCid)) { |
| 2180 WriteVMIsolateObject(kDoubleObject); | 2111 WriteVMIsolateObject(kDoubleObject); |
| 2181 RawDouble* rd = reinterpret_cast<RawDouble*>(rawobj); | 2112 RawDouble* rd = reinterpret_cast<RawDouble*>(rawobj); |
| 2182 WriteDouble(rd->ptr()->value_); | 2113 WriteDouble(rd->ptr()->value_); |
| 2183 return true; | 2114 return true; |
| 2184 } | 2115 } |
| 2185 | 2116 |
| 2186 // Check if object has already been serialized, in that case just write | 2117 // Check if object has already been serialized, in that case just write |
| 2187 // the object id out. | 2118 // the object id out. |
| 2188 uword tags = rawobj->ptr()->tags_; | 2119 intptr_t object_id = forward_list_->FindObject(rawobj); |
| 2189 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 2120 if (object_id != kInvalidIndex) { |
| 2190 intptr_t id = SerializedHeaderData::decode(tags); | 2121 WriteIndexedObject(object_id); |
| 2191 WriteIndexedObject(id); | |
| 2192 return true; | 2122 return true; |
| 2193 } | 2123 } |
| 2194 | 2124 |
| 2195 // Now check if it is an object from the VM isolate (NOTE: premarked objects | 2125 // Now check if it is an object from the VM isolate (NOTE: premarked objects |
| 2196 // are considered to be objects in the VM isolate). These objects are shared | 2126 // are considered to be objects in the VM isolate). These objects are shared |
| 2197 // by all isolates. | 2127 // by all isolates. |
| 2198 if (rawobj->IsVMHeapObject() && HandleVMIsolateObject(rawobj)) { | 2128 if (rawobj->IsVMHeapObject() && HandleVMIsolateObject(rawobj)) { |
| 2199 return true; | 2129 return true; |
| 2200 } | 2130 } |
| 2201 | 2131 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2234 | 2164 |
| 2235 | 2165 |
| 2236 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { | 2166 void SnapshotWriter::WriteObjectImpl(RawObject* raw, bool as_reference) { |
| 2237 // First check if object can be written as a simple predefined type. | 2167 // First check if object can be written as a simple predefined type. |
| 2238 if (CheckAndWritePredefinedObject(raw)) { | 2168 if (CheckAndWritePredefinedObject(raw)) { |
| 2239 return; | 2169 return; |
| 2240 } | 2170 } |
| 2241 | 2171 |
| 2242 // When we know that we are dealing with leaf or shallow objects we write | 2172 // When we know that we are dealing with leaf or shallow objects we write |
| 2243 // these objects inline even when 'as_reference' is true. | 2173 // these objects inline even when 'as_reference' is true. |
| 2244 bool write_as_reference = as_reference && !raw->IsCanonical(); | 2174 const bool write_as_reference = as_reference && !raw->IsCanonical(); |
| 2245 intptr_t tags = raw->ptr()->tags_; | 2175 intptr_t tags = raw->ptr()->tags_; |
| 2246 | 2176 |
| 2247 // Add object to the forward ref list and mark it so that future references | 2177 // Add object to the forward ref list and mark it so that future references |
| 2248 // to this object in the snapshot will use this object id. Mark the | 2178 // to this object in the snapshot will use this object id. Mark the |
| 2249 // serialization state so that we do the right thing when we go through | 2179 // serialization state so that we do the right thing when we go through |
| 2250 // the forward list. | 2180 // the forward list. |
| 2251 intptr_t class_id = raw->GetClassId(); | 2181 intptr_t class_id = raw->GetClassId(); |
| 2182 intptr_t object_id; |
| 2252 if (write_as_reference && IsSplitClassId(class_id)) { | 2183 if (write_as_reference && IsSplitClassId(class_id)) { |
| 2253 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); | 2184 object_id = forward_list_->AddObject(zone(), raw, kIsNotSerialized); |
| 2254 } else { | 2185 } else { |
| 2255 forward_list_->MarkAndAddObject(raw, kIsSerialized); | 2186 object_id = forward_list_->AddObject(zone(), raw, kIsSerialized); |
| 2256 } | 2187 } |
| 2257 intptr_t object_id; | |
| 2258 if (write_as_reference || !IsSplitClassId(class_id)) { | 2188 if (write_as_reference || !IsSplitClassId(class_id)) { |
| 2259 object_id = kOmittedObjectId; | 2189 object_id = kOmittedObjectId; |
| 2260 } else { | |
| 2261 ASSERT(SerializedHeaderTag::decode(raw->ptr()->tags_) == kObjectId); | |
| 2262 object_id = SerializedHeaderData::decode(raw->ptr()->tags_); | |
| 2263 } | 2190 } |
| 2264 WriteMarkedObjectImpl(raw, tags, object_id, write_as_reference); | 2191 WriteMarkedObjectImpl(raw, tags, object_id, write_as_reference); |
| 2265 } | 2192 } |
| 2266 | 2193 |
| 2267 | 2194 |
| 2268 void SnapshotWriter::WriteMarkedObjectImpl(RawObject* raw, | 2195 void SnapshotWriter::WriteMarkedObjectImpl(RawObject* raw, |
| 2269 intptr_t tags, | 2196 intptr_t tags, |
| 2270 intptr_t object_id, | 2197 intptr_t object_id, |
| 2271 bool as_reference) { | 2198 bool as_reference) { |
| 2272 NoSafepointScope no_safepoint; | 2199 NoSafepointScope no_safepoint; |
| 2273 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 2200 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
| 2274 intptr_t class_id = cls->ptr()->id_; | 2201 intptr_t class_id = cls->ptr()->id_; |
| 2275 ASSERT(class_id == RawObject::ClassIdTag::decode(tags)); | 2202 ASSERT(class_id == RawObject::ClassIdTag::decode(tags)); |
| 2276 if (class_id >= kNumPredefinedCids || | 2203 if (class_id >= kNumPredefinedCids || |
| 2277 RawObject::IsImplicitFieldClassId(class_id)) { | 2204 RawObject::IsImplicitFieldClassId(class_id)) { |
| 2278 WriteInstance(raw, cls, tags, object_id, as_reference); | 2205 WriteInstance(raw, cls, tags, object_id, as_reference); |
| 2279 return; | 2206 return; |
| 2280 } | 2207 } |
| 2281 | |
| 2282 switch (class_id) { | 2208 switch (class_id) { |
| 2283 #define SNAPSHOT_WRITE(clazz) \ | 2209 #define SNAPSHOT_WRITE(clazz) \ |
| 2284 case clazz::kClassId: { \ | 2210 case clazz::kClassId: { \ |
| 2285 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ | 2211 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ |
| 2286 raw_obj->WriteTo(this, object_id, kind_, as_reference); \ | 2212 raw_obj->WriteTo(this, object_id, kind_, as_reference); \ |
| 2287 return; \ | 2213 return; \ |
| 2288 } \ | 2214 } \ |
| 2289 | 2215 |
| 2290 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) | 2216 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
| 2291 #undef SNAPSHOT_WRITE | 2217 #undef SNAPSHOT_WRITE |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2315 FATAL1("Unexpected object: %s\n", obj.ToCString()); | 2241 FATAL1("Unexpected object: %s\n", obj.ToCString()); |
| 2316 } | 2242 } |
| 2317 | 2243 |
| 2318 | 2244 |
| 2319 class WriteInlinedObjectVisitor : public ObjectVisitor { | 2245 class WriteInlinedObjectVisitor : public ObjectVisitor { |
| 2320 public: | 2246 public: |
| 2321 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) | 2247 explicit WriteInlinedObjectVisitor(SnapshotWriter* writer) |
| 2322 : ObjectVisitor(Isolate::Current()), writer_(writer) {} | 2248 : ObjectVisitor(Isolate::Current()), writer_(writer) {} |
| 2323 | 2249 |
| 2324 virtual void VisitObject(RawObject* obj) { | 2250 virtual void VisitObject(RawObject* obj) { |
| 2325 intptr_t object_id = writer_->GetObjectId(obj); | 2251 intptr_t object_id = writer_->forward_list_->FindObject(obj); |
| 2252 ASSERT(object_id != kInvalidIndex); |
| 2326 intptr_t tags = writer_->GetObjectTags(obj); | 2253 intptr_t tags = writer_->GetObjectTags(obj); |
| 2327 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject); | 2254 writer_->WriteMarkedObjectImpl(obj, tags, object_id, kAsInlinedObject); |
| 2328 } | 2255 } |
| 2329 | 2256 |
| 2330 private: | 2257 private: |
| 2331 SnapshotWriter* writer_; | 2258 SnapshotWriter* writer_; |
| 2332 }; | 2259 }; |
| 2333 | 2260 |
| 2334 | 2261 |
| 2335 void SnapshotWriter::WriteForwardedObjects() { | 2262 void SnapshotWriter::WriteForwardedObjects() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2347 #ifdef DEBUG | 2274 #ifdef DEBUG |
| 2348 for (intptr_t i = first_object_id(); i < first_unprocessed_object_id_; ++i) { | 2275 for (intptr_t i = first_object_id(); i < first_unprocessed_object_id_; ++i) { |
| 2349 ASSERT(NodeForObjectId(i)->is_serialized()); | 2276 ASSERT(NodeForObjectId(i)->is_serialized()); |
| 2350 } | 2277 } |
| 2351 #endif // DEBUG | 2278 #endif // DEBUG |
| 2352 for (intptr_t id = first_unprocessed_object_id_; | 2279 for (intptr_t id = first_unprocessed_object_id_; |
| 2353 id < next_object_id(); | 2280 id < next_object_id(); |
| 2354 ++id) { | 2281 ++id) { |
| 2355 if (!NodeForObjectId(id)->is_serialized()) { | 2282 if (!NodeForObjectId(id)->is_serialized()) { |
| 2356 // Write the object out in the stream. | 2283 // Write the object out in the stream. |
| 2357 RawObject* raw = NodeForObjectId(id)->raw(); | 2284 RawObject* raw = NodeForObjectId(id)->obj()->raw(); |
| 2358 writer->VisitObject(raw); | 2285 writer->VisitObject(raw); |
| 2359 | 2286 |
| 2360 // Mark object as serialized. | 2287 // Mark object as serialized. |
| 2361 NodeForObjectId(id)->set_state(kIsSerialized); | 2288 NodeForObjectId(id)->set_state(kIsSerialized); |
| 2362 } | 2289 } |
| 2363 } | 2290 } |
| 2364 first_unprocessed_object_id_ = next_object_id(); | 2291 first_unprocessed_object_id_ = next_object_id(); |
| 2365 } | 2292 } |
| 2366 | 2293 |
| 2367 | 2294 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2474 } | 2401 } |
| 2475 // Not a closure of a top level method or static function, throw an | 2402 // Not a closure of a top level method or static function, throw an |
| 2476 // exception as we do not allow these objects to be serialized. | 2403 // exception as we do not allow these objects to be serialized. |
| 2477 HANDLESCOPE(thread()); | 2404 HANDLESCOPE(thread()); |
| 2478 | 2405 |
| 2479 const Class& clazz = Class::Handle(zone(), cls); | 2406 const Class& clazz = Class::Handle(zone(), cls); |
| 2480 const Function& errorFunc = Function::Handle(zone(), func); | 2407 const Function& errorFunc = Function::Handle(zone(), func); |
| 2481 ASSERT(!errorFunc.IsNull()); | 2408 ASSERT(!errorFunc.IsNull()); |
| 2482 | 2409 |
| 2483 // All other closures are errors. | 2410 // All other closures are errors. |
| 2484 UnmarkAll(); // Unmark objects now as we are about to print stuff. | |
| 2485 char* chars = OS::SCreate(thread()->zone(), | 2411 char* chars = OS::SCreate(thread()->zone(), |
| 2486 "Illegal argument in isolate message : (object is a closure - %s %s)", | 2412 "Illegal argument in isolate message : (object is a closure - %s %s)", |
| 2487 clazz.ToCString(), errorFunc.ToCString()); | 2413 clazz.ToCString(), errorFunc.ToCString()); |
| 2488 SetWriteException(Exceptions::kArgument, chars); | 2414 SetWriteException(Exceptions::kArgument, chars); |
| 2489 } | 2415 } |
| 2490 return Function::null(); | 2416 return Function::null(); |
| 2491 } | 2417 } |
| 2492 | 2418 |
| 2493 | 2419 |
| 2494 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { | 2420 RawClass* SnapshotWriter::GetFunctionOwner(RawFunction* func) { |
| 2495 RawObject* owner = func->ptr()->owner_; | 2421 RawObject* owner = func->ptr()->owner_; |
| 2496 uword tags = GetObjectTags(owner); | 2422 uword tags = GetObjectTags(owner); |
| 2497 intptr_t class_id = RawObject::ClassIdTag::decode(tags); | 2423 intptr_t class_id = RawObject::ClassIdTag::decode(tags); |
| 2498 if (class_id == kClassCid) { | 2424 if (class_id == kClassCid) { |
| 2499 return reinterpret_cast<RawClass*>(owner); | 2425 return reinterpret_cast<RawClass*>(owner); |
| 2500 } | 2426 } |
| 2501 ASSERT(class_id == kPatchClassCid); | 2427 ASSERT(class_id == kPatchClassCid); |
| 2502 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; | 2428 return reinterpret_cast<RawPatchClass*>(owner)->ptr()->patched_class_; |
| 2503 } | 2429 } |
| 2504 | 2430 |
| 2505 | 2431 |
| 2506 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { | 2432 void SnapshotWriter::CheckForNativeFields(RawClass* cls) { |
| 2507 if (cls->ptr()->num_native_fields_ != 0) { | 2433 if (cls->ptr()->num_native_fields_ != 0) { |
| 2508 // We do not allow objects with native fields in an isolate message. | 2434 // We do not allow objects with native fields in an isolate message. |
| 2509 HANDLESCOPE(thread()); | 2435 HANDLESCOPE(thread()); |
| 2510 UnmarkAll(); // Unmark objects now as we are about to print stuff. | |
| 2511 const Class& clazz = Class::Handle(zone(), cls); | 2436 const Class& clazz = Class::Handle(zone(), cls); |
| 2512 char* chars = OS::SCreate(thread()->zone(), | 2437 char* chars = OS::SCreate(thread()->zone(), |
| 2513 "Illegal argument in isolate message" | 2438 "Illegal argument in isolate message" |
| 2514 " : (object extends NativeWrapper - %s)", | 2439 " : (object extends NativeWrapper - %s)", |
| 2515 clazz.ToCString()); | 2440 clazz.ToCString()); |
| 2516 SetWriteException(Exceptions::kArgument, chars); | 2441 SetWriteException(Exceptions::kArgument, chars); |
| 2517 } | 2442 } |
| 2518 } | 2443 } |
| 2519 | 2444 |
| 2520 | 2445 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2534 intptr_t object_id, | 2459 intptr_t object_id, |
| 2535 bool as_reference) { | 2460 bool as_reference) { |
| 2536 // Check if the instance has native fields and throw an exception if it does. | 2461 // Check if the instance has native fields and throw an exception if it does. |
| 2537 CheckForNativeFields(cls); | 2462 CheckForNativeFields(cls); |
| 2538 | 2463 |
| 2539 if ((kind() == Snapshot::kMessage) || (kind() == Snapshot::kScript)) { | 2464 if ((kind() == Snapshot::kMessage) || (kind() == Snapshot::kScript)) { |
| 2540 // Check if object is a closure that is serializable, if the object is a | 2465 // Check if object is a closure that is serializable, if the object is a |
| 2541 // closure that is not serializable this will throw an exception. | 2466 // closure that is not serializable this will throw an exception. |
| 2542 RawFunction* func = IsSerializableClosure(cls, raw); | 2467 RawFunction* func = IsSerializableClosure(cls, raw); |
| 2543 if (func != Function::null()) { | 2468 if (func != Function::null()) { |
| 2544 forward_list_->SetState(raw, kIsSerialized); | 2469 forward_list_->SetState(object_id, kIsSerialized); |
| 2545 WriteStaticImplicitClosure(object_id, func, tags); | 2470 WriteStaticImplicitClosure(object_id, func, tags); |
| 2546 return; | 2471 return; |
| 2547 } | 2472 } |
| 2548 } | 2473 } |
| 2549 | 2474 |
| 2550 // Object is regular dart instance. | 2475 // Object is regular dart instance. |
| 2551 if (as_reference) { | 2476 if (as_reference) { |
| 2552 // Write out the serialization header value for this object. | 2477 // Write out the serialization header value for this object. |
| 2553 WriteInlinedObjectHeader(kOmittedObjectId); | 2478 WriteInlinedObjectHeader(kOmittedObjectId); |
| 2554 | 2479 |
| 2555 // Indicate this is an instance object. | 2480 // Indicate this is an instance object. |
| 2556 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2481 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
| 2557 WriteTags(tags); | 2482 WriteTags(tags); |
| 2558 | 2483 |
| 2559 // Write out the class information for this object. | 2484 // Write out the class information for this object. |
| 2560 WriteObjectImpl(cls, kAsInlinedObject); | 2485 WriteObjectImpl(cls, kAsInlinedObject); |
| 2561 } else { | 2486 } else { |
| 2562 ASSERT(SerializedHeaderTag::decode(raw->ptr()->tags_) == kObjectId); | |
| 2563 ASSERT(object_id == SerializedHeaderData::decode(raw->ptr()->tags_)); | |
| 2564 intptr_t next_field_offset = Class::IsSignatureClass(cls) ? | 2487 intptr_t next_field_offset = Class::IsSignatureClass(cls) ? |
| 2565 Closure::InstanceSize() : | 2488 Closure::InstanceSize() : |
| 2566 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; | 2489 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; |
| 2567 ASSERT(next_field_offset > 0); | 2490 ASSERT(next_field_offset > 0); |
| 2568 | 2491 |
| 2569 // Write out the serialization header value for this object. | 2492 // Write out the serialization header value for this object. |
| 2570 WriteInlinedObjectHeader(object_id); | 2493 WriteInlinedObjectHeader(object_id); |
| 2571 | 2494 |
| 2572 // Indicate this is an instance object. | 2495 // Indicate this is an instance object. |
| 2573 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2496 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2608 return (i + kMaxPredefinedObjectIds); | 2531 return (i + kMaxPredefinedObjectIds); |
| 2609 } | 2532 } |
| 2610 } | 2533 } |
| 2611 return kInvalidIndex; | 2534 return kInvalidIndex; |
| 2612 } | 2535 } |
| 2613 | 2536 |
| 2614 | 2537 |
| 2615 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, | 2538 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, |
| 2616 const char* msg) { | 2539 const char* msg) { |
| 2617 object_store()->clear_sticky_error(); | 2540 object_store()->clear_sticky_error(); |
| 2618 UnmarkAll(); | |
| 2619 if (msg != NULL) { | 2541 if (msg != NULL) { |
| 2620 const String& msg_obj = String::Handle(String::New(msg)); | 2542 const String& msg_obj = String::Handle(String::New(msg)); |
| 2621 const Array& args = Array::Handle(Array::New(1)); | 2543 const Array& args = Array::Handle(Array::New(1)); |
| 2622 args.SetAt(0, msg_obj); | 2544 args.SetAt(0, msg_obj); |
| 2623 Exceptions::ThrowByType(type, args); | 2545 Exceptions::ThrowByType(type, args); |
| 2624 } else { | 2546 } else { |
| 2625 Exceptions::ThrowByType(type, Object::empty_array()); | 2547 Exceptions::ThrowByType(type, Object::empty_array()); |
| 2626 } | 2548 } |
| 2627 UNREACHABLE(); | 2549 UNREACHABLE(); |
| 2628 } | 2550 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2639 intptr_t SnapshotWriter::FirstObjectId() { | 2561 intptr_t SnapshotWriter::FirstObjectId() { |
| 2640 intptr_t max_vm_isolate_object_id = | 2562 intptr_t max_vm_isolate_object_id = |
| 2641 Object::vm_isolate_snapshot_object_table().Length(); | 2563 Object::vm_isolate_snapshot_object_table().Length(); |
| 2642 return kMaxPredefinedObjectIds + max_vm_isolate_object_id; | 2564 return kMaxPredefinedObjectIds + max_vm_isolate_object_id; |
| 2643 } | 2565 } |
| 2644 | 2566 |
| 2645 | 2567 |
| 2646 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, | 2568 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, |
| 2647 ReAlloc alloc) | 2569 ReAlloc alloc) |
| 2648 : SnapshotWriter(Snapshot::kScript, | 2570 : SnapshotWriter(Snapshot::kScript, |
| 2571 Thread::Current(), |
| 2649 buffer, | 2572 buffer, |
| 2650 alloc, | 2573 alloc, |
| 2651 kInitialSize, | 2574 kInitialSize, |
| 2652 &forward_list_, | 2575 &forward_list_, |
| 2653 NULL, /* instructions_writer */ | 2576 NULL, /* instructions_writer */ |
| 2654 true, /* can_send_any_object */ | 2577 true, /* can_send_any_object */ |
| 2655 false, /* snapshot_code */ | 2578 false, /* snapshot_code */ |
| 2656 true /* vm_isolate_is_symbolic */), | 2579 true /* vm_isolate_is_symbolic */), |
| 2657 forward_list_(kMaxPredefinedObjectIds) { | 2580 forward_list_(thread(), kMaxPredefinedObjectIds) { |
| 2658 ASSERT(buffer != NULL); | 2581 ASSERT(buffer != NULL); |
| 2659 ASSERT(alloc != NULL); | 2582 ASSERT(alloc != NULL); |
| 2660 } | 2583 } |
| 2661 | 2584 |
| 2662 | 2585 |
| 2663 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 2586 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
| 2664 ASSERT(kind() == Snapshot::kScript); | 2587 ASSERT(kind() == Snapshot::kScript); |
| 2665 ASSERT(isolate() != NULL); | 2588 ASSERT(isolate() != NULL); |
| 2666 ASSERT(ClassFinalizer::AllClassesFinalized()); | 2589 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 2667 | 2590 |
| 2668 // Setup for long jump in case there is an exception while writing | 2591 // Setup for long jump in case there is an exception while writing |
| 2669 // the snapshot. | 2592 // the snapshot. |
| 2670 LongJumpScope jump; | 2593 LongJumpScope jump; |
| 2671 if (setjmp(*jump.Set()) == 0) { | 2594 if (setjmp(*jump.Set()) == 0) { |
| 2672 // Reserve space in the output buffer for a snapshot header. | 2595 // Reserve space in the output buffer for a snapshot header. |
| 2673 ReserveHeader(); | 2596 ReserveHeader(); |
| 2674 | 2597 |
| 2675 // Write out the version string. | 2598 // Write out the version string. |
| 2676 WriteVersion(); | 2599 WriteVersion(); |
| 2677 | 2600 |
| 2678 // Write out the library object. | 2601 // Write out the library object. |
| 2679 { | 2602 { |
| 2680 NoSafepointScope no_safepoint; | 2603 NoSafepointScope no_safepoint; |
| 2681 | 2604 |
| 2682 // Write out the library object. | 2605 // Write out the library object. |
| 2683 WriteObject(lib.raw()); | 2606 WriteObject(lib.raw()); |
| 2684 | 2607 |
| 2685 FillHeader(kind()); | 2608 FillHeader(kind()); |
| 2686 UnmarkAll(); | |
| 2687 } | 2609 } |
| 2688 } else { | 2610 } else { |
| 2689 ThrowException(exception_type(), exception_msg()); | 2611 ThrowException(exception_type(), exception_msg()); |
| 2690 } | 2612 } |
| 2691 } | 2613 } |
| 2692 | 2614 |
| 2693 | 2615 |
| 2694 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 2616 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 2695 for (RawObject** current = first; current <= last; current++) { | 2617 for (RawObject** current = first; current <= last; current++) { |
| 2696 RawObject* raw_obj = *current; | 2618 RawObject* raw_obj = *current; |
| 2697 writer_->WriteObjectImpl(raw_obj, as_references_); | 2619 writer_->WriteObjectImpl(raw_obj, as_references_); |
| 2698 } | 2620 } |
| 2699 } | 2621 } |
| 2700 | 2622 |
| 2701 | 2623 |
| 2702 MessageWriter::MessageWriter(uint8_t** buffer, | 2624 MessageWriter::MessageWriter(uint8_t** buffer, |
| 2703 ReAlloc alloc, | 2625 ReAlloc alloc, |
| 2704 bool can_send_any_object) | 2626 bool can_send_any_object) |
| 2705 : SnapshotWriter(Snapshot::kMessage, | 2627 : SnapshotWriter(Snapshot::kMessage, |
| 2628 Thread::Current(), |
| 2706 buffer, | 2629 buffer, |
| 2707 alloc, | 2630 alloc, |
| 2708 kInitialSize, | 2631 kInitialSize, |
| 2709 &forward_list_, | 2632 &forward_list_, |
| 2710 NULL, /* instructions_writer */ | 2633 NULL, /* instructions_writer */ |
| 2711 can_send_any_object, | 2634 can_send_any_object, |
| 2712 false, /* snapshot_code */ | 2635 false, /* snapshot_code */ |
| 2713 true /* vm_isolate_is_symbolic */), | 2636 true /* vm_isolate_is_symbolic */), |
| 2714 forward_list_(kMaxPredefinedObjectIds) { | 2637 forward_list_(thread(), kMaxPredefinedObjectIds) { |
| 2715 ASSERT(buffer != NULL); | 2638 ASSERT(buffer != NULL); |
| 2716 ASSERT(alloc != NULL); | 2639 ASSERT(alloc != NULL); |
| 2717 } | 2640 } |
| 2718 | 2641 |
| 2719 | 2642 |
| 2720 void MessageWriter::WriteMessage(const Object& obj) { | 2643 void MessageWriter::WriteMessage(const Object& obj) { |
| 2721 ASSERT(kind() == Snapshot::kMessage); | 2644 ASSERT(kind() == Snapshot::kMessage); |
| 2722 ASSERT(isolate() != NULL); | 2645 ASSERT(isolate() != NULL); |
| 2723 | 2646 |
| 2724 // Setup for long jump in case there is an exception while writing | 2647 // Setup for long jump in case there is an exception while writing |
| 2725 // the message. | 2648 // the message. |
| 2726 LongJumpScope jump; | 2649 LongJumpScope jump; |
| 2727 if (setjmp(*jump.Set()) == 0) { | 2650 if (setjmp(*jump.Set()) == 0) { |
| 2728 NoSafepointScope no_safepoint; | 2651 NoSafepointScope no_safepoint; |
| 2729 WriteObject(obj.raw()); | 2652 WriteObject(obj.raw()); |
| 2730 UnmarkAll(); | |
| 2731 } else { | 2653 } else { |
| 2732 ThrowException(exception_type(), exception_msg()); | 2654 ThrowException(exception_type(), exception_msg()); |
| 2733 } | 2655 } |
| 2734 } | 2656 } |
| 2735 | 2657 |
| 2736 | 2658 |
| 2737 } // namespace dart | 2659 } // namespace dart |
| OLD | NEW |