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