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