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...) 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 mark(Visitor*, const Collection&); | |
haraken
2014/01/15 04:48:35
Shouldn't this be "trace" instead of "mark"?
Erik Corry
2014/01/15 09:27:32
Done.
| |
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...) 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 mark(Visitor* v, const HashSet& set) | |
haraken
2014/01/15 04:48:35
v => visitor
Erik Corry
2014/01/15 09:27:32
Done.
| |
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(v, *it); | |
354 } | |
355 COMPILE_ASSERT(!Traits::isWeak, WeakOffHeapCollectionsConsideredDangerou s); | |
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 mark(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 mark(Visitor* v, const HashMap& map) | |
haraken
2014/01/15 04:48:35
v => visitor
Erik Corry
2014/01/15 09:27:32
Done.
| |
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(v, it->key); | |
383 CollectionBackingTraceTrait<ValueTraits::needsTracing, ValueTrai ts::isWeak, false, Value, ValueTraits>::mark(v, it->value); | |
384 } | |
385 } | |
haraken
2014/01/15 04:48:35
Shouldn't this be:
for (typename HashMap::const_i
Erik Corry
2014/01/15 09:27:32
This would go through the loop even if nothing nee
| |
386 COMPILE_ASSERT(!KeyTraits::isWeak, WeakOffHeapCollectionsConsideredDange rous); | |
387 COMPILE_ASSERT(!ValueTraits::isWeak, WeakOffHeapCollectionsConsideredDan gerous); | |
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 // Non-class types like char don't have an trace method, so we provide a more | 396 // Non-class types like char don't have an trace method, so we provide a more |
345 // specialized template instantiation here that will be selected in preference | 397 // specialized template instantiation here that will be selected in preference |
346 // to the default. Most of them do nothing, since the type in question cannot | 398 // to the default. Most of them do nothing, since the type in question cannot |
347 // point to other heap allocated objects. | 399 // point to other heap allocated objects. |
(...skipping 21 matching lines...) Loading... | |
369 { \ | 421 { \ |
370 return &info; \ | 422 return &info; \ |
371 } \ | 423 } \ |
372 static const GCInfo info; \ | 424 static const GCInfo info; \ |
373 }; | 425 }; |
374 | 426 |
375 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) | 427 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) |
376 | 428 |
377 #undef DECLARE_DO_NOTHING_TRAIT | 429 #undef DECLARE_DO_NOTHING_TRAIT |
378 | 430 |
431 // Vectors are simple collections, and it's possible to mark vectors in a more | |
432 // general way so that collections of objects (not pointers to objects) can be | |
433 // marked. | |
434 template<typename T, size_t N> | |
435 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > { | |
436 typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector; | |
437 | |
438 static void mark(Visitor* v, const Vector& vector) | |
haraken
2014/01/15 04:48:35
v => visitor
Erik Corry
2014/01/15 09:27:32
Done.
| |
439 { | |
440 if (vector.isEmpty()) | |
441 return; | |
442 for (typename Vector::const_iterator it = vector.begin(), end = vector.e nd(); it != end; ++it) | |
443 TraceTrait<T>::trace(v, const_cast<T*>(it)); | |
444 } | |
445 }; | |
446 | |
447 // Fallback definition. | |
448 template<typename Collection> void OffHeapCollectionTraceTrait<Collection>::mark (Visitor* visitor, const Collection& collection) | |
449 { | |
450 if (collection.isEmpty()) | |
451 return; | |
452 for (typename Collection::const_iterator it = collection.begin(), end = coll ection.end(); it != end; ++it) | |
453 visitor->trace(*it); | |
454 } | |
455 | |
379 #ifndef NDEBUG | 456 #ifndef NDEBUG |
380 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const T* t) | 457 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const T* t) |
381 { | 458 { |
382 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); | 459 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); |
383 } | 460 } |
384 #endif | 461 #endif |
385 | 462 |
386 template<typename T> void TraceTrait<T>::mark(Visitor* visitor, const T* t) | 463 template<typename T> void TraceTrait<T>::mark(Visitor* visitor, const T* t) |
387 { | 464 { |
388 // Default mark method of the trait just calls the two-argument mark | 465 // Default mark method of the trait just calls the two-argument mark |
389 // method on the visitor. The second argument is the static trace method | 466 // method on the visitor. The second argument is the static trace method |
390 // of the trait, which by default calls the instance method | 467 // of the trait, which by default calls the instance method |
391 // trace(Visitor*) on the object. | 468 // trace(Visitor*) on the object. |
392 visitor->mark(const_cast<T*>(t), &trace); | 469 visitor->mark(const_cast<T*>(t), &trace); |
393 } | 470 } |
394 | 471 |
395 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj) | 472 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj) |
396 { | 473 { |
397 return visitor->isMarked(obj); | 474 return visitor->isMarked(obj); |
398 } | 475 } |
399 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor , const Member<T>& obj) | 476 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor , const Member<T>& obj) |
400 { | 477 { |
401 return visitor->isMarked(obj.raw()); | 478 return visitor->isMarked(obj.raw()); |
402 } | 479 } |
403 | 480 |
404 } | 481 } |
405 | 482 |
406 #endif | 483 #endif |
OLD | NEW |