| Index: tools/clang/blink_gc_plugin/Edge.h
 | 
| diff --git a/tools/clang/blink_gc_plugin/Edge.h b/tools/clang/blink_gc_plugin/Edge.h
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..eca3158d75f925e1b7430991838ad4bea890c058
 | 
| --- /dev/null
 | 
| +++ b/tools/clang/blink_gc_plugin/Edge.h
 | 
| @@ -0,0 +1,257 @@
 | 
| +// 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 Value;
 | 
| +class RawPtr;
 | 
| +class RefPtr;
 | 
| +class OwnPtr;
 | 
| +class Member;
 | 
| +class WeakMember;
 | 
| +class Persistent;
 | 
| +class Collection;
 | 
| +
 | 
| +// Bare-bones visitor.
 | 
| +class EdgeVisitor {
 | 
| + public:
 | 
| +  virtual ~EdgeVisitor() {}
 | 
| +  virtual void VisitValue(Value*) {}
 | 
| +  virtual void VisitRawPtr(RawPtr*) {}
 | 
| +  virtual void VisitRefPtr(RefPtr*) {}
 | 
| +  virtual void VisitOwnPtr(OwnPtr*) {}
 | 
| +  virtual void VisitMember(Member*) {}
 | 
| +  virtual void VisitWeakMember(WeakMember*) {}
 | 
| +  virtual void VisitPersistent(Persistent*) {}
 | 
| +  virtual void VisitCollection(Collection*) {}
 | 
| +};
 | 
| +
 | 
| +// 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 VisitOwnPtr(OwnPtr*) override;
 | 
| +  void VisitMember(Member*) override;
 | 
| +  void VisitWeakMember(WeakMember*) override;
 | 
| +  void VisitPersistent(Persistent*) override;
 | 
| +  void VisitCollection(Collection*) override;
 | 
| +
 | 
| + protected:
 | 
| +  typedef std::deque<Edge*> Context;
 | 
| +  Context& context() { return context_; }
 | 
| +  Edge* Parent() { return context_.empty() ? 0 : context_.front(); }
 | 
| +  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 AtOwnPtr(OwnPtr*);
 | 
| +  virtual void AtMember(Member*);
 | 
| +  virtual void AtWeakMember(WeakMember*);
 | 
| +  virtual void AtPersistent(Persistent*);
 | 
| +  virtual void AtCollection(Collection*);
 | 
| +
 | 
| + 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 IsRawPtrClass() { return false; }
 | 
| +  virtual bool IsRefPtr() { return false; }
 | 
| +  virtual bool IsOwnPtr() { return false; }
 | 
| +  virtual bool IsMember() { return false; }
 | 
| +  virtual bool IsWeakMember() { return false; }
 | 
| +  virtual bool IsPersistent() { return false; }
 | 
| +  virtual bool IsCollection() { 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_ptr_class, bool is_ref_type)
 | 
| +      : PtrEdge(ptr)
 | 
| +      , is_ptr_class_(is_ptr_class)
 | 
| +      , is_ref_type_(is_ref_type)
 | 
| +  {
 | 
| +      assert(!(is_ptr_class_ && is_ref_type_));
 | 
| +  }
 | 
| +
 | 
| +  bool IsRawPtr() { return true; }
 | 
| +  bool IsRawPtrClass() { return is_ptr_class_; }
 | 
| +  LivenessKind Kind() { return kWeak; }
 | 
| +  bool NeedsFinalization() { return false; }
 | 
| +  TracingStatus NeedsTracing(NeedsTracingOption) {
 | 
| +    return TracingStatus::Unneeded();
 | 
| +  }
 | 
| +  void Accept(EdgeVisitor* visitor) { visitor->VisitRawPtr(this); }
 | 
| +
 | 
| +  bool HasReferenceType() { return is_ref_type_; }
 | 
| + private:
 | 
| +  bool is_ptr_class_;
 | 
| +  bool is_ref_type_;
 | 
| +};
 | 
| +
 | 
| +class RefPtr : public PtrEdge {
 | 
| + public:
 | 
| +  explicit RefPtr(Edge* ptr) : PtrEdge(ptr) { }
 | 
| +  bool IsRefPtr() { return true; }
 | 
| +  LivenessKind Kind() { return kStrong; }
 | 
| +  bool NeedsFinalization() { return true; }
 | 
| +  TracingStatus NeedsTracing(NeedsTracingOption) {
 | 
| +    return TracingStatus::Unneeded();
 | 
| +  }
 | 
| +  void Accept(EdgeVisitor* visitor) { visitor->VisitRefPtr(this); }
 | 
| +};
 | 
