| 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 |