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 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 #undef DECLARE_VISITOR_METHODS | 504 #undef DECLARE_VISITOR_METHODS |
505 | 505 |
506 #if ENABLE(GC_PROFILE_MARKING) | 506 #if ENABLE(GC_PROFILE_MARKING) |
507 void setHostInfo(void* object, const String& name) | 507 void setHostInfo(void* object, const String& name) |
508 { | 508 { |
509 m_hostObject = object; | 509 m_hostObject = object; |
510 m_hostName = name; | 510 m_hostName = name; |
511 } | 511 } |
512 #endif | 512 #endif |
513 | 513 |
| 514 inline bool canTraceEagerly() const { return m_traceDepth < kMaxEagerTraceDe
pth; } |
| 515 inline void incrementTraceDepth() { m_traceDepth++; } |
| 516 inline void decrementTraceDepth() { ASSERT(m_traceDepth > 0); m_traceDepth--
; } |
| 517 |
514 protected: | 518 protected: |
| 519 Visitor() |
| 520 : m_traceDepth(0) |
| 521 { |
| 522 } |
| 523 |
515 virtual void registerWeakCell(void**, WeakPointerCallback) = 0; | 524 virtual void registerWeakCell(void**, WeakPointerCallback) = 0; |
516 #if ENABLE(GC_PROFILE_MARKING) | 525 #if ENABLE(GC_PROFILE_MARKING) |
517 void* m_hostObject; | 526 void* m_hostObject; |
518 String m_hostName; | 527 String m_hostName; |
519 #endif | 528 #endif |
520 | 529 |
521 private: | 530 private: |
522 template<typename T> | 531 template<typename T> |
523 static void handleWeakCell(Visitor* self, void* obj) | 532 static void handleWeakCell(Visitor* self, void* obj) |
524 { | 533 { |
525 T** cell = reinterpret_cast<T**>(obj); | 534 T** cell = reinterpret_cast<T**>(obj); |
526 if (*cell && !self->isAlive(*cell)) | 535 if (*cell && !self->isAlive(*cell)) |
527 *cell = 0; | 536 *cell = 0; |
528 } | 537 } |
| 538 |
| 539 // The maximum depth of eager, unrolled trace() calls that is |
| 540 // considered safe and allowed. |
| 541 const int kMaxEagerTraceDepth = 100; |
| 542 |
| 543 int m_traceDepth; |
529 }; | 544 }; |
530 | 545 |
531 // We trace vectors by using the trace trait on each element, which means you | 546 // We trace vectors by using the trace trait on each element, which means you |
532 // can have vectors of general objects (not just pointers to objects) that can | 547 // can have vectors of general objects (not just pointers to objects) that can |
533 // be traced. | 548 // be traced. |
534 template<typename T, size_t N> | 549 template<typename T, size_t N> |
535 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > { | 550 struct OffHeapCollectionTraceTrait<WTF::Vector<T, N, WTF::DefaultAllocator> > { |
536 typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector; | 551 typedef WTF::Vector<T, N, WTF::DefaultAllocator> Vector; |
537 | 552 |
538 static void trace(Visitor* visitor, const Vector& vector) | 553 static void trace(Visitor* visitor, const Vector& vector) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 static void mark(Visitor* visitor, const T* t) | 587 static void mark(Visitor* visitor, const T* t) |
573 { | 588 { |
574 // Default mark method of the trait just calls the two-argument mark | 589 // Default mark method of the trait just calls the two-argument mark |
575 // method on the visitor. The second argument is the static trace method | 590 // method on the visitor. The second argument is the static trace method |
576 // of the trait, which by default calls the instance method | 591 // of the trait, which by default calls the instance method |
577 // trace(Visitor*) on the object. | 592 // trace(Visitor*) on the object. |
578 // | 593 // |
579 // If the trait allows it, invoke the trace callback right here on the | 594 // If the trait allows it, invoke the trace callback right here on the |
580 // not-yet-marked object. | 595 // not-yet-marked object. |
581 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<T>::value) { | 596 if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<T>::value) { |
582 if (visitor->ensureMarked(t)) | 597 // Protect against too deep trace call chains, and the |
583 TraceTrait<T>::trace(visitor, const_cast<T*>(t)); | 598 // unbounded system stack usage they can bring about. |
584 return; | 599 // |
| 600 // Assert against deep stacks so as to flush them out, |
| 601 // but test and appropriately handle them should they occur |
| 602 // in release builds. |
| 603 ASSERT(visitor->canTraceEagerly()); |
| 604 if (LIKELY(visitor->canTraceEagerly())) { |
| 605 if (visitor->ensureMarked(t)) { |
| 606 visitor->incrementTraceDepth(); |
| 607 TraceTrait<T>::trace(visitor, const_cast<T*>(t)); |
| 608 visitor->decrementTraceDepth(); |
| 609 } |
| 610 return; |
| 611 } |
585 } | 612 } |
586 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); | 613 visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); |
587 } | 614 } |
588 | 615 |
589 #if ENABLE(ASSERT) | 616 #if ENABLE(ASSERT) |
590 static void checkGCInfo(Visitor* visitor, const T* t) | 617 static void checkGCInfo(Visitor* visitor, const T* t) |
591 { | 618 { |
592 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); | 619 visitor->checkGCInfo(const_cast<T*>(t), GCInfoTrait<T>::get()); |
593 } | 620 } |
594 #endif | 621 #endif |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 struct GCInfoTrait { | 768 struct GCInfoTrait { |
742 static const GCInfo* get() | 769 static const GCInfo* get() |
743 { | 770 { |
744 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); | 771 return GCInfoAtBase<typename GetGarbageCollectedBase<T>::type>::get(); |
745 } | 772 } |
746 }; | 773 }; |
747 | 774 |
748 } | 775 } |
749 | 776 |
750 #endif | 777 #endif |
OLD | NEW |