From c3015a914fc8558ddfcd5e7c581808c5c8eae6cf Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 8 Mar 2010 20:56:29 +0000 Subject: [PATCH] Allocate ASTRecordLayout objects using the allocator associated with ASTContext. This allows them to be allocated using a BumpPtrAllocated in the common case. llvm-svn: 97978 --- clang/include/clang/AST/RecordLayout.h | 39 +++------------ clang/lib/AST/ASTContext.cpp | 26 +++++----- clang/lib/AST/CMakeLists.txt | 3 +- clang/lib/AST/RecordLayout.cpp | 69 ++++++++++++++++++++++++++ clang/lib/AST/RecordLayoutBuilder.cpp | 35 ++++++------- 5 files changed, 110 insertions(+), 62 deletions(-) create mode 100644 clang/lib/AST/RecordLayout.cpp diff --git a/clang/include/clang/AST/RecordLayout.h b/clang/include/clang/AST/RecordLayout.h index e8d1788ded88..cd25969db0b0 100644 --- a/clang/include/clang/AST/RecordLayout.h +++ b/clang/include/clang/AST/RecordLayout.h @@ -128,47 +128,24 @@ private: friend class ASTContext; friend class ASTRecordLayoutBuilder; - ASTRecordLayout(uint64_t size, unsigned alignment, unsigned datasize, - const uint64_t *fieldoffsets, unsigned fieldcount) - : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), - FieldCount(fieldcount), CXXInfo(0) { - if (FieldCount > 0) { - FieldOffsets = new uint64_t[FieldCount]; - for (unsigned i = 0; i < FieldCount; ++i) - FieldOffsets[i] = fieldoffsets[i]; - } - } + ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment, + unsigned datasize, const uint64_t *fieldoffsets, + unsigned fieldcount); // Constructor for C++ records. - ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize, + ASTRecordLayout(ASTContext &Ctx, + uint64_t size, unsigned alignment, uint64_t datasize, const uint64_t *fieldoffsets, unsigned fieldcount, uint64_t nonvirtualsize, unsigned nonvirtualalign, const PrimaryBaseInfo &PrimaryBase, const std::pair *bases, unsigned numbases, const std::pair *vbases, - unsigned numvbases) - : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), - FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) { - if (FieldCount > 0) { - FieldOffsets = new uint64_t[FieldCount]; - for (unsigned i = 0; i < FieldCount; ++i) - FieldOffsets[i] = fieldoffsets[i]; - } + unsigned numvbases); - CXXInfo->PrimaryBase = PrimaryBase; - CXXInfo->NonVirtualSize = nonvirtualsize; - CXXInfo->NonVirtualAlign = nonvirtualalign; - for (unsigned i = 0; i != numbases; ++i) - CXXInfo->BaseOffsets[bases[i].first] = bases[i].second; - for (unsigned i = 0; i != numvbases; ++i) - CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second; - } + ~ASTRecordLayout() {} - ~ASTRecordLayout() { - delete [] FieldOffsets; - delete CXXInfo; - } + void Destroy(ASTContext &Ctx); ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d8c1c8485824..e2c80a6da59d 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -78,21 +78,21 @@ ASTContext::~ASTContext() { // Increment in loop to prevent using deallocated memory. Deallocate(&*I++); } - } - for (llvm::DenseMap::iterator - I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) { - // Increment in loop to prevent using deallocated memory. - ASTRecordLayout *R = const_cast((I++)->second); - delete R; - } + for (llvm::DenseMap::iterator + I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) { + // Increment in loop to prevent using deallocated memory. + if (ASTRecordLayout *R = const_cast((I++)->second)) + R->Destroy(*this); + } - for (llvm::DenseMap::iterator - I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) { - // Increment in loop to prevent using deallocated memory. - ASTRecordLayout *R = const_cast((I++)->second); - delete R; + for (llvm::DenseMap::iterator + I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) { + // Increment in loop to prevent using deallocated memory. + if (ASTRecordLayout *R = const_cast((I++)->second)) + R->Destroy(*this); + } } // Destroy nested-name-specifiers. diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index e5bd9b7722c5..2f1a6af77aa9 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -4,8 +4,8 @@ add_clang_library(clangAST APValue.cpp ASTConsumer.cpp ASTContext.cpp - ASTImporter.cpp ASTDiagnostic.cpp + ASTImporter.cpp AttrImpl.cpp CXXInheritance.cpp Decl.cpp @@ -23,6 +23,7 @@ add_clang_library(clangAST InheritViz.cpp NestedNameSpecifier.cpp ParentMap.cpp + RecordLayout.cpp RecordLayoutBuilder.cpp Stmt.cpp StmtDumper.cpp diff --git a/clang/lib/AST/RecordLayout.cpp b/clang/lib/AST/RecordLayout.cpp new file mode 100644 index 000000000000..9f8bdec94ee6 --- /dev/null +++ b/clang/lib/AST/RecordLayout.cpp @@ -0,0 +1,69 @@ +//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the RecordLayout interface. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/ASTContext.h" +#include "clang/AST/RecordLayout.h" + +using namespace clang; + +void ASTRecordLayout::Destroy(ASTContext &Ctx) { + if (FieldOffsets) + Ctx.Deallocate(FieldOffsets); + if (CXXInfo) + Ctx.Deallocate(CXXInfo); + this->~ASTRecordLayout(); + Ctx.Deallocate(this); +} + +ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment, + unsigned datasize, const uint64_t *fieldoffsets, + unsigned fieldcount) + : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), + FieldCount(fieldcount), CXXInfo(0) { + if (FieldCount > 0) { + FieldOffsets = new (Ctx) uint64_t[FieldCount]; + for (unsigned i = 0; i < FieldCount; ++i) + FieldOffsets[i] = fieldoffsets[i]; + } +} + +// Constructor for C++ records. +ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, + uint64_t size, unsigned alignment, + uint64_t datasize, + const uint64_t *fieldoffsets, + unsigned fieldcount, + uint64_t nonvirtualsize, + unsigned nonvirtualalign, + const PrimaryBaseInfo &PrimaryBase, + const std::pair *bases, + unsigned numbases, + const std::pair *vbases, + unsigned numvbases) + : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment), + FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo) +{ + if (FieldCount > 0) { + FieldOffsets = new (Ctx) uint64_t[FieldCount]; + for (unsigned i = 0; i < FieldCount; ++i) + FieldOffsets[i] = fieldoffsets[i]; + } + + CXXInfo->PrimaryBase = PrimaryBase; + CXXInfo->NonVirtualSize = nonvirtualsize; + CXXInfo->NonVirtualAlign = nonvirtualalign; + for (unsigned i = 0; i != numbases; ++i) + CXXInfo->BaseOffsets[bases[i].first] = bases[i].second; + for (unsigned i = 0; i != numvbases; ++i) + CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second; +} diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index 10c5089f2253..22285ca42032 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -675,9 +675,10 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, Builder.Layout(D); if (!isa(D)) - return new ASTRecordLayout(Builder.Size, Builder.Alignment, Builder.Size, - Builder.FieldOffsets.data(), - Builder.FieldOffsets.size()); + return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment, + Builder.Size, + Builder.FieldOffsets.data(), + Builder.FieldOffsets.size()); // FIXME: This is not always correct. See the part about bitfields at // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info. @@ -690,16 +691,16 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, uint64_t NonVirtualSize = IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize; - return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize, - Builder.FieldOffsets.data(), - Builder.FieldOffsets.size(), - NonVirtualSize, - Builder.NonVirtualAlignment, - Builder.PrimaryBase, - Builder.Bases.data(), - Builder.Bases.size(), - Builder.VBases.data(), - Builder.VBases.size()); + return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment, + DataSize, Builder.FieldOffsets.data(), + Builder.FieldOffsets.size(), + NonVirtualSize, + Builder.NonVirtualAlignment, + Builder.PrimaryBase, + Builder.Bases.data(), + Builder.Bases.size(), + Builder.VBases.data(), + Builder.VBases.size()); } const ASTRecordLayout * @@ -710,10 +711,10 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, Builder.Layout(D, Impl); - return new ASTRecordLayout(Builder.Size, Builder.Alignment, - Builder.DataSize, - Builder.FieldOffsets.data(), - Builder.FieldOffsets.size()); + return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment, + Builder.DataSize, + Builder.FieldOffsets.data(), + Builder.FieldOffsets.size()); } const CXXMethodDecl * -- GitLab