| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1616 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1616 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
| 1617 | 1617 |
| 1618 // Clear descriptor cache. | 1618 // Clear descriptor cache. |
| 1619 isolate_->descriptor_lookup_cache()->Clear(); | 1619 isolate_->descriptor_lookup_cache()->Clear(); |
| 1620 | 1620 |
| 1621 // Used for updating survived_since_last_expansion_ at function end. | 1621 // Used for updating survived_since_last_expansion_ at function end. |
| 1622 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); | 1622 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); |
| 1623 | 1623 |
| 1624 SelectScavengingVisitorsTable(); | 1624 SelectScavengingVisitorsTable(); |
| 1625 | 1625 |
| 1626 PrepareArrayBufferDiscoveryInNewSpace(); | |
| 1627 | |
| 1628 // Flip the semispaces. After flipping, to space is empty, from space has | 1626 // Flip the semispaces. After flipping, to space is empty, from space has |
| 1629 // live objects. | 1627 // live objects. |
| 1630 new_space_.Flip(); | 1628 new_space_.Flip(); |
| 1631 new_space_.ResetAllocationInfo(); | 1629 new_space_.ResetAllocationInfo(); |
| 1632 | 1630 |
| 1633 // We need to sweep newly copied objects which can be either in the | 1631 // We need to sweep newly copied objects which can be either in the |
| 1634 // to space or promoted to the old generation. For to-space | 1632 // to space or promoted to the old generation. For to-space |
| 1635 // objects, we treat the bottom of the to space as a queue. Newly | 1633 // objects, we treat the bottom of the to space as a queue. Newly |
| 1636 // copied and unswept objects lie between a 'front' mark and the | 1634 // copied and unswept objects lie between a 'front' mark and the |
| 1637 // allocation pointer. | 1635 // allocation pointer. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 ProcessYoungWeakReferences(&weak_object_retainer); | 1697 ProcessYoungWeakReferences(&weak_object_retainer); |
| 1700 | 1698 |
| 1701 DCHECK(new_space_front == new_space_.top()); | 1699 DCHECK(new_space_front == new_space_.top()); |
| 1702 | 1700 |
| 1703 // Set age mark. | 1701 // Set age mark. |
| 1704 new_space_.set_age_mark(new_space_.top()); | 1702 new_space_.set_age_mark(new_space_.top()); |
| 1705 | 1703 |
| 1706 new_space_.LowerInlineAllocationLimit( | 1704 new_space_.LowerInlineAllocationLimit( |
| 1707 new_space_.inline_allocation_limit_step()); | 1705 new_space_.inline_allocation_limit_step()); |
| 1708 | 1706 |
| 1709 FreeDeadArrayBuffers(true); | |
| 1710 | |
| 1711 // Update how much has survived scavenge. | 1707 // Update how much has survived scavenge. |
| 1712 IncrementYoungSurvivorsCounter(static_cast<int>( | 1708 IncrementYoungSurvivorsCounter(static_cast<int>( |
| 1713 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); | 1709 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); |
| 1714 | 1710 |
| 1715 LOG(isolate_, ResourceEvent("scavenge", "end")); | 1711 LOG(isolate_, ResourceEvent("scavenge", "end")); |
| 1716 | 1712 |
| 1717 gc_state_ = NOT_IN_GC; | 1713 gc_state_ = NOT_IN_GC; |
| 1718 } | 1714 } |
| 1719 | 1715 |
| 1720 | 1716 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1794 } | 1790 } |
| 1795 | 1791 |
| 1796 | 1792 |
| 1797 void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { | 1793 void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer) { |
| 1798 Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer); | 1794 Object* head = VisitWeakList<Context>(this, native_contexts_list(), retainer); |
| 1799 // Update the head of the list of contexts. | 1795 // Update the head of the list of contexts. |
| 1800 set_native_contexts_list(head); | 1796 set_native_contexts_list(head); |
| 1801 } | 1797 } |
| 1802 | 1798 |
| 1803 | 1799 |
| 1804 void Heap::RegisterNewArrayBufferHelper(std::map<void*, size_t>& live_buffers, | 1800 void Heap::RegisterNewArrayBuffer(void* data, size_t length) { |
| 1805 void* data, size_t length) { | |
| 1806 live_buffers[data] = length; | |
| 1807 } | |
| 1808 | |
| 1809 | |
| 1810 void Heap::UnregisterArrayBufferHelper( | |
| 1811 std::map<void*, size_t>& live_buffers, | |
| 1812 std::map<void*, size_t>& not_yet_discovered_buffers, void* data) { | |
| 1813 DCHECK(live_buffers.count(data) > 0); | |
| 1814 live_buffers.erase(data); | |
| 1815 not_yet_discovered_buffers.erase(data); | |
| 1816 } | |
| 1817 | |
| 1818 | |
| 1819 void Heap::RegisterLiveArrayBufferHelper( | |
| 1820 std::map<void*, size_t>& not_yet_discovered_buffers, void* data) { | |
| 1821 not_yet_discovered_buffers.erase(data); | |
| 1822 } | |
| 1823 | |
| 1824 | |
| 1825 size_t Heap::FreeDeadArrayBuffersHelper( | |
| 1826 Isolate* isolate, std::map<void*, size_t>& live_buffers, | |
| 1827 std::map<void*, size_t>& not_yet_discovered_buffers) { | |
| 1828 size_t freed_memory = 0; | |
| 1829 for (auto buffer = not_yet_discovered_buffers.begin(); | |
| 1830 buffer != not_yet_discovered_buffers.end(); ++buffer) { | |
| 1831 isolate->array_buffer_allocator()->Free(buffer->first, buffer->second); | |
| 1832 freed_memory += buffer->second; | |
| 1833 live_buffers.erase(buffer->first); | |
| 1834 } | |
| 1835 not_yet_discovered_buffers = live_buffers; | |
| 1836 return freed_memory; | |
| 1837 } | |
| 1838 | |
| 1839 | |
| 1840 void Heap::TearDownArrayBuffersHelper( | |
| 1841 Isolate* isolate, std::map<void*, size_t>& live_buffers, | |
| 1842 std::map<void*, size_t>& not_yet_discovered_buffers) { | |
| 1843 for (auto buffer = live_buffers.begin(); buffer != live_buffers.end(); | |
| 1844 ++buffer) { | |
| 1845 isolate->array_buffer_allocator()->Free(buffer->first, buffer->second); | |
| 1846 } | |
| 1847 live_buffers.clear(); | |
| 1848 not_yet_discovered_buffers.clear(); | |
| 1849 } | |
| 1850 | |
| 1851 | |
| 1852 void Heap::RegisterNewArrayBuffer(bool in_new_space, void* data, | |
| 1853 size_t length) { | |
| 1854 if (!data) return; | 1801 if (!data) return; |
| 1855 RegisterNewArrayBufferHelper( | 1802 live_array_buffers_[data] = length; |
| 1856 in_new_space ? live_new_array_buffers_ : live_array_buffers_, data, | |
| 1857 length); | |
| 1858 reinterpret_cast<v8::Isolate*>(isolate_) | 1803 reinterpret_cast<v8::Isolate*>(isolate_) |
| 1859 ->AdjustAmountOfExternalAllocatedMemory(length); | 1804 ->AdjustAmountOfExternalAllocatedMemory(length); |
| 1860 } | 1805 } |
| 1861 | 1806 |
| 1862 | 1807 |
| 1863 void Heap::UnregisterArrayBuffer(bool in_new_space, void* data) { | 1808 void Heap::UnregisterArrayBuffer(void* data) { |
| 1864 if (!data) return; | 1809 if (!data) return; |
| 1865 UnregisterArrayBufferHelper( | 1810 DCHECK(live_array_buffers_.count(data) > 0); |
| 1866 in_new_space ? live_new_array_buffers_ : live_array_buffers_, | 1811 live_array_buffers_.erase(data); |
| 1867 in_new_space ? not_yet_discovered_new_array_buffers_ | 1812 not_yet_discovered_array_buffers_.erase(data); |
| 1868 : not_yet_discovered_array_buffers_, | |
| 1869 data); | |
| 1870 } | 1813 } |
| 1871 | 1814 |
| 1872 | 1815 |
| 1873 void Heap::RegisterLiveArrayBuffer(bool in_new_space, void* data) { | 1816 void Heap::RegisterLiveArrayBuffer(void* data) { |
| 1874 RegisterLiveArrayBufferHelper(in_new_space | 1817 not_yet_discovered_array_buffers_.erase(data); |
| 1875 ? not_yet_discovered_new_array_buffers_ | |
| 1876 : not_yet_discovered_array_buffers_, | |
| 1877 data); | |
| 1878 } | 1818 } |
| 1879 | 1819 |
| 1880 | 1820 |
| 1881 void Heap::FreeDeadArrayBuffers(bool in_new_space) { | 1821 void Heap::FreeDeadArrayBuffers() { |
| 1882 size_t freed_memory = FreeDeadArrayBuffersHelper( | 1822 for (auto buffer = not_yet_discovered_array_buffers_.begin(); |
| 1883 isolate_, in_new_space ? live_new_array_buffers_ : live_array_buffers_, | 1823 buffer != not_yet_discovered_array_buffers_.end(); ++buffer) { |
| 1884 in_new_space ? not_yet_discovered_new_array_buffers_ | 1824 isolate_->array_buffer_allocator()->Free(buffer->first, buffer->second); |
| 1885 : not_yet_discovered_array_buffers_); | 1825 // Don't use the API method here since this could trigger another GC. |
| 1886 if (freed_memory) { | 1826 amount_of_external_allocated_memory_ -= buffer->second; |
| 1887 reinterpret_cast<v8::Isolate*>(isolate_) | 1827 live_array_buffers_.erase(buffer->first); |
| 1888 ->AdjustAmountOfExternalAllocatedMemory( | |
| 1889 -static_cast<int64_t>(freed_memory)); | |
| 1890 } | 1828 } |
| 1829 not_yet_discovered_array_buffers_ = live_array_buffers_; |
| 1891 } | 1830 } |
| 1892 | 1831 |
| 1893 | 1832 |
| 1894 void Heap::TearDownArrayBuffers() { | 1833 void Heap::TearDownArrayBuffers() { |
| 1895 TearDownArrayBuffersHelper(isolate_, live_array_buffers_, | 1834 for (auto buffer = live_array_buffers_.begin(); |
| 1896 not_yet_discovered_array_buffers_); | 1835 buffer != live_array_buffers_.end(); ++buffer) { |
| 1897 TearDownArrayBuffersHelper(isolate_, live_new_array_buffers_, | 1836 isolate_->array_buffer_allocator()->Free(buffer->first, buffer->second); |
| 1898 not_yet_discovered_new_array_buffers_); | 1837 } |
| 1838 live_array_buffers_.clear(); |
| 1839 not_yet_discovered_array_buffers_.clear(); |
| 1899 } | 1840 } |
| 1900 | 1841 |
| 1901 | 1842 |
| 1902 void Heap::PrepareArrayBufferDiscoveryInNewSpace() { | |
| 1903 not_yet_discovered_new_array_buffers_ = live_new_array_buffers_; | |
| 1904 } | |
| 1905 | |
| 1906 | |
| 1907 void Heap::PromoteArrayBuffer(Object* obj) { | |
| 1908 JSArrayBuffer* buffer = JSArrayBuffer::cast(obj); | |
| 1909 if (buffer->is_external()) return; | |
| 1910 void* data = buffer->backing_store(); | |
| 1911 if (!data) return; | |
| 1912 DCHECK(live_new_array_buffers_.count(data) > 0); | |
| 1913 live_array_buffers_[data] = live_new_array_buffers_[data]; | |
| 1914 live_new_array_buffers_.erase(data); | |
| 1915 not_yet_discovered_new_array_buffers_.erase(data); | |
| 1916 } | |
| 1917 | |
| 1918 | |
| 1919 void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) { | 1843 void Heap::ProcessAllocationSites(WeakObjectRetainer* retainer) { |
| 1920 Object* allocation_site_obj = | 1844 Object* allocation_site_obj = |
| 1921 VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer); | 1845 VisitWeakList<AllocationSite>(this, allocation_sites_list(), retainer); |
| 1922 set_allocation_sites_list(allocation_site_obj); | 1846 set_allocation_sites_list(allocation_site_obj); |
| 1923 } | 1847 } |
| 1924 | 1848 |
| 1925 | 1849 |
| 1926 void Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) { | 1850 void Heap::ResetAllAllocationSitesDependentCode(PretenureFlag flag) { |
| 1927 DisallowHeapAllocation no_allocation_scope; | 1851 DisallowHeapAllocation no_allocation_scope; |
| 1928 Object* cur = allocation_sites_list(); | 1852 Object* cur = allocation_sites_list(); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2158 public: | 2082 public: |
| 2159 static void Initialize() { | 2083 static void Initialize() { |
| 2160 table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); | 2084 table_.Register(kVisitSeqOneByteString, &EvacuateSeqOneByteString); |
| 2161 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); | 2085 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); |
| 2162 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); | 2086 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); |
| 2163 table_.Register(kVisitByteArray, &EvacuateByteArray); | 2087 table_.Register(kVisitByteArray, &EvacuateByteArray); |
| 2164 table_.Register(kVisitFixedArray, &EvacuateFixedArray); | 2088 table_.Register(kVisitFixedArray, &EvacuateFixedArray); |
| 2165 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); | 2089 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); |
| 2166 table_.Register(kVisitFixedTypedArray, &EvacuateFixedTypedArray); | 2090 table_.Register(kVisitFixedTypedArray, &EvacuateFixedTypedArray); |
| 2167 table_.Register(kVisitFixedFloat64Array, &EvacuateFixedFloat64Array); | 2091 table_.Register(kVisitFixedFloat64Array, &EvacuateFixedFloat64Array); |
| 2168 table_.Register(kVisitJSArrayBuffer, &EvacuateJSArrayBuffer); | |
| 2169 | 2092 |
| 2170 table_.Register( | 2093 table_.Register( |
| 2171 kVisitNativeContext, | 2094 kVisitNativeContext, |
| 2172 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< | 2095 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< |
| 2173 Context::kSize>); | 2096 Context::kSize>); |
| 2174 | 2097 |
| 2175 table_.Register( | 2098 table_.Register( |
| 2176 kVisitConsString, | 2099 kVisitConsString, |
| 2177 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< | 2100 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< |
| 2178 ConsString::kSize>); | 2101 ConsString::kSize>); |
| 2179 | 2102 |
| 2180 table_.Register( | 2103 table_.Register( |
| 2181 kVisitSlicedString, | 2104 kVisitSlicedString, |
| 2182 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< | 2105 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< |
| 2183 SlicedString::kSize>); | 2106 SlicedString::kSize>); |
| 2184 | 2107 |
| 2185 table_.Register( | 2108 table_.Register( |
| 2186 kVisitSymbol, | 2109 kVisitSymbol, |
| 2187 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< | 2110 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< |
| 2188 Symbol::kSize>); | 2111 Symbol::kSize>); |
| 2189 | 2112 |
| 2190 table_.Register( | 2113 table_.Register( |
| 2191 kVisitSharedFunctionInfo, | 2114 kVisitSharedFunctionInfo, |
| 2192 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< | 2115 &ObjectEvacuationStrategy<POINTER_OBJECT>::template VisitSpecialized< |
| 2193 SharedFunctionInfo::kSize>); | 2116 SharedFunctionInfo::kSize>); |
| 2194 | 2117 |
| 2195 table_.Register(kVisitJSWeakCollection, | 2118 table_.Register(kVisitJSWeakCollection, |
| 2196 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); | 2119 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); |
| 2197 | 2120 |
| 2121 table_.Register(kVisitJSArrayBuffer, |
| 2122 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); |
| 2123 |
| 2198 table_.Register(kVisitJSTypedArray, | 2124 table_.Register(kVisitJSTypedArray, |
| 2199 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); | 2125 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); |
| 2200 | 2126 |
| 2201 table_.Register(kVisitJSDataView, | 2127 table_.Register(kVisitJSDataView, |
| 2202 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); | 2128 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); |
| 2203 | 2129 |
| 2204 table_.Register(kVisitJSRegExp, | 2130 table_.Register(kVisitJSRegExp, |
| 2205 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); | 2131 &ObjectEvacuationStrategy<POINTER_OBJECT>::Visit); |
| 2206 | 2132 |
| 2207 if (marks_handling == IGNORE_MARKS) { | 2133 if (marks_handling == IGNORE_MARKS) { |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2415 } | 2341 } |
| 2416 | 2342 |
| 2417 | 2343 |
| 2418 static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, | 2344 static inline void EvacuateFixedFloat64Array(Map* map, HeapObject** slot, |
| 2419 HeapObject* object) { | 2345 HeapObject* object) { |
| 2420 int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); | 2346 int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size(); |
| 2421 EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size); | 2347 EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size); |
| 2422 } | 2348 } |
| 2423 | 2349 |
| 2424 | 2350 |
| 2425 static inline void EvacuateJSArrayBuffer(Map* map, HeapObject** slot, | |
| 2426 HeapObject* object) { | |
| 2427 ObjectEvacuationStrategy<POINTER_OBJECT>::Visit(map, slot, object); | |
| 2428 | |
| 2429 Heap* heap = map->GetHeap(); | |
| 2430 MapWord map_word = object->map_word(); | |
| 2431 DCHECK(map_word.IsForwardingAddress()); | |
| 2432 HeapObject* target = map_word.ToForwardingAddress(); | |
| 2433 if (!heap->InNewSpace(target)) heap->PromoteArrayBuffer(target); | |
| 2434 } | |
| 2435 | |
| 2436 | |
| 2437 static inline void EvacuateByteArray(Map* map, HeapObject** slot, | 2351 static inline void EvacuateByteArray(Map* map, HeapObject** slot, |
| 2438 HeapObject* object) { | 2352 HeapObject* object) { |
| 2439 int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); | 2353 int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); |
| 2440 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); | 2354 EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size); |
| 2441 } | 2355 } |
| 2442 | 2356 |
| 2443 | 2357 |
| 2444 static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, | 2358 static inline void EvacuateSeqOneByteString(Map* map, HeapObject** slot, |
| 2445 HeapObject* object) { | 2359 HeapObject* object) { |
| 2446 int object_size = SeqOneByteString::cast(object) | 2360 int object_size = SeqOneByteString::cast(object) |
| (...skipping 4255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6702 *object_type = "CODE_TYPE"; \ | 6616 *object_type = "CODE_TYPE"; \ |
| 6703 *object_sub_type = "CODE_AGE/" #name; \ | 6617 *object_sub_type = "CODE_AGE/" #name; \ |
| 6704 return true; | 6618 return true; |
| 6705 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6619 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
| 6706 #undef COMPARE_AND_RETURN_NAME | 6620 #undef COMPARE_AND_RETURN_NAME |
| 6707 } | 6621 } |
| 6708 return false; | 6622 return false; |
| 6709 } | 6623 } |
| 6710 } // namespace internal | 6624 } // namespace internal |
| 6711 } // namespace v8 | 6625 } // namespace v8 |
| OLD | NEW |