@@ -358,8 +358,9 @@ bool MCPseudoProbeDecoder::buildGUID2FuncDescMap(const uint8_t *Start,
358
358
return true ;
359
359
}
360
360
361
- bool MCPseudoProbeDecoder::buildAddress2ProbeMap (const uint8_t *Start,
362
- std::size_t Size) {
361
+ bool MCPseudoProbeDecoder::buildAddress2ProbeMap (
362
+ MCDecodedPseudoProbeInlineTree *Cur, uint64_t &LastAddr,
363
+ std::unordered_set<uint64_t > &GuildFilter) {
363
364
// The pseudo_probe section encodes an inline forest and each tree has a
364
365
// format like:
365
366
// FUNCTION BODY (one for each uninlined function present in the text
@@ -390,101 +391,110 @@ bool MCPseudoProbeDecoder::buildAddress2ProbeMap(const uint8_t *Start,
390
391
// FUNCTION BODY
391
392
// A FUNCTION BODY entry describing the inlined function.
392
393
393
- Data = Start;
394
- End = Data + Size;
395
-
396
- MCDecodedPseudoProbeInlineTree *Root = &DummyInlineRoot;
397
- MCDecodedPseudoProbeInlineTree *Cur = &DummyInlineRoot;
398
- uint64_t LastAddr = 0 ;
399
394
uint32_t Index = 0 ;
400
- // A DFS-based decoding
401
- while (Data < End) {
402
- if (Root == Cur) {
403
- // Use a sequential id for top level inliner.
404
- Index = Root->getChildren ().size ();
405
- } else {
406
- // Read inline site for inlinees
407
- auto ErrorOrIndex = readUnsignedNumber<uint32_t >();
408
- if (!ErrorOrIndex)
409
- return false ;
410
- Index = std::move (*ErrorOrIndex);
411
- }
395
+ if (Cur == &DummyInlineRoot) {
396
+ // Use a sequential id for top level inliner.
397
+ Index = Cur->getChildren ().size ();
398
+ } else {
399
+ // Read inline site for inlinees
400
+ auto ErrorOrIndex = readUnsignedNumber<uint32_t >();
401
+ if (!ErrorOrIndex)
402
+ return false ;
403
+ Index = std::move (*ErrorOrIndex);
404
+ }
405
+
406
+ // Read guid
407
+ auto ErrorOrCurGuid = readUnencodedNumber<uint64_t >();
408
+ if (!ErrorOrCurGuid)
409
+ return false ;
410
+ uint64_t Guid = std::move (*ErrorOrCurGuid);
411
+
412
+ // Decide if top-level node should be disgarded.
413
+ if (Cur == &DummyInlineRoot && !GuildFilter.empty () &&
414
+ !GuildFilter.count (Guid))
415
+ Cur = nullptr ;
416
+
417
+ // If the incoming node is null, all its children nodes should be disgarded.
418
+ if (Cur) {
412
419
// Switch/add to a new tree node(inlinee)
413
420
Cur = Cur->getOrAddNode (std::make_tuple (Cur->Guid , Index));
414
- // Read guid
415
- auto ErrorOrCurGuid = readUnencodedNumber<uint64_t >();
416
- if (!ErrorOrCurGuid)
417
- return false ;
418
- Cur->Guid = std::move (*ErrorOrCurGuid);
419
- // Read number of probes in the current node.
420
- auto ErrorOrNodeCount = readUnsignedNumber<uint32_t >();
421
- if (!ErrorOrNodeCount)
421
+ Cur->Guid = Guid;
422
+ }
423
+
424
+ // Read number of probes in the current node.
425
+ auto ErrorOrNodeCount = readUnsignedNumber<uint32_t >();
426
+ if (!ErrorOrNodeCount)
427
+ return false ;
428
+ uint32_t NodeCount = std::move (*ErrorOrNodeCount);
429
+ // Read number of direct inlinees
430
+ auto ErrorOrCurChildrenToProcess = readUnsignedNumber<uint32_t >();
431
+ if (!ErrorOrCurChildrenToProcess)
432
+ return false ;
433
+ // Read all probes in this node
434
+ for (std::size_t I = 0 ; I < NodeCount; I++) {
435
+ // Read index
436
+ auto ErrorOrIndex = readUnsignedNumber<uint32_t >();
437
+ if (!ErrorOrIndex)
422
438
return false ;
423
- uint32_t NodeCount = std::move (*ErrorOrNodeCount );
424
- // Read number of direct inlinees
425
- auto ErrorOrCurChildrenToProcess = readUnsignedNumber< uint32_t >();
426
- if (!ErrorOrCurChildrenToProcess )
439
+ uint32_t Index = std::move (*ErrorOrIndex );
440
+ // Read type | flag.
441
+ auto ErrorOrValue = readUnencodedNumber< uint8_t >();
442
+ if (!ErrorOrValue )
427
443
return false ;
428
- Cur->ChildrenToProcess = std::move (*ErrorOrCurChildrenToProcess);
429
- // Read all probes in this node
430
- for (std::size_t I = 0 ; I < NodeCount; I++) {
431
- // Read index
432
- auto ErrorOrIndex = readUnsignedNumber<uint32_t >();
433
- if (!ErrorOrIndex)
444
+ uint8_t Value = std::move (*ErrorOrValue);
445
+ uint8_t Kind = Value & 0xf ;
446
+ uint8_t Attr = (Value & 0x70 ) >> 4 ;
447
+ // Read address
448
+ uint64_t Addr = 0 ;
449
+ if (Value & 0x80 ) {
450
+ auto ErrorOrOffset = readSignedNumber<int64_t >();
451
+ if (!ErrorOrOffset)
434
452
return false ;
435
- uint32_t Index = std::move (*ErrorOrIndex);
436
- // Read type | flag.
437
- auto ErrorOrValue = readUnencodedNumber<uint8_t >();
438
- if (!ErrorOrValue)
453
+ int64_t Offset = std::move (*ErrorOrOffset);
454
+ Addr = LastAddr + Offset;
455
+ } else {
456
+ auto ErrorOrAddr = readUnencodedNumber<int64_t >();
457
+ if (!ErrorOrAddr)
439
458
return false ;
440
- uint8_t Value = std::move (*ErrorOrValue);
441
- uint8_t Kind = Value & 0xf ;
442
- uint8_t Attr = (Value & 0x70 ) >> 4 ;
443
- // Read address
444
- uint64_t Addr = 0 ;
445
- if (Value & 0x80 ) {
446
- auto ErrorOrOffset = readSignedNumber<int64_t >();
447
- if (!ErrorOrOffset)
448
- return false ;
449
- int64_t Offset = std::move (*ErrorOrOffset);
450
- Addr = LastAddr + Offset;
451
- } else {
452
- auto ErrorOrAddr = readUnencodedNumber<int64_t >();
453
- if (!ErrorOrAddr)
454
- return false ;
455
- Addr = std::move (*ErrorOrAddr);
456
- }
459
+ Addr = std::move (*ErrorOrAddr);
460
+ }
461
+
462
+ if (Cur) {
457
463
// Populate Address2ProbesMap
458
464
auto &Probes = Address2ProbesMap[Addr];
459
465
Probes.emplace_back (Addr, Cur->Guid , Index, PseudoProbeType (Kind), Attr,
460
466
Cur);
461
467
Cur->addProbes (&Probes.back ());
462
- LastAddr = Addr;
463
468
}
469
+ LastAddr = Addr;
470
+ }
464
471
465
- // Look for the parent for the next node by subtracting the current
466
- // node count from tree counts along the parent chain. The first node
467
- // in the chain that has a non-zero tree count is the target.
468
- while (Cur != Root) {
469
- if (Cur->ChildrenToProcess == 0 ) {
470
- Cur = static_cast <MCDecodedPseudoProbeInlineTree *>(Cur->Parent );
471
- if (Cur != Root) {
472
- assert (Cur->ChildrenToProcess > 0 &&
473
- " Should have some unprocessed nodes" );
474
- Cur->ChildrenToProcess -= 1 ;
475
- }
476
- } else {
477
- break ;
478
- }
479
- }
472
+ uint32_t ChildrenToProcess = std::move (*ErrorOrCurChildrenToProcess);
473
+ for (uint32_t I = 0 ; I < ChildrenToProcess; I++) {
474
+ buildAddress2ProbeMap (Cur, LastAddr, GuildFilter);
480
475
}
481
476
477
+ return true ;
478
+ }
479
+
480
+ bool MCPseudoProbeDecoder::buildAddress2ProbeMap (
481
+ const uint8_t *Start, std::size_t Size,
482
+ std::unordered_set<uint64_t > &GuildFilter) {
483
+ Data = Start;
484
+ End = Data + Size;
485
+ uint64_t LastAddr = 0 ;
486
+ while (Data < End)
487
+ buildAddress2ProbeMap (&DummyInlineRoot, LastAddr, GuildFilter);
482
488
assert (Data == End && " Have unprocessed data in pseudo_probe section" );
483
- assert (Cur == Root &&
484
- " Cur should point to root when the forest is fully built up" );
485
489
return true ;
486
490
}
487
491
492
+ bool MCPseudoProbeDecoder::buildAddress2ProbeMap (const uint8_t *Start,
493
+ std::size_t Size) {
494
+ std::unordered_set<uint64_t > GuildFilter;
495
+ return buildAddress2ProbeMap (Start, Size, GuildFilter);
496
+ }
497
+
488
498
void MCPseudoProbeDecoder::printGUID2FuncDescMap (raw_ostream &OS) {
489
499
OS << " Pseudo Probe Desc:\n " ;
490
500
// Make the output deterministic
0 commit comments