OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 | 188 |
189 static void mark(Visitor*, const T*); | 189 static void mark(Visitor*, const T*); |
190 | 190 |
191 #ifndef NDEBUG | 191 #ifndef NDEBUG |
192 static void checkTypeMarker(Visitor*, const T*); | 192 static void checkTypeMarker(Visitor*, const T*); |
193 #endif | 193 #endif |
194 }; | 194 }; |
195 | 195 |
196 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 196 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
197 | 197 |
| 198 template<typename Collection> |
| 199 struct OffHeapCollectionTraceTrait { |
| 200 static void trace(Visitor*, const Collection&); |
| 201 }; |
| 202 |
198 template<typename T> | 203 template<typename T> |
199 struct ObjectAliveTrait { | 204 struct ObjectAliveTrait { |
200 static bool isAlive(Visitor*, T); | 205 static bool isAlive(Visitor*, T); |
201 }; | 206 }; |
202 | 207 |
203 template<typename T> | 208 template<typename T> |
204 struct ObjectAliveTrait<Member<T> > { | 209 struct ObjectAliveTrait<Member<T> > { |
205 static bool isAlive(Visitor*, const Member<T>&); | 210 static bool isAlive(Visitor*, const Member<T>&); |
206 }; | 211 }; |
207 | 212 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 333 |
329 private: | 334 private: |
330 template<typename T> | 335 template<typename T> |
331 static void handleWeakCell(Visitor* self, void* obj) | 336 static void handleWeakCell(Visitor* self, void* obj) |
332 { | 337 { |
333 T** cell = reinterpret_cast<T**>(obj); | 338 T** cell = reinterpret_cast<T**>(obj); |
334 if (*cell && !self->isAlive(*cell)) | 339 if (*cell && !self->isAlive(*cell)) |
335 *cell = 0; | 340 *cell = 0; |
336 } | 341 } |
337 }; | 342 }; |
| 343 template<typename T, typename HashFunctions, typename Traits> |
| 344 struct OffHeapCollectionTraceTrait<WTF::HashSet<T, WTF::DefaultAllocator, HashFu
nctions, Traits> > { |
| 345 typedef WTF::HashSet<T, WTF::DefaultAllocator, HashFunctions, Traits> HashSe
t; |
| 346 |
| 347 static void trace(Visitor* visitor, const HashSet& set) |
| 348 { |
| 349 if (set.isEmpty()) |
| 350 return; |
| 351 if (WTF::NeedsTracing<T>::value) { |
| 352 for (typename HashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) |
| 353 CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak
, false, T, Traits>::mark(visitor, *it); |
| 354 } |
| 355 COMPILE_ASSERT(!Traits::isWeak, WeakOffHeapCollectionsConsideredDangerou
s0); |
| 356 } |
| 357 }; |
| 358 |
| 359 template<typename T, size_t inlineCapacity, typename HashFunctions> |
| 360 struct OffHeapCollectionTraceTrait<WTF::ListHashSet<T, inlineCapacity, HashFunct
ions> > { |
| 361 typedef WTF::ListHashSet<T, inlineCapacity, HashFunctions> ListHashSet; |
| 362 |
| 363 static void trace(Visitor* visitor, const ListHashSet& set) |
| 364 { |
| 365 if (set.isEmpty()) |
| 366 return; |
| 367 for (typename ListHashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) |
| 368 visitor->trace(*it); |
| 369 } |
| 370 }; |
| 371 |
| 372 template<typename Key, typename Value, typename HashFunctions, typename KeyTrait
s, typename ValueTraits> |
| 373 struct OffHeapCollectionTraceTrait<WTF::HashMap<Key, Value, WTF::DefaultAllocato
r, HashFunctions, KeyTraits, ValueTraits> > { |
| 374 typedef WTF::HashMap<Key, Value, WTF::DefaultAllocator, HashFunctions, KeyTr
aits, ValueTraits> HashMap; |
| 375 |
| 376 static void trace(Visitor* visitor, const HashMap& map) |
| 377 { |
| 378 if (map.isEmpty()) |
| 379 return; |
| 380 if (WTF::NeedsTracing<Key>::value || WTF::NeedsTracing<Value>::value) { |
| 381 for (typename HashMap::const_iterator it = map.begin(), end = map.en
d(); it != end; ++it) { |
| 382 CollectionBackingTraceTrait<KeyTraits::needsTracing, KeyTraits::
isWeak, false, Key, KeyTraits>::mark(visitor, it->key); |
| 383 CollectionBackingTraceTrait<ValueTraits::needsTracing, ValueTrai
ts::isWeak, false, Value, ValueTraits>::mark(visitor, it->value); |
| 384 } |
| 385 } |
| 386 COMPILE_ASSERT(!KeyTraits::isWeak, WeakOffHeapCollectionsConsideredDange
rous1); |
| 387 COMPILE_ASSERT(!ValueTraits::isWeak, WeakOffHeapCollectionsConsideredDan
gerous2); |
| 388 } |
| 389 }; |
338 | 390 |
339 template<typename T, typename Traits = WTF::VectorTraits<T> > | 391 template<typename T, typename Traits = WTF::VectorTraits<T> > |
340 class HeapVectorBacking; | 392 class HeapVectorBacking; |
341 template<typename Key, typename Value, typename Extractor, typename Traits, type
name KeyTraits> | 393 template<typename Key, typename Value, typename Extractor, typename Traits, type
name KeyTraits> |
342 class HeapHashTableBacking; | 394 class HeapHashTableBacking; |
343 | 395 |
344 inline void doNothingTrace(Visitor*, void*) { } | 396 inline void doNothingTrace(Visitor*, void*) { } |
345 | 397 |
346 // Non-class types like char don't have an trace method, so we provide a more | 398 // Non-class types like char don't have an trace method, so we provide a more |
347 // specialized template instantiation here that will be selected in preference | 399 // specialized template instantiation here that will be selected in preference |
348 // to the default. Most of them do nothing, since the type in question cannot | 400 // to the default. Most of them do nothing, since the type in question cannot |
349 // point to other heap allocated objects. | 401 // point to other heap allocated objects. |
350 #define ITERATE_DO_NOTHING_TYPES(f) \ | 402 #define ITERATE_DO_NOTHING_TYPES(f) \ |
351 f(uint8_t) \ | 403 f(uint8_t) \ |
352 f(void) | 404 f(void) |
353 | 405 |
354 #define DECLARE_DO_NOTHING_TRAIT(type) \ | 406 #define DECLARE_DO_NOTHING_TRAIT(type) \ |
355 template<> \ | 407 template<> \ |
356 class TraceTrait<type> { \ | 408 class TraceTrait<type> { \ |
357 public: \ | 409 public: \ |
358 static void checkTypeMarker(Visitor*, const void*) { } \ | 410 static void checkTypeMarker(Visitor*, const void*) { } \ |
359 static void mark(Visitor* v, const type* p) { \ | 411 static void mark(Visitor* visitor, const type* p) { \ |
360 v->mark(p, reinterpret_cast<TraceCallback>(0)); \ | 412 visitor->mark(p, reinterpret_cast<TraceCallback>(0)); \ |
361 } \ | 413 } \ |
362 }; \ | 414 }; \ |
363 template<> \ | 415 template<> \ |
364 struct FinalizerTrait<type> { \ | 416 struct FinalizerTrait<type> { \ |
365 static void finalize(void*) { } \ | 417 static void finalize(void*) { } \ |
366 static const bool nonTrivialFinalizer = false; \ | 418 static const bool nonTrivialFinalizer = false; \ |
367 }; \ | 419 }; \ |
368 template<> \ | 420 template<> \ |
369 struct HEAP_EXPORT GCInfoTrait<type> { \ | 421 struct HEAP_EXPORT GCInfoTrait<type> { \ |
370 static const GCInfo* get() \ | 422 static const GCInfo* get() \ |
371 { \ | 423 { \ |
372 return &info; \ | 424 return &info; \ |
373 } \ | 425 } \ |
374 static const GCInfo info; \ | 426 static const GCInfo info; \ |
375 }; | 427 }; |
376 | 428 |
377 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) | 429 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) |
378 | 430 |
379 #undef DECLARE_DO_NOTHING_TRAIT | 431 #undef DECLARE_DO_NOTHING_TRAIT |
380 | 432 |
| 433 // Vectors are simple collections, and it's possible to mark vectors in a more |
| 434 // general way so that collections of objects (not pointers to objects) can be |
| 435 // marked. |
| 436 template<typename T, size_t N> |
| 437 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > { |
| 438 typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector; |
| 439 |
| 440 static void trace(Visitor* visitor, const Vector& vector) |
| 441 { |
| 442 if (vector.isEmpty()) |
| 443 return; |
| 444 for (typename Vector::const_iterator it = vector.begin(), end = vector.e
nd(); it != end; ++it) |
| 445 TraceTrait<T>::trace(visitor, const_cast<T*>(it)); |
| 446 } |
| 447 }; |
| 448 |
| 449 // Fallback definition. |
| 450 template<typename Collection> |
| 451 void OffHeapCollectionTraceTrait<Collection>::trace(Visitor* visitor, const Coll
ection& collection) |
| 452 { |
| 453 if (collection.isEmpty()) |
| 454 return; |
| 455 for (typename Collection::const_iterator it = collection.begin(), end = coll
ection.end(); it != end; ++it) |
| 456 visitor->trace(*it); |
| 457 } |
| 458 |
381 #ifndef NDEBUG | 459 #ifndef NDEBUG |
382 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const
T* t) | 460 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const
T* t) |
383 { | 461 { |
384 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); | 462 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); |
385 } | 463 } |
386 #endif | 464 #endif |
387 | 465 |
388 template<typename T> void TraceTrait<T>::mark(Visitor* visitor, const T* t) | 466 template<typename T> void TraceTrait<T>::mark(Visitor* visitor, const T* t) |
389 { | 467 { |
390 // Default mark method of the trait just calls the two-argument mark | 468 // Default mark method of the trait just calls the two-argument mark |
391 // method on the visitor. The second argument is the static trace method | 469 // method on the visitor. The second argument is the static trace method |
392 // of the trait, which by default calls the instance method | 470 // of the trait, which by default calls the instance method |
393 // trace(Visitor*) on the object. | 471 // trace(Visitor*) on the object. |
394 visitor->mark(const_cast<T*>(t), &trace); | 472 visitor->mark(const_cast<T*>(t), &trace); |
395 } | 473 } |
396 | 474 |
397 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj) | 475 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj) |
398 { | 476 { |
399 return visitor->isMarked(obj); | 477 return visitor->isMarked(obj); |
400 } | 478 } |
401 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor
, const Member<T>& obj) | 479 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor
, const Member<T>& obj) |
402 { | 480 { |
403 return visitor->isMarked(obj.get()); | 481 return visitor->isMarked(obj.get()); |
404 } | 482 } |
405 | 483 |
406 } | 484 } |
407 | 485 |
408 #endif | 486 #endif |
OLD | NEW |