Skip to content

Commit 14f4430

Browse files
committed
[nfc] [lldb] Prevent needless copies of DataExtractor
lldb_private::DataExtractor contains DataBufferSP m_data_sp which is relatively expensive to copy (due to multi-threading locking). llvm::DataExtractor does not have this problem as it uses StringRef instead. The copy constructor is explicit as otherwise it is easy to make unintended modification of a local copy instead of a caller's instance (D107470 but that is llvm::DataExtractor). Reviewed By: clayborg Differential Revision: https://reviews.llvm.org/D107485
1 parent 214f99b commit 14f4430

File tree

9 files changed

+37
-26
lines changed

9 files changed

+37
-26
lines changed

lldb/include/lldb/DataFormatters/StringPrinter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ class StringPrinter {
133133
ReadBufferAndDumpToStreamOptions(
134134
const ReadStringAndDumpToStreamOptions &options);
135135

136-
void SetData(DataExtractor d) { m_data = d; }
136+
void SetData(DataExtractor &&d) { m_data = std::move(d); }
137137

138-
lldb_private::DataExtractor GetData() const { return m_data; }
138+
const lldb_private::DataExtractor &GetData() const { return m_data; }
139139

140140
void SetIsTruncated(bool t) { m_is_truncated = t; }
141141

lldb/include/lldb/Utility/DataExtractor.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,12 @@ class DataExtractor {
134134
DataExtractor(const DataExtractor &data, lldb::offset_t offset,
135135
lldb::offset_t length, uint32_t target_byte_size = 1);
136136

137-
DataExtractor(const DataExtractor &rhs);
137+
/// Copy constructor.
138+
///
139+
/// The copy constructor is explicit as otherwise it is easy to make
140+
/// unintended modification of a local copy instead of a caller's instance.
141+
/// Also a needless copy of the \a m_data_sp shared pointer is/ expensive.
142+
explicit DataExtractor(const DataExtractor &rhs);
138143

139144
/// Assignment operator.
140145
///
@@ -149,6 +154,12 @@ class DataExtractor {
149154
/// A const reference to this object.
150155
const DataExtractor &operator=(const DataExtractor &rhs);
151156

157+
/// Move constructor and move assignment operators to complete the rule of 5.
158+
///
159+
/// They would get deleted as we already defined those of rule of 3.
160+
DataExtractor(DataExtractor &&rhs) = default;
161+
DataExtractor &operator=(DataExtractor &&rhs) = default;
162+
152163
/// Destructor
153164
///
154165
/// If this object contains a valid shared data reference, the reference
@@ -1005,7 +1016,8 @@ class DataExtractor {
10051016
uint32_t m_addr_size; ///< The address size to use when extracting addresses.
10061017
/// The shared pointer to data that can be shared among multiple instances
10071018
lldb::DataBufferSP m_data_sp;
1008-
const uint32_t m_target_byte_size = 1;
1019+
/// Making it const would require implementation of move assignment operator.
1020+
uint32_t m_target_byte_size = 1;
10091021
};
10101022

10111023
} // namespace lldb_private

lldb/source/DataFormatters/StringPrinter.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -475,11 +475,9 @@ static bool ReadEncodedBufferAndDumpToStream(
475475
return true;
476476
}
477477

478-
DataExtractor data(buffer_sp, process_sp->GetByteOrder(),
479-
process_sp->GetAddressByteSize());
480-
481478
StringPrinter::ReadBufferAndDumpToStreamOptions dump_options(options);
482-
dump_options.SetData(data);
479+
dump_options.SetData(DataExtractor(buffer_sp, process_sp->GetByteOrder(),
480+
process_sp->GetAddressByteSize()));
483481
dump_options.SetSourceSize(sourceSize);
484482
dump_options.SetIsTruncated(is_truncated);
485483
dump_options.SetNeedsZeroTermination(needs_zero_terminator);

lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ bool lldb_private::formatters::Char8SummaryProvider(
168168
stream.Printf("%s ", value.c_str());
169169

170170
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
171-
options.SetData(data);
171+
options.SetData(std::move(data));
172172
options.SetStream(&stream);
173173
options.SetPrefixToken("u8");
174174
options.SetQuote('\'');
@@ -194,7 +194,7 @@ bool lldb_private::formatters::Char16SummaryProvider(
194194
stream.Printf("%s ", value.c_str());
195195

196196
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
197-
options.SetData(data);
197+
options.SetData(std::move(data));
198198
options.SetStream(&stream);
199199
options.SetPrefixToken("u");
200200
options.SetQuote('\'');
@@ -220,7 +220,7 @@ bool lldb_private::formatters::Char32SummaryProvider(
220220
stream.Printf("%s ", value.c_str());
221221

222222
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
223-
options.SetData(data);
223+
options.SetData(std::move(data));
224224
options.SetStream(&stream);
225225
options.SetPrefixToken("U");
226226
options.SetQuote('\'');
@@ -254,7 +254,7 @@ bool lldb_private::formatters::WCharSummaryProvider(
254254
const uint32_t wchar_size = *size;
255255

256256
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
257-
options.SetData(data);
257+
options.SetData(std::move(data));
258258
options.SetStream(&stream);
259259
options.SetPrefixToken("L");
260260
options.SetQuote('\'');

lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
686686
if (!wchar_t_size)
687687
return false;
688688

689-
options.SetData(extractor);
689+
options.SetData(std::move(extractor));
690690
options.SetStream(&stream);
691691
options.SetPrefixToken("L");
692692
options.SetQuote('"');
@@ -743,12 +743,14 @@ bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
743743
}
744744
}
745745

746-
DataExtractor extractor;
747-
const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
748-
if (bytes_read < size)
749-
return false;
746+
{
747+
DataExtractor extractor;
748+
const size_t bytes_read = location_sp->GetPointeeData(extractor, 0, size);
749+
if (bytes_read < size)
750+
return false;
750751

751-
options.SetData(extractor);
752+
options.SetData(std::move(extractor));
753+
}
752754
options.SetStream(&stream);
753755
if (prefix_token.empty())
754756
options.SetPrefixToken(nullptr);

lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -519,9 +519,8 @@ ProcessElfCore::parseSegment(const DataExtractor &segment) {
519519

520520
size_t note_start = offset;
521521
size_t note_size = llvm::alignTo(note.n_descsz, 4);
522-
DataExtractor note_data(segment, note_start, note_size);
523522

524-
result.push_back({note, note_data});
523+
result.push_back({note, DataExtractor(segment, note_start, note_size)});
525524
offset += note_size;
526525
}
527526

@@ -897,7 +896,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) {
897896
/// A note segment consists of one or more NOTE entries, but their types and
898897
/// meaning differ depending on the OS.
899898
llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
900-
const elf::ELFProgramHeader &segment_header, DataExtractor segment_data) {
899+
const elf::ELFProgramHeader &segment_header,
900+
const DataExtractor &segment_data) {
901901
assert(segment_header.p_type == llvm::ELF::PT_NOTE);
902902

903903
auto notes_or_error = parseSegment(segment_data);

lldb/source/Plugins/Process/elf-core/ProcessElfCore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class ProcessElfCore : public lldb_private::PostMortemProcess {
148148
// Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
149149
llvm::Error ParseThreadContextsFromNoteSegment(
150150
const elf::ELFProgramHeader &segment_header,
151-
lldb_private::DataExtractor segment_data);
151+
const lldb_private::DataExtractor &segment_data);
152152

153153
// Returns number of thread contexts stored in the core file
154154
uint32_t GetNumThreadContexts();

lldb/source/Plugins/Process/elf-core/RegisterUtilities.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ DataExtractor lldb_private::getRegset(llvm::ArrayRef<CoreNote> Notes,
3434
uint32_t Type = *TypeOr;
3535
auto Iter = llvm::find_if(
3636
Notes, [Type](const CoreNote &Note) { return Note.info.n_type == Type; });
37-
return Iter == Notes.end() ? DataExtractor() : Iter->data;
37+
return Iter == Notes.end() ? DataExtractor() : DataExtractor(Iter->data);
3838
}

lldb/unittests/DataFormatter/StringPrinterTests.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ static Optional<std::string> format(StringRef input,
3737
opts.SetEscapeNonPrintables(true);
3838
opts.SetIgnoreMaxLength(false);
3939
opts.SetEscapeStyle(escape_style);
40-
DataExtractor extractor(input.data(), input.size(),
41-
endian::InlHostByteOrder(), sizeof(void *));
42-
opts.SetData(extractor);
40+
opts.SetData(DataExtractor(input.data(), input.size(),
41+
endian::InlHostByteOrder(), sizeof(void *)));
4342
const bool success = StringPrinter::ReadBufferAndDumpToStream<elem_ty>(opts);
4443
if (!success)
4544
return llvm::None;

0 commit comments

Comments
 (0)