| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 #define TRACE_GC_USING_CLASSOF 1 | 46 #define TRACE_GC_USING_CLASSOF 1 |
| 47 #else | 47 #else |
| 48 #define TRACE_GC_USING_CLASSOF 0 | 48 #define TRACE_GC_USING_CLASSOF 0 |
| 49 #endif | 49 #endif |
| 50 | 50 |
| 51 namespace WebCore { | 51 namespace WebCore { |
| 52 | 52 |
| 53 template<typename T> class Member; | 53 template<typename T> class Member; |
| 54 template<typename T> class WeakMember; | 54 template<typename T> class WeakMember; |
| 55 class HeapAllocator; | 55 class HeapAllocator; |
| 56 template<bool needsVisiting, bool isWeak, bool visitWeakPointersStrongly, typena
me T, typename Traits> struct VisitCollectionBackingTrait; | 56 template<bool needsTracing, bool isWeak, bool markWeakPointersStrongly, typename
T, typename Traits> struct CollectionBackingTraceTrait; |
| 57 | 57 |
| 58 typedef void (*FinalizationCallback)(void*); | 58 typedef void (*FinalizationCallback)(void*); |
| 59 | 59 |
| 60 class Visitor; | 60 class Visitor; |
| 61 typedef void (*VisitorCallback)(Visitor*, void* self); | 61 typedef void (*VisitorCallback)(Visitor*, void* self); |
| 62 typedef VisitorCallback TraceCallback; | 62 typedef VisitorCallback TraceCallback; |
| 63 typedef VisitorCallback WeakPointerCallback; | 63 typedef VisitorCallback WeakPointerCallback; |
| 64 | 64 |
| 65 template<typename T, void (T::*method)(Visitor*)> | 65 template<typename T, void (T::*method)(Visitor*)> |
| 66 struct TraceMethodDelegate { | 66 struct TraceMethodDelegate { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 template<typename T> | 187 template<typename T> |
| 188 class TraceTrait { | 188 class TraceTrait { |
| 189 public: | 189 public: |
| 190 // Default implementation of TraceTrait<T>::trace just statically | 190 // Default implementation of TraceTrait<T>::trace just statically |
| 191 // dispatches to the trace method of the class T. | 191 // dispatches to the trace method of the class T. |
| 192 static void trace(Visitor* visitor, void* self) | 192 static void trace(Visitor* visitor, void* self) |
| 193 { | 193 { |
| 194 static_cast<T*>(self)->trace(visitor); | 194 static_cast<T*>(self)->trace(visitor); |
| 195 } | 195 } |
| 196 | 196 |
| 197 static void visit(Visitor*, const T*); | 197 static void mark(Visitor*, const T*); |
| 198 | 198 |
| 199 #ifndef NDEBUG | 199 #ifndef NDEBUG |
| 200 static void checkTypeMarker(Visitor*, const T*); | 200 static void checkTypeMarker(Visitor*, const T*); |
| 201 #endif | 201 #endif |
| 202 }; | 202 }; |
| 203 | 203 |
| 204 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 204 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
| 205 | 205 |
| 206 template<typename K, typename V, typename HashTraits, typename KeyTraits, typena
me ValueTraits> | 206 template<typename K, typename V, typename HashTraits, typename KeyTraits, typena
me ValueTraits> |
| 207 void processWeakOffHeapHashMap(Visitor*, void* map); | 207 void processWeakOffHeapHashMap(Visitor*, void* map); |
| 208 template<typename T, typename HashFunctions, typename Traits> | 208 template<typename T, typename HashFunctions, typename Traits> |
| 209 void processWeakOffHeapHashSet(Visitor*, void* set); | 209 void processWeakOffHeapHashSet(Visitor*, void* set); |
| 210 | 210 |
| 211 template<typename Collection> | 211 template<typename Collection> |
| 212 struct CollectionVisitingTrait { | 212 struct OffHeapCollectionTraceTrait { |
| 213 static void visit(Visitor*, const Collection&); | 213 static void mark(Visitor*, const Collection&); |
| 214 }; | 214 }; |
| 215 | 215 |
| 216 template<typename T> | 216 template<typename T> |
| 217 struct ObjectAliveTrait { | 217 struct ObjectAliveTrait { |
| 218 static bool isAlive(Visitor*, T); | 218 static bool isAlive(Visitor*, T); |
| 219 }; | 219 }; |
| 220 | 220 |
| 221 template<typename T> | 221 template<typename T> |
| 222 struct ObjectAliveTrait<Member<T> > { | 222 struct ObjectAliveTrait<Member<T> > { |
| 223 static bool isAlive(Visitor*, const Member<T>&); | 223 static bool isAlive(Visitor*, const Member<T>&); |
| 224 }; | 224 }; |
| 225 | 225 |
| 226 class HeapObjectHeader; | 226 class HeapObjectHeader; |
| 227 class FinalizedHeapObjectHeader; | 227 class FinalizedHeapObjectHeader; |
| 228 | 228 |
| 229 #ifndef NDEBUG | 229 #ifndef NDEBUG |
| 230 #define DEBUG_ONLY(x) x | 230 #define DEBUG_ONLY(x) x |
| 231 #else | 231 #else |
| 232 #define DEBUG_ONLY(x) | 232 #define DEBUG_ONLY(x) |
| 233 #endif | 233 #endif |
| 234 | 234 |
| 235 class Visitor { | 235 class Visitor { |
| 236 public: | 236 public: |
| 237 #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING | 237 #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING |
| 238 Visitor() : m_hostObject(0), m_hostName(0) { } | 238 Visitor() : m_hostObject(0), m_hostName(0) { } |
| 239 #endif | 239 #endif |
| 240 | 240 |
| 241 // One-argument templated visit method. This uses the static type of | 241 // One-argument templated mark method. This uses the static type of |
| 242 // the argument to get the TraceTrait. By default, the visit method | 242 // the argument to get the TraceTrait. By default, the mark method |
| 243 // of the TraceTrait just calls the virtual two-argument visit method on thi
s | 243 // of the TraceTrait just calls the virtual two-argument mark method on this |
| 244 // visitor, where the second argument is the static trace method. | 244 // visitor, where the second argument is the static trace method. |
| 245 template<typename T> | 245 template<typename T> |
| 246 void visit(T* t) | 246 void mark(T* t) |
| 247 { | 247 { |
| 248 if (!t) | 248 if (!t) |
| 249 return; | 249 return; |
| 250 #ifndef NDEBUG | 250 #ifndef NDEBUG |
| 251 TraceTrait<T>::checkTypeMarker(this, t); | 251 TraceTrait<T>::checkTypeMarker(this, t); |
| 252 #endif | 252 #endif |
| 253 TraceTrait<T>::visit(this, t); | 253 TraceTrait<T>::mark(this, t); |
| 254 } | 254 } |
| 255 | 255 |
| 256 // Member version of the one-argument templated visit method. | 256 // Member version of the one-argument templated mark method. |
| 257 template<typename T> | 257 template<typename T> |
| 258 void trace(const Member<T>& t) | 258 void trace(const Member<T>& t) |
| 259 { | 259 { |
| 260 if (!t) | 260 if (!t) |
| 261 return; | 261 return; |
| 262 #ifndef NDEBUG | 262 #ifndef NDEBUG |
| 263 TraceTrait<T>::checkTypeMarker(this, t.raw()); | 263 TraceTrait<T>::checkTypeMarker(this, t.raw()); |
| 264 #endif | 264 #endif |
| 265 TraceTrait<T>::visit(this, t.raw()); | 265 TraceTrait<T>::mark(this, t.raw()); |
| 266 } | 266 } |
| 267 | 267 |
| 268 // Doesn't keep the visited thing alive, but will write null to the | 268 // Doesn't keep the traced thing alive, but will write null to the |
| 269 // WeakMember later if the pointed-to object is dead. | 269 // WeakMember later if the pointed-to object is dead. |
| 270 template<typename T> | 270 template<typename T> |
| 271 void trace(const WeakMember<T>& t) | 271 void trace(const WeakMember<T>& t) |
| 272 { | 272 { |
| 273 registerWeakCell(t.cell()); | 273 registerWeakCell(t.cell()); |
| 274 } | 274 } |
| 275 | 275 |
| 276 // The following visit methods are for off-heap collections. | 276 // The following mark methods are for off-heap collections. |
| 277 template<typename T, size_t inlineCapacity> | 277 template<typename T, size_t inlineCapacity> |
| 278 void trace(const Vector<T, inlineCapacity, WTF::FastAllocator>& vector) | 278 void trace(const Vector<T, inlineCapacity, WTF::FastAllocator>& vector) |
| 279 { | 279 { |
| 280 CollectionVisitingTrait<Vector<T, inlineCapacity, WTF::FastAllocator> >:
:visit(this, vector); | 280 OffHeapCollectionTraceTrait<Vector<T, inlineCapacity, WTF::FastAllocator
> >::mark(this, vector); |
| 281 } | 281 } |
| 282 | 282 |
| 283 template<typename T, typename U, typename V> | 283 template<typename T, typename U, typename V> |
| 284 void trace(const HashSet<T, WTF::FastAllocator, U, V>& hashSet) | 284 void trace(const HashSet<T, WTF::FastAllocator, U, V>& hashSet) |
| 285 { | 285 { |
| 286 CollectionVisitingTrait<HashSet<T, WTF::FastAllocator, U, V> >::visit(th
is, hashSet); | 286 OffHeapCollectionTraceTrait<HashSet<T, WTF::FastAllocator, U, V> >::mark
(this, hashSet); |
| 287 } | 287 } |
| 288 | 288 |
| 289 template<typename T, size_t inlineCapacity, typename U> | 289 template<typename T, size_t inlineCapacity, typename U> |
| 290 void trace(const ListHashSet<T, inlineCapacity, U>& hashSet) | 290 void trace(const ListHashSet<T, inlineCapacity, U>& hashSet) |
| 291 { | 291 { |
| 292 CollectionVisitingTrait<ListHashSet<T, inlineCapacity, U> >::visit(this,
hashSet); | 292 OffHeapCollectionTraceTrait<ListHashSet<T, inlineCapacity, U> >::mark(th
is, hashSet); |
| 293 } | 293 } |
| 294 | 294 |
| 295 template<typename T, size_t N> | 295 template<typename T, size_t N> |
| 296 void trace(const Deque<T, N>& deque) | 296 void trace(const Deque<T, N>& deque) |
| 297 { | 297 { |
| 298 CollectionVisitingTrait<Deque<T, N> >::visit(this, deque); | 298 OffHeapCollectionTraceTrait<Deque<T, N> >::mark(this, deque); |
| 299 } | 299 } |
| 300 | 300 |
| 301 template<typename T, typename U, typename V, typename W, typename X> | 301 template<typename T, typename U, typename V, typename W, typename X> |
| 302 void trace(const HashMap<T, U, WTF::FastAllocator, V, W, X>& map) | 302 void trace(const HashMap<T, U, WTF::FastAllocator, V, W, X>& map) |
| 303 { | 303 { |
| 304 CollectionVisitingTrait<HashMap<T, U, WTF::FastAllocator, V, W, X> >::vi
sit(this, map); | 304 OffHeapCollectionTraceTrait<HashMap<T, U, WTF::FastAllocator, V, W, X> >
::mark(this, map); |
| 305 } | 305 } |
| 306 | 306 |
| 307 // Fallback trace method for part objects to allow individual | 307 // Fallback trace method for part objects to allow individual |
| 308 // trace methods to trace through a part object with | 308 // trace methods to trace through a part object with |
| 309 // visitor->trace(m_partObject). | 309 // visitor->trace(m_partObject). |
| 310 template<typename T> | 310 template<typename T> |
| 311 void trace(const T& t) | 311 void trace(const T& t) |
| 312 { | 312 { |
| 313 const_cast<T&>(t).trace(this); | 313 const_cast<T&>(t).trace(this); |
| 314 } | 314 } |
| 315 | 315 |
| 316 // OwnPtrs that are traced are treated as part objects and the | 316 // OwnPtrs that are traced are treated as part objects and the |
| 317 // trace method of the owned object is called. | 317 // trace method of the owned object is called. |
| 318 template<typename T> | 318 template<typename T> |
| 319 void trace(const OwnPtr<T>& t) | 319 void trace(const OwnPtr<T>& t) |
| 320 { | 320 { |
| 321 t->trace(this); | 321 t->trace(this); |
| 322 } | 322 } |
| 323 | 323 |
| 324 // This method adds the object to the set of objects that should have their | 324 // This method adds the object to the set of objects that should have their |
| 325 // trace method called. Since not all objects have vtables we have to have | 325 // trace method called. Since not all objects have vtables we have to have |
| 326 // the callback as an explicit argument, but we can use the templated | 326 // the callback as an explicit argument, but we can use the templated |
| 327 // one-argument visit method above to automatically provide the callback | 327 // one-argument mark method above to automatically provide the callback |
| 328 // function. | 328 // function. |
| 329 virtual void visit(const void*, TraceCallback) = 0; | 329 virtual void mark(const void*, TraceCallback) = 0; |
| 330 | 330 |
| 331 // Used during conservative scanning. | 331 // Used during conservative scanning. |
| 332 virtual void visit(HeapObjectHeader*, TraceCallback) = 0; | 332 virtual void mark(HeapObjectHeader*, TraceCallback) = 0; |
| 333 virtual void visit(FinalizedHeapObjectHeader*, TraceCallback) = 0; | 333 virtual void mark(FinalizedHeapObjectHeader*, TraceCallback) = 0; |
| 334 | 334 |
| 335 // If the object calls this during the regular trace callback, then the | 335 // If the object calls this during the regular trace callback, then the |
| 336 // WeakPointerCallback argument may be called later, when the strong roots | 336 // WeakPointerCallback argument may be called later, when the strong roots |
| 337 // have all been found. The WeakPointerCallback will normally use isAlive | 337 // have all been found. The WeakPointerCallback will normally use isAlive |
| 338 // to find out whether some pointers are pointing to dying objects. When | 338 // to find out whether some pointers are pointing to dying objects. When |
| 339 // the WeakPointerCallback is done the object must have purged all pointers | 339 // the WeakPointerCallback is done the object must have purged all pointers |
| 340 // to objects where isAlive returned false. | 340 // to objects where isAlive returned false. |
| 341 virtual void registerWeakPointers(const void*, WeakPointerCallback) = 0; | 341 virtual void registerWeakPointers(const void*, WeakPointerCallback) = 0; |
| 342 | 342 |
| 343 template<typename T, void (T::*method)(Visitor*)> | 343 template<typename T, void (T::*method)(Visitor*)> |
| (...skipping 26 matching lines...) Expand all Loading... |
| 370 } | 370 } |
| 371 #endif | 371 #endif |
| 372 | 372 |
| 373 #ifndef NDEBUG | 373 #ifndef NDEBUG |
| 374 void checkTypeMarker(const void*, const char* marker); | 374 void checkTypeMarker(const void*, const char* marker); |
| 375 #endif | 375 #endif |
| 376 | 376 |
| 377 // Macro to declare methods needed for each typed heap. | 377 // Macro to declare methods needed for each typed heap. |
| 378 #define DECLARE_VISITOR_METHODS(Type) \ | 378 #define DECLARE_VISITOR_METHODS(Type) \ |
| 379 DEBUG_ONLY(void checkTypeMarker(const Type*, const char* marker);) \ | 379 DEBUG_ONLY(void checkTypeMarker(const Type*, const char* marker);) \ |
| 380 virtual void visit(const Type*, TraceCallback) = 0; \ | 380 virtual void mark(const Type*, TraceCallback) = 0; \ |
| 381 virtual bool isMarked(const Type*) = 0; | 381 virtual bool isMarked(const Type*) = 0; |
| 382 | 382 |
| 383 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) | 383 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) |
| 384 #undef DECLARE_VISITOR_METHODS | 384 #undef DECLARE_VISITOR_METHODS |
| 385 | 385 |
| 386 #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING | 386 #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING |
| 387 protected: | 387 protected: |
| 388 void* m_hostObject; | 388 void* m_hostObject; |
| 389 const char* m_hostName; | 389 const char* m_hostName; |
| 390 #endif | 390 #endif |
| 391 private: | 391 private: |
| 392 template<typename T> | 392 template<typename T> |
| 393 static void handleWeakCell(Visitor* self, void* obj) | 393 static void handleWeakCell(Visitor* self, void* obj) |
| 394 { | 394 { |
| 395 T** cell = reinterpret_cast<T**>(obj); | 395 T** cell = reinterpret_cast<T**>(obj); |
| 396 if (*cell && !self->isAlive(*cell)) | 396 if (*cell && !self->isAlive(*cell)) |
| 397 *cell = 0; | 397 *cell = 0; |
| 398 } | 398 } |
| 399 }; | 399 }; |
| 400 | 400 |
| 401 template<typename T, typename HashFunctions, typename Traits> | 401 template<typename T, typename HashFunctions, typename Traits> |
| 402 struct CollectionVisitingTrait<WTF::HashSet<T, WTF::FastAllocator, HashFunctions
, Traits> > { | 402 struct OffHeapCollectionTraceTrait<WTF::HashSet<T, WTF::FastAllocator, HashFunct
ions, Traits> > { |
| 403 typedef WTF::HashSet<T, WTF::FastAllocator, HashFunctions, Traits> HashSet; | 403 typedef WTF::HashSet<T, WTF::FastAllocator, HashFunctions, Traits> HashSet; |
| 404 | 404 |
| 405 static void visit(Visitor* v, const HashSet& set) | 405 static void mark(Visitor* v, const HashSet& set) |
| 406 { | 406 { |
| 407 if (set.isEmpty()) | 407 if (set.isEmpty()) |
| 408 return; | 408 return; |
| 409 if (WTF::NeedsVisiting<T>::value) { | 409 if (WTF::NeedsTracing<T>::value) { |
| 410 for (typename HashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) | 410 for (typename HashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) |
| 411 VisitCollectionBackingTrait<Traits::needsVisiting, Traits::isWea
k, false, T, Traits>::visit(v, *it); | 411 CollectionBackingTraceTrait<Traits::needsTracing, Traits::isWeak
, false, T, Traits>::mark(v, *it); |
| 412 } | 412 } |
| 413 if (Traits::isWeak) { | 413 if (Traits::isWeak) { |
| 414 if (!set.isEmpty()) | 414 if (!set.isEmpty()) |
| 415 v->registerWeakPointers(&set, processWeakOffHeapHashSet<T, HashF
unctions, Traits>); | 415 v->registerWeakPointers(&set, processWeakOffHeapHashSet<T, HashF
unctions, Traits>); |
| 416 } | 416 } |
| 417 } | 417 } |
| 418 }; | 418 }; |
| 419 | 419 |
| 420 template<typename T, size_t inlineCapacity, typename HashFunctions> | 420 template<typename T, size_t inlineCapacity, typename HashFunctions> |
| 421 struct CollectionVisitingTrait<WTF::ListHashSet<T, inlineCapacity, HashFunctions
> > { | 421 struct OffHeapCollectionTraceTrait<WTF::ListHashSet<T, inlineCapacity, HashFunct
ions> > { |
| 422 typedef WTF::ListHashSet<T, inlineCapacity, HashFunctions> ListHashSet; | 422 typedef WTF::ListHashSet<T, inlineCapacity, HashFunctions> ListHashSet; |
| 423 | 423 |
| 424 static void visit(Visitor* visitor, const ListHashSet& set) | 424 static void mark(Visitor* visitor, const ListHashSet& set) |
| 425 { | 425 { |
| 426 if (set.isEmpty()) | 426 if (set.isEmpty()) |
| 427 return; | 427 return; |
| 428 for (typename ListHashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) | 428 for (typename ListHashSet::const_iterator it = set.begin(), end = set.en
d(); it != end; ++it) |
| 429 visitor->trace(*it); | 429 visitor->trace(*it); |
| 430 } | 430 } |
| 431 }; | 431 }; |
| 432 | 432 |
| 433 template<typename Key, typename Value, typename HashFunctions, typename KeyTrait
s, typename ValueTraits> | 433 template<typename Key, typename Value, typename HashFunctions, typename KeyTrait
s, typename ValueTraits> |
| 434 struct CollectionVisitingTrait<WTF::HashMap<Key, Value, WTF::FastAllocator, Hash
Functions, KeyTraits, ValueTraits> > { | 434 struct OffHeapCollectionTraceTrait<WTF::HashMap<Key, Value, WTF::FastAllocator,
HashFunctions, KeyTraits, ValueTraits> > { |
| 435 typedef WTF::HashMap<Key, Value, WTF::FastAllocator, HashFunctions, KeyTrait
s, ValueTraits> HashMap; | 435 typedef WTF::HashMap<Key, Value, WTF::FastAllocator, HashFunctions, KeyTrait
s, ValueTraits> HashMap; |
| 436 | 436 |
| 437 static void visit(Visitor* v, const HashMap& map) | 437 static void mark(Visitor* v, const HashMap& map) |
| 438 { | 438 { |
| 439 if (map.isEmpty()) | 439 if (map.isEmpty()) |
| 440 return; | 440 return; |
| 441 if (WTF::NeedsVisiting<Key>::value || WTF::NeedsVisiting<Value>::value)
{ | 441 if (WTF::NeedsTracing<Key>::value || WTF::NeedsTracing<Value>::value) { |
| 442 for (typename HashMap::const_iterator it = map.begin(), end = map.en
d(); it != end; ++it) { | 442 for (typename HashMap::const_iterator it = map.begin(), end = map.en
d(); it != end; ++it) { |
| 443 VisitCollectionBackingTrait<KeyTraits::needsVisiting, KeyTraits:
:isWeak, false, Key, KeyTraits>::visit(v, it->key); | 443 CollectionBackingTraceTrait<KeyTraits::needsTracing, KeyTraits::
isWeak, false, Key, KeyTraits>::mark(v, it->key); |
| 444 VisitCollectionBackingTrait<ValueTraits::needsVisiting, ValueTra
its::isWeak, false, Value, ValueTraits>::visit(v, it->value); | 444 CollectionBackingTraceTrait<ValueTraits::needsTracing, ValueTrai
ts::isWeak, false, Value, ValueTraits>::mark(v, it->value); |
| 445 } | 445 } |
| 446 } | 446 } |
| 447 if (KeyTraits::isWeak || ValueTraits::isWeak) { | 447 if (KeyTraits::isWeak || ValueTraits::isWeak) { |
| 448 if (!map.isEmpty()) | 448 if (!map.isEmpty()) |
| 449 v->registerWeakPointers(&map, processWeakOffHeapHashMap<Key, Val
ue, HashFunctions, KeyTraits, ValueTraits>); | 449 v->registerWeakPointers(&map, processWeakOffHeapHashMap<Key, Val
ue, HashFunctions, KeyTraits, ValueTraits>); |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 }; | 452 }; |
| 453 | 453 |
| 454 #ifndef NDEBUG | 454 #ifndef NDEBUG |
| 455 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const
T* t) | 455 template<typename T> void TraceTrait<T>::checkTypeMarker(Visitor* visitor, const
T* t) |
| 456 { | 456 { |
| 457 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); | 457 visitor->checkTypeMarker(const_cast<T*>(t), getTypeMarker<T>()); |
| 458 } | 458 } |
| 459 #endif | 459 #endif |
| 460 | 460 |
| 461 template<typename T> void TraceTrait<T>::visit(Visitor* visitor, const T* t) | 461 template<typename T> void TraceTrait<T>::mark(Visitor* visitor, const T* t) |
| 462 { | 462 { |
| 463 // Default visit method of the trait just calls the two-argument visit | 463 // Default mark method of the trait just calls the two-argument mark |
| 464 // method on the visitor. The second argument is the static trace method | 464 // method on the visitor. The second argument is the static trace method |
| 465 // of the trait, which by default calls the instance method | 465 // of the trait, which by default calls the instance method |
| 466 // trace(Visitor*) on the object. | 466 // trace(Visitor*) on the object. |
| 467 visitor->visit(const_cast<T*>(t), &trace); | 467 visitor->mark(const_cast<T*>(t), &trace); |
| 468 } | 468 } |
| 469 | 469 |
| 470 inline void doNothingTrace(Visitor*, void*) | 470 inline void doNothingTrace(Visitor*, void*) |
| 471 { | 471 { |
| 472 } | 472 } |
| 473 | 473 |
| 474 template<typename T, typename Traits = WTF::VectorTraits<T> > | 474 template<typename T, typename Traits = WTF::VectorTraits<T> > |
| 475 class HeapVectorBacking; | 475 class HeapVectorBacking; |
| 476 template<typename Key, typename Value, typename Extractor, typename Traits, type
name KeyTraits> | 476 template<typename Key, typename Value, typename Extractor, typename Traits, type
name KeyTraits> |
| 477 class HeapHashTableBacking; | 477 class HeapHashTableBacking; |
| 478 | 478 |
| 479 // Non-class types like char don't have an trace method, so we provide a more | 479 // Non-class types like char don't have an trace method, so we provide a more |
| 480 // specialized template instantiation here that will be selected in preference | 480 // specialized template instantiation here that will be selected in preference |
| 481 // to the default. Most of them do nothing, since the type in question cannot | 481 // to the default. Most of them do nothing, since the type in question cannot |
| 482 // point to other heap allocated objects. | 482 // point to other heap allocated objects. |
| 483 #define ITERATE_DO_NOTHING_TYPES(f) \ | 483 #define ITERATE_DO_NOTHING_TYPES(f) \ |
| 484 f(uint8_t) \ | 484 f(uint8_t) \ |
| 485 f(void) | 485 f(void) |
| 486 | 486 |
| 487 #define DECLARE_DO_NOTHING_TRAIT(type) \ | 487 #define DECLARE_DO_NOTHING_TRAIT(type) \ |
| 488 template<> \ | 488 template<> \ |
| 489 class TraceTrait<type> { \ | 489 class TraceTrait<type> { \ |
| 490 public: \ | 490 public: \ |
| 491 static void checkTypeMarker(Visitor*, const void*) { } \ | 491 static void checkTypeMarker(Visitor*, const void*) { } \ |
| 492 static void visit(Visitor* v, const type* p) { \ | 492 static void mark(Visitor* v, const type* p) { \ |
| 493 v->visit(p, nullptr); \ | 493 v->mark(p, nullptr); \ |
| 494 } \ | 494 } \ |
| 495 }; \ | 495 }; \ |
| 496 template<> \ | 496 template<> \ |
| 497 struct FinalizerTrait<type> { \ | 497 struct FinalizerTrait<type> { \ |
| 498 static void finalize(void*) { } \ | 498 static void finalize(void*) { } \ |
| 499 static const bool nonTrivialFinalizer = false; \ | 499 static const bool nonTrivialFinalizer = false; \ |
| 500 }; \ | 500 }; \ |
| 501 template<> \ | 501 template<> \ |
| 502 struct GCInfoTrait<type> { \ | 502 struct GCInfoTrait<type> { \ |
| 503 static const GCInfo* get() \ | 503 static const GCInfo* get() \ |
| 504 { \ | 504 { \ |
| 505 return &info; \ | 505 return &info; \ |
| 506 } \ | 506 } \ |
| 507 static const GCInfo info; \ | 507 static const GCInfo info; \ |
| 508 }; | 508 }; |
| 509 | 509 |
| 510 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) | 510 ITERATE_DO_NOTHING_TYPES(DECLARE_DO_NOTHING_TRAIT) |
| 511 | 511 |
| 512 #undef DECLARE_DO_NOTHING_TRAIT | 512 #undef DECLARE_DO_NOTHING_TRAIT |
| 513 | 513 |
| 514 // Vectors are simple collections, and it's possible to visit vectors in a more | 514 // Vectors are simple collections, and it's possible to mark vectors in a more |
| 515 // general way so that collections of objects (not pointers to objects) can be | 515 // general way so that collections of objects (not pointers to objects) can be |
| 516 // visited. | 516 // marked. |
| 517 template<typename T, size_t N> | 517 template<typename T, size_t N> |
| 518 struct CollectionVisitingTrait<WTF::Vector<T, N, WTF::FastAllocator> > { | 518 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::FastAllocator> > { |
| 519 typedef WTF::Vector<T, N, WTF::FastAllocator> Vector; | 519 typedef WTF::Vector<T, N, WTF::FastAllocator> Vector; |
| 520 | 520 |
| 521 static void visit(Visitor* v, const Vector& vector) | 521 static void mark(Visitor* v, const Vector& vector) |
| 522 { | 522 { |
| 523 if (vector.isEmpty()) | 523 if (vector.isEmpty()) |
| 524 return; | 524 return; |
| 525 for (typename Vector::const_iterator it = vector.begin(), end = vector.e
nd(); it != end; ++it) | 525 for (typename Vector::const_iterator it = vector.begin(), end = vector.e
nd(); it != end; ++it) |
| 526 TraceTrait<T>::trace(v, const_cast<T*>(it)); | 526 TraceTrait<T>::trace(v, const_cast<T*>(it)); |
| 527 } | 527 } |
| 528 }; | 528 }; |
| 529 | 529 |
| 530 // Fallback definition. | 530 // Fallback definition. |
| 531 template<typename Collection> void CollectionVisitingTrait<Collection>::visit(Vi
sitor* visitor, const Collection& collection) | 531 template<typename Collection> void OffHeapCollectionTraceTrait<Collection>::mark
(Visitor* visitor, const Collection& collection) |
| 532 { | 532 { |
| 533 if (collection.isEmpty()) | 533 if (collection.isEmpty()) |
| 534 return; | 534 return; |
| 535 for (typename Collection::const_iterator it = collection.begin(), end = coll
ection.end(); it != end; ++it) | 535 for (typename Collection::const_iterator it = collection.begin(), end = coll
ection.end(); it != end; ++it) |
| 536 visitor->trace(*it); | 536 visitor->trace(*it); |
| 537 } | 537 } |
| 538 | 538 |
| 539 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj) | 539 template<typename T> bool ObjectAliveTrait<T>::isAlive(Visitor* visitor, T obj) |
| 540 { | 540 { |
| 541 return visitor->isMarked(obj); | 541 return visitor->isMarked(obj); |
| 542 } | 542 } |
| 543 | 543 |
| 544 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor
, const Member<T>& obj) | 544 template<typename T> bool ObjectAliveTrait<Member<T> >::isAlive(Visitor* visitor
, const Member<T>& obj) |
| 545 { | 545 { |
| 546 return visitor->isMarked(obj.raw()); | 546 return visitor->isMarked(obj.raw()); |
| 547 } | 547 } |
| 548 | 548 |
| 549 class HeapVisitable { | 549 class HeapVisitable { |
| 550 public: | 550 public: |
| 551 virtual void trace(Visitor*) = 0; | 551 virtual void trace(Visitor*) = 0; |
| 552 virtual ~HeapVisitable() | 552 virtual ~HeapVisitable() |
| 553 { | 553 { |
| 554 } | 554 } |
| 555 }; | 555 }; |
| 556 | 556 |
| 557 } | 557 } |
| 558 #endif | 558 #endif |
| OLD | NEW |