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 |