Skip to content

Commit e90b6fb

Browse files
Merge pull request #7970 from rastogishubham/uleboptimizestable
Cherry-pick PR. #7952 to stable/20230725
2 parents 3c1c797 + a88e90c commit e90b6fb

File tree

1 file changed

+94
-92
lines changed

1 file changed

+94
-92
lines changed

llvm/lib/MCCAS/MCCASObjectV1.cpp

Lines changed: 94 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -505,12 +505,13 @@ static Error materializeDebugInfoOpt(MCCASReader &Reader,
505505
StringRef FormData, bool) {
506506
if (Form == dwarf::Form::DW_FORM_ref4_cas ||
507507
Form == dwarf::Form::DW_FORM_strp_cas) {
508-
auto Reader = BinaryStreamReader(FormData, support::endianness::little);
509-
uint64_t Data64;
510-
if (auto Err = Reader.readULEB128(Data64))
511-
handleAllErrors(std::move(Err));
508+
DataExtractor Extractor(FormData, true, 8);
509+
DataExtractor::Cursor Cursor(0);
510+
uint64_t Data64 = Extractor.getULEB128(Cursor);
511+
if (!Cursor)
512+
handleAllErrors(Cursor.takeError());
512513
uint32_t Data32 = Data64;
513-
assert(Data32 == Data64 && Reader.empty());
514+
assert(Data32 == Data64 && Extractor.eof(Cursor));
514515
SectionStream->write(reinterpret_cast<char *>(&Data32), sizeof(Data32));
515516
} else
516517
*SectionStream << FormData;
@@ -1703,13 +1704,14 @@ Error MCCASBuilder::createStringSection(
17031704
/// Reads and returns the length field of a dwarf header contained in Reader,
17041705
/// assuming Reader is positioned at the beginning of the header. The Reader's
17051706
/// state is advanced to the first byte after the header.
1706-
static Expected<size_t> getSizeFromDwarfHeader(BinaryStreamReader &Reader) {
1707+
static Expected<size_t> getSizeFromDwarfHeader(DataExtractor &Extractor,
1708+
DataExtractor::Cursor &Cursor) {
17071709
// From DWARF 5 section 7.4:
17081710
// In the 32-bit DWARF format, an initial length field [...] is an unsigned
17091711
// 4-byte integer (which must be less than 0xfffffff0);
1710-
uint32_t Word1;
1711-
if (auto E = Reader.readInteger(Word1))
1712-
return std::move(E);
1712+
uint32_t Word1 = Extractor.getU32(Cursor);
1713+
if (!Cursor)
1714+
return Cursor.takeError();
17131715

17141716
// TODO: handle 64-bit DWARF format.
17151717
if (Word1 >= 0xfffffff0)
@@ -1719,17 +1721,6 @@ static Expected<size_t> getSizeFromDwarfHeader(BinaryStreamReader &Reader) {
17191721
return Word1;
17201722
}
17211723

1722-
// TODO: Remove
1723-
Expected<size_t>
1724-
mccasformats::v1::getSizeFromDwarfHeaderAndSkip(BinaryStreamReader &Reader) {
1725-
Expected<size_t> Size = getSizeFromDwarfHeader(Reader);
1726-
if (!Size)
1727-
return Size.takeError();
1728-
if (auto E = Reader.skip(*Size))
1729-
return std::move(E);
1730-
return Size;
1731-
}
1732-
17331724
/// Returns the Abbreviation Offset field of a Dwarf Compilation Unit (CU)
17341725
/// contained in CUData, as well as the total number of bytes taken by the CU.
17351726
/// Note: this is different from the length field of the Dwarf header, which
@@ -1738,43 +1729,45 @@ static Expected<CUInfo>
17381729
getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
17391730
support::endianness Endian,
17401731
std::optional<uint32_t> NewOffset) {
1741-
BinaryStreamReader Reader(toStringRef(CUData), Endian);
1742-
Expected<size_t> Size = getSizeFromDwarfHeader(Reader);
1732+
DataExtractor Extractor(toStringRef(CUData),
1733+
Endian == support::endianness::little, 8);
1734+
DataExtractor::Cursor Cursor(0);
1735+
Expected<size_t> Size = getSizeFromDwarfHeader(Extractor, Cursor);
17431736
if (!Size)
17441737
return Size.takeError();
17451738

1746-
size_t AfterSizeOffset = Reader.getOffset();
1739+
size_t AfterSizeOffset = Cursor.tell();
17471740

17481741
// 2-byte Dwarf version identifier.
1749-
uint16_t DwarfVersion;
1750-
if (auto E = Reader.readInteger(DwarfVersion))
1751-
return std::move(E);
1742+
uint16_t DwarfVersion = Extractor.getU16(Cursor);
1743+
if (!Cursor)
1744+
return Cursor.takeError();
17521745

17531746
if (DwarfVersion >= 5) {
17541747
// From Dwarf 5 Section 7.5.1.1:
17551748
// Compile Unit Header Format is now changed with unit_type and address_size
17561749
// after the version. Parse both values from the header.
1757-
uint8_t UnitType;
1758-
if (auto E = Reader.readInteger(UnitType))
1759-
return std::move(E);
1750+
uint8_t UnitType = Extractor.getU8(Cursor);
1751+
if (!Cursor)
1752+
return Cursor.takeError();
17601753
if (UnitType != dwarf::DW_UT_compile)
17611754
return createStringError(
17621755
inconvertibleErrorCode(),
17631756
"Unit type is not DW_UT_compile, and is incompatible with MCCAS!");
1764-
uint8_t AddressSize;
1765-
if (auto E = Reader.readInteger(AddressSize))
1766-
return std::move(E);
1757+
uint8_t AddressSize = Extractor.getU8(Cursor);
1758+
if (!Cursor)
1759+
return Cursor.takeError();
17671760
if (AddressSize != 8)
17681761
return createStringError(
17691762
inconvertibleErrorCode(),
17701763
"Address size is not 8 bytes, unsupported architecture for MCCAS!");
17711764
}
17721765

17731766
// TODO: Handle Dwarf 64 format, which uses 8 bytes.
1774-
size_t AbbrevPosition = Reader.getOffset();
1775-
uint32_t AbbrevOffset;
1776-
if (auto E = Reader.readInteger(AbbrevOffset))
1777-
return std::move(E);
1767+
size_t AbbrevPosition = Cursor.tell();
1768+
uint32_t AbbrevOffset = Extractor.getU32(Cursor);
1769+
if (!Cursor)
1770+
return Cursor.takeError();
17781771

17791772
if (NewOffset.has_value()) {
17801773
// FIXME: safe but ugly cast. Similar to: llvm::arrayRefFromStringRef.
@@ -1786,11 +1779,8 @@ getAndSetDebugAbbrevOffsetAndSkip(MutableArrayRef<char> CUData,
17861779
return std::move(E);
17871780
}
17881781

1789-
Reader.setOffset(AfterSizeOffset);
1790-
if (auto E = Reader.skip(*Size))
1791-
return std::move(E);
1792-
1793-
return CUInfo{Reader.getOffset(), AbbrevOffset, DwarfVersion};
1782+
Cursor.seek(AfterSizeOffset + *Size);
1783+
return CUInfo{Cursor.tell(), AbbrevOffset, DwarfVersion};
17941784
}
17951785

17961786
/// Given a list of MCFragments, return a vector with the concatenation of their
@@ -3113,14 +3103,15 @@ struct DIEVisitor {
31133103

31143104
Error visitDIERef(DIEDedupeTopLevelRef Ref);
31153105
Error visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack);
3116-
Error visitDIEAttrs(BinaryStreamReader &DataReader, StringRef DIEData,
3117-
ArrayRef<AbbrevContent> DIEContents);
3106+
Error visitDIEAttrs(DataExtractor &Extractor, DataExtractor::Cursor &Cursor,
3107+
StringRef DIEData, ArrayRef<AbbrevContent> DIEContents);
31183108
Error materializeAbbrevDIE(unsigned AbbrevIdx);
31193109

31203110
uint16_t DwarfVersion;
31213111
SmallVector<AbbrevEntry> AbbrevEntryCache;
31223112
ArrayRef<StringRef> AbbrevEntries;
3123-
BinaryStreamReader DistinctReader;
3113+
DataExtractor DistinctExtractor;
3114+
DataExtractor::Cursor DistinctCursor;
31243115
StringRef DistinctData;
31253116

31263117
std::function<void(StringRef)> HeaderCallback;
@@ -3131,7 +3122,8 @@ struct DIEVisitor {
31313122
std::function<void(StringRef)> NewBlockCallback;
31323123
};
31333124

3134-
Error DIEVisitor::visitDIEAttrs(BinaryStreamReader &DataReader,
3125+
Error DIEVisitor::visitDIEAttrs(DataExtractor &Extractor,
3126+
DataExtractor::Cursor &Cursor,
31353127
StringRef DIEData,
31363128
ArrayRef<AbbrevContent> DIEContents) {
31373129
constexpr auto IsLittleEndian = true;
@@ -3141,29 +3133,32 @@ Error DIEVisitor::visitDIEAttrs(BinaryStreamReader &DataReader,
31413133

31423134
for (auto Contents : DIEContents) {
31433135
bool DataInDistinct = Contents.FormInDistinctData;
3144-
auto &ReaderForData = DataInDistinct ? DistinctReader : DataReader;
3136+
auto &ExtractorForData = DataInDistinct ? DistinctExtractor : Extractor;
3137+
auto &CursorForData = DataInDistinct ? DistinctCursor : Cursor;
31453138
StringRef DataToUse = DataInDistinct ? DistinctData : DIEData;
31463139
Expected<uint64_t> FormSize =
31473140
Contents.FormSize
31483141
? *Contents.FormSize
31493142
: getFormSize(Contents.Form, FormParams, DataToUse,
3150-
ReaderForData.getOffset(), IsLittleEndian, AddrSize);
3143+
CursorForData.tell(), IsLittleEndian, AddrSize);
31513144
if (!FormSize)
31523145
return FormSize.takeError();
31533146

3154-
ArrayRef<char> RawBytes;
3155-
if (auto E = ReaderForData.readArray(RawBytes, *FormSize))
3156-
return E;
3157-
AttrCallback(Contents.Attr, Contents.Form, toStringRef(RawBytes),
3158-
DataInDistinct);
3147+
StringRef RawBytes;
3148+
if (*FormSize)
3149+
RawBytes = ExtractorForData.getBytes(CursorForData, *FormSize);
3150+
if (!CursorForData)
3151+
return CursorForData.takeError();
3152+
AttrCallback(Contents.Attr, Contents.Form, RawBytes, DataInDistinct);
31593153
}
31603154
return Error::success();
31613155
}
31623156

3163-
static Expected<uint64_t> readAbbrevIdx(BinaryStreamReader &Reader) {
3164-
uint64_t Idx;
3165-
if (auto E = Reader.readULEB128(Idx))
3166-
return std::move(E);
3157+
static Expected<uint64_t> readAbbrevIdx(DataExtractor &Extractor,
3158+
DataExtractor::Cursor &Cursor) {
3159+
uint64_t Idx = Extractor.getULEB128(Cursor);
3160+
if (!Cursor)
3161+
return Cursor.takeError();
31673162
return Idx;
31683163
}
31693164

@@ -3284,12 +3279,13 @@ Error DIEVisitor::materializeAbbrevDIE(unsigned AbbrevIdx) {
32843279
/// implementation of a Depth First Search, and this function is used to
32853280
/// simulate a return from a recursive callback, by restoring the locals to a
32863281
/// previous stack frame.
3287-
static void popStack(BinaryStreamReader &Reader, StringRef &Data,
3282+
static void popStack(DataExtractor &Extractor, DataExtractor::Cursor &Cursor,
3283+
StringRef &Data,
32883284
std::stack<std::pair<StringRef, unsigned>> &StackOfNodes) {
32893285
auto DataAndOffset = StackOfNodes.top();
3290-
Reader = BinaryStreamReader(DataAndOffset.first, support::endianness::little);
3286+
Extractor = DataExtractor(DataAndOffset.first, true, 8);
32913287
Data = DataAndOffset.first;
3292-
Reader.setOffset(DataAndOffset.second);
3288+
Cursor.seek(DataAndOffset.second);
32933289
StackOfNodes.pop();
32943290
}
32953291

@@ -3303,11 +3299,13 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
33033299
std::stack<std::pair<StringRef, unsigned>> StackOfNodes;
33043300
auto Data = DIEChildrenStack.empty() ? StringRef()
33053301
: DIEChildrenStack.front().getData();
3306-
BinaryStreamReader Reader(Data, support::endianness::little);
3302+
DataExtractor Extractor(Data, true, 8);
3303+
DataExtractor::Cursor Cursor(0);
33073304

3308-
while (!DistinctReader.empty()) {
3305+
while (!DistinctExtractor.eof(DistinctCursor)) {
33093306

3310-
Expected<uint64_t> MaybeAbbrevIdx = readAbbrevIdx(DistinctReader);
3307+
Expected<uint64_t> MaybeAbbrevIdx =
3308+
readAbbrevIdx(DistinctExtractor, DistinctCursor);
33113309
if (!MaybeAbbrevIdx)
33123310
return MaybeAbbrevIdx.takeError();
33133311
auto AbbrevIdx = *MaybeAbbrevIdx;
@@ -3317,20 +3315,21 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
33173315
// continue materialization of the parent's siblings that may exist.
33183316
if (AbbrevIdx == getEndOfDIESiblingsMarker()) {
33193317
EndTagCallback(true /*HadChildren*/);
3320-
if (!StackOfNodes.empty() && Reader.empty())
3321-
popStack(Reader, Data, StackOfNodes);
3318+
if (!StackOfNodes.empty() && Extractor.eof(Cursor))
3319+
popStack(Extractor, Cursor, Data, StackOfNodes);
33223320
continue;
33233321
}
33243322

33253323
// If we see a DIEInAnotherBlockMarker, we know that the next DIE is in
33263324
// another CAS Block, we have to push the current CAS Object on the stack,
33273325
// and materialize the next DIE from the DIEChildrenStack.
33283326
if (AbbrevIdx == getDIEInAnotherBlockMarker()) {
3329-
StackOfNodes.push(std::make_pair(Data, Reader.getOffset()));
3327+
StackOfNodes.push(std::make_pair(Data, Cursor.tell()));
33303328
DIEChildrenStack = DIEChildrenStack.drop_front();
33313329
Data = DIEChildrenStack.front().getData();
33323330
NewBlockCallback(DIEChildrenStack.front().getID().toString());
3333-
Reader = BinaryStreamReader(Data, support::endianness::little);
3331+
Extractor = DataExtractor(Data, true, 8);
3332+
Cursor.seek(0);
33343333
continue;
33353334
}
33363335

@@ -3339,16 +3338,16 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
33393338
AbbrevEntryCache[decodeAbbrevIndexAsAbbrevSetIdx(AbbrevIdx)];
33403339
StartTagCallback(AbbrevEntryCacheVal.Tag, AbbrevIdx);
33413340

3342-
if (auto E =
3343-
visitDIEAttrs(Reader, Data, AbbrevEntryCacheVal.AbbrevContents))
3341+
if (auto E = visitDIEAttrs(Extractor, Cursor, Data,
3342+
AbbrevEntryCacheVal.AbbrevContents))
33443343
return E;
33453344

33463345
// If the current DIE doesn't have any children, the current CAS Object will
33473346
// not contain any more data, pop the stack to continue materializing its
33483347
// parent's siblings that may exist.
33493348
if (!AbbrevEntryCacheVal.HasChildren) {
3350-
if (!StackOfNodes.empty() && Reader.empty())
3351-
popStack(Reader, Data, StackOfNodes);
3349+
if (!StackOfNodes.empty() && Extractor.eof(Cursor))
3350+
popStack(Extractor, Cursor, Data, StackOfNodes);
33523351
EndTagCallback(false /*HadChildren*/);
33533352
}
33543353
}
@@ -3357,8 +3356,9 @@ Error DIEVisitor::visitDIERef(ArrayRef<DIEDataRef> &DIEChildrenStack) {
33573356

33583357
Error DIEVisitor::visitDIERef(DIEDedupeTopLevelRef StartDIERef) {
33593358

3360-
auto Offset = DistinctReader.getOffset();
3361-
Expected<uint64_t> MaybeAbbrevIdx = readAbbrevIdx(DistinctReader);
3359+
auto Offset = DistinctCursor.tell();
3360+
Expected<uint64_t> MaybeAbbrevIdx =
3361+
readAbbrevIdx(DistinctExtractor, DistinctCursor);
33623362
if (!MaybeAbbrevIdx)
33633363
return MaybeAbbrevIdx.takeError();
33643364
auto AbbrevIdx = *MaybeAbbrevIdx;
@@ -3367,7 +3367,7 @@ Error DIEVisitor::visitDIERef(DIEDedupeTopLevelRef StartDIERef) {
33673367
assert(AbbrevIdx != getEndOfDIESiblingsMarker() &&
33683368
AbbrevIdx != getDIEInAnotherBlockMarker());
33693369

3370-
DistinctReader.setOffset(Offset);
3370+
DistinctCursor.seek(Offset);
33713371

33723372
NewBlockCallback(StartDIERef.getID().toString());
33733373

@@ -3405,34 +3405,36 @@ Error mccasformats::v1::visitDebugInfo(
34053405
compression::zlib::decompress(BuffRef, OutBuff, UncompressedSize))
34063406
return E;
34073407
DistinctData = toStringRef(OutBuff);
3408-
BinaryStreamReader DistinctReader(DistinctData, support::endianness::little);
3409-
#else
3410-
BinaryStreamReader DistinctReader(DistinctData, support::endianness::little);
34113408
#endif
3412-
ArrayRef<char> HeaderData;
3409+
DataExtractor DistinctExtractor(DistinctData, true, 8);
3410+
DataExtractor::Cursor DistinctCursor(0);
34133411

3414-
auto BeginOffset = DistinctReader.getOffset();
3415-
auto Size = getSizeFromDwarfHeader(DistinctReader);
3412+
auto Size = getSizeFromDwarfHeader(DistinctExtractor, DistinctCursor);
34163413
if (!Size)
34173414
return Size.takeError();
34183415

34193416
// 2-byte Dwarf version identifier.
3420-
uint16_t DwarfVersion;
3421-
if (auto E = DistinctReader.readInteger(DwarfVersion))
3422-
return E;
3423-
3424-
DistinctReader.setOffset(BeginOffset);
3417+
uint16_t DwarfVersion = DistinctExtractor.getU16(DistinctCursor);
3418+
DistinctCursor.seek(0);
34253419

3426-
if (auto E = DistinctReader.readArray(
3427-
HeaderData,
3428-
DwarfVersion >= 5 ? Dwarf5HeaderSize32Bit : Dwarf4HeaderSize32Bit))
3429-
return E;
3430-
HeaderCallback(toStringRef(HeaderData));
3420+
StringRef HeaderData = DistinctExtractor.getBytes(
3421+
DistinctCursor,
3422+
DwarfVersion >= 5 ? Dwarf5HeaderSize32Bit : Dwarf4HeaderSize32Bit);
3423+
if (!DistinctCursor)
3424+
return DistinctCursor.takeError();
3425+
HeaderCallback(HeaderData);
34313426

34323427
append_range(TotAbbrevEntries, LoadedTopRef->AbbrevEntries);
3433-
DIEVisitor Visitor{DwarfVersion, {}, TotAbbrevEntries,
3434-
DistinctReader, DistinctData, HeaderCallback,
3435-
StartTagCallback, AttrCallback, EndTagCallback,
3428+
DIEVisitor Visitor{DwarfVersion,
3429+
{},
3430+
TotAbbrevEntries,
3431+
DistinctExtractor,
3432+
DataExtractor::Cursor(DistinctCursor.tell()),
3433+
DistinctData,
3434+
HeaderCallback,
3435+
StartTagCallback,
3436+
AttrCallback,
3437+
EndTagCallback,
34363438
NewBlockCallback};
34373439
return Visitor.visitDIERef(LoadedTopRef->RootDIE);
34383440
}

0 commit comments

Comments
 (0)