• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 // This file defines the names used by GC infrastructure.
6 
7 #ifndef TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
8 #define TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
9 
10 #include "clang/AST/AST.h"
11 #include "clang/AST/Attr.h"
12 
13 const char kNewOperatorName[] = "operator new";
14 const char kCreateName[] = "create";
15 const char kTraceName[] = "trace";
16 const char kFinalizeName[] = "finalizeGarbageCollectedObject";
17 const char kTraceAfterDispatchName[] = "traceAfterDispatch";
18 const char kRegisterWeakMembersName[] = "registerWeakMembers";
19 const char kHeapAllocatorName[] = "HeapAllocator";
20 const char kTraceIfNeededName[] = "TraceIfNeeded";
21 
22 class Config {
23  public:
IsMember(const std::string & name)24   static bool IsMember(const std::string& name) {
25     return name == "Member";
26   }
27 
IsWeakMember(const std::string & name)28   static bool IsWeakMember(const std::string& name) {
29     return name == "WeakMember";
30   }
31 
IsMemberHandle(const std::string & name)32   static bool IsMemberHandle(const std::string& name) {
33     return IsMember(name) ||
34            IsWeakMember(name);
35   }
36 
IsPersistent(const std::string & name)37   static bool IsPersistent(const std::string& name) {
38     return name == "Persistent";
39   }
40 
IsPersistentHandle(const std::string & name)41   static bool IsPersistentHandle(const std::string& name) {
42     return IsPersistent(name) ||
43            IsPersistentGCCollection(name);
44   }
45 
IsRawPtr(const std::string & name)46   static bool IsRawPtr(const std::string& name) {
47     return name == "RawPtr";
48   }
49 
IsRefPtr(const std::string & name)50   static bool IsRefPtr(const std::string& name) {
51     return name == "RefPtr";
52   }
53 
IsOwnPtr(const std::string & name)54   static bool IsOwnPtr(const std::string& name) {
55     return name == "OwnPtr";
56   }
57 
IsWTFCollection(const std::string & name)58   static bool IsWTFCollection(const std::string& name) {
59     return name == "Vector" ||
60            name == "Deque" ||
61            name == "HashSet" ||
62            name == "ListHashSet" ||
63            name == "LinkedHashSet" ||
64            name == "HashCountedSet" ||
65            name == "HashMap";
66   }
67 
IsGCCollection(const std::string & name)68   static bool IsGCCollection(const std::string& name) {
69     return name == "HeapVector" ||
70            name == "HeapDeque" ||
71            name == "HeapHashSet" ||
72            name == "HeapListHashSet" ||
73            name == "HeapLinkedHashSet" ||
74            name == "HeapHashCountedSet" ||
75            name == "HeapHashMap" ||
76            IsPersistentGCCollection(name);
77   }
78 
IsPersistentGCCollection(const std::string & name)79   static bool IsPersistentGCCollection(const std::string& name) {
80     return name == "PersistentHeapVector" ||
81            name == "PersistentHeapDeque" ||
82            name == "PersistentHeapHashSet" ||
83            name == "PersistentHeapListHashSet" ||
84            name == "PersistentHeapLinkedHashSet" ||
85            name == "PersistentHeapHashCountedSet" ||
86            name == "PersistentHeapHashMap";
87   }
88 
IsHashMap(const std::string & name)89   static bool IsHashMap(const std::string& name) {
90     return name == "HashMap" ||
91            name == "HeapHashMap" ||
92            name == "PersistentHeapHashMap";
93   }
94 
95   // Following http://crrev.com/369633033 (Blink r177436),
96   // ignore blink::ScriptWrappable's destructor.
97   // FIXME: remove when its non-Oilpan destructor is removed.
HasIgnorableDestructor(const std::string & ns,const std::string & name)98   static bool HasIgnorableDestructor(const std::string& ns,
99                                      const std::string& name) {
100     return ns == "blink" && name == "ScriptWrappable";
101   }
102 
103   // Assumes name is a valid collection name.
CollectionDimension(const std::string & name)104   static size_t CollectionDimension(const std::string& name) {
105     return (IsHashMap(name) || name == "pair") ? 2 : 1;
106   }
107 
IsDummyBase(const std::string & name)108   static bool IsDummyBase(const std::string& name) {
109     return name == "DummyBase";
110   }
111 
IsRefCountedBase(const std::string & name)112   static bool IsRefCountedBase(const std::string& name) {
113     return name == "RefCounted" ||
114            name == "ThreadSafeRefCounted";
115   }
116 
IsGCMixinBase(const std::string & name)117   static bool IsGCMixinBase(const std::string& name) {
118     return name == "GarbageCollectedMixin";
119   }
120 
IsGCFinalizedBase(const std::string & name)121   static bool IsGCFinalizedBase(const std::string& name) {
122     return name == "GarbageCollectedFinalized" ||
123            name == "RefCountedGarbageCollected" ||
124            name == "ThreadSafeRefCountedGarbageCollected";
125   }
126 
IsGCBase(const std::string & name)127   static bool IsGCBase(const std::string& name) {
128     return name == "GarbageCollected" ||
129            IsGCFinalizedBase(name) ||
130            IsGCMixinBase(name);
131   }
132 
133   // Returns true of the base classes that do not need a vtable entry for trace
134   // because they cannot possibly initiate a GC during construction.
IsSafePolymorphicBase(const std::string & name)135   static bool IsSafePolymorphicBase(const std::string& name) {
136     return IsGCBase(name) || IsDummyBase(name) || IsRefCountedBase(name);
137   }
138 
IsAnnotated(clang::Decl * decl,const std::string & anno)139   static bool IsAnnotated(clang::Decl* decl, const std::string& anno) {
140     clang::AnnotateAttr* attr = decl->getAttr<clang::AnnotateAttr>();
141     return attr && (attr->getAnnotation() == anno);
142   }
143 
IsStackAnnotated(clang::Decl * decl)144   static bool IsStackAnnotated(clang::Decl* decl) {
145     return IsAnnotated(decl, "blink_stack_allocated");
146   }
147 
IsIgnoreAnnotated(clang::Decl * decl)148   static bool IsIgnoreAnnotated(clang::Decl* decl) {
149     return IsAnnotated(decl, "blink_gc_plugin_ignore");
150   }
151 
IsIgnoreCycleAnnotated(clang::Decl * decl)152   static bool IsIgnoreCycleAnnotated(clang::Decl* decl) {
153     return IsAnnotated(decl, "blink_gc_plugin_ignore_cycle") ||
154            IsIgnoreAnnotated(decl);
155   }
156 
IsVisitor(const std::string & name)157   static bool IsVisitor(const std::string& name) { return name == "Visitor"; }
158 
159   static bool IsTraceMethod(clang::FunctionDecl* method,
160                             bool* isTraceAfterDispatch = 0) {
161     if (method->getNumParams() != 1)
162       return false;
163 
164     const std::string& name = method->getNameAsString();
165     if (name != kTraceName && name != kTraceAfterDispatchName)
166       return false;
167 
168     const clang::QualType& formal_type = method->getParamDecl(0)->getType();
169     if (!formal_type->isPointerType())
170       return false;
171 
172     clang::CXXRecordDecl* pointee_type =
173         formal_type->getPointeeType()->getAsCXXRecordDecl();
174     if (!pointee_type)
175       return false;
176 
177     if (!IsVisitor(pointee_type->getName()))
178       return false;
179 
180     if (isTraceAfterDispatch)
181       *isTraceAfterDispatch = (name == kTraceAfterDispatchName);
182     return true;
183   }
184 
StartsWith(const std::string & str,const std::string & prefix)185   static bool StartsWith(const std::string& str, const std::string& prefix) {
186     if (prefix.size() > str.size())
187       return false;
188     return str.compare(0, prefix.size(), prefix) == 0;
189   }
190 
EndsWith(const std::string & str,const std::string & suffix)191   static bool EndsWith(const std::string& str, const std::string& suffix) {
192     if (suffix.size() > str.size())
193       return false;
194     return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
195   }
196 };
197 
198 #endif  // TOOLS_BLINK_GC_PLUGIN_CONFIG_H_
199