OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1758 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1769 return; | 1769 return; |
1770 } | 1770 } |
1771 } | 1771 } |
1772 } | 1772 } |
1773 // One of the strings in the natives cache should match the resource. We | 1773 // One of the strings in the natives cache should match the resource. We |
1774 // can't serialize any other kinds of external strings. | 1774 // can't serialize any other kinds of external strings. |
1775 UNREACHABLE(); | 1775 UNREACHABLE(); |
1776 } | 1776 } |
1777 | 1777 |
1778 | 1778 |
| 1779 static Code* CloneCodeObject(HeapObject* code) { |
| 1780 Address copy = new byte[code->Size()]; |
| 1781 OS::MemCopy(copy, code->address(), code->Size()); |
| 1782 return Code::cast(HeapObject::FromAddress(copy)); |
| 1783 } |
| 1784 |
| 1785 |
| 1786 static void WipeOutRelocations(Code* code) { |
| 1787 int mode_mask = |
| 1788 RelocInfo::kCodeTargetMask | |
| 1789 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |
| 1790 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | |
| 1791 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); |
| 1792 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { |
| 1793 it.rinfo()->WipeOut(); |
| 1794 } |
| 1795 } |
| 1796 |
| 1797 |
1779 int Serializer::ObjectSerializer::OutputRawData( | 1798 int Serializer::ObjectSerializer::OutputRawData( |
1780 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { | 1799 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { |
1781 Address object_start = object_->address(); | 1800 Address object_start = object_->address(); |
1782 Address base = object_start + bytes_processed_so_far_; | 1801 int base = bytes_processed_so_far_; |
1783 int up_to_offset = static_cast<int>(up_to - object_start); | 1802 int up_to_offset = static_cast<int>(up_to - object_start); |
1784 int to_skip = up_to_offset - bytes_processed_so_far_; | 1803 int to_skip = up_to_offset - bytes_processed_so_far_; |
1785 int bytes_to_output = to_skip; | 1804 int bytes_to_output = to_skip; |
1786 bytes_processed_so_far_ += to_skip; | 1805 bytes_processed_so_far_ += to_skip; |
1787 // This assert will fail if the reloc info gives us the target_address_address | 1806 // This assert will fail if the reloc info gives us the target_address_address |
1788 // locations in a non-ascending order. Luckily that doesn't happen. | 1807 // locations in a non-ascending order. Luckily that doesn't happen. |
1789 ASSERT(to_skip >= 0); | 1808 ASSERT(to_skip >= 0); |
1790 bool outputting_code = false; | 1809 bool outputting_code = false; |
1791 if (to_skip != 0 && code_object_ && !code_has_been_output_) { | 1810 if (to_skip != 0 && code_object_ && !code_has_been_output_) { |
1792 // Output the code all at once and fix later. | 1811 // Output the code all at once and fix later. |
1793 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; | 1812 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; |
1794 outputting_code = true; | 1813 outputting_code = true; |
1795 code_has_been_output_ = true; | 1814 code_has_been_output_ = true; |
1796 } | 1815 } |
1797 if (bytes_to_output != 0 && | 1816 if (bytes_to_output != 0 && |
1798 (!code_object_ || outputting_code)) { | 1817 (!code_object_ || outputting_code)) { |
1799 #define RAW_CASE(index) \ | 1818 #define RAW_CASE(index) \ |
1800 if (!outputting_code && bytes_to_output == index * kPointerSize && \ | 1819 if (!outputting_code && bytes_to_output == index * kPointerSize && \ |
1801 index * kPointerSize == to_skip) { \ | 1820 index * kPointerSize == to_skip) { \ |
1802 sink_->PutSection(kRawData + index, "RawDataFixed"); \ | 1821 sink_->PutSection(kRawData + index, "RawDataFixed"); \ |
1803 to_skip = 0; /* This insn already skips. */ \ | 1822 to_skip = 0; /* This insn already skips. */ \ |
1804 } else /* NOLINT */ | 1823 } else /* NOLINT */ |
1805 COMMON_RAW_LENGTHS(RAW_CASE) | 1824 COMMON_RAW_LENGTHS(RAW_CASE) |
1806 #undef RAW_CASE | 1825 #undef RAW_CASE |
1807 { /* NOLINT */ | 1826 { /* NOLINT */ |
1808 // We always end up here if we are outputting the code of a code object. | 1827 // We always end up here if we are outputting the code of a code object. |
1809 sink_->Put(kRawData, "RawData"); | 1828 sink_->Put(kRawData, "RawData"); |
1810 sink_->PutInt(bytes_to_output, "length"); | 1829 sink_->PutInt(bytes_to_output, "length"); |
1811 } | 1830 } |
| 1831 |
| 1832 // To make snapshots reproducible, we need to wipe out all pointers in code. |
| 1833 if (code_object_) { |
| 1834 Code* code = CloneCodeObject(object_); |
| 1835 WipeOutRelocations(code); |
| 1836 // We need to wipe out the header fields *after* wiping out the |
| 1837 // relocations, because some of these fields are needed for the latter. |
| 1838 code->WipeOutHeader(); |
| 1839 object_start = code->address(); |
| 1840 } |
| 1841 |
| 1842 const char* description = code_object_ ? "Code" : "Byte"; |
1812 for (int i = 0; i < bytes_to_output; i++) { | 1843 for (int i = 0; i < bytes_to_output; i++) { |
1813 unsigned int data = base[i]; | 1844 sink_->PutSection(object_start[base + i], description); |
1814 sink_->PutSection(data, "Byte"); | |
1815 } | 1845 } |
| 1846 if (code_object_) delete[] object_start; |
1816 } | 1847 } |
1817 if (to_skip != 0 && return_skip == kIgnoringReturn) { | 1848 if (to_skip != 0 && return_skip == kIgnoringReturn) { |
1818 sink_->Put(kSkip, "Skip"); | 1849 sink_->Put(kSkip, "Skip"); |
1819 sink_->PutInt(to_skip, "SkipDistance"); | 1850 sink_->PutInt(to_skip, "SkipDistance"); |
1820 to_skip = 0; | 1851 to_skip = 0; |
1821 } | 1852 } |
1822 return to_skip; | 1853 return to_skip; |
1823 } | 1854 } |
1824 | 1855 |
1825 | 1856 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1864 | 1895 |
1865 bool SnapshotByteSource::AtEOF() { | 1896 bool SnapshotByteSource::AtEOF() { |
1866 if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false; | 1897 if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false; |
1867 for (int x = position_; x < length_; x++) { | 1898 for (int x = position_; x < length_; x++) { |
1868 if (data_[x] != SerializerDeserializer::nop()) return false; | 1899 if (data_[x] != SerializerDeserializer::nop()) return false; |
1869 } | 1900 } |
1870 return true; | 1901 return true; |
1871 } | 1902 } |
1872 | 1903 |
1873 } } // namespace v8::internal | 1904 } } // namespace v8::internal |
OLD | NEW |