Allocate CodeCompletionString and all of its components in a
BumpPtrAllocator, rather than manually new/delete'ing them. This optimization also allows us to avoid allocating memory for and copying constant strings (e.g., "return", "class"). This also required embedding the priority and availability of results within the code completion string, to avoid extra memory allocation within libclang. llvm-svn: 124673
This commit is contained in:
@@ -45,31 +45,12 @@
|
||||
using namespace clang;
|
||||
using namespace clang::cxstring;
|
||||
|
||||
namespace {
|
||||
/// \brief Stored representation of a completion string.
|
||||
///
|
||||
/// This is the representation behind a CXCompletionString.
|
||||
class CXStoredCodeCompletionString : public CodeCompletionString {
|
||||
unsigned Priority;
|
||||
CXAvailabilityKind Availability;
|
||||
|
||||
public:
|
||||
CXStoredCodeCompletionString(unsigned Priority,
|
||||
CXAvailabilityKind Availability)
|
||||
: Priority(Priority), Availability(Availability) { }
|
||||
|
||||
unsigned getPriority() const { return Priority; }
|
||||
CXAvailabilityKind getAvailability() const { return Availability; }
|
||||
};
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
enum CXCompletionChunkKind
|
||||
clang_getCompletionChunkKind(CXCompletionString completion_string,
|
||||
unsigned chunk_number) {
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
if (!CCStr || chunk_number >= CCStr->size())
|
||||
return CXCompletionChunk_Text;
|
||||
|
||||
@@ -124,8 +105,7 @@ clang_getCompletionChunkKind(CXCompletionString completion_string,
|
||||
|
||||
CXString clang_getCompletionChunkText(CXCompletionString completion_string,
|
||||
unsigned chunk_number) {
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
if (!CCStr || chunk_number >= CCStr->size())
|
||||
return createCXString((const char*)0);
|
||||
|
||||
@@ -165,8 +145,7 @@ CXString clang_getCompletionChunkText(CXCompletionString completion_string,
|
||||
CXCompletionString
|
||||
clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
|
||||
unsigned chunk_number) {
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
if (!CCStr || chunk_number >= CCStr->size())
|
||||
return 0;
|
||||
|
||||
@@ -203,22 +182,20 @@ clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
|
||||
}
|
||||
|
||||
unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
return CCStr? CCStr->size() : 0;
|
||||
}
|
||||
|
||||
unsigned clang_getCompletionPriority(CXCompletionString completion_string) {
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
|
||||
}
|
||||
|
||||
enum CXAvailabilityKind
|
||||
clang_getCompletionAvailability(CXCompletionString completion_string) {
|
||||
CXStoredCodeCompletionString *CCStr
|
||||
= (CXStoredCodeCompletionString *)completion_string;
|
||||
return CCStr? CCStr->getAvailability() : CXAvailability_Available;
|
||||
CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
|
||||
return CCStr? static_cast<CXAvailabilityKind>(CCStr->getAvailability())
|
||||
: CXAvailability_Available;
|
||||
}
|
||||
|
||||
/// \brief The CXCodeCompleteResults structure we allocate internally;
|
||||
@@ -251,6 +228,9 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
|
||||
/// \brief Temporary buffers that will be deleted once we have finished with
|
||||
/// the code-completion results.
|
||||
llvm::SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
|
||||
|
||||
/// \brief Allocator used to store code completion results.
|
||||
llvm::BumpPtrAllocator CodeCompletionAllocator;
|
||||
};
|
||||
|
||||
/// \brief Tracks the number of code-completion result objects that are
|
||||
@@ -272,8 +252,6 @@ AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults()
|
||||
}
|
||||
|
||||
AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
|
||||
for (unsigned I = 0, N = NumResults; I != N; ++I)
|
||||
delete (CXStoredCodeCompletionString *)Results[I].CompletionString;
|
||||
delete [] Results;
|
||||
|
||||
for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
|
||||
@@ -293,9 +271,8 @@ namespace {
|
||||
class CaptureCompletionResults : public CodeCompleteConsumer {
|
||||
AllocatedCXCodeCompleteResults &AllocatedResults;
|
||||
llvm::SmallVector<CXCompletionResult, 16> StoredResults;
|
||||
|
||||
public:
|
||||
explicit CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
|
||||
CaptureCompletionResults(AllocatedCXCodeCompleteResults &Results)
|
||||
: CodeCompleteConsumer(true, false, true, false),
|
||||
AllocatedResults(Results) { }
|
||||
~CaptureCompletionResults() { Finish(); }
|
||||
@@ -306,10 +283,9 @@ namespace {
|
||||
unsigned NumResults) {
|
||||
StoredResults.reserve(StoredResults.size() + NumResults);
|
||||
for (unsigned I = 0; I != NumResults; ++I) {
|
||||
CXStoredCodeCompletionString *StoredCompletion
|
||||
= new CXStoredCodeCompletionString(Results[I].Priority,
|
||||
Results[I].Availability);
|
||||
(void)Results[I].CreateCodeCompletionString(S, StoredCompletion);
|
||||
CodeCompletionString *StoredCompletion
|
||||
= Results[I].CreateCodeCompletionString(S,
|
||||
AllocatedResults.CodeCompletionAllocator);
|
||||
|
||||
CXCompletionResult R;
|
||||
R.CursorKind = Results[I].CursorKind;
|
||||
@@ -323,11 +299,9 @@ namespace {
|
||||
unsigned NumCandidates) {
|
||||
StoredResults.reserve(StoredResults.size() + NumCandidates);
|
||||
for (unsigned I = 0; I != NumCandidates; ++I) {
|
||||
// FIXME: Set priority, availability appropriately.
|
||||
CXStoredCodeCompletionString *StoredCompletion
|
||||
= new CXStoredCodeCompletionString(1, CXAvailability_Available);
|
||||
(void)Candidates[I].CreateSignatureString(CurrentArg, S,
|
||||
StoredCompletion);
|
||||
CodeCompletionString *StoredCompletion
|
||||
= Candidates[I].CreateSignatureString(CurrentArg, S,
|
||||
AllocatedResults.CodeCompletionAllocator);
|
||||
|
||||
CXCompletionResult R;
|
||||
R.CursorKind = CXCursor_NotImplemented;
|
||||
@@ -336,6 +310,10 @@ namespace {
|
||||
}
|
||||
}
|
||||
|
||||
virtual llvm::BumpPtrAllocator &getAllocator() {
|
||||
return AllocatedResults.CodeCompletionAllocator;
|
||||
}
|
||||
|
||||
private:
|
||||
void Finish() {
|
||||
AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
|
||||
@@ -596,10 +574,10 @@ namespace {
|
||||
struct OrderCompletionResults {
|
||||
bool operator()(const CXCompletionResult &XR,
|
||||
const CXCompletionResult &YR) const {
|
||||
CXStoredCodeCompletionString *X
|
||||
= (CXStoredCodeCompletionString *)XR.CompletionString;
|
||||
CXStoredCodeCompletionString *Y
|
||||
= (CXStoredCodeCompletionString *)YR.CompletionString;
|
||||
CodeCompletionString *X
|
||||
= (CodeCompletionString *)XR.CompletionString;
|
||||
CodeCompletionString *Y
|
||||
= (CodeCompletionString *)YR.CompletionString;
|
||||
|
||||
llvm::SmallString<256> XBuffer;
|
||||
llvm::StringRef XText = GetTypedName(X, XBuffer);
|
||||
|
||||
Reference in New Issue
Block a user