forked from OSchip/llvm-project
Unique code-completion strings. On Cocoa.h, this costs us about 4% in
speed but saves us about 25% of the memory usage for strings. llvm-svn: 124704
This commit is contained in:
parent
0917d6e5d5
commit
801acff462
|
@ -15,7 +15,9 @@
|
|||
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/AST/CanonicalType.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "clang-c/Index.h"
|
||||
|
@ -421,11 +423,47 @@ public:
|
|||
std::string getAsString() const;
|
||||
};
|
||||
|
||||
/// \brief \c DenseMap information object for StringRefs.
|
||||
struct DenseMapStringRefInfo {
|
||||
static inline llvm::StringRef getEmptyKey() {
|
||||
return llvm::StringRef(reinterpret_cast<const char*>((intptr_t)-1), 0);
|
||||
}
|
||||
static inline llvm::StringRef getTombstoneKey() {
|
||||
return llvm::StringRef(reinterpret_cast<const char *>((intptr_t)-2), 0);
|
||||
}
|
||||
static unsigned getHashValue(llvm::StringRef Str) {
|
||||
return llvm::HashString(Str);
|
||||
}
|
||||
static bool isEqual(llvm::StringRef LHS, llvm::StringRef RHS) {
|
||||
if (LHS.size() == 0 && RHS.size() == 0) {
|
||||
intptr_t LHSVal = reinterpret_cast<intptr_t>(LHS.data());
|
||||
intptr_t RHSVal = reinterpret_cast<intptr_t>(RHS.data());
|
||||
if (LHSVal == -1 || LHSVal == -2 || RHSVal == -1 || RHSVal == -2)
|
||||
return LHSVal == RHSVal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief An allocator used specifically for the purpose of code completion.
|
||||
class CodeCompletionAllocator : public llvm::BumpPtrAllocator {
|
||||
llvm::DenseSet<llvm::StringRef, DenseMapStringRefInfo> UniqueStrings;
|
||||
unsigned StringBytesAllocated;
|
||||
unsigned StringBytesUniqued;
|
||||
unsigned StringsAllocated;
|
||||
unsigned StringsUniqued;
|
||||
|
||||
public:
|
||||
CodeCompletionAllocator();
|
||||
~CodeCompletionAllocator();
|
||||
|
||||
/// \brief Copy the given string into this allocator.
|
||||
const char *CopyString(llvm::StringRef String);
|
||||
|
||||
void PrintStats();
|
||||
};
|
||||
|
||||
/// \brief A builder class used to construct new code-completion strings.
|
||||
|
|
|
@ -220,10 +220,41 @@ const char *CodeCompletionString::getTypedText() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
CodeCompletionAllocator::CodeCompletionAllocator()
|
||||
: llvm::BumpPtrAllocator(), StringBytesAllocated(0), StringBytesUniqued(0),
|
||||
StringsAllocated(0), StringsUniqued(0)
|
||||
{
|
||||
}
|
||||
|
||||
CodeCompletionAllocator::~CodeCompletionAllocator() { }
|
||||
|
||||
void CodeCompletionAllocator::PrintStats() {
|
||||
llvm::errs() << "---Code completion memory allocation---\n"
|
||||
<< "String bytes uniqued: " << StringBytesUniqued << "/"
|
||||
<< StringBytesAllocated << " ("
|
||||
<< ((float)StringBytesUniqued*100/StringBytesAllocated)
|
||||
<< ")\nStrings uniqued: " << StringsUniqued << "/" << StringsAllocated
|
||||
<< " (" << ((float)StringsUniqued*100/StringsAllocated)
|
||||
<< ")\n";
|
||||
|
||||
llvm::BumpPtrAllocator::PrintStats();
|
||||
}
|
||||
|
||||
const char *CodeCompletionAllocator::CopyString(llvm::StringRef String) {
|
||||
llvm::DenseSet<llvm::StringRef, DenseMapStringRefInfo>::iterator Uniqued
|
||||
= UniqueStrings.find(String);
|
||||
++StringsAllocated;
|
||||
StringBytesAllocated += String.size() + 1;
|
||||
if (Uniqued != UniqueStrings.end()) {
|
||||
StringBytesUniqued += String.size() + 1;
|
||||
++StringsUniqued;
|
||||
return Uniqued->data();
|
||||
}
|
||||
|
||||
char *Mem = (char *)Allocate(String.size() + 1, 1);
|
||||
std::copy(String.begin(), String.end(), Mem);
|
||||
Mem[String.size()] = 0;
|
||||
UniqueStrings.insert(llvm::StringRef(Mem, String.size()));
|
||||
return Mem;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue