Skip to content

Commit 8f17b13

Browse files
committed
[index] Cache USR and name for decls
We were calculating these for every decl-occurrence, but we really only need them once per decl.
1 parent 5e63574 commit 8f17b13

File tree

2 files changed

+74
-34
lines changed

2 files changed

+74
-34
lines changed

include/swift/Index/IndexSymbol.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,11 @@ struct IndexSymbol {
8686
SymbolKind kind;
8787
SymbolSubKind subKind = SymbolSubKind::None;
8888
bool isRef;
89-
SmallString<32> name;
90-
SmallString<64> USR;
91-
SmallString<16> group;
89+
// The following strings are guaranteed to live at least as long as the
90+
// current indexing action.
91+
StringRef name;
92+
StringRef USR; // USR may be safely compared by pointer.
93+
StringRef group;
9294
unsigned line = 0;
9395
unsigned column = 0;
9496

@@ -105,7 +107,7 @@ struct FuncDeclIndexSymbol : public IndexSymbol {
105107
};
106108

107109
struct CallRefIndexSymbol : public IndexSymbol {
108-
llvm::SmallString<64> ReceiverUSR;
110+
StringRef ReceiverUSR;
109111
bool IsDynamic = false;
110112

111113
CallRefIndexSymbol() : IndexSymbol(CallReference) {}

lib/Index/Index.cpp

Lines changed: 68 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,21 @@
1616
#include "swift/AST/SourceEntityWalker.h"
1717
#include "swift/AST/USRGeneration.h"
1818
#include "swift/Basic/SourceManager.h"
19+
#include "swift/Basic/StringExtras.h"
1920
#include "llvm/ADT/APInt.h"
2021
#include "llvm/Support/FileSystem.h"
2122

2223
using namespace swift;
2324
using namespace swift::index;
2425

26+
static bool printDisplayName(const swift::ValueDecl *D, llvm::raw_ostream &OS) {
27+
if (!D->hasName())
28+
return true;
29+
30+
OS << D->getFullName();
31+
return false;
32+
}
33+
2534
namespace {
2635
// Adapter providing a common interface for a SourceFile/Module.
2736
class SourceFileOrModule {
@@ -83,6 +92,53 @@ class IndexSwiftASTWalker : public SourceEntityWalker {
8392
SmallVector<Expr *, 8> ExprStack;
8493
bool Cancelled = false;
8594

95+
struct NameAndUSR {
96+
StringRef USR;
97+
StringRef name;
98+
};
99+
typedef llvm::PointerIntPair<Decl *, 3> DeclAccessorPair;
100+
llvm::DenseMap<Decl *, NameAndUSR> nameAndUSRCache;
101+
llvm::DenseMap<DeclAccessorPair, StringRef> accessorUSRCache;
102+
StringScratchSpace stringStorage;
103+
104+
bool getNameAndUSR(ValueDecl *D, StringRef &name, StringRef &USR) {
105+
auto &result = nameAndUSRCache[D];
106+
if (result.USR.empty()) {
107+
SmallString<128> storage;
108+
{
109+
llvm::raw_svector_ostream OS(storage);
110+
if (ide::printDeclUSR(D, OS))
111+
return true;
112+
result.USR = stringStorage.copyString(OS.str());
113+
}
114+
115+
storage.clear();
116+
{
117+
llvm::raw_svector_ostream OS(storage);
118+
printDisplayName(D, OS);
119+
result.name = stringStorage.copyString(OS.str());
120+
}
121+
}
122+
123+
name = result.name;
124+
USR = result.USR;
125+
return false;
126+
}
127+
128+
StringRef getAccessorUSR(AbstractStorageDecl *D, AccessorKind AK) {
129+
assert(AK != AccessorKind::NotAccessor);
130+
assert(static_cast<int>(AK) < 0x111 && "AccessorKind too big for pair");
131+
DeclAccessorPair key(D, static_cast<int>(AK));
132+
auto &result = accessorUSRCache[key];
133+
if (result.empty()) {
134+
SmallString<128> storage;
135+
llvm::raw_svector_ostream OS(storage);
136+
ide::printAccessorUSR(D, AK, OS);
137+
result = stringStorage.copyString(OS.str());
138+
}
139+
return result;
140+
}
141+
86142
public:
87143
IndexSwiftASTWalker(IndexDataConsumer &IdxConsumer, ASTContext &Ctx,
88144
unsigned BufferID)
@@ -522,11 +578,9 @@ bool IndexSwiftASTWalker::reportPseudoAccessor(AbstractStorageDecl *D,
522578
auto handleInfo = [this, D, AccKind](IndexSymbol &Info) {
523579
Info.kind = SymbolKind::Accessor;
524580
Info.subKind = getSubKindForAccessor(AccKind);
525-
Info.name.clear();
526-
Info.USR.clear();
527-
Info.group.clear();
528-
llvm::raw_svector_ostream OS(Info.USR);
529-
ide::printAccessorUSR(D, AccKind, OS);
581+
Info.name = "";
582+
Info.USR = getAccessorUSR(D, AccKind);
583+
Info.group = "";
530584

531585
if (!IdxConsumer.startSourceEntity(Info)) {
532586
Cancelled = true;
@@ -708,14 +762,6 @@ bool IndexSwiftASTWalker::reportRef(ValueDecl *D, SourceLoc Loc) {
708762
return !Cancelled;
709763
}
710764

711-
static bool printDisplayName(const swift::ValueDecl *D, llvm::raw_ostream &OS) {
712-
if (!D->hasName())
713-
return true;
714-
715-
OS << D->getFullName();
716-
return false;
717-
}
718-
719765
bool IndexSwiftASTWalker::initIndexSymbol(ValueDecl *D, SourceLoc Loc,
720766
bool IsRef, IndexSymbol &Info) {
721767
assert(D);
@@ -729,18 +775,12 @@ bool IndexSwiftASTWalker::initIndexSymbol(ValueDecl *D, SourceLoc Loc,
729775

730776
Info.isRef = IsRef;
731777

732-
Info.name.clear();
733-
llvm::raw_svector_ostream NameOS(Info.name);
734-
printDisplayName(D, NameOS);
735-
736-
llvm::raw_svector_ostream OS(Info.USR);
737-
if (ide::printDeclUSR(D, OS))
778+
if (getNameAndUSR(D, Info.name, Info.USR))
738779
return true;
780+
739781
std::tie(Info.line, Info.column) = getLineCol(Loc);
740-
if (auto Group = D->getGroupName()) {
741-
Info.group.clear();
742-
Info.group.append(Group.getValue());
743-
}
782+
if (auto Group = D->getGroupName())
783+
Info.group = Group.getValue();
744784
return false;
745785
}
746786

@@ -784,10 +824,8 @@ bool IndexSwiftASTWalker::initFuncDeclIndexSymbol(ValueDecl *D,
784824
return true;
785825

786826
Info.IsTestCandidate = isTestCandidate(D);
787-
if (auto Group = D->getGroupName()) {
788-
Info.group.clear();
789-
Info.group.append(Group.getValue());
790-
}
827+
if (auto Group = D->getGroupName())
828+
Info.group = Group.getValue();
791829
return false;
792830
}
793831

@@ -848,9 +886,9 @@ bool IndexSwiftASTWalker::initCallRefIndexSymbol(Expr *CurrentE, Expr *ParentE,
848886
ReceiverTy = MetaT->getInstanceType();
849887

850888
if (auto TyD = ReceiverTy->getAnyNominal()) {
851-
llvm::raw_svector_ostream OS(Info.ReceiverUSR);
852-
ide::printDeclUSR(TyD, OS);
853-
889+
StringRef unused;
890+
if (getNameAndUSR(TyD, unused, Info.ReceiverUSR))
891+
return true;
854892
Info.IsDynamic = isDynamicCall(BaseE, D);
855893
}
856894
}

0 commit comments

Comments
 (0)