Chromium Code Reviews| Index: Source/platform/heap/Visitor.h |
| diff --git a/Source/platform/heap/Visitor.h b/Source/platform/heap/Visitor.h |
| index 096e228b24c36ddad88f7c7d331af50d573d30cf..0a7f5456fb38d6cacd9d3a7141fb9ca67f5f41fe 100644 |
| --- a/Source/platform/heap/Visitor.h |
| +++ b/Source/platform/heap/Visitor.h |
| @@ -512,6 +512,11 @@ public: |
| #endif |
| protected: |
| + Visitor() |
| + : m_traceDepth(0) |
| + { |
| + } |
| + |
| virtual void registerWeakCell(void**, WeakPointerCallback) = 0; |
| #if ENABLE(GC_PROFILE_MARKING) |
| void* m_hostObject; |
| @@ -526,6 +531,18 @@ private: |
| if (*cell && !self->isAlive(*cell)) |
| *cell = 0; |
| } |
| + |
| + // The maximum depth of eager, unrolled trace() calls that is |
|
haraken
2014/12/04 15:45:09
is => are
sof
2014/12/04 20:15:44
The maximum depth ... is
|
| + // considered safe and allowed. |
| + const int kMaxEagerTraceDepth = 100; |
| + |
| + template<typename U, bool>friend class DefaultTraceTrait; |
|
haraken
2014/12/04 15:45:09
Add one space after '>'
sof
2014/12/04 20:15:44
Done.
|
| + |
| + inline bool canTraceEagerly() const { return m_traceDepth < kMaxEagerTraceDepth; } |
| + inline void incTraceDepth() { m_traceDepth++; } |
|
haraken
2014/12/04 15:45:09
incrementTraceDepth
sof
2014/12/04 20:15:43
Done.
|
| + inline void decTraceDepth() { ASSERT(m_traceDepth > 0); m_traceDepth--; } |
|
haraken
2014/12/04 15:45:09
decrementTraceDepth
sof
2014/12/04 20:15:44
Done.
|
| + |
| + int m_traceDepth; |
| }; |
| // We trace vectors by using the trace trait on each element, which means you |
| @@ -579,9 +596,21 @@ public: |
| // If the trait allows it, invoke the trace callback right here on the |
| // not-yet-marked object. |
| if (!DISABLE_ALL_EAGER_TRACING && TraceEagerlyTrait<T>::value) { |
| - if (visitor->ensureMarked(t)) |
| - TraceTrait<T>::trace(visitor, const_cast<T*>(t)); |
| - return; |
| + // Protect against too deep trace call chains, and the |
| + // unbounded system stack usage they can bring about. |
| + // |
| + // Assert against deep stacks so as to flush them out, |
| + // but test and appropriately handle them should they occur |
| + // in release builds. |
| + ASSERT(visitor->canTraceEagerly()); |
| + if (visitor->canTraceEagerly()) { |
|
haraken
2014/12/04 15:45:09
LIKELY just in case? Not sure.
sof
2014/12/04 20:15:44
Good idea; I had that when initially evaluating th
|
| + if (visitor->ensureMarked(t)) { |
| + visitor->incTraceDepth(); |
| + TraceTrait<T>::trace(visitor, const_cast<T*>(t)); |
| + visitor->decTraceDepth(); |
| + } |
| + return; |
| + } |
| } |
| visitor->mark(const_cast<T*>(t), &TraceTrait<T>::trace); |
| } |