 Chromium Code Reviews
 Chromium Code Reviews Issue 1160143002:
  Oilpan: Always enter a GCScope when we run a GC  (Closed) 
  Base URL: svn://svn.chromium.org/blink/trunk
    
  
    Issue 1160143002:
  Oilpan: Always enter a GCScope when we run a GC  (Closed) 
  Base URL: svn://svn.chromium.org/blink/trunk| 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 102 | 102 | 
| 103 #if ENABLE(GC_PROFILING) | 103 #if ENABLE(GC_PROFILING) | 
| 104 static String classOf(const void* object) | 104 static String classOf(const void* object) | 
| 105 { | 105 { | 
| 106 if (const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_ cast<void*>(object)))) | 106 if (const GCInfo* gcInfo = Heap::findGCInfo(reinterpret_cast<Address>(const_ cast<void*>(object)))) | 
| 107 return gcInfo->m_className; | 107 return gcInfo->m_className; | 
| 108 return "unknown"; | 108 return "unknown"; | 
| 109 } | 109 } | 
| 110 #endif | 110 #endif | 
| 111 | 111 | 
| 112 class GCScope { | 112 class GCScope final { | 
| 113 public: | 113 public: | 
| 114 explicit GCScope(ThreadState::StackState stackState) | 114 GCScope(ThreadState::StackState stackState, ThreadState::GCType gcType) | 
| 115 : m_state(ThreadState::current()) | 115 : m_state(ThreadState::current()) | 
| 116 , m_safePointScope(stackState) | 116 , m_gcType(gcType) | 
| 117 , m_parkedAllThreads(false) | 117 , m_parkedAllThreads(false) | 
| 118 { | 118 { | 
| 119 TRACE_EVENT0("blink_gc", "Heap::GCScope"); | 119 TRACE_EVENT0("blink_gc", "Heap::GCScope"); | 
| 120 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); | 120 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); | 
| 121 if (m_state->isMainThread()) | 121 if (m_state->isMainThread()) | 
| 122 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); | 122 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); | 
| 123 | 123 | 
| 124 m_state->checkThread(); | 124 m_state->checkThread(); | 
| 125 | 125 | 
| 126 // FIXME: in an unlikely coincidence that two threads decide | 126 // We explicitly do not enter a safepoint while doing thread specific | 
| 127 // to collect garbage at the same time, avoid doing two GCs in | 127 // garbage collection since we don't want to allow a global GC at the | 
| 128 // a row. | 128 // same time as a thread local GC. | 
| 129 if (LIKELY(ThreadState::stopThreads())) { | 129 if (gcType != ThreadState::ThreadTerminationGC) { | 
| 130 m_parkedAllThreads = true; | 130 RELEASE_ASSERT(!ThreadState::current()->isAtSafePoint()); | 
| 131 m_state->enterSafePoint(stackState, this); | |
| 132 | |
| 133 // FIXME: in an unlikely coincidence that two threads decide | |
| 
sof
2015/05/29 13:14:07
nit: s/FIXME/TODO/
 
haraken
2015/05/29 14:42:27
Done.
 | |
| 134 // to collect garbage at the same time, avoid doing two GCs in | |
| 135 // a row. | |
| 136 if (LIKELY(ThreadState::stopThreads())) { | |
| 137 m_parkedAllThreads = true; | |
| 138 } | |
| 131 } | 139 } | 
| 140 | |
| 132 if (m_state->isMainThread()) | 141 if (m_state->isMainThread()) | 
| 133 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); | 142 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); | 
| 134 } | 143 } | 
| 135 | 144 | 
| 136 bool allThreadsParked() { return m_parkedAllThreads; } | 145 bool allThreadsParked() { return m_parkedAllThreads; } | 
| 137 | 146 | 
| 138 ~GCScope() | 147 ~GCScope() | 
| 139 { | 148 { | 
| 140 // Only cleanup if we parked all threads in which case the GC happened | 149 if (m_gcType != ThreadState::ThreadTerminationGC) { | 
| 141 // and we need to resume the other threads. | 150 // Only cleanup if we parked all threads in which case the GC happen ed | 
| 142 if (LIKELY(m_parkedAllThreads)) { | 151 // and we need to resume the other threads. | 
| 143 ThreadState::resumeThreads(); | 152 if (LIKELY(m_parkedAllThreads)) { | 
| 153 ThreadState::resumeThreads(); | |
| 154 } | |
| 155 | |
| 156 m_state->leaveSafePoint(); | |
| 144 } | 157 } | 
| 145 } | 158 } | 
| 146 | 159 | 
| 147 private: | 160 private: | 
| 148 ThreadState* m_state; | 161 ThreadState* m_state; | 
| 149 SafePointScope m_safePointScope; | 162 ThreadState::GCType m_gcType; | 
| 150 bool m_parkedAllThreads; // False if we fail to park all threads | 163 bool m_parkedAllThreads; // False if we fail to park all threads | 
| 151 }; | 164 }; | 
| 152 | 165 | 
| 153 #if ENABLE(ASSERT) | 166 #if ENABLE(ASSERT) | 
| 154 NO_SANITIZE_ADDRESS | 167 NO_SANITIZE_ADDRESS | 
| 155 void HeapObjectHeader::zapMagic() | 168 void HeapObjectHeader::zapMagic() | 
| 156 { | 169 { | 
| 157 checkHeader(); | 170 checkHeader(); | 
| 158 m_magic = zappedMagic; | 171 m_magic = zappedMagic; | 
| 159 } | 172 } | 
| (...skipping 1720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1880 } | 1893 } | 
| 1881 | 1894 | 
| 1882 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::GCTyp e gcType, GCReason reason) | 1895 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::GCTyp e gcType, GCReason reason) | 
| 1883 { | 1896 { | 
| 1884 ThreadState* state = ThreadState::current(); | 1897 ThreadState* state = ThreadState::current(); | 
| 1885 RELEASE_ASSERT(!state->isInGC()); | 1898 RELEASE_ASSERT(!state->isInGC()); | 
| 1886 state->completeSweep(); | 1899 state->completeSweep(); | 
| 1887 ThreadState::GCState originalGCState = state->gcState(); | 1900 ThreadState::GCState originalGCState = state->gcState(); | 
| 1888 state->setGCState(ThreadState::StoppingOtherThreads); | 1901 state->setGCState(ThreadState::StoppingOtherThreads); | 
| 1889 | 1902 | 
| 1890 GCScope gcScope(stackState); | 1903 GCScope gcScope(stackState, gcType); | 
| 1891 // Check if we successfully parked the other threads. If not we bail out of | 1904 // Check if we successfully parked the other threads. If not we bail out of | 
| 1892 // the GC. | 1905 // the GC. | 
| 1893 if (!gcScope.allThreadsParked()) { | 1906 if (!gcScope.allThreadsParked()) { | 
| 1894 // Restore the original GCState. | 1907 // Restore the original GCState. | 
| 1895 if (LIKELY(state->gcState() == ThreadState::StoppingOtherThreads)) | 1908 if (LIKELY(state->gcState() == ThreadState::StoppingOtherThreads)) | 
| 1896 state->setGCState(originalGCState); | 1909 state->setGCState(originalGCState); | 
| 1897 return; | 1910 return; | 
| 1898 } | 1911 } | 
| 1899 | 1912 | 
| 1900 if (state->isMainThread()) | 1913 if (state->isMainThread()) | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1962 Platform::current()->histogramEnumeration("BlinkGC.GCReason", reason, Number OfGCReason); | 1975 Platform::current()->histogramEnumeration("BlinkGC.GCReason", reason, Number OfGCReason); | 
| 1963 Heap::reportMemoryUsageHistogram(); | 1976 Heap::reportMemoryUsageHistogram(); | 
| 1964 WTF::Partitions::reportMemoryUsageHistogram(); | 1977 WTF::Partitions::reportMemoryUsageHistogram(); | 
| 1965 | 1978 | 
| 1966 if (state->isMainThread()) | 1979 if (state->isMainThread()) | 
| 1967 ScriptForbiddenScope::exit(); | 1980 ScriptForbiddenScope::exit(); | 
| 1968 } | 1981 } | 
| 1969 | 1982 | 
| 1970 void Heap::collectGarbageForTerminatingThread(ThreadState* state) | 1983 void Heap::collectGarbageForTerminatingThread(ThreadState* state) | 
| 1971 { | 1984 { | 
| 1972 // We explicitly do not enter a safepoint while doing thread specific | |
| 1973 // garbage collection since we don't want to allow a global GC at the | |
| 1974 // same time as a thread local GC. | |
| 1975 { | 1985 { | 
| 1986 GCScope gcScope(ThreadState::NoHeapPointersOnStack, ThreadState::ThreadT erminationGC); | |
| 
sof
2015/05/29 13:14:07
Just to make sure I understand motivation -- this
 
haraken
2015/05/29 14:42:27
Sorry for not being clear.
I want to implement GC
 | |
| 1987 | |
| 1976 MarkingVisitor<Visitor::ThreadLocalMarking> markingVisitor; | 1988 MarkingVisitor<Visitor::ThreadLocalMarking> markingVisitor; | 
| 1977 ThreadState::NoAllocationScope noAllocationScope(state); | 1989 ThreadState::NoAllocationScope noAllocationScope(state); | 
| 1978 | 1990 | 
| 1979 state->preGC(); | 1991 state->preGC(); | 
| 1980 StackFrameDepthScope stackDepthScope; | 1992 StackFrameDepthScope stackDepthScope; | 
| 1981 | 1993 | 
| 1982 // 1. Trace the thread local persistent roots. For thread local GCs we | 1994 // 1. Trace the thread local persistent roots. For thread local GCs we | 
| 1983 // don't trace the stack (ie. no conservative scanning) since this is | 1995 // don't trace the stack (ie. no conservative scanning) since this is | 
| 1984 // only called during thread shutdown where there should be no objects | 1996 // only called during thread shutdown where there should be no objects | 
| 1985 // on the stack. | 1997 // on the stack. | 
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2234 size_t Heap::s_allocatedObjectSize = 0; | 2246 size_t Heap::s_allocatedObjectSize = 0; | 
| 2235 size_t Heap::s_allocatedSpace = 0; | 2247 size_t Heap::s_allocatedSpace = 0; | 
| 2236 size_t Heap::s_markedObjectSize = 0; | 2248 size_t Heap::s_markedObjectSize = 0; | 
| 2237 // We don't want to use 0 KB for the initial value because it may end up | 2249 // We don't want to use 0 KB for the initial value because it may end up | 
| 2238 // triggering the first GC of some thread too prematurely. | 2250 // triggering the first GC of some thread too prematurely. | 
| 2239 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2251 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 
| 2240 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2252 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 
| 2241 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2253 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 
| 2242 | 2254 | 
| 2243 } // namespace blink | 2255 } // namespace blink | 
| OLD | NEW |