Skip to content

Commit 69971af

Browse files
committed
[SourceKit] Avoid one memcpy on potentially big sourcekit response data
A kind indicator is needed before the actual data when custom data are storeed as xpc dictionary values. Instead of prepending the kind bit by copying data to another buffer, let the data producers include it in the created data.
1 parent a07b35a commit 69971af

11 files changed

+51
-60
lines changed

tools/SourceKit/tools/sourcekitd/include/sourcekitd/CompactArray.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace sourcekitd {
2020

2121
class CompactArrayBuilderImpl {
2222
public:
23-
std::unique_ptr<llvm::MemoryBuffer> createBuffer() const;
23+
std::unique_ptr<llvm::MemoryBuffer> createBuffer(CustomBufferKind Kind) const;
2424
void appendTo(llvm::SmallVectorImpl<char> &Buf) const;
2525
unsigned copyInto(char *BufPtr) const;
2626
size_t sizeInBytes() const;

tools/SourceKit/tools/sourcekitd/include/sourcekitd/Internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class ResponseBuilder {
8686
void setBool(SourceKit::UIdent Key, bool val);
8787
Array setArray(SourceKit::UIdent Key);
8888
Dictionary setDictionary(SourceKit::UIdent Key);
89-
void setCustomBuffer(SourceKit::UIdent Key, CustomBufferKind Kind,
89+
void setCustomBuffer(SourceKit::UIdent Key,
9090
std::unique_ptr<llvm::MemoryBuffer> MemBuf);
9191

9292
private:

tools/SourceKit/tools/sourcekitd/lib/API/CodeCompletionResultsArray.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ void CodeCompletionResultsArrayBuilder::add(
7575

7676
std::unique_ptr<llvm::MemoryBuffer>
7777
CodeCompletionResultsArrayBuilder::createBuffer() {
78-
return Impl.Builder.createBuffer();
78+
return Impl.Builder.createBuffer(
79+
CustomBufferKind::CodeCompletionResultsArray);
7980
}
8081

8182
namespace {

tools/SourceKit/tools/sourcekitd/lib/API/CompactArray.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,13 @@ unsigned CompactArrayBuilderImpl::getOffsetForString(StringRef Str) {
7070
}
7171

7272
std::unique_ptr<llvm::MemoryBuffer>
73-
CompactArrayBuilderImpl::createBuffer() const {
73+
CompactArrayBuilderImpl::createBuffer(CustomBufferKind Kind) const {
74+
auto bodySize = sizeInBytes();
7475
std::unique_ptr<llvm::WritableMemoryBuffer> Buf;
75-
Buf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(sizeInBytes());
76-
copyInto(Buf->getBufferStart(), Buf->getBufferSize());
76+
Buf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
77+
sizeof(uint64_t) + bodySize);
78+
*reinterpret_cast<uint64_t*>(Buf->getBufferStart()) = (uint64_t)Kind;
79+
copyInto(Buf->getBufferStart() + sizeof(uint64_t), bodySize);
7780
return std::move(Buf);
7881
}
7982

tools/SourceKit/tools/sourcekitd/lib/API/DocStructureArray.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,16 +244,21 @@ std::unique_ptr<llvm::MemoryBuffer> DocStructureArrayBuilder::createBuffer() {
244244
size_t structureArrayBufferSize = impl.structureArrayBuffer.size();
245245
size_t structureBufferSize = impl.structureBuilder.sizeInBytes();
246246

247+
size_t kindSize = sizeof(uint64_t);
248+
247249
// Header:
248250
// * offset of each section start (5)
249251
// * offset of top structure array (relative to structure array section) (1)
250252
size_t headerSize = sizeof(uint64_t) * 6;
251253

252254
auto result = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
253255
inheritedTypesBufferSize + attrsBufferSize + elementsBufferSize +
254-
structureArrayBufferSize + structureBufferSize + headerSize);
256+
structureArrayBufferSize + structureBufferSize + headerSize + kindSize);
257+
258+
*reinterpret_cast<uint64_t *>(result->getBufferStart()) =
259+
(uint64_t)CustomBufferKind::DocStructureArray;
255260

256-
char *start = result->getBufferStart();
261+
char *start = result->getBufferStart() + kindSize;
257262
char *headerPtr = start;
258263
char *ptr = start + headerSize;
259264

tools/SourceKit/tools/sourcekitd/lib/API/DocSupportAnnotationArray.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ void DocSupportAnnotationArrayBuilder::add(const DocEntityInfo &Info) {
5353

5454
std::unique_ptr<llvm::MemoryBuffer>
5555
DocSupportAnnotationArrayBuilder::createBuffer() {
56-
return Impl.Builder.createBuffer();
56+
return Impl.Builder.createBuffer(CustomBufferKind::DocSupportAnnotationArray);
5757
}
5858

5959
namespace {

tools/SourceKit/tools/sourcekitd/lib/API/ExpressionTypeArray.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,18 @@ struct ExpressionTypeArrayBuilder::Implementation {
176176
return reader.count();
177177
}
178178

179-
std::unique_ptr<llvm::MemoryBuffer> createBuffer() {
179+
std::unique_ptr<llvm::MemoryBuffer> createBuffer(CustomBufferKind Kind) {
180180
std::array<CompactArrayBuilderImpl*, 3> builders =
181181
{&builder, &strBuilder, &protoBuilder};
182+
auto kindSize = sizeof(uint64_t);
182183
size_t headerSize = sizeof(uint64_t) * builders.size();
183-
auto allSize = headerSize;
184+
auto allSize = kindSize + headerSize;
184185
for (auto *b: builders)
185186
allSize += b->sizeInBytes();
186187
auto result = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(allSize);
187-
char *start = result->getBufferStart();
188+
*reinterpret_cast<uint64_t*>(result->getBufferStart()) = (uint64_t)Kind;
189+
190+
char *start = result->getBufferStart() + kindSize;
188191
char *headerPtr = start;
189192
char *ptr = start + headerSize;
190193
auto addBuilder = [&](CompactArrayBuilderImpl& buffer) {
@@ -223,7 +226,7 @@ void ExpressionTypeArrayBuilder::add(const ExpressionType &expType) {
223226

224227
std::unique_ptr<llvm::MemoryBuffer>
225228
ExpressionTypeArrayBuilder::createBuffer() {
226-
return Impl.createBuffer();
229+
return Impl.createBuffer(CustomBufferKind::ExpressionTypeArray);
227230
}
228231

229232
VariantFunctions ExpressionTypeArrayBuilder::Funcs = {

tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,9 +1422,7 @@ class SKDocConsumer : public DocInfoConsumer {
14221422
}
14231423

14241424
sourcekitd_response_t createResponse() {
1425-
TopDict.setCustomBuffer(KeyAnnotations,
1426-
CustomBufferKind::DocSupportAnnotationArray,
1427-
AnnotationsBuilder.createBuffer());
1425+
TopDict.setCustomBuffer(KeyAnnotations, AnnotationsBuilder.createBuffer());
14281426
return RespBuilder.createResponse();
14291427
}
14301428

@@ -1866,8 +1864,7 @@ static void reportExpressionTypeInfo(const RequestResult<ExpressionTypesInFile>
18661864
for (auto &R: Info.Results) {
18671865
ArrBuilder.add(R);
18681866
}
1869-
Dict.setCustomBuffer(KeyExpressionTypeList, CustomBufferKind::ExpressionTypeArray,
1870-
ArrBuilder.createBuffer());
1867+
Dict.setCustomBuffer(KeyExpressionTypeList, ArrBuilder.createBuffer());
18711868
Rec(Builder.createResponse());
18721869
}
18731870

@@ -1924,8 +1921,7 @@ class SKCodeCompletionConsumer : public CodeCompletionConsumer {
19241921
return createErrorRequestFailed(ErrorDescription.c_str());
19251922

19261923
RespBuilder.getDictionary().setCustomBuffer(KeyResults,
1927-
CustomBufferKind::CodeCompletionResultsArray,
1928-
ResultsBuilder.createBuffer());
1924+
ResultsBuilder.createBuffer());
19291925
return RespBuilder.createResponse();
19301926
}
19311927

@@ -2558,18 +2554,13 @@ sourcekitd_response_t SKEditorConsumer::createResponse() {
25582554
return Error;
25592555

25602556
if (Opts.EnableSyntaxMap) {
2561-
Dict.setCustomBuffer(KeySyntaxMap,
2562-
CustomBufferKind::TokenAnnotationsArray,
2563-
SyntaxMap.createBuffer());
2557+
Dict.setCustomBuffer(KeySyntaxMap, SyntaxMap.createBuffer());
25642558
}
25652559
if (!SemanticAnnotations.empty()) {
2566-
Dict.setCustomBuffer(KeyAnnotations,
2567-
CustomBufferKind::TokenAnnotationsArray,
2568-
SemanticAnnotations.createBuffer());
2560+
Dict.setCustomBuffer(KeyAnnotations, SemanticAnnotations.createBuffer());
25692561
}
25702562
if (Opts.EnableStructure) {
2571-
Dict.setCustomBuffer(KeySubStructure, CustomBufferKind::DocStructureArray,
2572-
DocStructure.createBuffer());
2563+
Dict.setCustomBuffer(KeySubStructure, DocStructure.createBuffer());
25732564
}
25742565

25752566

@@ -2756,11 +2747,13 @@ void serializeSyntaxTreeAsByteTree(
27562747
*SyntaxTree.getRaw(), UserInfo);
27572748

27582749
std::unique_ptr<llvm::WritableMemoryBuffer> Buf =
2759-
llvm::WritableMemoryBuffer::getNewUninitMemBuffer(Stream.data().size());
2760-
memcpy(Buf->getBufferStart(), Stream.data().data(), Stream.data().size());
2750+
llvm::WritableMemoryBuffer::getNewUninitMemBuffer(sizeof(uint64_t) + Stream.data().size());
2751+
*reinterpret_cast<uint64_t*>(Buf->getBufferStart()) =
2752+
(uint64_t)CustomBufferKind::RawData;
2753+
memcpy(Buf->getBufferStart() + sizeof(uint64_t),
2754+
Stream.data().data(), Stream.data().size());
27612755

2762-
Dict.setCustomBuffer(KeySerializedSyntaxTree, CustomBufferKind::RawData,
2763-
std::move(Buf));
2756+
Dict.setCustomBuffer(KeySerializedSyntaxTree, std::move(Buf));
27642757

27652758
auto EndClock = clock();
27662759
LOG_SECTION("incrParse Performance", InfoLowPrio) {

tools/SourceKit/tools/sourcekitd/lib/API/TokenAnnotationsArray.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ bool TokenAnnotationsArrayBuilder::empty() const {
5555

5656
std::unique_ptr<llvm::MemoryBuffer>
5757
TokenAnnotationsArrayBuilder::createBuffer() {
58-
return Impl.Builder.createBuffer();
58+
return Impl.Builder.createBuffer(CustomBufferKind::TokenAnnotationsArray);
5959
}
6060

6161
namespace {

tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-InProc.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -237,19 +237,15 @@ class SKDBool: public SKDObject {
237237

238238
class SKDCustomData: public SKDObject {
239239
public:
240-
SKDCustomData(CustomBufferKind BufferKind,
241-
std::unique_ptr<llvm::MemoryBuffer>& MemBuf)
242-
: SKDObject(ObjectKind::CustomData), BufferKind(BufferKind),
243-
BufferPtr(llvm::MemoryBuffer::getMemBufferCopy(
244-
MemBuf->getBuffer(),
245-
MemBuf->getBufferIdentifier()))
240+
SKDCustomData(std::unique_ptr<llvm::MemoryBuffer> MemBuf)
241+
: SKDObject(ObjectKind::CustomData), BufferPtr(std::move(MemBuf))
246242
{}
247243

248244
SKDCustomData(SKDCustomData const&) = delete;
249245
SKDCustomData &operator=(SKDCustomData const&) = delete;
250246

251247
sourcekitd_variant_type_t getVariantType() const override {
252-
switch (BufferKind) {
248+
switch (getBufferKind()) {
253249
case CustomBufferKind::TokenAnnotationsArray:
254250
case CustomBufferKind::DocSupportAnnotationArray:
255251
case CustomBufferKind::CodeCompletionResultsArray:
@@ -266,23 +262,24 @@ class SKDCustomData: public SKDObject {
266262
}
267263

268264
CustomBufferKind getBufferKind() const {
269-
return BufferKind;
265+
return ((CustomBufferKind)*(const uint64_t*)_getStartPtr());
270266
}
271267

272268
const void *getDataPtr() const override {
273-
return BufferPtr->getBuffer().data();
269+
return ((const void*)(((const uint64_t*)_getStartPtr())+1));
274270
}
275271

276272
size_t getDataSize() const override {
277-
return BufferPtr->getBuffer().size();
273+
return BufferPtr->getBuffer().size() - sizeof(uint64_t);
278274
}
279275

280276
static bool classof(const SKDObject *O) {
281277
return O->getKind() == ObjectKind::CustomData;
282278
}
283279
private:
284-
CustomBufferKind BufferKind;
285280
std::unique_ptr<llvm::MemoryBuffer> BufferPtr;
281+
282+
const void *_getStartPtr() const { return BufferPtr->getBuffer().data(); }
286283
};
287284

288285
class SKDError: public SKDObject {
@@ -675,10 +672,9 @@ ResponseBuilder::Dictionary::setDictionary(UIdent Key) {
675672
}
676673

677674
void ResponseBuilder::Dictionary::setCustomBuffer(
678-
SourceKit::UIdent Key,
679-
CustomBufferKind Kind, std::unique_ptr<llvm::MemoryBuffer> MemBuf) {
675+
SourceKit::UIdent Key, std::unique_ptr<llvm::MemoryBuffer> MemBuf) {
680676
static_cast<SKDObject *>(Impl)->set(SKDUIDFromUIdent(Key),
681-
new SKDCustomData(Kind, MemBuf));
677+
new SKDCustomData(std::move(MemBuf)));
682678
}
683679

684680
ResponseBuilder::Array

tools/SourceKit/tools/sourcekitd/lib/API/sourcekitdAPI-XPC.cpp

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -258,19 +258,9 @@ ResponseBuilder::Dictionary::setDictionary(UIdent Key) {
258258
}
259259

260260
void ResponseBuilder::Dictionary::setCustomBuffer(
261-
SourceKit::UIdent Key,
262-
CustomBufferKind Kind, std::unique_ptr<llvm::MemoryBuffer> MemBuf) {
263-
264-
std::unique_ptr<llvm::WritableMemoryBuffer> CustomBuf;
265-
CustomBuf = llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
266-
sizeof(uint64_t) + MemBuf->getBufferSize());
267-
char *BufPtr = CustomBuf->getBufferStart();
268-
*reinterpret_cast<uint64_t*>(BufPtr) = (uint64_t)Kind;
269-
BufPtr += sizeof(uint64_t);
270-
memcpy(BufPtr, MemBuf->getBufferStart(), MemBuf->getBufferSize());
271-
272-
xpc_object_t xdata = xpc_data_create(CustomBuf->getBufferStart(),
273-
CustomBuf->getBufferSize());
261+
SourceKit::UIdent Key, std::unique_ptr<llvm::MemoryBuffer> Buf) {
262+
xpc_object_t xdata = xpc_data_create(Buf->getBufferStart(),
263+
Buf->getBufferSize());
274264
xpc_dictionary_set_value(Impl, Key.c_str(), xdata);
275265
xpc_release(xdata);
276266
}

0 commit comments

Comments
 (0)