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 ~EdgeVisitor() {}
28 virtual void VisitValue(Value
*) {}
29 virtual void VisitRawPtr(RawPtr
*) {}
30 virtual void VisitRefPtr(RefPtr
*) {}
31 virtual void VisitOwnPtr(OwnPtr
*) {}
32 virtual void VisitMember(Member
*) {}
33 virtual void VisitWeakMember(WeakMember
*) {}
34 virtual void VisitPersistent(Persistent
*) {}
35 virtual void VisitCollection(Collection
*) {}
38 // Recursive edge visitor. The traversed path is accessible in context.
39 class RecursiveEdgeVisitor
: public EdgeVisitor
{
41 // Overrides that recursively walk the edges and record the path.
42 virtual void VisitValue(Value
*) override
;
43 virtual void VisitRawPtr(RawPtr
*) override
;
44 virtual void VisitRefPtr(RefPtr
*) override
;
45 virtual void VisitOwnPtr(OwnPtr
*) override
;
46 virtual void VisitMember(Member
*) override
;
47 virtual void VisitWeakMember(WeakMember
*) override
;
48 virtual void VisitPersistent(Persistent
*) override
;
49 virtual void VisitCollection(Collection
*) override
;
52 typedef std::deque
<Edge
*> Context
;
53 Context
& context() { return context_
; }
54 Edge
* Parent() { return context_
.empty() ? 0 : context_
.front(); }
55 void Enter(Edge
* e
) { return context_
.push_front(e
); }
56 void Leave() { context_
.pop_front(); }
58 // Default callback to overwrite in visitor subclass.
59 virtual void AtValue(Value
*);
60 virtual void AtRawPtr(RawPtr
*);
61 virtual void AtRefPtr(RefPtr
*);
62 virtual void AtOwnPtr(OwnPtr
*);
63 virtual void AtMember(Member
*);
64 virtual void AtWeakMember(WeakMember
*);
65 virtual void AtPersistent(Persistent
*);
66 virtual void AtCollection(Collection
*);
72 // Base class for all edges.
75 enum NeedsTracingOption
{ kRecursive
, kNonRecursive
};
76 enum LivenessKind
{ kWeak
, kStrong
, kRoot
};
79 virtual LivenessKind
Kind() = 0;
80 virtual void Accept(EdgeVisitor
*) = 0;
81 virtual bool NeedsFinalization() = 0;
82 virtual TracingStatus
NeedsTracing(NeedsTracingOption
) {
83 return TracingStatus::Unknown();
86 virtual bool IsValue() { return false; }
87 virtual bool IsRawPtr() { return false; }
88 virtual bool IsRawPtrClass() { return false; }
89 virtual bool IsRefPtr() { return false; }
90 virtual bool IsOwnPtr() { return false; }
91 virtual bool IsMember() { return false; }
92 virtual bool IsWeakMember() { return false; }
93 virtual bool IsPersistent() { return false; }
94 virtual bool IsCollection() { return false; }
97 // A value edge is a direct edge to some type, eg, part-object edges.
98 class Value
: public Edge
{
100 explicit Value(RecordInfo
* value
) : value_(value
) {};
101 bool IsValue() override
{ return true; }
102 LivenessKind
Kind() override
{ return kStrong
; }
103 bool NeedsFinalization() override
;
104 TracingStatus
NeedsTracing(NeedsTracingOption
) override
;
105 void Accept(EdgeVisitor
* visitor
) override
{ visitor
->VisitValue(this); }
106 RecordInfo
* value() { return value_
; }
112 // Shared base for smart-pointer edges.
113 class PtrEdge
: public Edge
{
115 ~PtrEdge() { delete ptr_
; }
116 Edge
* ptr() { return ptr_
; }
118 PtrEdge(Edge
* ptr
) : ptr_(ptr
) {
119 assert(ptr
&& "EdgePtr pointer must be non-null");
125 class RawPtr
: public PtrEdge
{
127 explicit RawPtr(Edge
* ptr
, bool is_ptr_class
)
128 : PtrEdge(ptr
), is_ptr_class_(is_ptr_class
) { }
129 bool IsRawPtr() { return true; }
130 bool IsRawPtrClass() { return is_ptr_class_
; }
131 LivenessKind
Kind() { return kWeak
; }
132 bool NeedsFinalization() { return false; }
133 TracingStatus
NeedsTracing(NeedsTracingOption
) {
134 return TracingStatus::Unneeded();
136 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitRawPtr(this); }
141 class RefPtr
: public PtrEdge
{
143 explicit RefPtr(Edge
* ptr
) : PtrEdge(ptr
) { }
144 bool IsRefPtr() { return true; }
145 LivenessKind
Kind() { return kStrong
; }
146 bool NeedsFinalization() { return true; }
147 TracingStatus
NeedsTracing(NeedsTracingOption
) {
148 return TracingStatus::Unneeded();
150 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitRefPtr(this); }
153 class OwnPtr
: public PtrEdge
{
155 explicit OwnPtr(Edge
* ptr
) : PtrEdge(ptr
) { }
156 bool IsOwnPtr() { return true; }
157 LivenessKind
Kind() { return kStrong
; }
158 bool NeedsFinalization() { return true; }
159 TracingStatus
NeedsTracing(NeedsTracingOption
) {
160 return TracingStatus::Unneeded();
162 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitOwnPtr(this); }
165 class Member
: public PtrEdge
{
167 explicit Member(Edge
* ptr
) : PtrEdge(ptr
) { }
168 bool IsMember() { return true; }
169 LivenessKind
Kind() { return kStrong
; }
170 bool NeedsFinalization() { return false; }
171 TracingStatus
NeedsTracing(NeedsTracingOption
) {
172 return TracingStatus::Needed();
174 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitMember(this); }
177 class WeakMember
: public PtrEdge
{
179 explicit WeakMember(Edge
* ptr
) : PtrEdge(ptr
) { }
180 bool IsWeakMember() { return true; }
181 LivenessKind
Kind() { return kWeak
; }
182 bool NeedsFinalization() { return false; }
183 TracingStatus
NeedsTracing(NeedsTracingOption
) {
184 return TracingStatus::Needed();
186 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitWeakMember(this); }
189 class Persistent
: public PtrEdge
{
191 explicit Persistent(Edge
* ptr
) : PtrEdge(ptr
) { }
192 bool IsPersistent() { return true; }
193 LivenessKind
Kind() { return kRoot
; }
194 bool NeedsFinalization() { return true; }
195 TracingStatus
NeedsTracing(NeedsTracingOption
) {
196 return TracingStatus::Unneeded();
198 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitPersistent(this); }
201 class Collection
: public Edge
{
203 typedef std::vector
<Edge
*> Members
;
204 Collection(RecordInfo
* info
, bool on_heap
, bool is_root
)
209 for (Members::iterator it
= members_
.begin(); it
!= members_
.end(); ++it
) {
210 assert(*it
&& "Collection-edge members must be non-null");
214 bool IsCollection() { return true; }
215 LivenessKind
Kind() { return is_root_
? kRoot
: kStrong
; }
216 bool on_heap() { return on_heap_
; }
217 bool is_root() { return is_root_
; }
218 Members
& members() { return members_
; }
219 void Accept(EdgeVisitor
* visitor
) { visitor
->VisitCollection(this); }
220 void AcceptMembers(EdgeVisitor
* visitor
) {
221 for (Members::iterator it
= members_
.begin(); it
!= members_
.end(); ++it
)
222 (*it
)->Accept(visitor
);
224 bool NeedsFinalization();
225 TracingStatus
NeedsTracing(NeedsTracingOption
) {
227 return TracingStatus::Unneeded();
229 return TracingStatus::Needed();
230 // For off-heap collections, determine tracing status of members.
231 TracingStatus status
= TracingStatus::Unneeded();
232 for (Members::iterator it
= members_
.begin(); it
!= members_
.end(); ++it
) {
233 // Do a non-recursive test here since members could equal the holder.
234 status
= status
.LUB((*it
)->NeedsTracing(kNonRecursive
));
246 #endif // TOOLS_BLINK_GC_PLUGIN_EDGE_H_