OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2014 Google Inc. All rights reserved. | 2 * Copyright (C) 2014 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 visitor->registerWeakCell(&m_raw); | 131 visitor->registerWeakCell(&m_raw); |
132 } else { | 132 } else { |
133 visitor->mark(m_raw); | 133 visitor->mark(m_raw); |
134 } | 134 } |
135 } | 135 } |
136 | 136 |
137 RawPtr<T> release() | 137 RawPtr<T> release() |
138 { | 138 { |
139 RawPtr<T> result = m_raw; | 139 RawPtr<T> result = m_raw; |
140 m_raw = nullptr; | 140 m_raw = nullptr; |
141 updatePersistentNode(); | |
141 return result; | 142 return result; |
142 } | 143 } |
143 | 144 |
144 void clear() { m_raw = nullptr; } | 145 void clear() |
146 { | |
147 m_raw = nullptr; | |
148 updatePersistentNode(); | |
149 } | |
145 T& operator*() const { return *m_raw; } | 150 T& operator*() const { return *m_raw; } |
146 bool operator!() const { return !m_raw; } | 151 bool operator!() const { return !m_raw; } |
147 operator T*() const { return m_raw; } | 152 operator T*() const { return m_raw; } |
148 operator RawPtr<T>() const { return m_raw; } | 153 operator RawPtr<T>() const { return m_raw; } |
149 T* operator->() const { return *this; } | 154 T* operator->() const { return *this; } |
150 T* get() const { return m_raw; } | 155 T* get() const { return m_raw; } |
151 | 156 |
152 template<typename U> | 157 template<typename U> |
153 PersistentBase& operator=(U* other) | 158 PersistentBase& operator=(U* other) |
154 { | 159 { |
155 m_raw = other; | 160 m_raw = other; |
161 updatePersistentNode(); | |
156 checkPointer(); | 162 checkPointer(); |
157 recordBacktrace(); | 163 recordBacktrace(); |
158 return *this; | 164 return *this; |
159 } | 165 } |
160 | 166 |
161 PersistentBase& operator=(std::nullptr_t) | 167 PersistentBase& operator=(std::nullptr_t) |
162 { | 168 { |
163 m_raw = nullptr; | 169 m_raw = nullptr; |
170 updatePersistentNode(); | |
164 return *this; | 171 return *this; |
165 } | 172 } |
166 | 173 |
167 PersistentBase& operator=(const PersistentBase& other) | 174 PersistentBase& operator=(const PersistentBase& other) |
168 { | 175 { |
169 m_raw = other; | 176 m_raw = other; |
177 updatePersistentNode(); | |
170 checkPointer(); | 178 checkPointer(); |
171 recordBacktrace(); | 179 recordBacktrace(); |
172 return *this; | 180 return *this; |
173 } | 181 } |
174 | 182 |
175 template<typename U> | 183 template<typename U> |
176 PersistentBase& operator=(const PersistentBase<U, weaknessConfiguration, cro ssThreadnessConfiguration>& other) | 184 PersistentBase& operator=(const PersistentBase<U, weaknessConfiguration, cro ssThreadnessConfiguration>& other) |
177 { | 185 { |
178 m_raw = other; | 186 m_raw = other; |
187 updatePersistentNode(); | |
179 checkPointer(); | 188 checkPointer(); |
180 recordBacktrace(); | 189 recordBacktrace(); |
181 return *this; | 190 return *this; |
182 } | 191 } |
183 | 192 |
184 template<typename U> | 193 template<typename U> |
185 PersistentBase& operator=(const Member<U>& other) | 194 PersistentBase& operator=(const Member<U>& other) |
186 { | 195 { |
187 m_raw = other; | 196 m_raw = other; |
197 updatePersistentNode(); | |
188 checkPointer(); | 198 checkPointer(); |
189 recordBacktrace(); | 199 recordBacktrace(); |
190 return *this; | 200 return *this; |
191 } | 201 } |
192 | 202 |
193 template<typename U> | 203 template<typename U> |
194 PersistentBase& operator=(const RawPtr<U>& other) | 204 PersistentBase& operator=(const RawPtr<U>& other) |
195 { | 205 { |
196 m_raw = other; | 206 m_raw = other; |
207 updatePersistentNode(); | |
197 checkPointer(); | 208 checkPointer(); |
198 recordBacktrace(); | 209 recordBacktrace(); |
199 return *this; | 210 return *this; |
200 } | 211 } |
201 | 212 |
202 | 213 |
203 private: | 214 private: |
204 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 215 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
216 void updatePersistentNode() | |
haraken
2015/09/13 12:36:56
Maybe I'd prefer renaming this to assign() and do
sof
2015/09/14 06:34:04
Switched to that scheme; I think it is ok to leave
| |
217 { | |
218 if (m_raw) { | |
219 if (!m_persistentNode) | |
220 initialize(); | |
221 return; | |
222 } | |
223 if (m_persistentNode && crossThreadnessConfiguration != CrossThreadPersi stentConfiguration) | |
224 uninitialize(); | |
haraken
2015/09/13 12:36:56
Will this remove the restriction that a (non-cross
sof
2015/09/14 06:34:04
It removes that restriction, as detailed on https:
| |
225 } | |
226 | |
227 NO_LAZY_SWEEP_SANITIZE_ADDRESS | |
205 void initialize() | 228 void initialize() |
206 { | 229 { |
230 if (m_persistentNode || !m_raw) | |
haraken
2015/09/13 12:36:56
Is it possible that m_persistentNode is non-null h
sof
2015/09/14 06:34:04
It no longer is, thanks - replaced with an assert.
| |
231 return; | |
232 | |
207 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon figuration, crossThreadnessConfiguration>::trace>::trampoline; | 233 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon figuration, crossThreadnessConfiguration>::trace>::trampoline; |
208 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { | 234 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { |
209 m_persistentNode = ThreadState::crossThreadPersistentRegion().alloca tePersistentNode(this, traceCallback); | 235 m_persistentNode = ThreadState::crossThreadPersistentRegion().alloca tePersistentNode(this, traceCallback); |
210 } else { | 236 } else { |
211 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st ate(); | 237 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st ate(); |
212 ASSERT(state->checkThread()); | 238 ASSERT(state->checkThread()); |
213 m_persistentNode = state->persistentRegion()->allocatePersistentNode (this, traceCallback); | 239 m_persistentNode = state->persistentRegion()->allocatePersistentNode (this, traceCallback); |
214 #if ENABLE(ASSERT) | 240 #if ENABLE(ASSERT) |
215 m_state = state; | 241 m_state = state; |
216 #endif | 242 #endif |
217 } | 243 } |
218 } | 244 } |
219 | 245 |
220 void uninitialize() | 246 void uninitialize() |
221 { | 247 { |
248 if (!m_persistentNode) | |
249 return; | |
250 | |
222 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { | 251 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { |
223 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_pers istentNode); | 252 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_pers istentNode); |
224 } else { | 253 } else { |
225 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st ate(); | 254 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st ate(); |
226 ASSERT(state->checkThread()); | 255 ASSERT(state->checkThread()); |
227 // Persistent handle must be created and destructed in the same thre ad. | 256 // Persistent handle must be created and destructed in the same thre ad. |
228 ASSERT(m_state == state); | 257 ASSERT(m_state == state); |
229 state->persistentRegion()->freePersistentNode(m_persistentNode); | 258 state->persistentRegion()->freePersistentNode(m_persistentNode); |
230 } | 259 } |
260 m_persistentNode = nullptr; | |
231 } | 261 } |
232 | 262 |
233 void checkPointer() | 263 void checkPointer() |
234 { | 264 { |
235 #if ENABLE(ASSERT) | 265 #if ENABLE(ASSERT) |
236 if (!m_raw) | 266 if (!m_raw) |
237 return; | 267 return; |
238 | 268 |
239 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 269 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
240 // object. In other words, it checks that the pointer is either of: | 270 // object. In other words, it checks that the pointer is either of: |
(...skipping 13 matching lines...) Expand all Loading... | |
254 if (m_raw) | 284 if (m_raw) |
255 m_tracingName = Heap::createBacktraceString(); | 285 m_tracingName = Heap::createBacktraceString(); |
256 } | 286 } |
257 | 287 |
258 String m_tracingName; | 288 String m_tracingName; |
259 #else | 289 #else |
260 inline void recordBacktrace() const { } | 290 inline void recordBacktrace() const { } |
261 #endif | 291 #endif |
262 // m_raw is accessed most, so put it at the first field. | 292 // m_raw is accessed most, so put it at the first field. |
263 T* m_raw; | 293 T* m_raw; |
264 PersistentNode* m_persistentNode; | 294 PersistentNode* m_persistentNode = nullptr; |
265 #if ENABLE(ASSERT) | 295 #if ENABLE(ASSERT) |
266 ThreadState* m_state; | 296 ThreadState* m_state = nullptr; |
267 #endif | 297 #endif |
268 }; | 298 }; |
269 | 299 |
270 // Persistent is a way to create a strong pointer from an off-heap object | 300 // Persistent is a way to create a strong pointer from an off-heap object |
271 // to another on-heap object. As long as the Persistent handle is alive | 301 // to another on-heap object. As long as the Persistent handle is alive |
272 // the GC will keep the object pointed to alive. The Persistent handle is | 302 // the GC will keep the object pointed to alive. The Persistent handle is |
273 // always a GC root from the point of view of the GC. | 303 // always a GC root from the point of view of the GC. |
274 // | 304 // |
275 // We have to construct and destruct Persistent in the same thread. | 305 // We have to construct and destruct Persistent in the same thread. |
276 template<typename T> | 306 template<typename T> |
(...skipping 932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1209 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C rossThread)WeakPersistent. | 1239 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C rossThread)WeakPersistent. |
1210 static T* unwrap(const StorageType& value) { return value.get(); } | 1240 static T* unwrap(const StorageType& value) { return value.get(); } |
1211 }; | 1241 }; |
1212 | 1242 |
1213 template<typename T> | 1243 template<typename T> |
1214 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; | 1244 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; |
1215 | 1245 |
1216 } // namespace WTF | 1246 } // namespace WTF |
1217 | 1247 |
1218 #endif | 1248 #endif |
OLD | NEW |