Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(653)

Side by Side Diff: Source/platform/heap/Heap.cpp

Issue 1145423009: Oilpan: simplify away StoppingOtherThreads pseudo GCState. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: revert 'explicit' removal Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Source/platform/heap/SafePoint.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 GCForbiddenScope final {
113 public:
114 explicit GCForbiddenScope(ThreadState* state)
115 : m_state(state)
116 {
117 // Prevent nested collectGarbage() invocations.
118 m_state->enterGCForbiddenScope();
119 }
120
121 ~GCForbiddenScope()
122 {
123 m_state->leaveGCForbiddenScope();
124 }
125
126 private:
127 ThreadState* m_state;
128 };
129
112 class GCScope final { 130 class GCScope final {
113 public: 131 public:
114 GCScope(ThreadState::StackState stackState, ThreadState::GCType gcType) 132 GCScope(ThreadState* state, ThreadState::StackState stackState, ThreadState: :GCType gcType)
115 : m_state(ThreadState::current()) 133 : m_state(state)
134 , m_gcForbiddenScope(state)
135 // See collectGarbageForTerminatingThread() comment on why a
136 // safepoint scope isn't entered for its GCScope.
137 , m_safePointScope(stackState, gcType != ThreadState::ThreadTerminationG C ? state : nullptr)
116 , m_gcType(gcType) 138 , m_gcType(gcType)
117 , m_parkedAllThreads(false) 139 , m_parkedAllThreads(false)
118 { 140 {
119 TRACE_EVENT0("blink_gc", "Heap::GCScope"); 141 TRACE_EVENT0("blink_gc", "Heap::GCScope");
120 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); 142 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE();
121 if (m_state->isMainThread()) 143 if (m_state->isMainThread())
122 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); 144 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting");
123 145
124 m_state->checkThread(); 146 m_state->checkThread();
125 147
126 // We explicitly do not enter a safepoint while doing thread specific 148 // TODO(haraken): In an unlikely coincidence that two threads decide
127 // garbage collection since we don't want to allow a global GC at the 149 // to collect garbage at the same time, avoid doing two GCs in
128 // same time as a thread local GC. 150 // a row.
129 if (gcType != ThreadState::ThreadTerminationGC) { 151 if (LIKELY(gcType != ThreadState::ThreadTerminationGC && ThreadState::st opThreads()))
130 RELEASE_ASSERT(!ThreadState::current()->isAtSafePoint()); 152 m_parkedAllThreads = true;
131 m_state->enterSafePoint(stackState, this);
132
133 // TODO(haraken): In an unlikely coincidence that two threads decide
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 }
139 }
140 153
141 if (m_state->isMainThread()) 154 if (m_state->isMainThread())
142 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); 155 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState);
143 } 156 }
144 157
145 bool allThreadsParked() { return m_parkedAllThreads; } 158 bool allThreadsParked() { return m_parkedAllThreads; }
146 159
147 ~GCScope() 160 ~GCScope()
148 { 161 {
149 if (m_gcType != ThreadState::ThreadTerminationGC) { 162 // Only cleanup if we parked all threads in which case the GC happened
150 // Only cleanup if we parked all threads in which case the GC happen ed 163 // and we need to resume the other threads.
151 // and we need to resume the other threads. 164 if (LIKELY(m_gcType != ThreadState::ThreadTerminationGC && m_parkedAllTh reads))
152 if (LIKELY(m_parkedAllThreads)) { 165 ThreadState::resumeThreads();
153 ThreadState::resumeThreads();
154 }
155
156 m_state->leaveSafePoint();
157 }
158 } 166 }
159 167
160 private: 168 private:
161 ThreadState* m_state; 169 ThreadState* m_state;
170 // The ordering of the two scope objects matters: GCs must first be forbidde n
171 // before entering the safe point scope. Prior to reaching the safe point,
172 // ThreadState::runScheduledGC() is called. See its comment why we need
173 // to be in a GC forbidden scope when doing so.
174 GCForbiddenScope m_gcForbiddenScope;
175 SafePointScope m_safePointScope;
162 ThreadState::GCType m_gcType; 176 ThreadState::GCType m_gcType;
163 bool m_parkedAllThreads; // False if we fail to park all threads 177 bool m_parkedAllThreads; // False if we fail to park all threads
164 }; 178 };
165 179
166 #if ENABLE(ASSERT) 180 #if ENABLE(ASSERT)
167 NO_SANITIZE_ADDRESS 181 NO_SANITIZE_ADDRESS
168 void HeapObjectHeader::zapMagic() 182 void HeapObjectHeader::zapMagic()
169 { 183 {
170 checkHeader(); 184 checkHeader();
171 m_magic = zappedMagic; 185 m_magic = zappedMagic;
(...skipping 1716 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 STRINGIFY_REASON(ForcedGC); 1902 STRINGIFY_REASON(ForcedGC);
1889 #undef STRINGIFY_REASON 1903 #undef STRINGIFY_REASON
1890 case NumberOfGCReason: ASSERT_NOT_REACHED(); 1904 case NumberOfGCReason: ASSERT_NOT_REACHED();
1891 } 1905 }
1892 return "<Unknown>"; 1906 return "<Unknown>";
1893 } 1907 }
1894 1908
1895 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::GCTyp e gcType, GCReason reason) 1909 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::GCTyp e gcType, GCReason reason)
1896 { 1910 {
1897 ThreadState* state = ThreadState::current(); 1911 ThreadState* state = ThreadState::current();
1898 RELEASE_ASSERT(!state->isInGC()); 1912 // Nested collectGarbage() invocations aren't supported.
1913 RELEASE_ASSERT(!state->isGCForbidden());
1899 state->completeSweep(); 1914 state->completeSweep();
1900 ThreadState::GCState originalGCState = state->gcState();
1901 state->setGCState(ThreadState::StoppingOtherThreads);
1902 1915
1903 GCScope gcScope(stackState, gcType); 1916 GCScope gcScope(state, stackState, gcType);
1904 // Check if we successfully parked the other threads. If not we bail out of 1917 // Check if we successfully parked the other threads. If not we bail out of
1905 // the GC. 1918 // the GC.
1906 if (!gcScope.allThreadsParked()) { 1919 if (!gcScope.allThreadsParked())
1907 // Restore the original GCState.
1908 if (LIKELY(state->gcState() == ThreadState::StoppingOtherThreads))
1909 state->setGCState(originalGCState);
1910 return; 1920 return;
1911 }
1912 1921
1913 if (state->isMainThread()) 1922 if (state->isMainThread())
1914 ScriptForbiddenScope::enter(); 1923 ScriptForbiddenScope::enter();
1915 1924
1916 s_lastGCWasConservative = false; 1925 s_lastGCWasConservative = false;
1917 1926
1918 TRACE_EVENT2("blink_gc", "Heap::collectGarbage", 1927 TRACE_EVENT2("blink_gc", "Heap::collectGarbage",
1919 "lazySweeping", gcType == ThreadState::GCWithoutSweep, 1928 "lazySweeping", gcType == ThreadState::GCWithoutSweep,
1920 "gcReason", gcReasonString(reason)); 1929 "gcReason", gcReasonString(reason));
1921 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); 1930 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC");
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1976 Heap::reportMemoryUsageHistogram(); 1985 Heap::reportMemoryUsageHistogram();
1977 WTF::Partitions::reportMemoryUsageHistogram(); 1986 WTF::Partitions::reportMemoryUsageHistogram();
1978 1987
1979 if (state->isMainThread()) 1988 if (state->isMainThread())
1980 ScriptForbiddenScope::exit(); 1989 ScriptForbiddenScope::exit();
1981 } 1990 }
1982 1991
1983 void Heap::collectGarbageForTerminatingThread(ThreadState* state) 1992 void Heap::collectGarbageForTerminatingThread(ThreadState* state)
1984 { 1993 {
1985 { 1994 {
1986 GCScope gcScope(ThreadState::NoHeapPointersOnStack, ThreadState::ThreadT erminationGC); 1995 // A thread-specific termination GC must not allow other global GCs to g o
1996 // ahead while it is running, hence the termination GC does not enter a
1997 // safepoint. GCScope will not enter also a safepoint scope for
1998 // ThreadTerminationGC.
1999 GCScope gcScope(state, ThreadState::NoHeapPointersOnStack, ThreadState:: ThreadTerminationGC);
1987 2000
1988 MarkingVisitor<Visitor::ThreadLocalMarking> markingVisitor; 2001 MarkingVisitor<Visitor::ThreadLocalMarking> markingVisitor;
1989 ThreadState::NoAllocationScope noAllocationScope(state); 2002 ThreadState::NoAllocationScope noAllocationScope(state);
1990 2003
1991 state->preGC(); 2004 state->preGC();
1992 StackFrameDepthScope stackDepthScope; 2005 StackFrameDepthScope stackDepthScope;
1993 2006
1994 // 1. Trace the thread local persistent roots. For thread local GCs we 2007 // 1. Trace the thread local persistent roots. For thread local GCs we
1995 // don't trace the stack (ie. no conservative scanning) since this is 2008 // don't trace the stack (ie. no conservative scanning) since this is
1996 // only called during thread shutdown where there should be no objects 2009 // only called during thread shutdown where there should be no objects
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
2246 size_t Heap::s_allocatedObjectSize = 0; 2259 size_t Heap::s_allocatedObjectSize = 0;
2247 size_t Heap::s_allocatedSpace = 0; 2260 size_t Heap::s_allocatedSpace = 0;
2248 size_t Heap::s_markedObjectSize = 0; 2261 size_t Heap::s_markedObjectSize = 0;
2249 // We don't want to use 0 KB for the initial value because it may end up 2262 // We don't want to use 0 KB for the initial value because it may end up
2250 // triggering the first GC of some thread too prematurely. 2263 // triggering the first GC of some thread too prematurely.
2251 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; 2264 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024;
2252 size_t Heap::s_externalObjectSizeAtLastGC = 0; 2265 size_t Heap::s_externalObjectSizeAtLastGC = 0;
2253 double Heap::s_estimatedMarkingTimePerByte = 0.0; 2266 double Heap::s_estimatedMarkingTimePerByte = 0.0;
2254 2267
2255 } // namespace blink 2268 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | Source/platform/heap/SafePoint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698