18
18
#include " llvm/MC/MCObjectStreamer.h"
19
19
#include " llvm/MC/MCSymbol.h"
20
20
#include " llvm/Support/Endian.h"
21
+ #include " llvm/Support/Error.h"
21
22
#include " llvm/Support/LEB128.h"
22
23
#include " llvm/Support/MD5.h"
23
24
#include " llvm/Support/raw_ostream.h"
@@ -429,17 +430,11 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
429
430
Index = Cur->getChildren ().size ();
430
431
} else {
431
432
// 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 >()));
436
434
}
437
435
438
436
// 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 >()));
443
438
444
439
// Decide if top-level node should be disgarded.
445
440
if (IsTopLevelFunc && !GuidFilter.empty () && !GuidFilter.count (Guid))
@@ -457,41 +452,27 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
457
452
}
458
453
459
454
// 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 >()));
464
457
// 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 >()));
468
460
// Read all probes in this node
469
461
for (std::size_t I = 0 ; I < NodeCount; I++) {
470
462
// 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 >()));
475
465
// 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 >()));
480
467
uint8_t Kind = Value & 0xf ;
481
468
uint8_t Attr = (Value & 0x70 ) >> 4 ;
482
469
// Read address
483
470
uint64_t Addr = 0 ;
484
471
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 >()));
489
473
Addr = LastAddr + Offset;
490
474
} 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 >()));
495
476
if (isSentinelProbe (Attr)) {
496
477
// For sentinel probe, the addr field actually stores the GUID of the
497
478
// split function. Convert it to the real address.
@@ -508,10 +489,8 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
508
489
509
490
uint32_t Discriminator = 0 ;
510
491
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 >()));
515
494
}
516
495
517
496
if (Cur && !isSentinelProbe (Attr)) {
@@ -524,17 +503,109 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(
524
503
LastAddr = Addr;
525
504
}
526
505
527
- uint32_t ChildrenToProcess = std::move (*ErrorOrCurChildrenToProcess);
528
506
for (uint32_t I = 0 ; I < ChildrenToProcess; I++) {
529
507
buildAddress2ProbeMap (Cur, LastAddr, GuidFilter, FuncStartAddrs);
530
508
}
509
+ return true ;
510
+ }
511
+
512
+ template <bool IsTopLevelFunc>
513
+ bool MCPseudoProbeDecoder::countRecords (bool &Discard, 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
+ }
531
579
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 ;
532
588
return true ;
533
589
}
534
590
535
591
bool MCPseudoProbeDecoder::buildAddress2ProbeMap (
536
592
const uint8_t *Start, std::size_t Size, const Uint64Set &GuidFilter,
537
593
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
+
538
609
Data = Start;
539
610
End = Data + Size;
540
611
uint64_t LastAddr = 0 ;
0 commit comments