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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 private: | 209 private: |
| 210 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &P ersistentAnchor::trace>::trampoline) | 210 PersistentAnchor() : PersistentNode(TraceMethodDelegate<PersistentAnchor, &P ersistentAnchor::trace>::trampoline) |
| 211 { | 211 { |
| 212 m_next = this; | 212 m_next = this; |
| 213 m_prev = this; | 213 m_prev = this; |
| 214 } | 214 } |
| 215 | 215 |
| 216 friend class ThreadState; | 216 friend class ThreadState; |
| 217 }; | 217 }; |
| 218 | 218 |
| 219 #ifndef NDEBUG | |
| 220 // For global persistent handles we cannot check that the | |
| 221 // pointer is in the heap because that would involve | |
| 222 // inspecting the heap of running threads. | |
| 223 #define ASSERT_IS_VALID_PERSISTENT_POINTER(pointer) \ | |
| 224 bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersistents>: :value; \ | |
| 225 ASSERT(!pointer || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::A ffinity>::state()->contains(pointer)) | |
| 226 #else | |
| 227 #define ASSERT_IS_VALID_PERSISTENT_POINTER(raw) | |
| 228 #endif | |
| 229 | |
| 219 template<typename T> | 230 template<typename T> |
| 220 class CrossThreadPersistent; | 231 class CrossThreadPersistent; |
| 221 | 232 |
| 222 // Persistent handles are used to store pointers into the | 233 // Persistent handles are used to store pointers into the |
| 223 // managed heap. As long as the Persistent handle is alive | 234 // managed heap. As long as the Persistent handle is alive |
| 224 // the GC will keep the object pointed to alive. Persistent | 235 // the GC will keep the object pointed to alive. Persistent |
| 225 // handles can be stored in objects and they are not scoped. | 236 // handles can be stored in objects and they are not scoped. |
| 226 // Persistent handles must not be used to contain pointers | 237 // Persistent handles must not be used to contain pointers |
| 227 // between objects that are in the managed heap. They are only | 238 // between objects that are in the managed heap. They are only |
| 228 // meant to point to managed heap objects from variables/members | 239 // meant to point to managed heap objects from variables/members |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 244 } | 255 } |
| 245 | 256 |
| 246 Persistent(std::nullptr_t) : m_raw(0) | 257 Persistent(std::nullptr_t) : m_raw(0) |
| 247 { | 258 { |
| 248 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); | 259 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); |
| 249 } | 260 } |
| 250 | 261 |
| 251 Persistent(T* raw) : m_raw(raw) | 262 Persistent(T* raw) : m_raw(raw) |
| 252 { | 263 { |
| 253 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); | 264 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); |
| 254 #ifndef NDEBUG | 265 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); |
| 255 // For global persistent handles we cannot check that the | 266 } |
| 256 // pointer is in the heap because that would involve | 267 |
| 257 // inspecting the heap of running threads. | 268 explicit Persistent(T& raw) : m_raw(&raw) |
| 258 bool isGlobalPersistent = WTF::IsSubclass<RootsAccessor, GlobalPersisten ts>::value; | 269 { |
| 259 ASSERT(!raw || isGlobalPersistent || ThreadStateFor<ThreadingTrait<T>::A ffinity>::state()->contains(raw)); | 270 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); |
| 260 #endif | 271 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); |
| 261 } | 272 } |
| 262 | 273 |
| 263 Persistent(const Persistent& other) : m_raw(other) | 274 Persistent(const Persistent& other) : m_raw(other) |
| 264 { | 275 { |
| 265 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); | 276 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); |
| 266 } | 277 } |
| 267 | 278 |
| 268 template<typename U> | 279 template<typename U> |
| 269 Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { } | 280 Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { } |
| 270 | 281 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 } | 357 } |
| 347 | 358 |
| 348 T* get() const { return m_raw; } | 359 T* get() const { return m_raw; } |
| 349 | 360 |
| 350 private: | 361 private: |
| 351 T* m_raw; | 362 T* m_raw; |
| 352 | 363 |
| 353 friend class CrossThreadPersistent<T>; | 364 friend class CrossThreadPersistent<T>; |
| 354 }; | 365 }; |
| 355 | 366 |
| 367 #undef ASSERT_IS_VALID_PERSISTENT_POINTER | |
| 368 | |
| 356 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread | 369 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread |
| 357 // different from the construction thread. | 370 // different from the construction thread. |
| 358 template<typename T> | 371 template<typename T> |
| 359 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> { | 372 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> { |
| 360 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent); | 373 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent); |
| 361 WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent); | 374 WTF_DISALLOW_ZERO_ASSIGNMENT(CrossThreadPersistent); |
| 362 public: | 375 public: |
| 363 CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { } | 376 CrossThreadPersistent(T* raw) : Persistent<T, GlobalPersistents>(raw) { } |
| 364 | 377 |
| 365 using Persistent<T, GlobalPersistents>::operator=; | 378 using Persistent<T, GlobalPersistents>::operator=; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 Member(std::nullptr_t) : m_raw(0) | 438 Member(std::nullptr_t) : m_raw(0) |
| 426 { | 439 { |
| 427 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember ); | 440 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember ); |
| 428 } | 441 } |
| 429 | 442 |
| 430 Member(T* raw) : m_raw(raw) | 443 Member(T* raw) : m_raw(raw) |
| 431 { | 444 { |
| 432 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember ); | 445 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember ); |
| 433 } | 446 } |
| 434 | 447 |
| 448 explicit Member(T& raw) : m_raw(&raw) | |
| 449 { | |
| 450 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember ); | |
|
haraken
2014/04/02 07:49:41
Can we implement ASSERT_IS_VALID_MEMBER_POINTER as
sof
2014/04/02 08:05:50
Catching out cross-heap references would be useful
haraken
2014/04/02 08:09:29
Oh, sorry. Cross-heap references are allowed, so w
sof
2014/04/02 08:12:54
Interesting, what code relies on creating such cro
haraken
2014/04/02 08:15:41
I think some classes in webdatabase/ are using cro
Mads Ager (chromium)
2014/04/02 08:22:04
That is correct, we have cross thread pointers in
| |
| 451 } | |
| 452 | |
| 435 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) | 453 Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) |
| 436 { | 454 { |
| 437 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember ); | 455 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember ); |
| 438 } | 456 } |
| 439 | 457 |
| 440 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); } | 458 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>( -1); } |
| 441 | 459 |
| 442 template<typename U> | 460 template<typename U> |
| 443 Member(const Persistent<U>& other) : m_raw(other) { } | 461 Member(const Persistent<U>& other) : m_raw(other) { } |
| 444 | 462 |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 941 }; | 959 }; |
| 942 | 960 |
| 943 template<typename T, typename U> | 961 template<typename T, typename U> |
| 944 struct NeedsTracing<HashMap<T, U> > { | 962 struct NeedsTracing<HashMap<T, U> > { |
| 945 static const bool value = false; | 963 static const bool value = false; |
| 946 }; | 964 }; |
| 947 | 965 |
| 948 } // namespace WTF | 966 } // namespace WTF |
| 949 | 967 |
| 950 #endif | 968 #endif |
| OLD | NEW |