File: Edge.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (327 lines) | stat: -rw-r--r-- 10,395 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TOOLS_BLINK_GC_PLUGIN_EDGE_H_
#define TOOLS_BLINK_GC_PLUGIN_EDGE_H_

#include <cassert>
#include <deque>
#include <string>
#include <vector>

#include "TracingStatus.h"

class RecordInfo;

class Edge;
class Collection;
class CrossThreadPersistent;
class Iterator;
class Member;
class Persistent;
class RawPtr;
class RefPtr;
class UniquePtr;
class Value;
class WeakMember;
class TraceWrapperV8Reference;
class ArrayEdge;

// Bare-bones visitor.
class EdgeVisitor {
 public:
  virtual ~EdgeVisitor() {}
  virtual void VisitValue(Value*) {}
  virtual void VisitRawPtr(RawPtr*) {}
  virtual void VisitRefPtr(RefPtr*) {}
  virtual void VisitUniquePtr(UniquePtr*) {}
  virtual void VisitMember(Member*) {}
  virtual void VisitWeakMember(WeakMember*) {}
  virtual void VisitPersistent(Persistent*) {}
  virtual void VisitCrossThreadPersistent(CrossThreadPersistent*) {}
  virtual void VisitCollection(Collection*) {}
  virtual void VisitIterator(Iterator*) {}
  virtual void VisitTraceWrapperV8Reference(TraceWrapperV8Reference*) {}
  virtual void VisitArrayEdge(ArrayEdge*) {}
};

// Recursive edge visitor. The traversed path is accessible in context.
class RecursiveEdgeVisitor : public EdgeVisitor {
 public:
  // Overrides that recursively walk the edges and record the path.
  void VisitValue(Value*) override;
  void VisitRawPtr(RawPtr*) override;
  void VisitRefPtr(RefPtr*) override;
  void VisitUniquePtr(UniquePtr*) override;
  void VisitMember(Member*) override;
  void VisitWeakMember(WeakMember*) override;
  void VisitPersistent(Persistent*) override;
  void VisitCrossThreadPersistent(CrossThreadPersistent*) override;
  void VisitCollection(Collection*) override;
  void VisitIterator(Iterator*) override;
  void VisitTraceWrapperV8Reference(TraceWrapperV8Reference*) override;
  void VisitArrayEdge(ArrayEdge*) override;

 protected:
  typedef std::deque<Edge*> Context;
  Context& context() { return context_; }
  Edge* Parent() { return context_.empty() ? 0 : context_.front(); }
  Edge* GrandParent() {
    return Parent() ? (context_.size() > 1 ? context_[1] : nullptr) : nullptr;
  }
  void Enter(Edge* e) { return context_.push_front(e); }
  void Leave() { context_.pop_front(); }

  // Default callback to overwrite in visitor subclass.
  virtual void AtValue(Value*);
  virtual void AtRawPtr(RawPtr*);
  virtual void AtRefPtr(RefPtr*);
  virtual void AtUniquePtr(UniquePtr*);
  virtual void AtMember(Member*);
  virtual void AtWeakMember(WeakMember*);
  virtual void AtTraceWrapperV8Reference(TraceWrapperV8Reference*);
  virtual void AtPersistent(Persistent*);
  virtual void AtCrossThreadPersistent(CrossThreadPersistent*);
  virtual void AtCollection(Collection*);
  virtual void AtIterator(Iterator*);
  virtual void AtArrayEdge(ArrayEdge*);

 private:
  Context context_;
};

// Base class for all edges.
class Edge {
 public:
  enum NeedsTracingOption { kRecursive, kNonRecursive };
  enum LivenessKind { kWeak, kStrong, kRoot };

  virtual ~Edge() {}
  virtual LivenessKind Kind() = 0;
  virtual void Accept(EdgeVisitor*) = 0;
  virtual bool NeedsFinalization() = 0;
  virtual TracingStatus NeedsTracing(NeedsTracingOption) {
    return TracingStatus::Unknown();
  }

  virtual bool IsValue() { return false; }
  virtual bool IsRawPtr() { return false; }
  virtual bool IsRefPtr() { return false; }
  virtual bool IsUniquePtr() { return false; }
  virtual bool IsMember() { return false; }
  virtual bool IsWeakMember() { return false; }
  virtual bool IsCollection() { return false; }
  virtual bool IsArray() { return false; }
  virtual bool IsTraceWrapperV8Reference() { return false; }
};

// A value edge is a direct edge to some type, eg, part-object edges.
class Value : public Edge {
 public:
  explicit Value(RecordInfo* value) : value_(value) {};
  bool IsValue() override { return true; }
  LivenessKind Kind() override { return kStrong; }
  bool NeedsFinalization() override;
  TracingStatus NeedsTracing(NeedsTracingOption) override;
  void Accept(EdgeVisitor* visitor) override { visitor->VisitValue(this); }
  RecordInfo* value() { return value_; }

 private:
  RecordInfo* value_;
};

class ArrayEdge : public Edge {
 public:
  explicit ArrayEdge(Edge* value) : value_(value){};
  LivenessKind Kind() override { return kStrong; }
  bool NeedsFinalization() override { return false; }
  TracingStatus NeedsTracing(NeedsTracingOption option) override {
    return value_->NeedsTracing(option);
  }
  void Accept(EdgeVisitor* visitor) override { visitor->VisitArrayEdge(this); }
  Edge* element() { return value_; }
  bool IsArray() override { return true; }

 private:
  Edge* value_;
};

// Shared base for smart-pointer edges.
class PtrEdge : public Edge {
 public:
  ~PtrEdge() { delete ptr_; }
  Edge* ptr() { return ptr_; }
 protected:
  PtrEdge(Edge* ptr) : ptr_(ptr) {
    assert(ptr && "EdgePtr pointer must be non-null");
  }
 private:
  Edge* ptr_;
};

class RawPtr : public PtrEdge {
 public:
  RawPtr(Edge* ptr, bool is_ref_type)
      : PtrEdge(ptr)
      , is_ref_type_(is_ref_type)
  {
  }

  bool IsRawPtr() override { return true; }
  LivenessKind Kind() override { return kWeak; }
  bool NeedsFinalization() override { return false; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    return TracingStatus::Illegal();
  }
  void Accept(EdgeVisitor* visitor) override { visitor->VisitRawPtr(this); }

  bool HasReferenceType() { return is_ref_type_; }
 private:
  bool is_ref_type_;
};

class RefPtr : public PtrEdge {
 public:
  RefPtr(Edge* ptr, LivenessKind kind) : PtrEdge(ptr), kind_(kind) {}
  bool IsRefPtr() override { return true; }
  LivenessKind Kind() override { return kind_; }
  bool NeedsFinalization() override { return true; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    return TracingStatus::Illegal();
  }
  void Accept(EdgeVisitor* visitor) override { visitor->VisitRefPtr(this); }

 private:
  LivenessKind kind_;
};

class UniquePtr : public PtrEdge {
 public:
  explicit UniquePtr(Edge* ptr) : PtrEdge(ptr) { }
  bool IsUniquePtr() override { return true; }
  LivenessKind Kind() override { return kStrong; }
  bool NeedsFinalization() override { return true; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    return TracingStatus::Illegal();
  }
  void Accept(EdgeVisitor* visitor) override { visitor->VisitUniquePtr(this); }
};

class Member : public PtrEdge {
 public:
  explicit Member(Edge* ptr) : PtrEdge(ptr) { }
  bool IsMember() override { return true; }
  LivenessKind Kind() override { return kStrong; }
  bool NeedsFinalization() override { return false; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    return TracingStatus::Needed();
  }
  void Accept(EdgeVisitor* visitor) override { visitor->VisitMember(this); }
};

class WeakMember : public PtrEdge {
 public:
  explicit WeakMember(Edge* ptr) : PtrEdge(ptr) { }
  bool IsWeakMember() override { return true; }
  LivenessKind Kind() override { return kWeak; }
  bool NeedsFinalization() override { return false; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    return TracingStatus::Needed();
  }
  void Accept(EdgeVisitor* visitor) override { visitor->VisitWeakMember(this); }
};

class Persistent : public PtrEdge {
 public:
  explicit Persistent(Edge* ptr) : PtrEdge(ptr) { }
  LivenessKind Kind() override { return kRoot; }
  bool NeedsFinalization() override { return true; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    return TracingStatus::Illegal();
  }
  void Accept(EdgeVisitor* visitor) override { visitor->VisitPersistent(this); }
};

class CrossThreadPersistent : public PtrEdge {
 public:
  explicit CrossThreadPersistent(Edge* ptr) : PtrEdge(ptr) { }
  LivenessKind Kind() override { return kRoot; }
  bool NeedsFinalization() override { return true; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    return TracingStatus::Illegal();
  }
  void Accept(EdgeVisitor* visitor) override {
    visitor->VisitCrossThreadPersistent(this);
  }
};

class TraceWrapperV8Reference : public PtrEdge {
 public:
  explicit TraceWrapperV8Reference(Edge* ptr) : PtrEdge(ptr) {}
  bool IsTraceWrapperV8Reference() override { return true; }
  LivenessKind Kind() override { return kStrong; }
  bool NeedsFinalization() override { return true; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    return TracingStatus::Needed();
  }
  void Accept(EdgeVisitor* visitor) override {
    visitor->VisitTraceWrapperV8Reference(this);
  }
};

class Collection : public Edge {
 public:
  typedef std::vector<Edge*> Members;
  Collection(RecordInfo* info, bool on_heap) : info_(info), on_heap_(on_heap) {}
  ~Collection() {
    for (Members::iterator it = members_.begin(); it != members_.end(); ++it) {
      assert(*it && "Collection-edge members must be non-null");
      delete *it;
    }
  }
  bool IsCollection() override { return true; }
  bool IsSTDCollection();
  LivenessKind Kind() override { return kStrong; }
  bool on_heap() { return on_heap_; }
  Members& members() { return members_; }
  void Accept(EdgeVisitor* visitor) override { visitor->VisitCollection(this); }
  void AcceptMembers(EdgeVisitor* visitor) {
    for (Members::iterator it = members_.begin(); it != members_.end(); ++it)
      (*it)->Accept(visitor);
  }
  bool NeedsFinalization() override;
  TracingStatus NeedsTracing(NeedsTracingOption) override;
  std::string GetCollectionName() const;

 private:
  RecordInfo* info_;
  Members members_;
  bool on_heap_;
};

// An iterator edge is a direct edge to some iterator type.
class Iterator : public Edge {
 public:
  Iterator(RecordInfo* info, bool on_heap) : info_(info), on_heap_(on_heap) {}
  ~Iterator() {}

  void Accept(EdgeVisitor* visitor) override { visitor->VisitIterator(this); }
  LivenessKind Kind() override { return kStrong; }
  bool NeedsFinalization() override { return false; }
  TracingStatus NeedsTracing(NeedsTracingOption) override {
    if (on_heap_)
      return TracingStatus::Illegal();
    return TracingStatus::Unneeded();
  }

  RecordInfo* info() const { return info_; }

  bool on_heap() const { return on_heap_; }

 private:
  RecordInfo* info_;
  bool on_heap_;
};

#endif  // TOOLS_BLINK_GC_PLUGIN_EDGE_H_