| 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 |