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_
10 #include "TracingStatus.h"
24 // Bare-bones visitor.
27 virtual void VisitValue(Value
*) {}
28 virtual void VisitRawPtr(RawPtr
*) {}
29 virtual void VisitRefPtr(RefPtr
*) {}
30 virtual void VisitOwnPtr(OwnPtr
*) {}
31 virtual void VisitMember(Member
*) {}
32 virtual void VisitWeakMember(WeakMember
*) {}
33 virtual void VisitPersistent(Persistent
*) {}
34 virtual void VisitCollection(Collection
*) {}
37 // Recursive edge visitor. The traversed path is accessible in context.
38 class RecursiveEdgeVisitor
: public EdgeVisitor
{
40 // Overrides that recursively walk the edges and record the path.
41 virtual void VisitValue(Value
*) override
;
42 virtual void VisitRawPtr(RawPtr
*) override
;
43 virtual void VisitRefPtr(RefPtr
*) override
;
44 virtual void VisitOwnPtr(OwnPtr
*) override
;
45 virtual void VisitMember(Member
*) override
;
46 virtual void VisitWeakMember(WeakMember
*) override
;
47 virtual void VisitPersistent(Persistent
*) override
;
48 virtual void VisitCollection(Collection
*) override
;
51 typedef std::deque
<Edge
*> Context
;
52 Context
& context() { return context_
; }
53 Edge
* Parent() { return context_
.empty() ? 0 : context_
.front(); }
54 void Enter(Edge
* e
) { return context_
.push_front(e
); }
55 void Leave() { context_
.pop_front(); }
57 // Default callback to overwrite in visitor subclass.
58 virtual void AtValue(Value
*);
59 virtual void AtRawPtr(RawPtr
*);
60 virtual void AtRefPtr(RefPtr
*);
61 virtual void AtOwnPtr(OwnPtr
*);
62 virtual void AtMember(Member
*);
63 virtual void AtWeakMember(WeakMember
*);
64 virtual void AtPersistent(Persistent
*);
65 virtual void AtCollection(Collection
*);
71 // Base class for all edges.
74 enum NeedsTracingOption
{ kRecursive
, kNonRecursive
};
75 enum LivenessKind
{ kWeak
, kStrong
, kRoot
};
78 virtual LivenessKind
Kind() = 0;
79 virtual void Accept(EdgeVisitor
*) = 0;
80 virtual bool NeedsFinalization() = 0;
81 virtual TracingStatus
NeedsTracing(NeedsTracingOption
) {
82 return TracingStatus::Unknown();
85 virtual bool IsValue() { return false; }
86 virtual bool IsRawPtr() { return false; }
87 virtual bool IsRawPtrClass() { return false; }
88 virtual bool IsRefPtr() { return false; }
89 virtual bool IsOwnPtr() { return false; }
90 virtual bool IsMember() { return false; }
91 virtual bool IsWeakMember() { return false; }
92 virtual bool IsPersistent() { return false; }
93 virtual bool IsCollection() { return false; }
96 // A value edge is a direct edge to some type, eg, part-object edges.
97 class Value
: public Edge
{
99 explicit Value(RecordInfo
* value
) : value_(value
) {};
100 bool IsValue() override
{ return true; }
101 LivenessKind
Kind() override
{ return kStrong
; }
102 bool NeedsFinalization() override
;
103 TracingStatus
NeedsTracing(NeedsTracingOption
) override
;
104 void Accept(EdgeVisitor
* visitor
) override
{ visitor
->VisitValue(this); }
105 RecordInfo
* value() { return value_
; }
111 // Shared base for smart-pointer edges.
112 class PtrEdge
: public Edge
{
114 ~PtrEdge() { delete ptr_
; }
115 Edge
* ptr() { return ptr_
; }
117 PtrEdge(Edge
* ptr
) : ptr_(ptr
) {
118 assert(ptr
&& "EdgePtr pointer must be non-null");
124 class RawPtr
: public PtrEdge
{
126 explicit RawPtr(Edge
* ptr
, bool is_ptr_class
)
127 : PtrEdge(ptr
), is_ptr_class_(is_ptr_class
) { }
128 bool IsRawPtr() { return true; }
129 bool IsRawPtrClass() { return is_ptr_class_
; }
130 LivenessKind
Kind() { return kWeak
; }
131 bool NeedsFinalization() { return false; }
132 TracingStatus
NeedsTracing(NeedsTracingOption
) {
133 return TracingStatus::Unneeded();
135 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitRawPtr(this); }
140 class RefPtr
: public PtrEdge
{
142 explicit RefPtr(Edge
* ptr
) : PtrEdge(ptr
) { }
143 bool IsRefPtr() { return true; }
144 LivenessKind
Kind() { return kStrong
; }
145 bool NeedsFinalization() { return true; }
146 TracingStatus
NeedsTracing(NeedsTracingOption
) {
147 return TracingStatus::Unneeded();
149 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitRefPtr(this); }
152 class OwnPtr
: public PtrEdge
{
154 explicit OwnPtr(Edge
* ptr
) : PtrEdge(ptr
) { }
155 bool IsOwnPtr() { 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
->VisitOwnPtr(this); }
164 class Member
: public PtrEdge
{
166 explicit Member(Edge
* ptr
) : PtrEdge(ptr
) { }
167 bool IsMember() { return true; }
168 LivenessKind
Kind() { return kStrong
; }
169 bool NeedsFinalization() { return false; }
170 TracingStatus
NeedsTracing(NeedsTracingOption
) {
171 return TracingStatus::Needed();
173 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitMember(this); }
176 class WeakMember
: public PtrEdge
{
178 explicit WeakMember(Edge
* ptr
) : PtrEdge(ptr
) { }
179 bool IsWeakMember() { return true; }
180 LivenessKind
Kind() { return kWeak
; }
181 bool NeedsFinalization() { return false; }
182 TracingStatus
NeedsTracing(NeedsTracingOption
) {
183 return TracingStatus::Needed();
185 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitWeakMember(this); }
188 class Persistent
: public PtrEdge
{
190 explicit Persistent(Edge
* ptr
) : PtrEdge(ptr
) { }
191 bool IsPersistent() { return true; }
192 LivenessKind
Kind() { return kRoot
; }
193 bool NeedsFinalization() { return true; }
194 TracingStatus
NeedsTracing(NeedsTracingOption
) {
195 return TracingStatus::Unneeded();
197 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitPersistent(this); }
200 class Collection
: public Edge
{
202 typedef std::vector
<Edge
*> Members
;
203 Collection(RecordInfo
* info
, bool on_heap
, bool is_root
)
208 for (Members::iterator it
= members_
.begin(); it
!= members_
.end(); ++it
) {
209 assert(*it
&& "Collection-edge members must be non-null");
213 bool IsCollection() { return true; }
214 LivenessKind
Kind() { return is_root_
? kRoot
: kStrong
; }
215 bool on_heap() { return on_heap_
; }
216 bool is_root() { return is_root_
; }
217 Members
& members() { return members_
; }
218 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitCollection(this); }
219 void AcceptMembers(EdgeVisitor
* visitor
) {
220 for (Members::iterator it
= members_
.begin(); it
!= members_
.end(); ++it
)
221 (*it
)->Accept(visitor
);
223 bool NeedsFinalization();
224 TracingStatus
NeedsTracing(NeedsTracingOption
) {
226 return TracingStatus::Unneeded();
228 return TracingStatus::Needed();
229 // For off-heap collections, determine tracing status of members.
230 TracingStatus status
= TracingStatus::Unneeded();
231 for (Members::iterator it
= members_
.begin(); it
!= members_
.end(); ++it
) {
232 // Do a non-recursive test here since members could equal the holder.
233 status
= status
.LUB((*it
)->NeedsTracing(kNonRecursive
));
245 #endif // TOOLS_BLINK_GC_PLUGIN_EDGE_H_