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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 // A Persistent is always a GC root from the point of view of | 280 // A Persistent is always a GC root from the point of view of |
281 // the garbage collector. | 281 // the garbage collector. |
282 // | 282 // |
283 // We have to construct and destruct Persistent with default RootsAccessor in | 283 // We have to construct and destruct Persistent with default RootsAccessor in |
284 // the same thread. | 284 // the same thread. |
285 template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<Threadin gTrait<T>::Affinity > */ > | 285 template<typename T, typename RootsAccessor /* = ThreadLocalPersistents<Threadin gTrait<T>::Affinity > */ > |
286 class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAcces sor> > { | 286 class Persistent : public PersistentBase<RootsAccessor, Persistent<T, RootsAcces sor> > { |
287 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent); | 287 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(Persistent); |
288 WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent); | 288 WTF_DISALLOW_ZERO_ASSIGNMENT(Persistent); |
289 public: | 289 public: |
290 Persistent() : m_raw(0) { } | 290 Persistent() : m_raw(0) { recordBacktrace(); } |
haraken
2014/06/16 01:15:40
I'm not sure if you want to record a backtrace for
| |
291 | 291 |
292 Persistent(std::nullptr_t) : m_raw(0) { } | 292 Persistent(std::nullptr_t) : m_raw(0) { recordBacktrace(); } |
haraken
2014/06/16 01:15:40
Ditto.
| |
293 | 293 |
294 Persistent(T* raw) : m_raw(raw) | 294 Persistent(T* raw) : m_raw(raw) |
295 { | 295 { |
296 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); | 296 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); |
297 recordBacktrace(); | |
297 } | 298 } |
298 | 299 |
299 explicit Persistent(T& raw) : m_raw(&raw) | 300 explicit Persistent(T& raw) : m_raw(&raw) |
300 { | 301 { |
301 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); | 302 ASSERT_IS_VALID_PERSISTENT_POINTER(m_raw); |
303 recordBacktrace(); | |
302 } | 304 } |
303 | 305 |
304 Persistent(const Persistent& other) : m_raw(other) { } | 306 Persistent(const Persistent& other) : m_raw(other) { recordBacktrace(); } |
305 | 307 |
306 template<typename U> | 308 template<typename U> |
307 Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { } | 309 Persistent(const Persistent<U, RootsAccessor>& other) : m_raw(other) { recor dBacktrace(); } |
308 | 310 |
309 template<typename U> | 311 template<typename U> |
310 Persistent(const Member<U>& other) : m_raw(other) { } | 312 Persistent(const Member<U>& other) : m_raw(other) { recordBacktrace(); } |
311 | 313 |
312 template<typename U> | 314 template<typename U> |
313 Persistent(const RawPtr<U>& other) : m_raw(other.get()) { } | 315 Persistent(const RawPtr<U>& other) : m_raw(other.get()) { recordBacktrace(); } |
314 | 316 |
315 template<typename U> | 317 template<typename U> |
316 Persistent& operator=(U* other) | 318 Persistent& operator=(U* other) |
317 { | 319 { |
318 m_raw = other; | 320 m_raw = other; |
haraken
2014/06/16 01:15:40
You'll need recordBacktrace() here as well.
| |
319 return *this; | 321 return *this; |
320 } | 322 } |
321 | 323 |
322 Persistent& operator=(std::nullptr_t) | 324 Persistent& operator=(std::nullptr_t) |
323 { | 325 { |
324 m_raw = 0; | 326 m_raw = 0; |
325 return *this; | 327 return *this; |
326 } | 328 } |
327 | 329 |
328 void clear() { m_raw = 0; } | 330 void clear() { m_raw = 0; } |
329 | 331 |
330 virtual ~Persistent() | 332 virtual ~Persistent() |
331 { | 333 { |
332 m_raw = 0; | 334 m_raw = 0; |
333 } | 335 } |
334 | 336 |
335 template<typename U> | 337 template<typename U> |
336 U* as() const | 338 U* as() const |
337 { | 339 { |
338 return static_cast<U*>(m_raw); | 340 return static_cast<U*>(m_raw); |
339 } | 341 } |
340 | 342 |
341 void trace(Visitor* visitor) | 343 void trace(Visitor* visitor) |
342 { | 344 { |
343 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); | 345 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInPersis tent); |
344 #if ENABLE(GC_TRACING) | 346 #if ENABLE(GC_TRACING) |
345 visitor->setHostInfo(this, "Persistent"); | 347 visitor->setHostInfo(this, m_tracingName.isEmpty() ? "Persistent" : m_tr acingName); |
haraken
2014/06/16 01:15:40
Just help me understand: In what situation can the
tkent
2014/06/16 02:34:47
When we forget to add recordBacktrace() :-)
| |
346 #endif | 348 #endif |
347 visitor->mark(m_raw); | 349 visitor->mark(m_raw); |
348 } | 350 } |
349 | 351 |
350 T* release() | 352 T* release() |
351 { | 353 { |
352 T* result = m_raw; | 354 T* result = m_raw; |
353 m_raw = 0; | 355 m_raw = 0; |
354 return result; | 356 return result; |
355 } | 357 } |
356 | 358 |
357 T& operator*() const { return *m_raw; } | 359 T& operator*() const { return *m_raw; } |
358 | 360 |
359 bool operator!() const { return !m_raw; } | 361 bool operator!() const { return !m_raw; } |
360 | 362 |
361 operator T*() const { return m_raw; } | 363 operator T*() const { return m_raw; } |
362 operator RawPtr<T>() const { return m_raw; } | 364 operator RawPtr<T>() const { return m_raw; } |
363 | 365 |
364 T* operator->() const { return *this; } | 366 T* operator->() const { return *this; } |
365 | 367 |
366 Persistent& operator=(const Persistent& other) | 368 Persistent& operator=(const Persistent& other) |
367 { | 369 { |
368 m_raw = other; | 370 m_raw = other; |
haraken
2014/06/16 01:15:40
You'll need recordBacktrace() here.
| |
369 return *this; | 371 return *this; |
370 } | 372 } |
371 | 373 |
372 template<typename U> | 374 template<typename U> |
373 Persistent& operator=(const Persistent<U, RootsAccessor>& other) | 375 Persistent& operator=(const Persistent<U, RootsAccessor>& other) |
374 { | 376 { |
375 m_raw = other; | 377 m_raw = other; |
haraken
2014/06/16 01:15:40
You'll need recordBacktrace() here.
| |
376 return *this; | 378 return *this; |
377 } | 379 } |
378 | 380 |
379 template<typename U> | 381 template<typename U> |
380 Persistent& operator=(const Member<U>& other) | 382 Persistent& operator=(const Member<U>& other) |
381 { | 383 { |
382 m_raw = other; | 384 m_raw = other; |
haraken
2014/06/16 01:15:40
You'll need recordBacktrace() here.
| |
383 return *this; | 385 return *this; |
384 } | 386 } |
385 | 387 |
386 template<typename U> | 388 template<typename U> |
387 Persistent& operator=(const RawPtr<U>& other) | 389 Persistent& operator=(const RawPtr<U>& other) |
388 { | 390 { |
389 m_raw = other; | 391 m_raw = other; |
haraken
2014/06/16 01:15:40
You'll need recordBacktrace() here.
My proposal i
tkent
2014/06/16 02:34:47
I thought adding recordBacktrace() to constructors
| |
390 return *this; | 392 return *this; |
391 } | 393 } |
392 | 394 |
393 T* get() const { return m_raw; } | 395 T* get() const { return m_raw; } |
394 | 396 |
395 private: | 397 private: |
398 #if ENABLE(GC_TRACING) | |
399 void recordBacktrace() | |
400 { | |
401 m_tracingName = Heap::createBacktraceString(); | |
402 } | |
403 | |
404 String m_tracingName; | |
405 #else | |
406 inline void recordBacktrace() { } | |
407 #endif | |
396 T* m_raw; | 408 T* m_raw; |
397 | 409 |
398 friend class CrossThreadPersistent<T>; | 410 friend class CrossThreadPersistent<T>; |
399 }; | 411 }; |
400 | 412 |
401 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread | 413 // Unlike Persistent, we can destruct a CrossThreadPersistent in a thread |
402 // different from the construction thread. | 414 // different from the construction thread. |
403 template<typename T> | 415 template<typename T> |
404 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> { | 416 class CrossThreadPersistent : public Persistent<T, GlobalPersistents> { |
405 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent); | 417 WTF_DISALLOW_CONSTRUCTION_FROM_ZERO(CrossThreadPersistent); |
(...skipping 12 matching lines...) Expand all Loading... | |
418 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent | 430 // We overload the various new and delete operators with using the WTF Defau ltAllocator to ensure persistent |
419 // heap collections are always allocated off-heap. This allows persistent co llections to be used in | 431 // heap collections are always allocated off-heap. This allows persistent co llections to be used in |
420 // DEFINE_STATIC_LOCAL et. al. | 432 // DEFINE_STATIC_LOCAL et. al. |
421 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); | 433 WTF_USE_ALLOCATOR(PersistentHeapCollectionBase, WTF::DefaultAllocator); |
422 public: | 434 public: |
423 PersistentHeapCollectionBase() { } | 435 PersistentHeapCollectionBase() { } |
424 | 436 |
425 template<typename OtherCollection> | 437 template<typename OtherCollection> |
426 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe r) { } | 438 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe r) { } |
427 | 439 |
428 void trace(Visitor* visitor) { visitor->trace(*static_cast<Collection*>(this )); } | 440 void trace(Visitor* visitor) |
441 { | |
442 #if ENABLE(GC_TRACING) | |
443 visitor->setHostInfo(this, "PersistentHeapCollectionBase"); | |
444 #endif | |
445 visitor->trace(*static_cast<Collection*>(this)); | |
446 } | |
429 }; | 447 }; |
430 | 448 |
431 template< | 449 template< |
432 typename KeyArg, | 450 typename KeyArg, |
433 typename MappedArg, | 451 typename MappedArg, |
434 typename HashArg = typename DefaultHash<KeyArg>::Hash, | 452 typename HashArg = typename DefaultHash<KeyArg>::Hash, |
435 typename KeyTraitsArg = HashTraits<KeyArg>, | 453 typename KeyTraitsArg = HashTraits<KeyArg>, |
436 typename MappedTraitsArg = HashTraits<MappedArg> > | 454 typename MappedTraitsArg = HashTraits<MappedArg> > |
437 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<Ke yArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { }; | 455 class PersistentHeapHashMap : public PersistentHeapCollectionBase<HeapHashMap<Ke yArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> > { }; |
438 | 456 |
(...skipping 737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1176 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, WebCore::Is GarbageCollectedType<T>::value> { | 1194 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, WebCore::Is GarbageCollectedType<T>::value> { |
1177 }; | 1195 }; |
1178 | 1196 |
1179 template<typename T> | 1197 template<typename T> |
1180 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, Web Core::IsGarbageCollectedType<T>::value> { | 1198 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, Web Core::IsGarbageCollectedType<T>::value> { |
1181 }; | 1199 }; |
1182 | 1200 |
1183 } // namespace WTF | 1201 } // namespace WTF |
1184 | 1202 |
1185 #endif | 1203 #endif |
OLD | NEW |