Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: runtime/vm/snapshot.cc

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

Powered by Google App Engine
This is Rietveld 408576698