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