Chromium Code Reviews| 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 WipeOutCodeHeader(Code* code) { | |
| 1787 code->set_relocation_info( | |
|
Benedikt Meurer
2013/11/04 11:25:14
Nit: Can we do better here?
| |
| 1788 reinterpret_cast<ByteArray*>(Smi::FromInt(0)), SKIP_WRITE_BARRIER); | |
| 1789 code->set_handler_table( | |
| 1790 reinterpret_cast<FixedArray*>(Smi::FromInt(0)), SKIP_WRITE_BARRIER); | |
| 1791 code->set_deoptimization_data( | |
| 1792 reinterpret_cast<FixedArray*>(Smi::FromInt(0)), SKIP_WRITE_BARRIER); | |
| 1793 // Do not wipe out e.g. a minor key. | |
| 1794 if (!code->raw_type_feedback_info()->IsSmi()) { | |
| 1795 code->InitializeTypeFeedbackInfoNoWriteBarrier(Smi::FromInt(0)); | |
| 1796 } | |
| 1797 } | |
| 1798 | |
| 1799 | |
| 1800 static void WipeOutRelocations(Code* code) { | |
| 1801 int mode_mask = | |
| 1802 RelocInfo::kCodeTargetMask | | |
| 1803 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | | |
| 1804 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | | |
| 1805 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); | |
| 1806 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) { | |
| 1807 it.rinfo()->WipeOut(); | |
| 1808 } | |
| 1809 } | |
| 1810 | |
| 1811 | |
| 1779 int Serializer::ObjectSerializer::OutputRawData( | 1812 int Serializer::ObjectSerializer::OutputRawData( |
| 1780 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { | 1813 Address up_to, Serializer::ObjectSerializer::ReturnSkip return_skip) { |
| 1781 Address object_start = object_->address(); | 1814 Address object_start = object_->address(); |
| 1782 Address base = object_start + bytes_processed_so_far_; | 1815 int base = bytes_processed_so_far_; |
| 1783 int up_to_offset = static_cast<int>(up_to - object_start); | 1816 int up_to_offset = static_cast<int>(up_to - object_start); |
| 1784 int to_skip = up_to_offset - bytes_processed_so_far_; | 1817 int to_skip = up_to_offset - bytes_processed_so_far_; |
| 1785 int bytes_to_output = to_skip; | 1818 int bytes_to_output = to_skip; |
| 1786 bytes_processed_so_far_ += to_skip; | 1819 bytes_processed_so_far_ += to_skip; |
| 1787 // This assert will fail if the reloc info gives us the target_address_address | 1820 // 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. | 1821 // locations in a non-ascending order. Luckily that doesn't happen. |
| 1789 ASSERT(to_skip >= 0); | 1822 ASSERT(to_skip >= 0); |
| 1790 bool outputting_code = false; | 1823 bool outputting_code = false; |
| 1791 if (to_skip != 0 && code_object_ && !code_has_been_output_) { | 1824 if (to_skip != 0 && code_object_ && !code_has_been_output_) { |
| 1792 // Output the code all at once and fix later. | 1825 // Output the code all at once and fix later. |
| 1793 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; | 1826 bytes_to_output = object_->Size() + to_skip - bytes_processed_so_far_; |
| 1794 outputting_code = true; | 1827 outputting_code = true; |
| 1795 code_has_been_output_ = true; | 1828 code_has_been_output_ = true; |
| 1796 } | 1829 } |
| 1797 if (bytes_to_output != 0 && | 1830 if (bytes_to_output != 0 && |
| 1798 (!code_object_ || outputting_code)) { | 1831 (!code_object_ || outputting_code)) { |
| 1799 #define RAW_CASE(index) \ | 1832 #define RAW_CASE(index) \ |
| 1800 if (!outputting_code && bytes_to_output == index * kPointerSize && \ | 1833 if (!outputting_code && bytes_to_output == index * kPointerSize && \ |
| 1801 index * kPointerSize == to_skip) { \ | 1834 index * kPointerSize == to_skip) { \ |
| 1802 sink_->PutSection(kRawData + index, "RawDataFixed"); \ | 1835 sink_->PutSection(kRawData + index, "RawDataFixed"); \ |
| 1803 to_skip = 0; /* This insn already skips. */ \ | 1836 to_skip = 0; /* This insn already skips. */ \ |
| 1804 } else /* NOLINT */ | 1837 } else /* NOLINT */ |
| 1805 COMMON_RAW_LENGTHS(RAW_CASE) | 1838 COMMON_RAW_LENGTHS(RAW_CASE) |
| 1806 #undef RAW_CASE | 1839 #undef RAW_CASE |
| 1807 { /* NOLINT */ | 1840 { /* NOLINT */ |
| 1808 // We always end up here if we are outputting the code of a code object. | 1841 // We always end up here if we are outputting the code of a code object. |
| 1809 sink_->Put(kRawData, "RawData"); | 1842 sink_->Put(kRawData, "RawData"); |
| 1810 sink_->PutInt(bytes_to_output, "length"); | 1843 sink_->PutInt(bytes_to_output, "length"); |
| 1811 } | 1844 } |
| 1845 | |
| 1846 // To make snapshots reproducible, we need to wipe out all pointers in code. | |
| 1847 if (code_object_) { | |
| 1848 Code* code = CloneCodeObject(object_); | |
| 1849 WipeOutRelocations(code); | |
| 1850 // We need to wipe out the header fields *after* wiping out the | |
| 1851 // relocations, because some of these fields are needed for the latter. | |
| 1852 WipeOutCodeHeader(code); | |
| 1853 object_start = code->address(); | |
| 1854 } | |
| 1855 | |
| 1856 const char* description = code_object_ ? "Code" : "Byte"; | |
| 1812 for (int i = 0; i < bytes_to_output; i++) { | 1857 for (int i = 0; i < bytes_to_output; i++) { |
| 1813 unsigned int data = base[i]; | 1858 sink_->PutSection(object_start[base + i], description); |
| 1814 sink_->PutSection(data, "Byte"); | |
| 1815 } | 1859 } |
| 1860 if (code_object_) delete[] object_start; | |
| 1816 } | 1861 } |
| 1817 if (to_skip != 0 && return_skip == kIgnoringReturn) { | 1862 if (to_skip != 0 && return_skip == kIgnoringReturn) { |
| 1818 sink_->Put(kSkip, "Skip"); | 1863 sink_->Put(kSkip, "Skip"); |
| 1819 sink_->PutInt(to_skip, "SkipDistance"); | 1864 sink_->PutInt(to_skip, "SkipDistance"); |
| 1820 to_skip = 0; | 1865 to_skip = 0; |
| 1821 } | 1866 } |
| 1822 return to_skip; | 1867 return to_skip; |
| 1823 } | 1868 } |
| 1824 | 1869 |
| 1825 | 1870 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1864 | 1909 |
| 1865 bool SnapshotByteSource::AtEOF() { | 1910 bool SnapshotByteSource::AtEOF() { |
| 1866 if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false; | 1911 if (0u + length_ - position_ > 2 * sizeof(uint32_t)) return false; |
| 1867 for (int x = position_; x < length_; x++) { | 1912 for (int x = position_; x < length_; x++) { |
| 1868 if (data_[x] != SerializerDeserializer::nop()) return false; | 1913 if (data_[x] != SerializerDeserializer::nop()) return false; |
| 1869 } | 1914 } |
| 1870 return true; | 1915 return true; |
| 1871 } | 1916 } |
| 1872 | 1917 |
| 1873 } } // namespace v8::internal | 1918 } } // namespace v8::internal |
| OLD | NEW |