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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 if (weaknessConfiguration == WeakPersistentConfiguration) { | 130 if (weaknessConfiguration == WeakPersistentConfiguration) { |
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 assign(nullptr); |
141 return result; | 141 return result; |
142 } | 142 } |
143 | 143 |
144 void clear() { m_raw = nullptr; } | 144 void clear() { assign(nullptr); } |
145 T& operator*() const { return *m_raw; } | 145 T& operator*() const { return *m_raw; } |
146 bool operator!() const { return !m_raw; } | 146 bool operator!() const { return !m_raw; } |
147 operator T*() const { return m_raw; } | 147 operator T*() const { return m_raw; } |
148 operator RawPtr<T>() const { return m_raw; } | 148 operator RawPtr<T>() const { return m_raw; } |
149 T* operator->() const { return *this; } | 149 T* operator->() const { return *this; } |
150 T* get() const { return m_raw; } | 150 T* get() const { return m_raw; } |
151 | 151 |
152 template<typename U> | 152 template<typename U> |
153 PersistentBase& operator=(U* other) | 153 PersistentBase& operator=(U* other) |
154 { | 154 { |
155 m_raw = other; | 155 assign(other); |
156 checkPointer(); | |
157 recordBacktrace(); | |
158 return *this; | 156 return *this; |
159 } | 157 } |
160 | 158 |
161 PersistentBase& operator=(std::nullptr_t) | 159 PersistentBase& operator=(std::nullptr_t) |
162 { | 160 { |
163 m_raw = nullptr; | 161 assign(nullptr); |
164 return *this; | 162 return *this; |
165 } | 163 } |
166 | 164 |
167 PersistentBase& operator=(const PersistentBase& other) | 165 PersistentBase& operator=(const PersistentBase& other) |
168 { | 166 { |
169 m_raw = other; | 167 assign(other); |
170 checkPointer(); | |
171 recordBacktrace(); | |
172 return *this; | 168 return *this; |
173 } | 169 } |
174 | 170 |
175 template<typename U> | 171 template<typename U> |
176 PersistentBase& operator=(const PersistentBase<U, weaknessConfiguration, cro
ssThreadnessConfiguration>& other) | 172 PersistentBase& operator=(const PersistentBase<U, weaknessConfiguration, cro
ssThreadnessConfiguration>& other) |
177 { | 173 { |
178 m_raw = other; | 174 assign(other); |
179 checkPointer(); | |
180 recordBacktrace(); | |
181 return *this; | 175 return *this; |
182 } | 176 } |
183 | 177 |
184 template<typename U> | 178 template<typename U> |
185 PersistentBase& operator=(const Member<U>& other) | 179 PersistentBase& operator=(const Member<U>& other) |
186 { | 180 { |
187 m_raw = other; | 181 assign(other); |
188 checkPointer(); | |
189 recordBacktrace(); | |
190 return *this; | 182 return *this; |
191 } | 183 } |
192 | 184 |
193 template<typename U> | 185 template<typename U> |
194 PersistentBase& operator=(const RawPtr<U>& other) | 186 PersistentBase& operator=(const RawPtr<U>& other) |
195 { | 187 { |
196 m_raw = other; | 188 assign(other); |
197 checkPointer(); | |
198 recordBacktrace(); | |
199 return *this; | 189 return *this; |
200 } | 190 } |
201 | 191 |
202 | 192 |
203 private: | 193 private: |
204 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 194 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
| 195 void assign(T* ptr) |
| 196 { |
| 197 m_raw = ptr; |
| 198 checkPointer(); |
| 199 recordBacktrace(); |
| 200 if (m_raw) { |
| 201 if (!m_persistentNode) |
| 202 initialize(); |
| 203 return; |
| 204 } |
| 205 if (m_persistentNode && crossThreadnessConfiguration != CrossThreadPersi
stentConfiguration) |
| 206 uninitialize(); |
| 207 } |
| 208 |
| 209 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
205 void initialize() | 210 void initialize() |
206 { | 211 { |
| 212 ASSERT(!m_persistentNode); |
| 213 if (!m_raw) |
| 214 return; |
| 215 |
207 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak
nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon
figuration, crossThreadnessConfiguration>::trace>::trampoline; | 216 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak
nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon
figuration, crossThreadnessConfiguration>::trace>::trampoline; |
208 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ | 217 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ |
209 m_persistentNode = ThreadState::crossThreadPersistentRegion().alloca
tePersistentNode(this, traceCallback); | 218 m_persistentNode = ThreadState::crossThreadPersistentRegion().alloca
tePersistentNode(this, traceCallback); |
210 } else { | 219 } else { |
211 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st
ate(); | 220 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st
ate(); |
212 ASSERT(state->checkThread()); | 221 ASSERT(state->checkThread()); |
213 m_persistentNode = state->persistentRegion()->allocatePersistentNode
(this, traceCallback); | 222 m_persistentNode = state->persistentRegion()->allocatePersistentNode
(this, traceCallback); |
214 #if ENABLE(ASSERT) | 223 #if ENABLE(ASSERT) |
215 m_state = state; | 224 m_state = state; |
216 #endif | 225 #endif |
217 } | 226 } |
218 } | 227 } |
219 | 228 |
220 void uninitialize() | 229 void uninitialize() |
221 { | 230 { |
| 231 if (!m_persistentNode) |
| 232 return; |
| 233 |
222 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ | 234 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ |
223 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_pers
istentNode); | 235 ThreadState::crossThreadPersistentRegion().freePersistentNode(m_pers
istentNode); |
224 } else { | 236 } else { |
225 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st
ate(); | 237 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::st
ate(); |
226 ASSERT(state->checkThread()); | 238 ASSERT(state->checkThread()); |
227 // Persistent handle must be created and destructed in the same thre
ad. | 239 // Persistent handle must be created and destructed in the same thre
ad. |
228 ASSERT(m_state == state); | 240 ASSERT(m_state == state); |
229 state->persistentRegion()->freePersistentNode(m_persistentNode); | 241 state->persistentRegion()->freePersistentNode(m_persistentNode); |
230 } | 242 } |
| 243 m_persistentNode = nullptr; |
231 } | 244 } |
232 | 245 |
233 void checkPointer() | 246 void checkPointer() |
234 { | 247 { |
235 #if ENABLE(ASSERT) | 248 #if ENABLE(ASSERT) |
236 if (!m_raw) | 249 if (!m_raw) |
237 return; | 250 return; |
238 | 251 |
239 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable | 252 // Heap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
240 // object. In other words, it checks that the pointer is either of: | 253 // object. In other words, it checks that the pointer is either of: |
(...skipping 13 matching lines...) Expand all Loading... |
254 if (m_raw) | 267 if (m_raw) |
255 m_tracingName = Heap::createBacktraceString(); | 268 m_tracingName = Heap::createBacktraceString(); |
256 } | 269 } |
257 | 270 |
258 String m_tracingName; | 271 String m_tracingName; |
259 #else | 272 #else |
260 inline void recordBacktrace() const { } | 273 inline void recordBacktrace() const { } |
261 #endif | 274 #endif |
262 // m_raw is accessed most, so put it at the first field. | 275 // m_raw is accessed most, so put it at the first field. |
263 T* m_raw; | 276 T* m_raw; |
264 PersistentNode* m_persistentNode; | 277 PersistentNode* m_persistentNode = nullptr; |
265 #if ENABLE(ASSERT) | 278 #if ENABLE(ASSERT) |
266 ThreadState* m_state; | 279 ThreadState* m_state = nullptr; |
267 #endif | 280 #endif |
268 }; | 281 }; |
269 | 282 |
270 // Persistent is a way to create a strong pointer from an off-heap object | 283 // 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 | 284 // 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 | 285 // 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. | 286 // always a GC root from the point of view of the GC. |
274 // | 287 // |
275 // We have to construct and destruct Persistent in the same thread. | 288 // We have to construct and destruct Persistent in the same thread. |
276 template<typename T> | 289 template<typename T> |
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1369 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C
rossThread)WeakPersistent. | 1382 // TODO(sof): extend WTF::FunctionWrapper call overloading to also handle (C
rossThread)WeakPersistent. |
1370 static T* unwrap(const StorageType& value) { return value.get(); } | 1383 static T* unwrap(const StorageType& value) { return value.get(); } |
1371 }; | 1384 }; |
1372 | 1385 |
1373 template<typename T> | 1386 template<typename T> |
1374 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; | 1387 PassRefPtr<T> adoptRef(blink::RefCountedGarbageCollected<T>*) = delete; |
1375 | 1388 |
1376 } // namespace WTF | 1389 } // namespace WTF |
1377 | 1390 |
1378 #endif | 1391 #endif |
OLD | NEW |