Adding instrumentation to locate the source of jankiness.
[chromium-blink-merge.git] / tools / clang / blink_gc_plugin / RecordInfo.h
blob82fb604137dfedd0a0cb3361506600e1c9a2de08
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 // This file provides a wrapper for CXXRecordDecl that accumulates GC related
6 // information about a class. Accumulated information is memoized and the info
7 // objects are stored in a RecordCache.
9 #ifndef TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
10 #define TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_
12 #include <map>
13 #include <vector>
15 #include "Edge.h"
17 #include "clang/AST/AST.h"
18 #include "clang/AST/CXXInheritance.h"
20 class RecordCache;
22 // A potentially tracable and/or lifetime affecting point in the object graph.
23 class GraphPoint {
24 public:
25 GraphPoint() : traced_(false) {}
26 void MarkTraced() { traced_ = true; }
27 bool IsProperlyTraced() { return traced_ || !NeedsTracing().IsNeeded(); }
28 virtual const TracingStatus NeedsTracing() = 0;
30 private:
31 bool traced_;
34 class BasePoint : public GraphPoint {
35 public:
36 BasePoint(const clang::CXXBaseSpecifier& spec,
37 RecordInfo* info,
38 const TracingStatus& status)
39 : spec_(spec), info_(info), status_(status) {}
40 const TracingStatus NeedsTracing() { return status_; }
41 const clang::CXXBaseSpecifier& spec() { return spec_; }
42 RecordInfo* info() { return info_; }
44 private:
45 const clang::CXXBaseSpecifier& spec_;
46 RecordInfo* info_;
47 TracingStatus status_;
50 class FieldPoint : public GraphPoint {
51 public:
52 FieldPoint(clang::FieldDecl* field, Edge* edge)
53 : field_(field), edge_(edge) {}
54 const TracingStatus NeedsTracing() {
55 return edge_->NeedsTracing(Edge::kRecursive);
57 clang::FieldDecl* field() { return field_; }
58 Edge* edge() { return edge_; }
60 private:
61 clang::FieldDecl* field_;
62 Edge* edge_;
64 friend class RecordCache;
65 void deleteEdge() { delete edge_; }
68 // Wrapper class to lazily collect information about a C++ record.
69 class RecordInfo {
70 public:
71 typedef std::map<clang::CXXRecordDecl*, BasePoint> Bases;
72 typedef std::map<clang::FieldDecl*, FieldPoint> Fields;
73 typedef std::vector<const clang::Type*> TemplateArgs;
75 ~RecordInfo();
77 clang::CXXRecordDecl* record() const { return record_; }
78 const std::string& name() const { return name_; }
79 Fields& GetFields();
80 Bases& GetBases();
81 clang::CXXMethodDecl* GetTraceMethod();
82 clang::CXXMethodDecl* GetTraceDispatchMethod();
83 clang::CXXMethodDecl* GetFinalizeDispatchMethod();
85 bool GetTemplateArgs(size_t count, TemplateArgs* output_args);
87 bool IsHeapAllocatedCollection();
88 bool IsGCDerived();
89 bool IsGCAllocated();
90 bool IsGCFinalized();
91 bool IsGCMixin();
92 bool IsStackAllocated();
93 bool IsNonNewable();
94 bool IsOnlyPlacementNewable();
95 bool IsGCMixinInstance();
96 clang::CXXMethodDecl* DeclaresNewOperator();
98 bool RequiresTraceMethod();
99 bool NeedsFinalization();
100 bool DeclaresGCMixinMethods();
101 bool DeclaresLocalTraceMethod();
102 TracingStatus NeedsTracing(Edge::NeedsTracingOption);
103 clang::CXXMethodDecl* InheritsNonVirtualTrace();
104 bool IsConsideredAbstract();
106 static clang::CXXRecordDecl* GetDependentTemplatedDecl(const clang::Type&);
108 private:
109 RecordInfo(clang::CXXRecordDecl* record, RecordCache* cache);
111 void walkBases();
113 Fields* CollectFields();
114 Bases* CollectBases();
115 void DetermineTracingMethods();
116 bool InheritsTrace();
118 Edge* CreateEdge(const clang::Type* type);
120 RecordCache* cache_;
121 clang::CXXRecordDecl* record_;
122 const std::string name_;
123 TracingStatus fields_need_tracing_;
124 Bases* bases_;
125 Fields* fields_;
127 enum CachedBool { kFalse = 0, kTrue = 1, kNotComputed = 2 };
128 CachedBool is_stack_allocated_;
129 CachedBool is_non_newable_;
130 CachedBool is_only_placement_newable_;
131 CachedBool does_need_finalization_;
132 CachedBool has_gc_mixin_methods_;
133 CachedBool is_declaring_local_trace_;
135 bool determined_trace_methods_;
136 clang::CXXMethodDecl* trace_method_;
137 clang::CXXMethodDecl* trace_dispatch_method_;
138 clang::CXXMethodDecl* finalize_dispatch_method_;
140 bool is_gc_derived_;
142 std::vector<std::string> gc_base_names_;
144 friend class RecordCache;
147 class RecordCache {
148 public:
149 RecordInfo* Lookup(clang::CXXRecordDecl* record);
151 RecordInfo* Lookup(const clang::CXXRecordDecl* record) {
152 return Lookup(const_cast<clang::CXXRecordDecl*>(record));
155 RecordInfo* Lookup(clang::DeclContext* decl) {
156 return Lookup(clang::dyn_cast<clang::CXXRecordDecl>(decl));
159 RecordInfo* Lookup(const clang::Type* type) {
160 return Lookup(type->getAsCXXRecordDecl());
163 RecordInfo* Lookup(const clang::QualType& type) {
164 return Lookup(type.getTypePtr());
167 ~RecordCache() {
168 for (Cache::iterator it = cache_.begin(); it != cache_.end(); ++it) {
169 if (!it->second.fields_)
170 continue;
171 for (RecordInfo::Fields::iterator fit = it->second.fields_->begin();
172 fit != it->second.fields_->end();
173 ++fit) {
174 fit->second.deleteEdge();
179 private:
180 typedef std::map<clang::CXXRecordDecl*, RecordInfo> Cache;
181 Cache cache_;
184 #endif // TOOLS_BLINK_GC_PLUGIN_RECORD_INFO_H_