| 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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 // needed is when multiple inheritance leads to pointers that are not | 162 // needed is when multiple inheritance leads to pointers that are not |
| 163 // to the start of the object in the Blink garbage-collected heap. In | 163 // to the start of the object in the Blink garbage-collected heap. In |
| 164 // that case the pointer has to be adjusted before marking. | 164 // that case the pointer has to be adjusted before marking. |
| 165 template<typename T> | 165 template<typename T> |
| 166 class TraceTrait { | 166 class TraceTrait { |
| 167 public: | 167 public: |
| 168 // Default implementation of TraceTrait<T>::trace just statically | 168 // Default implementation of TraceTrait<T>::trace just statically |
| 169 // dispatches to the trace method of the class T. | 169 // dispatches to the trace method of the class T. |
| 170 static void trace(Visitor* visitor, void* self) | 170 static void trace(Visitor* visitor, void* self) |
| 171 { | 171 { |
| 172 static_cast<T*>(self)->trace(visitor); | |
| 173 } | 172 } |
| 174 | 173 |
| 175 static void mark(Visitor* visitor, const T* t) | 174 static void mark(Visitor* visitor, const T* t) |
| 176 { | 175 { |
| 177 DefaultTraceTrait<T>::mark(visitor, t); | |
| 178 } | 176 } |
| 179 | |
| 180 #if ENABLE(ASSERT) | |
| 181 static void checkGCInfo(Visitor* visitor, const T* t) | |
| 182 { | |
| 183 DefaultTraceTrait<T>::checkGCInfo(visitor, t); | |
| 184 } | |
| 185 #endif | |
| 186 }; | 177 }; |
| 187 | 178 |
| 188 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; | 179 template<typename T> class TraceTrait<const T> : public TraceTrait<T> { }; |
| 189 | 180 |
| 190 template<typename Collection> | 181 template<typename Collection> |
| 191 struct OffHeapCollectionTraceTrait; | 182 struct OffHeapCollectionTraceTrait; |
| 192 | 183 |
| 193 template<typename T> | 184 template<typename T> |
| 194 struct ObjectAliveTrait { | 185 struct ObjectAliveTrait { |
| 195 static bool isAlive(Visitor*, T*); | 186 static bool isAlive(Visitor*, T*); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 209 virtual ~Visitor() { } | 200 virtual ~Visitor() { } |
| 210 | 201 |
| 211 template<typename T> | 202 template<typename T> |
| 212 static void verifyGarbageCollectedIfMember(T*) | 203 static void verifyGarbageCollectedIfMember(T*) |
| 213 { | 204 { |
| 214 } | 205 } |
| 215 | 206 |
| 216 template<typename T> | 207 template<typename T> |
| 217 static void verifyGarbageCollectedIfMember(Member<T>* t) | 208 static void verifyGarbageCollectedIfMember(Member<T>* t) |
| 218 { | 209 { |
| 219 t->verifyTypeIsGarbageCollected(); | |
| 220 } | 210 } |
| 221 | 211 |
| 222 // One-argument templated mark method. This uses the static type of | 212 // One-argument templated mark method. This uses the static type of |
| 223 // the argument to get the TraceTrait. By default, the mark method | 213 // the argument to get the TraceTrait. By default, the mark method |
| 224 // of the TraceTrait just calls the virtual two-argument mark method on this | 214 // of the TraceTrait just calls the virtual two-argument mark method on this |
| 225 // visitor, where the second argument is the static trace method of the trai
t. | 215 // visitor, where the second argument is the static trace method of the trai
t. |
| 226 template<typename T> | 216 template<typename T> |
| 227 void mark(T* t) | 217 void mark(T* t) |
| 228 { | 218 { |
| 229 if (!t) | |
| 230 return; | |
| 231 #if ENABLE(ASSERT) | |
| 232 TraceTrait<T>::checkGCInfo(this, t); | |
| 233 #endif | |
| 234 TraceTrait<T>::mark(this, t); | |
| 235 | |
| 236 reinterpret_cast<const Member<T>*>(0)->verifyTypeIsGarbageCollected(); | |
| 237 } | 219 } |
| 238 | 220 |
| 239 // Member version of the one-argument templated trace method. | 221 // Member version of the one-argument templated trace method. |
| 240 template<typename T> | 222 template<typename T> |
| 241 void trace(const Member<T>& t) | 223 void trace(const Member<T>& t) |
| 242 { | 224 { |
| 243 mark(t.get()); | |
| 244 } | 225 } |
| 245 | 226 |
| 246 // Fallback method used only when we need to trace raw pointers of T. | 227 // Fallback method used only when we need to trace raw pointers of T. |
| 247 // This is the case when a member is a union where we do not support members
. | 228 // This is the case when a member is a union where we do not support members
. |
| 248 template<typename T> | 229 template<typename T> |
| 249 void trace(const T* t) | 230 void trace(const T* t) |
| 250 { | 231 { |
| 251 mark(const_cast<T*>(t)); | |
| 252 } | 232 } |
| 253 | 233 |
| 254 template<typename T> | 234 template<typename T> |
| 255 void trace(T* t) | 235 void trace(T* t) |
| 256 { | 236 { |
| 257 mark(t); | |
| 258 } | 237 } |
| 259 | 238 |
| 260 // WeakMember version of the templated trace method. It doesn't keep | 239 // WeakMember version of the templated trace method. It doesn't keep |
| 261 // the traced thing alive, but will write null to the WeakMember later | 240 // the traced thing alive, but will write null to the WeakMember later |
| 262 // if the pointed-to object is dead. It's lying for this to be const, | 241 // if the pointed-to object is dead. It's lying for this to be const, |
| 263 // but the overloading resolver prioritizes constness too high when | 242 // but the overloading resolver prioritizes constness too high when |
| 264 // picking the correct overload, so all these trace methods have to have | 243 // picking the correct overload, so all these trace methods have to have |
| 265 // the same constness on their argument to allow the type to decide. | 244 // the same constness on their argument to allow the type to decide. |
| 266 template<typename T> | 245 template<typename T> |
| 267 void trace(const WeakMember<T>& t) | 246 void trace(const WeakMember<T>& t) |
| 268 { | 247 { |
| 269 // Check that we actually know the definition of T when tracing. | |
| 270 COMPILE_ASSERT(sizeof(T), WeNeedToKnowTheDefinitionOfTheTypeWeAreTracing
); | |
| 271 registerWeakCell(const_cast<WeakMember<T>&>(t).cell()); | |
| 272 reinterpret_cast<const Member<T>*>(0)->verifyTypeIsGarbageCollected(); | |
| 273 } | 248 } |
| 274 | 249 |
| 275 template<typename T> | 250 template<typename T> |
| 276 void traceInCollection(T& t, WTF::ShouldWeakPointersBeMarkedStrongly strongi
fy) | 251 void traceInCollection(T& t, WTF::ShouldWeakPointersBeMarkedStrongly strongi
fy) |
| 277 { | 252 { |
| 278 HashTraits<T>::traceInCollection(this, t, strongify); | |
| 279 } | 253 } |
| 280 | 254 |
| 281 // Fallback trace method for part objects to allow individual trace methods | 255 // Fallback trace method for part objects to allow individual trace methods |
| 282 // to trace through a part object with visitor->trace(m_partObject). This | 256 // to trace through a part object with visitor->trace(m_partObject). This |
| 283 // takes a const argument, because otherwise it will match too eagerly: a | 257 // takes a const argument, because otherwise it will match too eagerly: a |
| 284 // non-const argument would match a non-const Vector<T>& argument better | 258 // non-const argument would match a non-const Vector<T>& argument better |
| 285 // than the specialization that takes const Vector<T>&. For a similar reason
, | 259 // than the specialization that takes const Vector<T>&. For a similar reason
, |
| 286 // the other specializations take a const argument even though they are | 260 // the other specializations take a const argument even though they are |
| 287 // usually used with non-const arguments, otherwise this function would matc
h | 261 // usually used with non-const arguments, otherwise this function would matc
h |
| 288 // too well. | 262 // too well. |
| 289 template<typename T> | 263 template<typename T> |
| 290 void trace(const T& t) | 264 void trace(const T& t) |
| 291 { | 265 { |
| 292 if (WTF::IsPolymorphic<T>::value) { | |
| 293 intptr_t vtable = *reinterpret_cast<const intptr_t*>(&t); | |
| 294 if (!vtable) | |
| 295 return; | |
| 296 } | |
| 297 const_cast<T&>(t).trace(this); | |
| 298 } | 266 } |
| 299 | 267 |
| 300 // The following trace methods are for off-heap collections. | 268 // The following trace methods are for off-heap collections. |
| 301 template<typename T, size_t inlineCapacity> | 269 template<typename T, size_t inlineCapacity> |
| 302 void trace(const Vector<T, inlineCapacity>& vector) | 270 void trace(const Vector<T, inlineCapacity>& vector) |
| 303 { | 271 { |
| 304 OffHeapCollectionTraceTrait<Vector<T, inlineCapacity, WTF::DefaultAlloca
tor> >::trace(this, vector); | |
| 305 } | 272 } |
| 306 | 273 |
| 307 template<typename T, size_t N> | 274 template<typename T, size_t N> |
| 308 void trace(const Deque<T, N>& deque) | 275 void trace(const Deque<T, N>& deque) |
| 309 { | 276 { |
| 310 OffHeapCollectionTraceTrait<Deque<T, N> >::trace(this, deque); | |
| 311 } | 277 } |
| 312 | 278 |
| 313 #if !ENABLE(OILPAN) | 279 #if !ENABLE(OILPAN) |
| 314 // These trace methods are needed to allow compiling and calling trace on | 280 // These trace methods are needed to allow compiling and calling trace on |
| 315 // transition types. We need to support calls in the non-oilpan build | 281 // transition types. We need to support calls in the non-oilpan build |
| 316 // because a fully transitioned type (which will have its trace method | 282 // because a fully transitioned type (which will have its trace method |
| 317 // called) might trace a field that is in transition. Once transition types | 283 // called) might trace a field that is in transition. Once transition types |
| 318 // are removed these can be removed. | 284 // are removed these can be removed. |
| 319 template<typename T> void trace(const OwnPtr<T>&) { } | 285 template<typename T> void trace(const OwnPtr<T>&) { } |
| 320 template<typename T> void trace(const RefPtr<T>&) { } | 286 template<typename T> void trace(const RefPtr<T>&) { } |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 } | 376 } |
| 411 template<typename T> inline bool isAlive(const Member<T>& member) | 377 template<typename T> inline bool isAlive(const Member<T>& member) |
| 412 { | 378 { |
| 413 return isAlive(member.get()); | 379 return isAlive(member.get()); |
| 414 } | 380 } |
| 415 template<typename T> inline bool isAlive(RawPtr<T> ptr) | 381 template<typename T> inline bool isAlive(RawPtr<T> ptr) |
| 416 { | 382 { |
| 417 return isAlive(ptr.get()); | 383 return isAlive(ptr.get()); |
| 418 } | 384 } |
| 419 | 385 |
| 420 #if ENABLE(ASSERT) | |
| 421 void checkGCInfo(const void*, const GCInfo*); | |
| 422 #endif | |
| 423 | |
| 424 // Macro to declare methods needed for each typed heap. | 386 // Macro to declare methods needed for each typed heap. |
| 425 #define DECLARE_VISITOR_METHODS(Type) \ | 387 #define DECLARE_VISITOR_METHODS(Type) \ |
| 426 DEBUG_ONLY(void checkGCInfo(const Type*, const GCInfo*);) \ | |
| 427 virtual void mark(const Type*, TraceCallback) = 0; \ | 388 virtual void mark(const Type*, TraceCallback) = 0; \ |
| 428 virtual bool isMarked(const Type*) = 0; | 389 virtual bool isMarked(const Type*) = 0; |
| 429 | 390 |
| 430 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) | 391 FOR_EACH_TYPED_HEAP(DECLARE_VISITOR_METHODS) |
| 431 #undef DECLARE_VISITOR_METHODS | 392 #undef DECLARE_VISITOR_METHODS |
| 432 | 393 |
| 433 #if ENABLE(GC_PROFILE_MARKING) | 394 #if ENABLE(GC_PROFILE_MARKING) |
| 434 void setHostInfo(void* object, const String& name) | 395 void setHostInfo(void* object, const String& name) |
| 435 { | 396 { |
| 436 m_hostObject = object; | 397 m_hostObject = object; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 457 | 418 |
| 458 // We trace vectors by using the trace trait on each element, which means you | 419 // We trace vectors by using the trace trait on each element, which means you |
| 459 // can have vectors of general objects (not just pointers to objects) that can | 420 // can have vectors of general objects (not just pointers to objects) that can |
| 460 // be traced. | 421 // be traced. |
| 461 template<typename T, size_t N> | 422 template<typename T, size_t N> |
| 462 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > { | 423 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > { |
| 463 typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector; | 424 typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector; |
| 464 | 425 |
| 465 static void trace(Visitor* visitor, const Vector& vector) | 426 static void trace(Visitor* visitor, const Vector& vector) |
| 466 { | 427 { |
| 467 if (vector.isEmpty()) | |
| 468 return; | |
| 469 for (typename Vector::const_iterator it = vector.begin(), end = vector.e
nd(); it != end; ++it) | |
| 470 TraceTrait<T>::trace(visitor, const_cast<T*>(it)); | |
| 471 } | 428 } |
| 472 }; | 429 }; |
| 473 | 430 |
| 474 template<typename T, size_t N> | 431 template<typename T, size_t N> |
| 475 struct OffHeapCollectionTraceTrait<WTF::Deque<T, N> > { | 432 struct OffHeapCollectionTraceTrait<WTF::Deque<T, N> > { |
| 476 typedef WTF::Deque<T, N> Deque; | 433 typedef WTF::Deque<T, N> Deque; |
| 477 | 434 |
| 478 static void trace(Visitor* visitor, const Deque& deque) | 435 static void trace(Visitor* visitor, const Deque& deque) |
| 479 { | 436 { |
| 480 if (deque.isEmpty()) | |
| 481 return; | |
| 482 for (typename Deque::const_iterator it = deque.begin(), end = deque.end(
); it != end; ++it) | |
| 483 TraceTrait<T>::trace(visitor, const_cast<T*>(&(*it))); | |
| 484 } | 437 } |
| 485 }; | 438 }; |
| 486 | 439 |
| 487 template<typename T, typename Traits = WTF::VectorTraits<T> > | 440 template<typename T, typename Traits = WTF::VectorTraits<T> > |
| 488 class HeapVectorBacking; | 441 class HeapVectorBacking; |
| 489 | 442 |
| 490 template<typename Table> | 443 template<typename Table> |
| 491 class HeapHashTableBacking { | 444 class HeapHashTableBacking { |
| 492 public: | 445 public: |
| 493 static void finalize(void* pointer); | 446 static void finalize(void* pointer); |
| 494 }; | 447 }; |
| 495 | 448 |
| 496 template<typename T> | 449 template<typename T> |
| 497 class DefaultTraceTrait<T, false> { | 450 class DefaultTraceTrait<T, false> { |
| 498 public: | 451 public: |
| 499 static void mark(Visitor* visitor, const T* t) | 452 static void mark(Visitor* visitor, const T* t) |
| 500 { | 453 { |
| 501 // Default mark method of the trait just calls the two-argument mark | |
| 502 // method on the visitor. The second argument is the static trace method | |
| 503 // of the trait, which by default calls the instance method | |
| 504 // trace(Visitor*) on the object. | |
| 505 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); | |
| 506 } | 454 } |
| 507 | |
| 508 #if ENABLE(ASSERT) | |
| 509 static void checkGCInfo(Visitor* visitor, const T* t) | |
| 510 { | |
| 511 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); | |
| 512 } | |
| 513 #endif | |
| 514 }; | 455 }; |
| 515 | 456 |
| 516 template<typename T> | 457 template<typename T> |
| 517 class DefaultTraceTrait<T, true> { | 458 class DefaultTraceTrait<T, true> { |
| 518 public: | 459 public: |
| 519 static void mark(Visitor* visitor, const T* self) | 460 static void mark(Visitor* visitor, const T* self) |
| 520 { | 461 { |
| 521 if (!self) | 462 if (!self) |
| 522 return; | 463 return; |
| 523 | 464 |
| 524 // Before doing adjustAndMark we need to check if the page is orphaned | 465 // Before doing adjustAndMark we need to check if the page is orphaned |
| 525 // since we cannot call adjustAndMark if so, as there will be no vtable. | 466 // since we cannot call adjustAndMark if so, as there will be no vtable. |
| 526 // If orphaned just mark the page as traced. | 467 // If orphaned just mark the page as traced. |
| 527 BaseHeapPage* heapPage = pageHeaderFromObject(self); | 468 BaseHeapPage* heapPage = pageHeaderFromObject(self); |
| 528 if (heapPage->orphaned()) { | 469 if (heapPage->orphaned()) { |
| 529 heapPage->setTracedAfterOrphaned(); | 470 heapPage->setTracedAfterOrphaned(); |
| 530 return; | 471 return; |
| 531 } | 472 } |
| 532 self->adjustAndMark(visitor); | 473 self->adjustAndMark(visitor); |
| 533 } | 474 } |
| 534 | |
| 535 #if ENABLE(ASSERT) | |
| 536 static void checkGCInfo(Visitor*, const T*) { } | |
| 537 #endif | |
| 538 }; | 475 }; |
| 539 | 476 |
| 540 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultObjectAli
veTrait; | 477 template<typename T, bool = NeedsAdjustAndMark<T>::value> class DefaultObjectAli
veTrait; |
| 541 | 478 |
| 542 template<typename T> | 479 template<typename T> |
| 543 class DefaultObjectAliveTrait<T, false> { | 480 class DefaultObjectAliveTrait<T, false> { |
| 544 public: | 481 public: |
| 545 static bool isAlive(Visitor* visitor, T* obj) | 482 static bool isAlive(Visitor* visitor, T* obj) |
| 546 { | 483 { |
| 547 return visitor->isMarked(obj); | 484 return visitor->isMarked(obj); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 struct GCInfoTrait { | 592 struct GCInfoTrait { |
| 656 static const GCInfo* get() | 593 static const GCInfo* get() |
| 657 { | 594 { |
| 658 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); | 595 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); |
| 659 } | 596 } |
| 660 }; | 597 }; |
| 661 | 598 |
| 662 } | 599 } |
| 663 | 600 |
| 664 #endif | 601 #endif |
| OLD | NEW |