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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 page->countObjectsToSweep(classAgeCounts); | 264 page->countObjectsToSweep(classAgeCounts); |
265 } | 265 } |
266 | 266 |
267 void BaseHeap::incrementMarkedObjectsAge() | 267 void BaseHeap::incrementMarkedObjectsAge() |
268 { | 268 { |
269 for (BasePage* page = m_firstPage; page; page = page->next()) | 269 for (BasePage* page = m_firstPage; page; page = page->next()) |
270 page->incrementMarkedObjectsAge(); | 270 page->incrementMarkedObjectsAge(); |
271 } | 271 } |
272 #endif | 272 #endif |
273 | 273 |
274 void BaseHeap::makeConsistentForSweeping(ThreadState::GCType gcType) | 274 void BaseHeap::makeConsistentForSweeping() |
275 { | 275 { |
276 // We don't want to clear free lists when taking a snapshot. | 276 clearFreeLists(); |
277 // This is fine because we don't sweep anything when taking a snapshot. | 277 ASSERT(isConsistentForSweeping()); |
278 if (gcType != ThreadState::TakeSnapshot) { | |
279 clearFreeLists(); | |
280 ASSERT(isConsistentForSweeping()); | |
281 } | |
282 | |
283 for (BasePage* page = m_firstPage; page; page = page->next()) | 278 for (BasePage* page = m_firstPage; page; page = page->next()) |
284 page->markAsUnswept(); | 279 page->markAsUnswept(); |
285 | 280 |
286 // If a new GC is requested before this thread got around to sweep, | 281 // If a new GC is requested before this thread got around to sweep, |
287 // ie. due to the thread doing a long running operation, we clear | 282 // ie. due to the thread doing a long running operation, we clear |
288 // the mark bits and mark any of the dead objects as dead. The latter | 283 // the mark bits and mark any of the dead objects as dead. The latter |
289 // is used to ensure the next GC marking does not trace already dead | 284 // is used to ensure the next GC marking does not trace already dead |
290 // objects. If we trace a dead object we could end up tracing into | 285 // objects. If we trace a dead object we could end up tracing into |
291 // garbage or the middle of another object via the newly conservatively | 286 // garbage or the middle of another object via the newly conservatively |
292 // found object. | 287 // found object. |
(...skipping 25 matching lines...) Expand all Loading... |
318 void BaseHeap::prepareHeapForTermination() | 313 void BaseHeap::prepareHeapForTermination() |
319 { | 314 { |
320 ASSERT(!m_firstUnsweptPage); | 315 ASSERT(!m_firstUnsweptPage); |
321 for (BasePage* page = m_firstPage; page; page = page->next()) { | 316 for (BasePage* page = m_firstPage; page; page = page->next()) { |
322 page->setTerminating(); | 317 page->setTerminating(); |
323 } | 318 } |
324 } | 319 } |
325 | 320 |
326 void BaseHeap::prepareForSweep() | 321 void BaseHeap::prepareForSweep() |
327 { | 322 { |
328 ASSERT(threadState()->isInGC()); | 323 ASSERT(!threadState()->isInGC()); |
329 ASSERT(!m_firstUnsweptPage); | 324 ASSERT(!m_firstUnsweptPage); |
330 | 325 |
331 // Move all pages to a list of unswept pages. | 326 // Move all pages to a list of unswept pages. |
332 m_firstUnsweptPage = m_firstPage; | 327 m_firstUnsweptPage = m_firstPage; |
333 m_firstPage = nullptr; | 328 m_firstPage = nullptr; |
334 } | 329 } |
335 | 330 |
336 #if defined(ADDRESS_SANITIZER) | 331 #if defined(ADDRESS_SANITIZER) |
337 void BaseHeap::poisonUnmarkedObjects() | 332 void BaseHeap::poisonUnmarkedObjects() |
338 { | 333 { |
(...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1839 } | 1834 } |
1840 | 1835 |
1841 #if ENABLE(ASSERT) | 1836 #if ENABLE(ASSERT) |
1842 bool Heap::weakTableRegistered(const void* table) | 1837 bool Heap::weakTableRegistered(const void* table) |
1843 { | 1838 { |
1844 ASSERT(s_ephemeronStack); | 1839 ASSERT(s_ephemeronStack); |
1845 return s_ephemeronStack->hasCallbackForObject(table); | 1840 return s_ephemeronStack->hasCallbackForObject(table); |
1846 } | 1841 } |
1847 #endif | 1842 #endif |
1848 | 1843 |
1849 void Heap::preGC(ThreadState::GCType gcType) | 1844 void Heap::preGC() |
1850 { | 1845 { |
1851 ASSERT(!ThreadState::current()->isInGC()); | 1846 ASSERT(!ThreadState::current()->isInGC()); |
1852 for (ThreadState* state : ThreadState::attachedThreads()) | 1847 for (ThreadState* state : ThreadState::attachedThreads()) |
1853 state->preGC(gcType); | 1848 state->preGC(); |
1854 } | 1849 } |
1855 | 1850 |
1856 void Heap::postGC(ThreadState::GCType gcType) | 1851 void Heap::postGC(ThreadState::GCType gcType) |
1857 { | 1852 { |
1858 ASSERT(ThreadState::current()->isInGC()); | 1853 ASSERT(ThreadState::current()->isInGC()); |
1859 for (ThreadState* state : ThreadState::attachedThreads()) | 1854 for (ThreadState* state : ThreadState::attachedThreads()) |
1860 state->postGC(gcType); | 1855 state->postGC(gcType); |
1861 } | 1856 } |
1862 | 1857 |
1863 const char* Heap::gcReasonString(GCReason reason) | 1858 const char* Heap::gcReasonString(GCReason reason) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1902 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); | 1897 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); |
1903 double timeStamp = WTF::currentTimeMS(); | 1898 double timeStamp = WTF::currentTimeMS(); |
1904 #if ENABLE(GC_PROFILING) | 1899 #if ENABLE(GC_PROFILING) |
1905 static_cast<MarkingVisitor<Visitor::GlobalMarking>*>(s_markingVisitor)->obje
ctGraph().clear(); | 1900 static_cast<MarkingVisitor<Visitor::GlobalMarking>*>(s_markingVisitor)->obje
ctGraph().clear(); |
1906 #endif | 1901 #endif |
1907 | 1902 |
1908 // Disallow allocation during garbage collection (but not during the | 1903 // Disallow allocation during garbage collection (but not during the |
1909 // finalization that happens when the gcScope is torn down). | 1904 // finalization that happens when the gcScope is torn down). |
1910 ThreadState::NoAllocationScope noAllocationScope(state); | 1905 ThreadState::NoAllocationScope noAllocationScope(state); |
1911 | 1906 |
1912 preGC(gcType); | 1907 preGC(); |
1913 | 1908 |
1914 StackFrameDepthScope stackDepthScope; | 1909 StackFrameDepthScope stackDepthScope; |
1915 | 1910 |
1916 size_t totalObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSiz
e(); | 1911 size_t totalObjectSize = Heap::allocatedObjectSize() + Heap::markedObjectSiz
e(); |
1917 Heap::resetHeapCounters(); | 1912 Heap::resetHeapCounters(); |
1918 | 1913 |
1919 // 1. Trace persistent roots. | 1914 // 1. Trace persistent roots. |
1920 ThreadState::visitPersistentRoots(s_markingVisitor); | 1915 ThreadState::visitPersistentRoots(s_markingVisitor); |
1921 | 1916 |
1922 // 2. Trace objects reachable from the persistent roots including | 1917 // 2. Trace objects reachable from the persistent roots including |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1963 | 1958 |
1964 void Heap::collectGarbageForTerminatingThread(ThreadState* state) | 1959 void Heap::collectGarbageForTerminatingThread(ThreadState* state) |
1965 { | 1960 { |
1966 // We explicitly do not enter a safepoint while doing thread specific | 1961 // We explicitly do not enter a safepoint while doing thread specific |
1967 // garbage collection since we don't want to allow a global GC at the | 1962 // garbage collection since we don't want to allow a global GC at the |
1968 // same time as a thread local GC. | 1963 // same time as a thread local GC. |
1969 { | 1964 { |
1970 MarkingVisitor<Visitor::ThreadLocalMarking> markingVisitor; | 1965 MarkingVisitor<Visitor::ThreadLocalMarking> markingVisitor; |
1971 ThreadState::NoAllocationScope noAllocationScope(state); | 1966 ThreadState::NoAllocationScope noAllocationScope(state); |
1972 | 1967 |
1973 state->preGC(ThreadState::GCWithSweep); | 1968 state->preGC(); |
1974 StackFrameDepthScope stackDepthScope; | 1969 StackFrameDepthScope stackDepthScope; |
1975 | 1970 |
1976 // 1. Trace the thread local persistent roots. For thread local GCs we | 1971 // 1. Trace the thread local persistent roots. For thread local GCs we |
1977 // don't trace the stack (ie. no conservative scanning) since this is | 1972 // don't trace the stack (ie. no conservative scanning) since this is |
1978 // only called during thread shutdown where there should be no objects | 1973 // only called during thread shutdown where there should be no objects |
1979 // on the stack. | 1974 // on the stack. |
1980 // We also assume that orphaned pages have no objects reachable from | 1975 // We also assume that orphaned pages have no objects reachable from |
1981 // persistent handles on other threads or CrossThreadPersistents. The | 1976 // persistent handles on other threads or CrossThreadPersistents. The |
1982 // only cases where this could happen is if a subsequent conservative | 1977 // only cases where this could happen is if a subsequent conservative |
1983 // global GC finds a "pointer" on the stack or due to a programming | 1978 // global GC finds a "pointer" on the stack or due to a programming |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2098 Platform::current()->histogramEnumeration("BlinkGC.CommittedSize", sizeI
nMB, supportedMaxSizeInMB); | 2093 Platform::current()->histogramEnumeration("BlinkGC.CommittedSize", sizeI
nMB, supportedMaxSizeInMB); |
2099 observedMaxSizeInMB = sizeInMB; | 2094 observedMaxSizeInMB = sizeInMB; |
2100 } | 2095 } |
2101 } | 2096 } |
2102 | 2097 |
2103 size_t Heap::objectPayloadSizeForTesting() | 2098 size_t Heap::objectPayloadSizeForTesting() |
2104 { | 2099 { |
2105 size_t objectPayloadSize = 0; | 2100 size_t objectPayloadSize = 0; |
2106 for (ThreadState* state : ThreadState::attachedThreads()) { | 2101 for (ThreadState* state : ThreadState::attachedThreads()) { |
2107 state->setGCState(ThreadState::GCRunning); | 2102 state->setGCState(ThreadState::GCRunning); |
2108 state->makeConsistentForSweeping(ThreadState::GCWithSweep); | 2103 state->makeConsistentForSweeping(); |
2109 objectPayloadSize += state->objectPayloadSizeForTesting(); | 2104 objectPayloadSize += state->objectPayloadSizeForTesting(); |
2110 state->setGCState(ThreadState::EagerSweepScheduled); | 2105 state->setGCState(ThreadState::EagerSweepScheduled); |
2111 state->setGCState(ThreadState::Sweeping); | 2106 state->setGCState(ThreadState::Sweeping); |
2112 state->setGCState(ThreadState::NoGCScheduled); | 2107 state->setGCState(ThreadState::NoGCScheduled); |
2113 } | 2108 } |
2114 return objectPayloadSize; | 2109 return objectPayloadSize; |
2115 } | 2110 } |
2116 | 2111 |
2117 BasePage* Heap::lookup(Address address) | 2112 BasePage* Heap::lookup(Address address) |
2118 { | 2113 { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2228 size_t Heap::s_allocatedObjectSize = 0; | 2223 size_t Heap::s_allocatedObjectSize = 0; |
2229 size_t Heap::s_allocatedSpace = 0; | 2224 size_t Heap::s_allocatedSpace = 0; |
2230 size_t Heap::s_markedObjectSize = 0; | 2225 size_t Heap::s_markedObjectSize = 0; |
2231 // We don't want to use 0 KB for the initial value because it may end up | 2226 // We don't want to use 0 KB for the initial value because it may end up |
2232 // triggering the first GC of some thread too prematurely. | 2227 // triggering the first GC of some thread too prematurely. |
2233 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2228 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
2234 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2229 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
2235 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2230 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
2236 | 2231 |
2237 } // namespace blink | 2232 } // namespace blink |
OLD | NEW |