Skip to content

Commit fbb7bfc

Browse files
authored
Merge pull request #30929 from rintaro/sourcekit-setcustombuffer-avoidmemcopy
[SourceKit] Avoid one memcpy on potentially big sourcekit response data
2 parents 579e662 + 69971af commit fbb7bfc

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)