dang created this revision. dang added reviewers: zixuw, QuietMisdreavus, ributzka. Herald added a project: All. dang requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Using a BumpPtrAllocator introduced memory leaks for APIRecords as they contain a std::vector. This meant that we needed to always keep a reference to the records in APISet and arrange for their destructor to get called appropriately. This was further complicated by the need for records to own sub-records as these subrecords would still need to be allocated via the BumpPtrAllocator and the owning record would now need to arrange for the destructor of its subrecords to be called appropriately. Since APIRecords contain a std::vector so whenever elements get added to that there is an associated heap allocation regardless. Since performance isn't currently our main priority it makes sense to use regular unique_ptr to keep track of APIRecords, this way we don't need to arrange for destructors to get called. The BumpPtrAllocator is still used for strings such as USRs so that we can easily de-duplicate them as necessary. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122331 Files: clang/include/clang/ExtractAPI/API.h clang/lib/ExtractAPI/API.cpp
Index: clang/lib/ExtractAPI/API.cpp =================================================================== --- clang/lib/ExtractAPI/API.cpp +++ clang/lib/ExtractAPI/API.cpp @@ -18,6 +18,7 @@ #include "clang/AST/RawCommentList.h" #include "clang/Index/USRGeneration.h" #include "llvm/Support/Allocator.h" +#include <memory> using namespace clang::extractapi; using namespace llvm; @@ -32,9 +33,9 @@ auto Result = Globals.insert({Name, nullptr}); if (Result.second) { // Create the record if it does not already exist. - auto Record = APIRecordUniquePtr<GlobalRecord>(new (Allocator) GlobalRecord{ + auto Record = std::make_unique<GlobalRecord>( Kind, Name, USR, Loc, Availability, Linkage, Comment, Fragments, - SubHeading, Signature}); + SubHeading, Signature); Result.first->second = std::move(Record); } return Result.first->second.get(); @@ -63,9 +64,8 @@ EnumRecord *Enum, StringRef Name, StringRef USR, PresumedLoc Loc, const AvailabilityInfo &Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading) { - auto Record = - APIRecordUniquePtr<EnumConstantRecord>(new (Allocator) EnumConstantRecord{ - Name, USR, Loc, Availability, Comment, Declaration, SubHeading}); + auto Record = std::make_unique<EnumConstantRecord>( + Name, USR, Loc, Availability, Comment, Declaration, SubHeading); return Enum->Constants.emplace_back(std::move(Record)).get(); } @@ -77,8 +77,8 @@ auto Result = Enums.insert({Name, nullptr}); if (Result.second) { // Create the record if it does not already exist. - auto Record = APIRecordUniquePtr<EnumRecord>(new (Allocator) EnumRecord{ - Name, USR, Loc, Availability, Comment, Declaration, SubHeading}); + auto Record = std::make_unique<EnumRecord>( + Name, USR, Loc, Availability, Comment, Declaration, SubHeading); Result.first->second = std::move(Record); } return Result.first->second.get(); @@ -90,9 +90,8 @@ const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading) { - auto Record = - APIRecordUniquePtr<StructFieldRecord>(new (Allocator) StructFieldRecord{ - Name, USR, Loc, Availability, Comment, Declaration, SubHeading}); + auto Record = std::make_unique<StructFieldRecord>( + Name, USR, Loc, Availability, Comment, Declaration, SubHeading); return Struct->Fields.emplace_back(std::move(Record)).get(); } @@ -104,8 +103,8 @@ auto Result = Structs.insert({Name, nullptr}); if (Result.second) { // Create the record if it does not already exist. - auto Record = APIRecordUniquePtr<StructRecord>(new (Allocator) StructRecord{ - Name, USR, Loc, Availability, Comment, Declaration, SubHeading}); + auto Record = std::make_unique<StructRecord>( + Name, USR, Loc, Availability, Comment, Declaration, SubHeading); Result.first->second = std::move(Record); } return Result.first->second.get(); Index: clang/include/clang/ExtractAPI/API.h =================================================================== --- clang/include/clang/ExtractAPI/API.h +++ clang/include/clang/ExtractAPI/API.h @@ -30,25 +30,6 @@ #include "llvm/Support/Casting.h" #include <memory> -namespace { - -/// \brief A custom deleter used for ``std::unique_ptr`` to APIRecords stored -/// in the BumpPtrAllocator. -/// -/// \tparam T the exact type of the APIRecord subclass. -template <typename T> struct UniquePtrBumpPtrAllocatorDeleter { - void operator()(T *Instance) { Instance->~T(); } -}; - -/// A unique pointer to an APIRecord stored in the BumpPtrAllocator. -/// -/// \tparam T the exact type of the APIRecord subclass. -template <typename T> -using APIRecordUniquePtr = - std::unique_ptr<T, UniquePtrBumpPtrAllocatorDeleter<T>>; - -} // anonymous namespace - namespace clang { namespace extractapi { @@ -165,7 +146,7 @@ /// This holds information associated with enums. struct EnumRecord : APIRecord { - SmallVector<APIRecordUniquePtr<EnumConstantRecord>> Constants; + SmallVector<std::unique_ptr<EnumConstantRecord>> Constants; EnumRecord(StringRef Name, StringRef USR, PresumedLoc Loc, const AvailabilityInfo &Availability, const DocComment &Comment, @@ -194,7 +175,7 @@ /// This holds information associated with structs. struct StructRecord : APIRecord { - SmallVector<APIRecordUniquePtr<StructFieldRecord>> Fields; + SmallVector<std::unique_ptr<StructFieldRecord>> Fields; StructRecord(StringRef Name, StringRef USR, PresumedLoc Loc, const AvailabilityInfo &Availability, const DocComment &Comment, @@ -302,17 +283,16 @@ /// A map to store the set of GlobalRecord%s with the declaration name as the /// key. using GlobalRecordMap = - llvm::MapVector<StringRef, APIRecordUniquePtr<GlobalRecord>>; + llvm::MapVector<StringRef, std::unique_ptr<GlobalRecord>>; /// A map to store the set of EnumRecord%s with the declaration name as the /// key. - using EnumRecordMap = - llvm::MapVector<StringRef, APIRecordUniquePtr<EnumRecord>>; + using EnumRecordMap = llvm::MapVector<StringRef, std::unique_ptr<EnumRecord>>; /// A map to store the set of StructRecord%s with the declaration name as the /// key. using StructRecordMap = - llvm::MapVector<StringRef, APIRecordUniquePtr<StructRecord>>; + llvm::MapVector<StringRef, std::unique_ptr<StructRecord>>; /// Get the target triple for the ExtractAPI invocation. const llvm::Triple &getTarget() const { return Target; } @@ -340,7 +320,9 @@ : Target(Target), LangOpts(LangOpts) {} private: - /// BumpPtrAllocator to store APIRecord%s and generated/copied strings. + /// BumpPtrAllocator to store generated/copied strings. + /// + /// Note: The main use for this is being able to deduplicate strings. llvm::BumpPtrAllocator Allocator; const llvm::Triple Target;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits