123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // 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 <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;
- // 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*) {}
- };
- // 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;
- 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*);
- 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 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_;
- };
- // 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::Unneeded();
- }
- 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; }
- 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 {
- if (on_heap_)
- return TracingStatus::Needed();
- // For off-heap collections, determine tracing status of members.
- TracingStatus status = TracingStatus::Unneeded();
- for (Members::iterator it = members_.begin(); it != members_.end(); ++it) {
- // Do a non-recursive test here since members could equal the holder.
- status = status.LUB((*it)->NeedsTracing(kNonRecursive));
- }
- return status;
- }
- 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, bool is_unsafe)
- : info_(info), on_heap_(on_heap), is_unsafe_(is_unsafe) {}
- ~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::Needed();
- return TracingStatus::Unneeded();
- }
- RecordInfo* info() const { return info_; }
- bool IsUnsafe() const { return is_unsafe_; }
- private:
- RecordInfo* info_;
- bool on_heap_;
- bool is_unsafe_;
- };
- #endif // TOOLS_BLINK_GC_PLUGIN_EDGE_H_
|