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 GCForbiddenScope { | |
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 { | 130 class GCScope { |
113 public: | 131 public: |
114 explicit GCScope(ThreadState::StackState stackState) | 132 GCScope(ThreadState* state, ThreadState::StackState stackState) |
115 : m_state(ThreadState::current()) | 133 : m_state(state) |
116 , m_safePointScope(stackState) | 134 , m_gcForbiddenScope(state) |
135 , m_safePointScope(stackState, state) | |
117 , m_parkedAllThreads(false) | 136 , m_parkedAllThreads(false) |
118 { | 137 { |
119 TRACE_EVENT0("blink_gc", "Heap::GCScope"); | 138 TRACE_EVENT0("blink_gc", "Heap::GCScope"); |
120 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); | 139 const char* samplingState = TRACE_EVENT_GET_SAMPLING_STATE(); |
121 if (m_state->isMainThread()) | 140 if (m_state->isMainThread()) |
122 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); | 141 TRACE_EVENT_SET_SAMPLING_STATE("blink_gc", "BlinkGCWaiting"); |
123 | 142 |
124 m_state->checkThread(); | 143 m_state->checkThread(); |
125 | 144 |
126 // FIXME: in an unlikely coincidence that two threads decide | 145 // FIXME: in an unlikely coincidence that two threads decide |
127 // to collect garbage at the same time, avoid doing two GCs in | 146 // to collect garbage at the same time, avoid doing two GCs in |
128 // a row. | 147 // a row. |
129 if (LIKELY(ThreadState::stopThreads())) { | 148 if (LIKELY(ThreadState::stopThreads())) |
130 m_parkedAllThreads = true; | 149 m_parkedAllThreads = true; |
131 } | 150 |
132 if (m_state->isMainThread()) | 151 if (m_state->isMainThread()) |
133 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); | 152 TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(samplingState); |
134 } | 153 } |
135 | 154 |
136 bool allThreadsParked() { return m_parkedAllThreads; } | 155 bool allThreadsParked() { return m_parkedAllThreads; } |
137 | 156 |
138 ~GCScope() | 157 ~GCScope() |
139 { | 158 { |
140 // Only cleanup if we parked all threads in which case the GC happened | 159 // Only cleanup if we parked all threads in which case the GC happened |
141 // and we need to resume the other threads. | 160 // and we need to resume the other threads. |
142 if (LIKELY(m_parkedAllThreads)) { | 161 if (LIKELY(m_parkedAllThreads)) |
143 ThreadState::resumeThreads(); | 162 ThreadState::resumeThreads(); |
144 } | |
145 } | 163 } |
146 | 164 |
147 private: | 165 private: |
148 ThreadState* m_state; | 166 ThreadState* m_state; |
167 GCForbiddenScope m_gcForbiddenScope; | |
149 SafePointScope m_safePointScope; | 168 SafePointScope m_safePointScope; |
haraken
2015/05/28 15:00:56
Add a comment and mention that the order between G
sof
2015/05/28 15:08:50
Will add a comment re: ordering.
sof
2015/05/29 18:52:18
Done.
| |
150 bool m_parkedAllThreads; // False if we fail to park all threads | 169 bool m_parkedAllThreads; // False if we fail to park all threads |
151 }; | 170 }; |
152 | 171 |
153 #if ENABLE(ASSERT) | 172 #if ENABLE(ASSERT) |
154 NO_SANITIZE_ADDRESS | 173 NO_SANITIZE_ADDRESS |
155 void HeapObjectHeader::zapMagic() | 174 void HeapObjectHeader::zapMagic() |
156 { | 175 { |
157 checkHeader(); | 176 checkHeader(); |
158 m_magic = zappedMagic; | 177 m_magic = zappedMagic; |
159 } | 178 } |
(...skipping 1705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1865 STRINGIFY_REASON(ForcedGC); | 1884 STRINGIFY_REASON(ForcedGC); |
1866 #undef STRINGIFY_REASON | 1885 #undef STRINGIFY_REASON |
1867 case NumberOfGCReason: ASSERT_NOT_REACHED(); | 1886 case NumberOfGCReason: ASSERT_NOT_REACHED(); |
1868 } | 1887 } |
1869 return "<Unknown>"; | 1888 return "<Unknown>"; |
1870 } | 1889 } |
1871 | 1890 |
1872 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::GCTyp e gcType, GCReason reason) | 1891 void Heap::collectGarbage(ThreadState::StackState stackState, ThreadState::GCTyp e gcType, GCReason reason) |
1873 { | 1892 { |
1874 ThreadState* state = ThreadState::current(); | 1893 ThreadState* state = ThreadState::current(); |
1875 RELEASE_ASSERT(!state->isInGC()); | 1894 RELEASE_ASSERT(!state->isGCForbidden()); |
haraken
2015/05/28 15:00:55
I'd move this check to GCForbiddenScope's construc
sof
2015/05/28 15:27:57
I don't understand the motivation behind the sugge
haraken
2015/05/28 15:28:46
ah, that makes sense!
sof
2015/05/29 18:52:18
Added a comment next to it.
| |
1876 state->completeSweep(); | 1895 state->completeSweep(); |
1877 ThreadState::GCState originalGCState = state->gcState(); | |
1878 state->setGCState(ThreadState::StoppingOtherThreads); | |
1879 | 1896 |
1880 GCScope gcScope(stackState); | 1897 GCScope gcScope(state, stackState); |
1881 // Check if we successfully parked the other threads. If not we bail out of | 1898 // Check if we successfully parked the other threads. If not we bail out of |
1882 // the GC. | 1899 // the GC. |
1883 if (!gcScope.allThreadsParked()) { | 1900 if (!gcScope.allThreadsParked()) |
1884 // Restore the original GCState. | |
1885 if (LIKELY(state->gcState() == ThreadState::StoppingOtherThreads)) | |
1886 state->setGCState(originalGCState); | |
1887 return; | 1901 return; |
1888 } | |
1889 | 1902 |
1890 if (state->isMainThread()) | 1903 if (state->isMainThread()) |
1891 ScriptForbiddenScope::enter(); | 1904 ScriptForbiddenScope::enter(); |
1892 | 1905 |
1893 s_lastGCWasConservative = false; | 1906 s_lastGCWasConservative = false; |
1894 | 1907 |
1895 TRACE_EVENT2("blink_gc", "Heap::collectGarbage", | 1908 TRACE_EVENT2("blink_gc", "Heap::collectGarbage", |
1896 "lazySweeping", gcType == ThreadState::GCWithoutSweep, | 1909 "lazySweeping", gcType == ThreadState::GCWithoutSweep, |
1897 "gcReason", gcReasonString(reason)); | 1910 "gcReason", gcReasonString(reason)); |
1898 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); | 1911 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink_gc", "BlinkGC"); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2224 size_t Heap::s_allocatedObjectSize = 0; | 2237 size_t Heap::s_allocatedObjectSize = 0; |
2225 size_t Heap::s_allocatedSpace = 0; | 2238 size_t Heap::s_allocatedSpace = 0; |
2226 size_t Heap::s_markedObjectSize = 0; | 2239 size_t Heap::s_markedObjectSize = 0; |
2227 // We don't want to use 0 KB for the initial value because it may end up | 2240 // We don't want to use 0 KB for the initial value because it may end up |
2228 // triggering the first GC of some thread too prematurely. | 2241 // triggering the first GC of some thread too prematurely. |
2229 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; | 2242 size_t Heap::s_estimatedLiveObjectSize = 512 * 1024; |
2230 size_t Heap::s_externalObjectSizeAtLastGC = 0; | 2243 size_t Heap::s_externalObjectSizeAtLastGC = 0; |
2231 double Heap::s_estimatedMarkingTimePerByte = 0.0; | 2244 double Heap::s_estimatedMarkingTimePerByte = 0.0; |
2232 | 2245 |
2233 } // namespace blink | 2246 } // namespace blink |
OLD | NEW |