Chromium Code Reviews| 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 |