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

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: code-review-comments 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 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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