Home | History | Annotate | Download | only in blink_gc_plugin
      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:
     24   static bool IsMember(const std::string& name) {
     25     return name == "Member";
     26   }
     27 
     28   static bool IsWeakMember(const std::string& name) {
     29     return name == "WeakMember";
     30   }
     31 
     32   static bool IsMemberHandle(const std::string& name) {
     33     return IsMember(name) ||
     34            IsWeakMember(name);
     35   }
     36 
     37   static bool IsPersistent(const std::string& name) {
     38     return name == "Persistent";
     39   }
     40 
     41   static bool IsPersistentHandle(const std::string& name) {
     42     return IsPersistent(name) ||
     43            IsPersistentGCCollection(name);
     44   }
     45 
     46   static bool IsRawPtr(const std::string& name) {
     47     return name == "RawPtr";
     48   }
     49 
     50   static bool IsRefPtr(const std::string& name) {
     51     return name == "RefPtr";
     52   }
     53 
     54   static bool IsOwnPtr(const std::string& name) {
     55     return name == "OwnPtr";
     56   }
     57 
     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 
     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 
     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 
     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.
     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.
    104   static size_t CollectionDimension(const std::string& name) {
    105     return (IsHashMap(name) || name == "pair") ? 2 : 1;
    106   }
    107 
    108   static bool IsDummyBase(const std::string& name) {
    109     return name == "DummyBase";
    110   }
    111 
    112   static bool IsRefCountedBase(const std::string& name) {
    113     return name == "RefCounted" ||
    114            name == "ThreadSafeRefCounted";
    115   }
    116 
    117   static bool IsGCMixinBase(const std::string& name) {
    118     return name == "GarbageCollectedMixin";
    119   }
    120 
    121   static bool IsGCFinalizedBase(const std::string& name) {
    122     return name == "GarbageCollectedFinalized" ||
    123            name == "RefCountedGarbageCollected" ||
    124            name == "ThreadSafeRefCountedGarbageCollected";
    125   }
    126 
    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.
    135   static bool IsSafePolymorphicBase(const std::string& name) {
    136     return IsGCBase(name) || IsDummyBase(name) || IsRefCountedBase(name);
    137   }
    138 
    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 
    144   static bool IsStackAnnotated(clang::Decl* decl) {
    145     return IsAnnotated(decl, "blink_stack_allocated");
    146   }
    147 
    148   static bool IsIgnoreAnnotated(clang::Decl* decl) {
    149     return IsAnnotated(decl, "blink_gc_plugin_ignore");
    150   }
    151 
    152   static bool IsIgnoreCycleAnnotated(clang::Decl* decl) {
    153     return IsAnnotated(decl, "blink_gc_plugin_ignore_cycle") ||
    154            IsIgnoreAnnotated(decl);
    155   }
    156 
    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 
    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 
    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