| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 1409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1420 visitor->markHeader(header, gcInfo->m_trace); | 1420 visitor->markHeader(header, gcInfo->m_trace); |
| 1421 } | 1421 } |
| 1422 } | 1422 } |
| 1423 | 1423 |
| 1424 void NormalPage::checkAndMarkPointer(Visitor* visitor, Address address) | 1424 void NormalPage::checkAndMarkPointer(Visitor* visitor, Address address) |
| 1425 { | 1425 { |
| 1426 ASSERT(contains(address)); | 1426 ASSERT(contains(address)); |
| 1427 HeapObjectHeader* header = findHeaderFromAddress(address); | 1427 HeapObjectHeader* header = findHeaderFromAddress(address); |
| 1428 if (!header || header->isDead()) | 1428 if (!header || header->isDead()) |
| 1429 return; | 1429 return; |
| 1430 #if ENABLE(GC_PROFILING) | |
| 1431 visitor->setHostInfo(&address, "stack"); | |
| 1432 #endif | |
| 1433 markPointer(visitor, header); | 1430 markPointer(visitor, header); |
| 1434 } | 1431 } |
| 1435 | 1432 |
| 1436 void NormalPage::markOrphaned() | 1433 void NormalPage::markOrphaned() |
| 1437 { | 1434 { |
| 1438 // Zap the payload with a recognizable value to detect any incorrect | 1435 // Zap the payload with a recognizable value to detect any incorrect |
| 1439 // cross thread pointer usage. | 1436 // cross thread pointer usage. |
| 1440 #if defined(ADDRESS_SANITIZER) | 1437 #if defined(ADDRESS_SANITIZER) |
| 1441 // This needs to zap poisoned memory as well. | 1438 // This needs to zap poisoned memory as well. |
| 1442 // Force unpoison memory before memset. | 1439 // Force unpoison memory before memset. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 ASAN_UNPOISON_MEMORY_REGION(header->payload(), header->payloadSize()
); | 1602 ASAN_UNPOISON_MEMORY_REGION(header->payload(), header->payloadSize()
); |
| 1606 } | 1603 } |
| 1607 } | 1604 } |
| 1608 #endif | 1605 #endif |
| 1609 | 1606 |
| 1610 void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address) | 1607 void LargeObjectPage::checkAndMarkPointer(Visitor* visitor, Address address) |
| 1611 { | 1608 { |
| 1612 ASSERT(contains(address)); | 1609 ASSERT(contains(address)); |
| 1613 if (!containedInObjectPayload(address) || heapObjectHeader()->isDead()) | 1610 if (!containedInObjectPayload(address) || heapObjectHeader()->isDead()) |
| 1614 return; | 1611 return; |
| 1615 #if ENABLE(GC_PROFILING) | |
| 1616 visitor->setHostInfo(&address, "stack"); | |
| 1617 #endif | |
| 1618 markPointer(visitor, heapObjectHeader()); | 1612 markPointer(visitor, heapObjectHeader()); |
| 1619 } | 1613 } |
| 1620 | 1614 |
| 1621 void LargeObjectPage::markOrphaned() | 1615 void LargeObjectPage::markOrphaned() |
| 1622 { | 1616 { |
| 1623 // Zap the payload with a recognizable value to detect any incorrect | 1617 // Zap the payload with a recognizable value to detect any incorrect |
| 1624 // cross thread pointer usage. | 1618 // cross thread pointer usage. |
| 1625 memset(payload(), orphanedZapValue, payloadSize()); | 1619 memset(payload(), orphanedZapValue, payloadSize()); |
| 1626 BasePage::markOrphaned(); | 1620 BasePage::markOrphaned(); |
| 1627 } | 1621 } |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 } | 1828 } |
| 1835 | 1829 |
| 1836 #if ENABLE(GC_PROFILING) | 1830 #if ENABLE(GC_PROFILING) |
| 1837 const GCInfo* Heap::findGCInfo(Address address) | 1831 const GCInfo* Heap::findGCInfo(Address address) |
| 1838 { | 1832 { |
| 1839 return ThreadState::findGCInfoFromAllThreads(address); | 1833 return ThreadState::findGCInfoFromAllThreads(address); |
| 1840 } | 1834 } |
| 1841 #endif | 1835 #endif |
| 1842 | 1836 |
| 1843 #if ENABLE(GC_PROFILING) | 1837 #if ENABLE(GC_PROFILING) |
| 1844 void Heap::dumpPathToObjectOnNextGC(void* p) | |
| 1845 { | |
| 1846 MarkingVisitor<Visitor::GlobalMarking> visitor; | |
| 1847 visitor->dumpPathToObjectOnNextGC(p); | |
| 1848 } | |
| 1849 | |
| 1850 String Heap::createBacktraceString() | 1838 String Heap::createBacktraceString() |
| 1851 { | 1839 { |
| 1852 int framesToShow = 3; | 1840 int framesToShow = 3; |
| 1853 int stackFrameSize = 16; | 1841 int stackFrameSize = 16; |
| 1854 ASSERT(stackFrameSize >= framesToShow); | 1842 ASSERT(stackFrameSize >= framesToShow); |
| 1855 using FramePointer = void*; | 1843 using FramePointer = void*; |
| 1856 FramePointer* stackFrame = static_cast<FramePointer*>(alloca(sizeof(FramePoi
nter) * stackFrameSize)); | 1844 FramePointer* stackFrame = static_cast<FramePointer*>(alloca(sizeof(FramePoi
nter) * stackFrameSize)); |
| 1857 WTFGetBacktrace(stackFrame, &stackFrameSize); | 1845 WTFGetBacktrace(stackFrame, &stackFrameSize); |
| 1858 | 1846 |
| 1859 StringBuilder builder; | 1847 StringBuilder builder; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1891 ASSERT(!Heap::orphanedPagePool()->contains(object)); | 1879 ASSERT(!Heap::orphanedPagePool()->contains(object)); |
| 1892 CallbackStack::Item* slot = s_markingStack->allocateEntry(); | 1880 CallbackStack::Item* slot = s_markingStack->allocateEntry(); |
| 1893 *slot = CallbackStack::Item(object, callback); | 1881 *slot = CallbackStack::Item(object, callback); |
| 1894 } | 1882 } |
| 1895 | 1883 |
| 1896 bool Heap::popAndInvokeTraceCallback(Visitor* visitor) | 1884 bool Heap::popAndInvokeTraceCallback(Visitor* visitor) |
| 1897 { | 1885 { |
| 1898 CallbackStack::Item* item = s_markingStack->pop(); | 1886 CallbackStack::Item* item = s_markingStack->pop(); |
| 1899 if (!item) | 1887 if (!item) |
| 1900 return false; | 1888 return false; |
| 1901 | |
| 1902 #if ENABLE(GC_PROFILING) | |
| 1903 visitor->setHostInfo(item->object(), classOf(item->object())); | |
| 1904 #endif | |
| 1905 item->call(visitor); | 1889 item->call(visitor); |
| 1906 return true; | 1890 return true; |
| 1907 } | 1891 } |
| 1908 | 1892 |
| 1909 void Heap::pushPostMarkingCallback(void* object, TraceCallback callback) | 1893 void Heap::pushPostMarkingCallback(void* object, TraceCallback callback) |
| 1910 { | 1894 { |
| 1911 ASSERT(ThreadState::current()->isInGC()); | 1895 ASSERT(ThreadState::current()->isInGC()); |
| 1912 | 1896 |
| 1913 // Trace should never reach an orphaned page. | 1897 // Trace should never reach an orphaned page. |
| 1914 ASSERT(!Heap::orphanedPagePool()->contains(object)); | 1898 ASSERT(!Heap::orphanedPagePool()->contains(object)); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2018 return; | 2002 return; |
| 2019 | 2003 |
| 2020 if (state->isMainThread()) | 2004 if (state->isMainThread()) |
| 2021 ScriptForbiddenScope::enter(); | 2005 ScriptForbiddenScope::enter(); |
| 2022 | 2006 |
| 2023 TRACE_EVENT2("blink_gc", "Heap::collectGarbage", | 2007 TRACE_EVENT2("blink_gc", "Heap::collectGarbage", |
| 2024 "lazySweeping", gcType == ThreadState::GCWithoutSweep, | 2008 "lazySweeping", gcType == ThreadState::GCWithoutSweep, |
| 2025 "gcReason", gcReasonString(reason)); | 2009 "gcReason", gcReasonString(reason)); |
| 2026 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); | 2010 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); |
| 2027 double timeStamp = WTF::currentTimeMS(); | 2011 double timeStamp = WTF::currentTimeMS(); |
| 2028 #if ENABLE(GC_PROFILING) | |
| 2029 gcScope.visitor()->objectGraph().clear(); | |
| 2030 #endif | |
| 2031 | 2012 |
| 2032 // Disallow allocation during garbage collection (but not during the | 2013 // Disallow allocation during garbage collection (but not during the |
| 2033 // finalization that happens when the gcScope is torn down). | 2014 // finalization that happens when the gcScope is torn down). |
| 2034 ThreadState::NoAllocationScope noAllocationScope(state); | 2015 ThreadState::NoAllocationScope noAllocationScope(state); |
| 2035 | 2016 |
| 2036 preGC(); | 2017 preGC(); |
| 2037 | 2018 |
| 2038 StackFrameDepthScope stackDepthScope; | 2019 StackFrameDepthScope stackDepthScope; |
| 2039 | 2020 |
| 2040 size_t totalObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSiz
e(); | 2021 size_t totalObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSiz
e(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2053 postMarkingProcessing(gcScope.visitor()); | 2034 postMarkingProcessing(gcScope.visitor()); |
| 2054 globalWeakProcessing(gcScope.visitor()); | 2035 globalWeakProcessing(gcScope.visitor()); |
| 2055 | 2036 |
| 2056 // Now we can delete all orphaned pages because there are no dangling | 2037 // Now we can delete all orphaned pages because there are no dangling |
| 2057 // pointers to the orphaned pages. (If we have such dangling pointers, | 2038 // pointers to the orphaned pages. (If we have such dangling pointers, |
| 2058 // we should have crashed during marking before getting here.) | 2039 // we should have crashed during marking before getting here.) |
| 2059 orphanedPagePool()->decommitOrphanedPages(); | 2040 orphanedPagePool()->decommitOrphanedPages(); |
| 2060 | 2041 |
| 2061 postGC(gcType); | 2042 postGC(gcType); |
| 2062 | 2043 |
| 2063 #if ENABLE(GC_PROFILING) | |
| 2064 gcScope.visitor()->reportStats(); | |
| 2065 #endif | |
| 2066 | |
| 2067 double markingTimeInMilliseconds = WTF::currentTimeMS() - timeStamp; | 2044 double markingTimeInMilliseconds = WTF::currentTimeMS() - timeStamp; |
| 2068 s_estimatedMarkingTimePerByte = totalObjectSize ? (markingTimeInMilliseconds
/ 1000 / totalObjectSize) : 0; | 2045 s_estimatedMarkingTimePerByte = totalObjectSize ? (markingTimeInMilliseconds
/ 1000 / totalObjectSize) : 0; |
| 2069 | 2046 |
| 2070 Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", marking
TimeInMilliseconds, 0, 10 * 1000, 50); | 2047 Platform::current()->histogramCustomCounts("BlinkGC.CollectGarbage", marking
TimeInMilliseconds, 0, 10 * 1000, 50); |
| 2071 Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", Heap:
:allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50); | 2048 Platform::current()->histogramCustomCounts("BlinkGC.TotalObjectSpace", Heap:
:allocatedObjectSize() / 1024, 0, 4 * 1024 * 1024, 50); |
| 2072 Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace", He
ap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50); | 2049 Platform::current()->histogramCustomCounts("BlinkGC.TotalAllocatedSpace", He
ap::allocatedSpace() / 1024, 0, 4 * 1024 * 1024, 50); |
| 2073 Platform::current()->histogramEnumeration("BlinkGC.GCReason", reason, Number
OfGCReason); | 2050 Platform::current()->histogramEnumeration("BlinkGC.GCReason", reason, Number
OfGCReason); |
| 2074 Heap::reportMemoryUsageHistogram(); | 2051 Heap::reportMemoryUsageHistogram(); |
| 2075 WTF::Partitions::reportMemoryUsageHistogram(); | 2052 WTF::Partitions::reportMemoryUsageHistogram(); |
| 2076 | 2053 |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2345 size_t Heap::s_allocatedObjectSize = 0; | 2322 size_t Heap::s_allocatedObjectSize = 0; |
| 2346 size_t Heap::s_allocatedSpace = 0; | 2323 size_t Heap::s_allocatedSpace = 0; |
| 2347 size_t Heap::s_markedObjectSize = 0; | 2324 size_t Heap::s_markedObjectSize = 0; |
| 2348 // We don't want to use 0 KB for the initial value because it may end up | 2325 // We don't want to use 0 KB for the initial value because it may end up |
| 2349 // triggering the first GC of some thread too prematurely. | 2326 // triggering the first GC of some thread too prematurely. |
| 2350 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2327 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
| 2351 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2328 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
| 2352 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2329 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
| 2353 | 2330 |
| 2354 } // namespace blink | 2331 } // namespace blink |
| OLD | NEW |