File tree Expand file tree Collapse file tree 1 file changed +19
-0
lines changed Expand file tree Collapse file tree 1 file changed +19
-0
lines changed Original file line number Diff line number Diff line change 21
21
#include " llvm/ADT/IntrusiveRefCntPtr.h"
22
22
#include " llvm/ADT/SmallPtrSet.h"
23
23
#include " llvm/Support/Allocator.h"
24
+ #include " llvm/ADT/STLExtras.h"
25
+ #include < set>
24
26
25
27
namespace swift {
26
28
namespace syntax {
@@ -68,9 +70,26 @@ class SyntaxArena : public llvm::ThreadSafeRefCountedBase<SyntaxArena> {
68
70
auto DidInsert = ChildArenas.insert (Arena);
69
71
if (DidInsert.second ) {
70
72
Arena->Retain ();
73
+ assert (!Arena->containsReferenceCycle ({this }));
71
74
}
72
75
}
73
76
77
+ #ifndef NDEBUG
78
+ // / Check if there are any reference cycles in the child arenas. This is done
79
+ // / by walking all child nodes from a root node, collecting all visited nodes
80
+ // / in \p VisitedArenas. If we find a node twice, there's a reference cycle.
81
+ bool
82
+ containsReferenceCycle (std::set<const SyntaxArena *> VisitedArenas = {}) const {
83
+ if (!VisitedArenas.insert (this ).second ) {
84
+ // this was already in VisitedArenas -> we have a reference cycle
85
+ return true ;
86
+ }
87
+ return llvm::any_of (ChildArenas, [&](const SyntaxArena *Child) {
88
+ return Child->containsReferenceCycle (VisitedArenas);
89
+ });
90
+ }
91
+ #endif
92
+
74
93
void setHotUseMemoryRegion (const void *Start, const void *End) {
75
94
assert (containsPointer (Start) &&
76
95
" The hot use memory region should be in the Arena's bump allocator" );
You can’t perform that action at this time.
0 commit comments