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 |