| +
 | 
| +class OwnPtr : public PtrEdge {
 | 
| + public:
 | 
| +  explicit OwnPtr(Edge* ptr) : PtrEdge(ptr) { }
 | 
| +  bool IsOwnPtr() { return true; }
 | 
| +  LivenessKind Kind() { return kStrong; }
 | 
| +  bool NeedsFinalization() { return true; }
 | 
| +  TracingStatus NeedsTracing(NeedsTracingOption) {
 | 
| +    return TracingStatus::Unneeded();
 | 
| +  }
 | 
| +  void Accept(EdgeVisitor* visitor) { visitor->VisitOwnPtr(this); }
 | 
| +};
 | 
| +
 | 
| +class Member : public PtrEdge {
 | 
| + public:
 | 
| +  explicit Member(Edge* ptr) : PtrEdge(ptr) { }
 | 
| +  bool IsMember() { return true; }
 | 
| +  LivenessKind Kind() { return kStrong; }
 | 
| +  bool NeedsFinalization() { return false; }
 | 
| +  TracingStatus NeedsTracing(NeedsTracingOption) {
 | 
| +    return TracingStatus::Needed();
 | 
| +  }
 | 
| +  void Accept(EdgeVisitor* visitor) { visitor->VisitMember(this); }
 | 
| +};
 | 
| +
 | 
| +class WeakMember : public PtrEdge {
 | 
| + public:
 | 
| +  explicit WeakMember(Edge* ptr) : PtrEdge(ptr) { }
 | 
| +  bool IsWeakMember() { return true; }
 | 
| +  LivenessKind Kind() { return kWeak; }
 | 
| +  bool NeedsFinalization() { return false; }
 | 
| +  TracingStatus NeedsTracing(NeedsTracingOption) {
 | 
| +    return TracingStatus::Needed();
 | 
| +  }
 | 
| +  void Accept(EdgeVisitor* visitor) { visitor->VisitWeakMember(this); }
 | 
| +};
 | 
| +
 | 
| +class Persistent : public PtrEdge {
 | 
| + public:
 | 
| +  explicit Persistent(Edge* ptr) : PtrEdge(ptr) { }
 | 
| +  bool IsPersistent() { return true; }
 | 
| +  LivenessKind Kind() { return kRoot; }
 | 
| +  bool NeedsFinalization() { return true; }
 | 
| +  TracingStatus NeedsTracing(NeedsTracingOption) {
 | 
| +    return TracingStatus::Unneeded();
 | 
| +  }
 | 
| +  void Accept(EdgeVisitor* visitor) { visitor->VisitPersistent(this); }
 | 
| +};
 | 
| +
 | 
| +class Collection : public Edge {
 | 
| + public:
 | 
| +  typedef std::vector<Edge*> Members;
 | 
| +  Collection(RecordInfo* info, bool on_heap, bool is_root)
 | 
| +      : info_(info),
 | 
| +        on_heap_(on_heap),
 | 
| +        is_root_(is_root) {}
 | 
| +  ~Collection() {
 | 
| +    for (Members::iterator it = members_.begin(); it != members_.end(); ++it) {
 | 
| +      assert(*it && "Collection-edge members must be non-null");
 | 
| +      delete *it;
 | 
| +    }
 | 
| +  }
 | 
| +  bool IsCollection() { return true; }
 | 
| +  LivenessKind Kind() { return is_root_ ? kRoot : kStrong; }
 | 
| +  bool on_heap() { return on_heap_; }
 | 
| +  bool is_root() { return is_root_; }
 | 
| +  Members& members() { return members_; }
 | 
| +  void Accept(EdgeVisitor* visitor) { visitor->VisitCollection(this); }
 | 
| +  void AcceptMembers(EdgeVisitor* visitor) {
 | 
| +    for (Members::iterator it = members_.begin(); it != members_.end(); ++it)
 | 
| +      (*it)->Accept(visitor);
 | 
| +  }
 | 
| +  bool NeedsFinalization();
 | 
| +  TracingStatus NeedsTracing(NeedsTracingOption) {
 | 
| +    if (is_root_)
 | 
| +      return TracingStatus::Unneeded();
 | 
| +    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_;
 | 
| +  bool is_root_;
 | 
| +};
 | 
| +
 | 
| +#endif  // TOOLS_BLINK_GC_PLUGIN_EDGE_H_
 | 
| 
 |