1818#include " llvm/MC/MCObjectStreamer.h"
1919#include " llvm/MC/MCSymbol.h"
2020#include " llvm/Support/Endian.h"
21+ #include " llvm/Support/Error.h"
2122#include " llvm/Support/LEB128.h"
2223#include " llvm/Support/MD5.h"
2324#include " llvm/Support/raw_ostream.h"
@@ -429,17 +430,11 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
429430 Index = Cur->getChildren ().size ();
430431 } else {
431432 // Read inline site for inlinees
432- auto ErrorOrIndex = readUnsignedNumber<uint32_t >();
433- if (!ErrorOrIndex)
434- return false ;
435- Index = std::move (*ErrorOrIndex);
433+ Index = cantFail (errorOrToExpected (readUnsignedNumber<uint32_t >()));
436434 }
437435
438436 // Read guid
439- auto ErrorOrCurGuid = readUnencodedNumber<uint64_t >();
440- if (!ErrorOrCurGuid)
441- return false ;
442- uint64_t Guid = std::move (*ErrorOrCurGuid);
437+ uint64_t Guid = cantFail (errorOrToExpected (readUnencodedNumber<uint64_t >()));
443438
444439 // Decide if top-level node should be disgarded.
445440 if (IsTopLevelFunc && !GuidFilter.empty () && !GuidFilter.count (Guid))
@@ -457,41 +452,27 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
457452 }
458453
459454 // Read number of probes in the current node.
460- auto ErrorOrNodeCount = readUnsignedNumber<uint32_t >();
461- if (!ErrorOrNodeCount)
462- return false ;
463- uint32_t NodeCount = std::move (*ErrorOrNodeCount);
455+ uint32_t NodeCount =
456+ cantFail (errorOrToExpected (readUnsignedNumber<uint32_t >()));
464457 // Read number of direct inlinees
465- auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t >();
466- if (!ErrorOrCurChildrenToProcess)
467- return false ;
458+ uint32_t ChildrenToProcess =
459+ cantFail (errorOrToExpected (readUnsignedNumber<uint32_t >()));
468460 // Read all probes in this node
469461 for (std::size_t I = 0 ; I < NodeCount; I++) {
470462 // Read index
471- auto ErrorOrIndex = readUnsignedNumber<uint32_t >();
472- if (!ErrorOrIndex)
473- return false ;
474- uint32_t Index = std::move (*ErrorOrIndex);
463+ uint32_t Index =
464+ cantFail (errorOrToExpected (readUnsignedNumber<uint32_t >()));
475465 // Read type | flag.
476- auto ErrorOrValue = readUnencodedNumber<uint8_t >();
477- if (!ErrorOrValue)
478- return false ;
479- uint8_t Value = std::move (*ErrorOrValue);
466+ uint8_t Value = cantFail (errorOrToExpected (readUnencodedNumber<uint8_t >()));
480467 uint8_t Kind = Value & 0xf ;
481468 uint8_t Attr = (Value & 0x70 ) >> 4 ;
482469 // Read address
483470 uint64_t Addr = 0 ;
484471 if (Value & 0x80 ) {
485- auto ErrorOrOffset = readSignedNumber<int64_t >();
486- if (!ErrorOrOffset)
487- return false ;
488- int64_t Offset = std::move (*ErrorOrOffset);
472+ int64_t Offset = cantFail (errorOrToExpected (readSignedNumber<int64_t >()));
489473 Addr = LastAddr + Offset;
490474 } else {
491- auto ErrorOrAddr = readUnencodedNumber<int64_t >();
492- if (!ErrorOrAddr)
493- return false ;
494- Addr = std::move (*ErrorOrAddr);
475+ Addr = cantFail (errorOrToExpected (readUnencodedNumber<int64_t >()));
495476 if (isSentinelProbe (Attr)) {
496477 // For sentinel probe, the addr field actually stores the GUID of the
497478 // split function. Convert it to the real address.
@@ -508,10 +489,8 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
508489
509490 uint32_t Discriminator = 0 ;
510491 if (hasDiscriminator (Attr)) {
511- auto ErrorOrDiscriminator = readUnsignedNumber<uint32_t >();
512- if (!ErrorOrDiscriminator)
513- return false ;
514- Discriminator = std::move (*ErrorOrDiscriminator);
492+ Discriminator =
493+ cantFail (errorOrToExpected (readUnsignedNumber<uint32_t >()));
515494 }
516495
517496 if (Cur && !isSentinelProbe (Attr)) {
@@ -524,17 +503,109 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
524503 LastAddr = Addr;
525504 }
526505
527- uint32_t ChildrenToProcess = std::move (*ErrorOrCurChildrenToProcess);
528506 for (uint32_t I = 0 ; I < ChildrenToProcess; I++) {
529507 buildAddress2ProbeMap (Cur, LastAddr, GuidFilter, FuncStartAddrs);
530508 }
509+ return true ;
510+ }
511+
512+ bool MCPseudoProbeDecoder::countRecords (bool IsTopLevelFunc, bool &Discard,
513+ uint32_t &ProbeCount,
514+ uint32_t &InlinedCount,
515+ const Uint64Set &GuidFilter) {
516+ if (!IsTopLevelFunc)
517+ // Read inline site for inlinees
518+ if (!readUnsignedNumber<uint32_t >())
519+ return false ;
520+
521+ // Read guid
522+ auto ErrorOrCurGuid = readUnencodedNumber<uint64_t >();
523+ if (!ErrorOrCurGuid)
524+ return false ;
525+ uint64_t Guid = std::move (*ErrorOrCurGuid);
526+
527+ // Decide if top-level node should be disgarded.
528+ if (IsTopLevelFunc) {
529+ Discard = !GuidFilter.empty () && !GuidFilter.count (Guid);
530+ if (!Discard)
531+ // Allocate an entry for top-level function record.
532+ ++InlinedCount;
533+ }
534+
535+ // Read number of probes in the current node.
536+ auto ErrorOrNodeCount = readUnsignedNumber<uint32_t >();
537+ if (!ErrorOrNodeCount)
538+ return false ;
539+ uint32_t NodeCount = std::move (*ErrorOrNodeCount);
540+ uint32_t CurrentProbeCount = 0 ;
541+
542+ // Read number of direct inlinees
543+ auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t >();
544+ if (!ErrorOrCurChildrenToProcess)
545+ return false ;
546+ uint32_t ChildrenToProcess = std::move (*ErrorOrCurChildrenToProcess);
547+
548+ // Read all probes in this node
549+ for (std::size_t I = 0 ; I < NodeCount; I++) {
550+ // Read index
551+ if (!readUnsignedNumber<uint32_t >())
552+ return false ;
553+
554+ // Read type | flag.
555+ auto ErrorOrValue = readUnencodedNumber<uint8_t >();
556+ if (!ErrorOrValue)
557+ return false ;
558+ uint8_t Value = std::move (*ErrorOrValue);
559+
560+ uint8_t Attr = (Value & 0x70 ) >> 4 ;
561+ if (Value & 0x80 ) {
562+ // Offset
563+ if (!readSignedNumber<int64_t >())
564+ return false ;
565+ } else {
566+ // Addr
567+ if (!readUnencodedNumber<int64_t >())
568+ return false ;
569+ }
570+
571+ if (hasDiscriminator (Attr))
572+ // Discriminator
573+ if (!readUnsignedNumber<uint32_t >())
574+ return false ;
575+
576+ if (!Discard && !isSentinelProbe (Attr))
577+ ++CurrentProbeCount;
578+ }
531579
580+ if (!Discard) {
581+ ProbeCount += CurrentProbeCount;
582+ InlinedCount += ChildrenToProcess;
583+ }
584+
585+ for (uint32_t I = 0 ; I < ChildrenToProcess; I++)
586+ if (!countRecords (false , Discard, ProbeCount, InlinedCount, GuidFilter))
587+ return false ;
532588 return true ;
533589}
534590
535591bool MCPseudoProbeDecoder::buildAddress2ProbeMap (
536592 const uint8_t *Start, std::size_t Size, const Uint64Set &GuidFilter,
537593 const Uint64Map &FuncStartAddrs) {
594+ // For function records in the order of their appearance in the encoded data
595+ // (DFS), count the number of contained probes and inlined function records.
596+ uint32_t ProbeCount = 0 ;
597+ uint32_t InlinedCount = 0 ;
598+ uint32_t TopLevelFuncs = 0 ;
599+ Data = Start;
600+ End = Data + Size;
601+ bool Discard = false ;
602+ while (Data < End) {
603+ if (!countRecords (true , Discard, ProbeCount, InlinedCount, GuidFilter))
604+ return false ;
605+ TopLevelFuncs += !Discard;
606+ }
607+ assert (Data == End && " Have unprocessed data in pseudo_probe section" );
608+
538609 Data = Start;
539610 End = Data + Size;
540611 uint64_t LastAddr = 0 ;
0 commit comments