Remove linux_chromium_gn_dbg from the chromium CQ.
[chromium-blink-merge.git] / tools / clang / blink_gc_plugin / Edge.h
blobeca3158d75f925e1b7430991838ad4bea890c058
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef TOOLS_BLINK_GC_PLUGIN_EDGE_H_
6 #define TOOLS_BLINK_GC_PLUGIN_EDGE_H_
8 #include <cassert>
9 #include <deque>
10 #include <vector>
12 #include "TracingStatus.h"
14 class RecordInfo;
16 class Edge;
17 class Value;
18 class RawPtr;
19 class RefPtr;
20 class OwnPtr;
21 class Member;
22 class WeakMember;
23 class Persistent;
24 class Collection;
26 // Bare-bones visitor.
27 class EdgeVisitor {
28 public:
29 virtual ~EdgeVisitor() {}
30 virtual void VisitValue(Value*) {}
31 virtual void VisitRawPtr(RawPtr*) {}
32 virtual void VisitRefPtr(RefPtr*) {}
33 virtual void VisitOwnPtr(OwnPtr*) {}
34 virtual void VisitMember(Member*) {}
35 virtual void VisitWeakMember(WeakMember*) {}
36 virtual void VisitPersistent(Persistent*) {}
37 virtual void VisitCollection(Collection*) {}
40 // Recursive edge visitor. The traversed path is accessible in context.
41 class RecursiveEdgeVisitor : public EdgeVisitor {
42 public:
43 // Overrides that recursively walk the edges and record the path.
44 void VisitValue(Value*) override;
45 void VisitRawPtr(RawPtr*) override;
46 void VisitRefPtr(RefPtr*) override;
47 void VisitOwnPtr(OwnPtr*) override;
48 void VisitMember(Member*) override;
49 void VisitWeakMember(WeakMember*) override;
50 void VisitPersistent(Persistent*) override;
51 void VisitCollection(Collection*) override;
53 protected:
54 typedef std::deque<Edge*> Context;
55 Context& context() { return context_; }
56 Edge* Parent() { return context_.empty() ? 0 : context_.front(); }
57 void Enter(Edge* e) { return context_.push_front(e); }
58 void Leave() { context_.pop_front(); }
60 // Default callback to overwrite in visitor subclass.
61 virtual void AtValue(Value*);
62 virtual void AtRawPtr(RawPtr*);
63 virtual void AtRefPtr(RefPtr*);
64 virtual void AtOwnPtr(OwnPtr*);
65 virtual void AtMember(Member*);
66 virtual void AtWeakMember(WeakMember*);
67 virtual void AtPersistent(Persistent*);
68 virtual void AtCollection(Collection*);
70 private:
71 Context context_;
74 // Base class for all edges.
75 class Edge {
76 public:
77 enum NeedsTracingOption { kRecursive, kNonRecursive };
78 enum LivenessKind { kWeak, kStrong, kRoot };
80 virtual ~Edge() {}
81 virtual LivenessKind Kind() = 0;
82 virtual void Accept(EdgeVisitor*) = 0;
83 virtual bool NeedsFinalization() = 0;
84 virtual TracingStatus NeedsTracing(NeedsTracingOption) {
85 return TracingStatus::Unknown();
88 virtual bool IsValue() { return false; }
89 virtual bool IsRawPtr() { return false; }
90 virtual bool IsRawPtrClass() { return false; }
91 virtual bool IsRefPtr() { return false; }
92 virtual bool IsOwnPtr() { return false; }
93 virtual bool IsMember() { return false; }
94 virtual bool IsWeakMember() { return false; }
95 virtual bool IsPersistent() { return false; }
96 virtual bool IsCollection() { return false; }
99 // A value edge is a direct edge to some type, eg, part-object edges.
100 class Value : public Edge {
101 public:
102 explicit Value(RecordInfo* value) : value_(value) {};
103 bool IsValue() override { return true; }
104 LivenessKind Kind() override { return kStrong; }
105 bool NeedsFinalization() override;
106 TracingStatus NeedsTracing(NeedsTracingOption) override;
107 void Accept(EdgeVisitor* visitor) override { visitor->VisitValue(this); }
108 RecordInfo* value() { return value_; }
110 private:
111 RecordInfo* value_;
114 // Shared base for smart-pointer edges.
115 class PtrEdge : public Edge {
116 public:
117 ~PtrEdge() { delete ptr_; }
118 Edge* ptr() { return ptr_; }
119 protected:
120 PtrEdge(Edge* ptr) : ptr_(ptr) {
121 assert(ptr && "EdgePtr pointer must be non-null");
123 private:
124 Edge* ptr_;
127 class RawPtr : public PtrEdge {
128 public:
129 RawPtr(Edge* ptr, bool is_ptr_class, bool is_ref_type)
130 : PtrEdge(ptr)
131 , is_ptr_class_(is_ptr_class)
132 , is_ref_type_(is_ref_type)
134 assert(!(is_ptr_class_ && is_ref_type_));
137 bool IsRawPtr() { return true; }
138 bool IsRawPtrClass() { return is_ptr_class_; }
139 LivenessKind Kind() { return kWeak; }
140 bool NeedsFinalization() { return false; }
141 TracingStatus NeedsTracing(NeedsTracingOption) {
142 return TracingStatus::Unneeded();
144 void Accept(EdgeVisitor* visitor) { visitor->VisitRawPtr(this); }
146 bool HasReferenceType() { return is_ref_type_; }
147 private:
148 bool is_ptr_class_;
149 bool is_ref_type_;
152 class RefPtr : public PtrEdge {
153 public:
154 explicit RefPtr(Edge* ptr) : PtrEdge(ptr) { }
155 bool IsRefPtr() { return true; }
156 LivenessKind Kind() { return kStrong; }
157 bool NeedsFinalization() { return true; }
158 TracingStatus NeedsTracing(NeedsTracingOption) {
159 return TracingStatus::Unneeded();
161 void Accept(EdgeVisitor* visitor) { visitor->VisitRefPtr(this); }
164 class OwnPtr : public PtrEdge {
165 public:
166 explicit OwnPtr(Edge* ptr) : PtrEdge(ptr) { }
167 bool IsOwnPtr() { return true; }
168 LivenessKind Kind() { return kStrong; }
169 bool NeedsFinalization() { return true; }
170 TracingStatus NeedsTracing(NeedsTracingOption) {
171 return TracingStatus::Unneeded();
173 void Accept(EdgeVisitor* visitor) { visitor->VisitOwnPtr(this); }
176 class Member : public PtrEdge {
177 public:
178 explicit Member(Edge* ptr) : PtrEdge(ptr) { }
179 bool IsMember() { return true; }
180 LivenessKind Kind() { return kStrong; }
181 bool NeedsFinalization() { return false; }
182 TracingStatus NeedsTracing(NeedsTracingOption) {
183 return TracingStatus::Needed();
185 void Accept(EdgeVisitor* visitor) { visitor->VisitMember(this); }
188 class WeakMember : public PtrEdge {
189 public:
190 explicit WeakMember(Edge* ptr) : PtrEdge(ptr) { }
191 bool IsWeakMember() { return true; }
192 LivenessKind Kind() { return kWeak; }
193 bool NeedsFinalization() { return false; }
194 TracingStatus NeedsTracing(NeedsTracingOption) {
195 return TracingStatus::Needed();
197 void Accept(EdgeVisitor* visitor) { visitor->VisitWeakMember(this); }
200 class Persistent : public PtrEdge {
201 public:
202 explicit Persistent(Edge* ptr) : PtrEdge(ptr) { }
203 bool IsPersistent() { return true; }
204 LivenessKind Kind() { return kRoot; }
205 bool NeedsFinalization() { return true; }
206 TracingStatus NeedsTracing(NeedsTracingOption) {
207 return TracingStatus::Unneeded();
209 void Accept(EdgeVisitor* visitor) { visitor->VisitPersistent(this); }
212 class Collection : public Edge {
213 public:
214 typedef std::vector<Edge*> Members;
215 Collection(RecordInfo* info, bool on_heap, bool is_root)
216 : info_(info),
217 on_heap_(on_heap),
218 is_root_(is_root) {}
219 ~Collection() {
220 for (Members::iterator it = members_.begin(); it != members_.end(); ++it) {
221 assert(*it && "Collection-edge members must be non-null");
222 delete *it;
225 bool IsCollection() { return true; }
226 LivenessKind Kind() { return is_root_ ? kRoot : kStrong; }
227 bool on_heap() { return on_heap_; }
228 bool is_root() { return is_root_; }
229 Members& members() { return members_; }
230 void Accept(EdgeVisitor* visitor) { visitor->VisitCollection(this); }
231 void AcceptMembers(EdgeVisitor* visitor) {
232 for (Members::iterator it = members_.begin(); it != members_.end(); ++it)
233 (*it)->Accept(visitor);
235 bool NeedsFinalization();
236 TracingStatus NeedsTracing(NeedsTracingOption) {
237 if (is_root_)
238 return TracingStatus::Unneeded();
239 if (on_heap_)
240 return TracingStatus::Needed();
241 // For off-heap collections, determine tracing status of members.
242 TracingStatus status = TracingStatus::Unneeded();
243 for (Members::iterator it = members_.begin(); it != members_.end(); ++it) {
244 // Do a non-recursive test here since members could equal the holder.
245 status = status.LUB((*it)->NeedsTracing(kNonRecursive));
247 return status;
250 private:
251 RecordInfo* info_;
252 Members members_;
253 bool on_heap_;
254 bool is_root_;
257 #endif // TOOLS_BLINK_GC_PLUGIN_EDGE_H_