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 |