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); |
} |