LLVM: lib/ProfileData/InstrProfReader.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

21

31#include

32#include

33#include

34#include

35#include

36#include

37#include <system_error>

38#include

39#include

40

41using namespace llvm;

42

43

44

49 }

52 }

55 }

58 }

61 }

64 }

67 }

70 }

71 return ProfileKind;

72}

73

77 : FS.getBufferForFile(Filename);

78 if (std::error_code EC = BufferOrErr.getError())

80 return std::move(BufferOrErr.get());

81}

82

86

87

88

89

90

91

92

93

94

98 std::vectorllvm::object::BuildID &BinaryIds,

101

102 const uint64_t BinaryIdsSize = BinaryIdsBuffer.size();

103 const uint8_t *BinaryIdsStart = BinaryIdsBuffer.data();

104

105 if (BinaryIdsSize == 0)

107

108 const uint8_t *BI = BinaryIdsStart;

109 const uint8_t *BIEnd = BinaryIdsStart + BinaryIdsSize;

112

113 while (BI < BIEnd) {

114 size_t Remaining = BIEnd - BI;

115

116 if (Remaining < sizeof(uint64_t))

119 "not enough data to read binary id length");

120

122 if (BILen == 0)

124 "binary id length is 0");

125

126 Remaining = BIEnd - BI;

127

131

132

134

135

137 if (BI > End)

140 "binary id section is greater than buffer size");

141 }

142

144}

145

148 OS << "Binary IDs: \n";

149 for (const auto &BI : BinaryIds) {

150 for (auto I : BI)

152 OS << "\n";

153 }

154}

155

161 std::function<void(Error)> Warn) {

162

164 if (Error E = BufferOrError.takeError())

165 return std::move(E);

167 BIDFetcher, BIDFetcherCorrelatorKind, Warn);

168}

169

171 std::unique_ptr Buffer, const InstrProfCorrelator *Correlator,

174 std::function<void(Error)> Warn) {

175 if (Buffer->getBufferSize() == 0)

177

178 std::unique_ptr Result;

179

184 BIDFetcher, BIDFetcherCorrelatorKind,

185 Warn));

188 BIDFetcher, BIDFetcherCorrelatorKind,

189 Warn));

192 else

194

195

197 return std::move(E);

198

199 return std::move(Result);

200}

201

204 const Twine &RemappingPath) {

205

207 if (Error E = BufferOrError.takeError())

208 return std::move(E);

209

210

211 std::unique_ptr RemappingBuffer;

212 std::string RemappingPathStr = RemappingPath.str();

213 if (!RemappingPathStr.empty()) {

214 auto RemappingBufferOrError = setupMemoryBuffer(RemappingPathStr, FS);

215 if (Error E = RemappingBufferOrError.takeError())

216 return std::move(E);

217 RemappingBuffer = std::move(RemappingBufferOrError.get());

218 }

219

221 std::move(RemappingBuffer));

222}

223

226 std::unique_ptr RemappingBuffer) {

227

230 auto Result = std::make_unique(

231 std::move(Buffer), std::move(RemappingBuffer));

232

233

235 return std::move(E);

236

237 return std::move(Result);

238}

239

241

242

245 return count == 0 ||

247 [](char c) { return isPrint(c) || isSpace(c); });

248}

249

250

251

252

255

256 while (Line->starts_with(":")) {

258 if (Str.equals_insensitive("ir"))

260 else if (Str.equals_insensitive("fe"))

262 else if (Str.equals_insensitive("csir")) {

265 } else if (Str.equals_insensitive("entry_first"))

267 else if (Str.equals_insensitive("not_entry_first"))

269 else if (Str.equals_insensitive("instrument_loop_entries"))

271 else if (Str.equals_insensitive("single_byte_coverage"))

273 else if (Str.equals_insensitive("temporal_prof_traces")) {

275 if (auto Err = readTemporalProfTraceData())

276 return error(std::move(Err));

277 } else

279 ++Line;

280 }

282}

283

284

285

286

287

288

289Error TextInstrProfReader::readTemporalProfTraceData() {

290 if ((++Line).is_at_end())

292

294 if (Line->getAsInteger(0, NumTraces))

296

297 if ((++Line).is_at_end())

299

302

303 for (uint32_t i = 0; i < NumTraces; i++) {

304 if ((++Line).is_at_end())

306

308 if (Line->getAsInteger(0, Trace.Weight))

310

311 if ((++Line).is_at_end())

313

315 Line->split(FuncNames, ",", -1, false);

316 for (auto &FuncName : FuncNames)

317 Trace.FunctionNameRefs.push_back(

320 }

322}

323

326

327#define CHECK_LINE_END(Line) \

328 if (Line.is_at_end()) \

329 return error(instrprof_error::truncated);

330#define READ_NUM(Str, Dst) \

331 if ((Str).getAsInteger(10, (Dst))) \

332 return error(instrprof_error::malformed);

333#define VP_READ_ADVANCE(Val) \

334 CHECK_LINE_END(Line); \

335 uint32_t Val; \

336 READ_NUM((*Line), (Val)); \

337 Line++;

338

339 if (Line.is_at_end())

341

342 uint32_t NumValueKinds;

343 if (Line->getAsInteger(10, NumValueKinds)) {

344

346 }

347 if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)

349 "number of value kinds is invalid");

350 Line++;

351

352 for (uint32_t VK = 0; VK < NumValueKinds; VK++) {

354 if (ValueKind > IPVK_Last)

356 ;

359 continue;

360

364

365 std::vector CurrentValues;

366 for (uint32_t V = 0; V < NumValueData; V++) {

368 std::pair<StringRef, StringRef> VD = Line->rsplit(':');

369 uint64_t TakenCount, Value;

370 if (ValueKind == IPVK_IndirectCallTarget) {

373 } else {

375 return E;

377 }

378 } else if (ValueKind == IPVK_VTableTarget) {

381 else {

382 if (Error E = Symtab->addVTableName(VD.first))

383 return E;

385 }

386 } else {

388 }

389 READ_NUM(VD.second, TakenCount);

390 CurrentValues.push_back({Value, TakenCount});

391 Line++;

392 }

393 assert(CurrentValues.size() == NumValueData);

394 Record.addValueData(ValueKind, S, CurrentValues, nullptr);

395 }

396 }

398

399#undef CHECK_LINE_END

400#undef READ_NUM

401#undef VP_READ_ADVANCE

402}

403

405

406 while (!Line.is_at_end() && (Line->empty() || Line->starts_with("#")))

407 ++Line;

408

409 if (Line.is_at_end()) {

411 }

412

413

414 Record.Name = *Line++;

416 return error(std::move(E));

417

418

419 if (Line.is_at_end())

421 if ((Line++)->getAsInteger(0, Record.Hash))

423 "function hash is not a valid integer");

424

425

427 if (Line.is_at_end())

429 if ((Line++)->getAsInteger(10, NumCounters))

431 "number of counters is not a valid integer");

434

435

439 if (Line.is_at_end())

442 if ((Line++)->getAsInteger(10, Count))

445 }

446

447

448 if (Line->starts_with("$")) {

449 Record.BitmapBytes.clear();

450

452 if ((Line++)->drop_front(1).trim().getAsInteger(0, NumBitmapBytes))

454 "number of bitmap bytes is not a valid integer");

456

459 if (Line.is_at_end())

462 if ((Line++)->getAsInteger(0, BitmapByte))

464 "bitmap byte is not a valid integer");

465 Record.BitmapBytes.push_back(BitmapByte);

466 }

467 }

468 }

469

470

471 if (Error E = readValueProfileData(Record))

472 return error(std::move(E));

473

475}

476

477template

481

482template

485 std::optional<uint64_t> Weight) {

486 if (TemporalProfTimestamps.empty()) {

489 }

490

491 std::sort(TemporalProfTimestamps.begin(), TemporalProfTimestamps.end());

493 if (Weight)

494 Trace.Weight = *Weight;

495 for (auto &[TimestampValue, NameRef] : TemporalProfTimestamps)

496 Trace.FunctionNameRefs.push_back(NameRef);

499}

500

501template

503 if (DataBuffer.getBufferSize() < sizeof(uint64_t))

504 return false;

506 *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart());

509}

510

511template

518 DataBuffer->getBufferStart());

521}

522

523template

524Error RawInstrProfReader::readNextHeader(const char *CurrentPos) {

525 const char *End = DataBuffer->getBufferEnd();

526

527 while (CurrentPos != End && *CurrentPos == 0)

528 ++CurrentPos;

529

530 if (CurrentPos == End)

532

533

536 "not enough space for another header");

537

538 if (reinterpret_cast<size_t>(CurrentPos) % alignof(uint64_t))

540 "insufficient padding");

541

542 uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos);

545

546

548 return readHeader(*Header);

549}

550

551template

554 StringRef(VNamesStart, VNamesEnd - VNamesStart)))

555 return error(std::move(E));

557 const IntPtrT FPtr = swap(I->FunctionPointer);

558 if (!FPtr)

559 continue;

560 Symtab.mapAddress(FPtr, swap(I->NameRef));

561 }

562

563 if (VTableBegin != nullptr && VTableEnd != nullptr) {

565 I != VTableEnd; ++I) {

566 const IntPtrT VPtr = swap(I->VTablePointer);

567 if (!VPtr)

568 continue;

569

570

571

572

574 swap(I->VTableNameHash));

575 }

576 }

578}

579

580template

586 ("Profile uses raw profile format version = " +

589 "\nPLEASE update this tool to version in the raw profile, or "

590 "regenerate raw profile with expected version.")

591 .str());

592

593 uint64_t BinaryIdSize = swap(Header.BinaryIdsSize);

594

595 const uint8_t *BinaryIdStart =

597 const uint8_t *BinaryIdEnd = BinaryIdStart + BinaryIdSize;

598 const uint8_t *BufferEnd = (const uint8_t *)DataBuffer->getBufferEnd();

599 if (BinaryIdSize % sizeof(uint64_t) || BinaryIdEnd > BufferEnd)

602 if (!BinaryIdsBuffer.empty()) {

604 BinaryIds, getDataEndianness()))

605 return Err;

606 }

607

610 NamesDelta = swap(Header.NamesDelta);

611 auto NumData = swap(Header.NumData);

612 auto PaddingBytesBeforeCounters = swap(Header.PaddingBytesBeforeCounters);

613 auto CountersSize = swap(Header.NumCounters) * getCounterTypeSize();

614 auto PaddingBytesAfterCounters = swap(Header.PaddingBytesAfterCounters);

616 auto PaddingBytesAfterBitmapBytes = swap(Header.PaddingBytesAfterBitmapBytes);

617 auto NamesSize = swap(Header.NamesSize);

618 auto VTableNameSize = swap(Header.VNamesSize);

619 auto NumVTables = swap(Header.NumVTables);

620 ValueKindLast = swap(Header.ValueKindLast);

621

623 auto PaddingBytesAfterNames = getNumPaddingBytes(NamesSize);

624 auto PaddingBytesAfterVTableNames = getNumPaddingBytes(VTableNameSize);

625

626 auto VTableSectionSize =

628 auto PaddingBytesAfterVTableProfData = getNumPaddingBytes(VTableSectionSize);

629

630

632 ptrdiff_t CountersOffset = DataOffset + DataSize + PaddingBytesBeforeCounters;

633 ptrdiff_t BitmapOffset =

634 CountersOffset + CountersSize + PaddingBytesAfterCounters;

635 ptrdiff_t NamesOffset =

636 BitmapOffset + NumBitmapBytes + PaddingBytesAfterBitmapBytes;

637 ptrdiff_t VTableProfDataOffset =

638 NamesOffset + NamesSize + PaddingBytesAfterNames;

639 ptrdiff_t VTableNameOffset = VTableProfDataOffset + VTableSectionSize +

640 PaddingBytesAfterVTableProfData;

641 ptrdiff_t ValueDataOffset =

642 VTableNameOffset + VTableNameSize + PaddingBytesAfterVTableNames;

643

644 auto *Start = reinterpret_cast<const char *>(&Header);

645 if (Start + ValueDataOffset > DataBuffer->getBufferEnd())

647

648 if (BIDFetcher) {

649 std::vectorobject::BuildID BinaryIDs;

650 if (Error E = readBinaryIds(BinaryIDs))

651 return E;

653 BIDFetcher, BinaryIDs)

654 .moveInto(BIDFetcherCorrelator)) {

655 return E;

656 }

657 if (auto Err = BIDFetcherCorrelator->correlateProfileData(0))

658 return Err;

659 }

660

661 if (Correlator) {

662

663

665 NamesDelta == 0))

667 Data = Correlator->getDataPointer();

670 NamesEnd = NamesStart + Correlator->getNamesSize();

671 } else if (BIDFetcherCorrelator) {

674 BIDFetcherCorrelator.get());

676 DataEnd = Data + BIDFetcherCorrelatorImpl->getDataSize();

677 NamesStart = BIDFetcherCorrelatorImpl->getNamesPointer();

678 NamesEnd = NamesStart + BIDFetcherCorrelatorImpl->getNamesSize();

679 } else {

681 Start + DataOffset);

682 DataEnd = Data + NumData;

683 VTableBegin =

685 Start + VTableProfDataOffset);

686 VTableEnd = VTableBegin + NumVTables;

687 NamesStart = Start + NamesOffset;

688 NamesEnd = NamesStart + NamesSize;

689 VNamesStart = Start + VTableNameOffset;

690 VNamesEnd = VNamesStart + VTableNameSize;

691 }

692

693 CountersStart = Start + CountersOffset;

694 CountersEnd = CountersStart + CountersSize;

695 BitmapStart = Start + BitmapOffset;

697 ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset);

698

699 std::unique_ptr NewSymtab = std::make_unique();

700 if (Error E = createSymtab(*NewSymtab))

701 return E;

702

703 Symtab = std::move(NewSymtab);

705}

706

707template

711}

712

713template

717}

718

719template

720Error RawInstrProfReader::readRawCounts(

725

727 if (CounterBaseOffset < 0)

730 ("counter offset " + Twine(CounterBaseOffset) + " is negative").str());

731

732 if (CounterBaseOffset >= CountersEnd - CountersStart)

734 ("counter offset " + Twine(CounterBaseOffset) +

735 " is greater than the maximum counter offset " +

736 Twine(CountersEnd - CountersStart - 1))

737 .str());

738

739 uint64_t MaxNumCounters =

740 (CountersEnd - (CountersStart + CounterBaseOffset)) /

741 getCounterTypeSize();

745 " is greater than the maximum number of counters " +

746 Twine(MaxNumCounters))

747 .str());

748

749 Record.Counts.clear();

752 const char *Ptr =

753 CountersStart + CounterBaseOffset + I * getCounterTypeSize();

754 if (I == 0 && hasTemporalProfile()) {

755 uint64_t TimestampValue = swap(*reinterpret_cast<const uint64_t *>(Ptr));

756 if (TimestampValue != 0 &&

757 TimestampValue != std::numeric_limits<uint64_t>::max()) {

758 TemporalProfTimestamps.emplace_back(TimestampValue,

760 TemporalProfTraceStreamSize = 1;

761 }

762 if (hasSingleByteCoverage()) {

763

764

765

766

767 I += 7;

768 }

769 continue;

770 }

771 if (hasSingleByteCoverage()) {

772

773 Record.Counts.push_back(*Ptr == 0 ? 1 : 0);

774 } else {

775 uint64_t CounterValue = swap(*reinterpret_cast<const uint64_t *>(Ptr));

776 if (CounterValue > MaxCounterValue && Warn)

779

780 Record.Counts.push_back(CounterValue);

781 }

782 }

783

785}

786

787template

790

791 Record.BitmapBytes.clear();

793

794

795

798

799

801 if (BitmapOffset < 0)

804 ("bitmap offset " + Twine(BitmapOffset) + " is negative").str());

805

806 if (BitmapOffset >= BitmapEnd - BitmapStart)

808 ("bitmap offset " + Twine(BitmapOffset) +

809 " is greater than the maximum bitmap offset " +

810 Twine(BitmapEnd - BitmapStart - 1))

811 .str());

812

813 uint64_t MaxNumBitmapBytes =

814 (BitmapEnd - (BitmapStart + BitmapOffset)) / sizeof(uint8_t);

818 " is greater than the maximum number of bitmap bytes " +

819 Twine(MaxNumBitmapBytes))

820 .str());

821

823 const char *Ptr = BitmapStart + BitmapOffset + I;

824 Record.BitmapBytes.push_back(swap(*Ptr));

825 }

826

828}

829

830template

831Error RawInstrProfReader::readValueProfilingData(

833 Record.clearValueData();

834 CurValueDataSize = 0;

835

836 uint32_t NumValueKinds = 0;

837 for (uint32_t I = 0; I < IPVK_Last + 1; I++)

838 NumValueKinds += (Data->NumValueSites[I] != 0);

839

840 if (!NumValueKinds)

842

844 ValueProfData::getValueProfData(

845 ValueDataStart, (const unsigned char *)DataBuffer->getBufferEnd(),

846 getDataEndianness());

847

849 return E;

850

851

852

853

854 VDataPtrOrErr.get()->deserializeTo(Record, Symtab.get());

855 CurValueDataSize = VDataPtrOrErr.get()->getSize();

857}

858

859template

861

862

863 while (atEnd())

864

865 if (Error E = readNextHeader(getNextHeaderPos()))

866 return error(std::move(E));

867

868

870 return error(std::move(E));

871

872

874 return error(std::move(E));

875

876

878 return error(std::move(E));

879

880

881 if (Error E = readRawBitmapBytes(Record))

882 return error(std::move(E));

883

884

885 if (Error E = readValueProfilingData(Record))

886 return error(std::move(E));

887

888

889 advanceData();

891}

892

893template

895 std::vectorllvm::object::BuildID &BinaryIds) {

896 BinaryIds.insert(BinaryIds.begin(), this->BinaryIds.begin(),

897 this->BinaryIds.end());

899}

900

901template

903 if (!BinaryIds.empty())

906}

907

908namespace llvm {

909

912

913}

914

919

922

924 const unsigned char *&D, const unsigned char *const End) {

926 ValueProfData::getValueProfData(D, End, ValueProfDataEndianness);

927

929 return false;

930

931 VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), nullptr);

932 D += VDataPtrOrErr.get()->TotalSize;

933

934 return true;

935}

936

940

941

944

945 DataBuffer.clear();

946 std::vector<uint64_t> CounterBuffer;

947 std::vector<uint8_t> BitmapByteBuffer;

948

949 const unsigned char *End = D + N;

950 while (D < End) {

951

955

956

958

963 }

964

965 if (D + CountsSize * sizeof(uint64_t) > End)

967

968 CounterBuffer.clear();

969 CounterBuffer.reserve(CountsSize);

970 for (uint64_t J = 0; J < CountsSize; ++J)

971 CounterBuffer.push_back(

973

974

980

981 if (D + BitmapBytes * sizeof(uint8_t) > End)

983 BitmapByteBuffer.clear();

984 BitmapByteBuffer.reserve(BitmapBytes);

985 for (uint64_t J = 0; J < BitmapBytes; ++J)

986 BitmapByteBuffer.push_back(static_cast<uint8_t>(

988 }

989

990 DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer),

991 std::move(BitmapByteBuffer));

992

993

996 DataBuffer.clear();

998 }

999 }

1000 return DataBuffer;

1001}

1002

1003template

1006 auto Iter = HashTable->find(FuncName);

1007 if (Iter == HashTable->end())

1009

1010 Data = (*Iter);

1011 if (Data.empty())

1013 "profile data is empty");

1014

1016}

1017

1018template

1023

1024 Data = *RecordIterator;

1025

1026 if (Data.empty())

1028 "profile data is empty");

1029

1031}

1032

1033template

1035 const unsigned char *Buckets, const unsigned char *const Payload,

1038 FormatVersion = Version;

1039 HashTable.reset(HashTableImpl::Create(

1040 Buckets, Payload, Base,

1041 typename HashTableImpl::InfoType(HashType, Version)));

1042 RecordIterator = HashTable->data_begin();

1043}

1044

1045template

1049

1050namespace {

1051

1054

1055public:

1057 : Underlying(Underlying) {}

1058

1061 return Underlying.getRecords(FuncName, Data);

1062 }

1063};

1064}

1065

1066

1067template

1070public:

1072 std::unique_ptr RemapBuffer,

1074 : RemapBuffer(std::move(RemapBuffer)), Underlying(Underlying) {

1075 }

1076

1077

1079

1080

1081

1082

1083 std::pair<StringRef, StringRef> Parts = {StringRef(), Name};

1084 while (true) {

1086 if (Parts.first.starts_with("_Z"))

1087 return Parts.first;

1088 if (Parts.second.empty())

1089 return Name;

1090 }

1091 }

1092

1093

1094

1103

1105 if (Error E = Remappings.read(*RemapBuffer))

1106 return E;

1107 for (StringRef Name : Underlying.HashTable->keys()) {

1109 if (auto Key = Remappings.insert(RealName)) {

1110

1111

1112

1113 MappedNames.insert({Key, RealName});

1114 }

1115 }

1117 }

1118

1122 if (auto Key = Remappings.lookup(RealName)) {

1123 StringRef Remapped = MappedNames.lookup(Key);

1124 if (!Remapped.empty()) {

1125 if (RealName.begin() == FuncName.begin() &&

1126 RealName.end() == FuncName.end())

1127 FuncName = Remapped;

1128 else {

1129

1131 reconstituteName(FuncName, RealName, Remapped, Reconstituted);

1132 Error E = Underlying.getRecords(Reconstituted, Data);

1133 if (!E)

1134 return E;

1135

1136

1137

1139 std::move(E), [](std::unique_ptr Err) {

1142 : Error(std::move(Err));

1143 }))

1144 return Unhandled;

1145 }

1146 }

1147 }

1148 return Underlying.getRecords(FuncName, Data);

1149 }

1150

1151private:

1152

1153

1154 std::unique_ptr RemapBuffer;

1155

1156

1158

1159

1160

1161

1162

1164

1165

1167};

1168

1170 using namespace support;

1171

1172 if (DataBuffer.getBufferSize() < 8)

1173 return false;

1176

1178}

1179

1180const unsigned char *

1182 const unsigned char *Cur, bool UseCS) {

1184 using namespace support;

1185

1195 std::unique_ptrIndexedInstrProf::Summary SummaryData =

1197

1198 const uint64_t *Src = reinterpret_cast<const uint64_t *>(SummaryInLE);

1199 uint64_t *Dst = reinterpret_cast<uint64_t *>(SummaryData.get());

1200 for (unsigned I = 0; I < SummarySize / sizeof(uint64_t); I++)

1202

1204 for (unsigned I = 0; I < SummaryData->NumCutoffEntries; I++) {

1208 }

1209 std::unique_ptrllvm::ProfileSummary &Summary =

1210 UseCS ? this->CS_Summary : this->Summary;

1211

1212

1213 Summary = std::make_unique(

1215 DetailedSummary, SummaryData->get(Summary::TotalBlockCount),

1216 SummaryData->get(Summary::MaxBlockCount),

1217 SummaryData->get(Summary::MaxInternalBlockCount),

1218 SummaryData->get(Summary::MaxFunctionCount),

1219 SummaryData->get(Summary::TotalNumBlocks),

1220 SummaryData->get(Summary::TotalNumFunctions));

1221 return Cur + SummarySize;

1222 } else {

1223

1224

1225

1226

1227

1229 Summary = Builder.getSummary();

1230 return Cur;

1231 }

1232}

1233

1235 using namespace support;

1236

1237 const unsigned char *Start =

1238 (const unsigned char *)DataBuffer->getBufferStart();

1239 const unsigned char *Cur = Start;

1240 if ((const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)

1242

1244 if (!HeaderOr)

1245 return HeaderOr.takeError();

1246

1248 Cur += Header->size();

1249

1251 false);

1254 true);

1255

1260

1261

1262 auto IndexPtr = std::make_unique<InstrProfReaderIndex>(

1263 Start + Header->HashOffset, Cur, Start, HashType, Header->Version);

1264

1265

1266

1267 if (Header->getIndexedProfileVersion() >= 8 &&

1269 if (Error E = MemProfReader.deserialize(Start, Header->MemProfOffset))

1270 return E;

1271 }

1272

1273

1274

1275 if (Header->getIndexedProfileVersion() >= 9) {

1276 const unsigned char *Ptr = Start + Header->BinaryIdOffset;

1277

1280 if (BinaryIdsSize % sizeof(uint64_t))

1282

1284 if (Ptr > (const unsigned char *)DataBuffer->getBufferEnd())

1286 "corrupted binary ids");

1287 }

1288

1289 if (Header->getIndexedProfileVersion() >= 12) {

1290 const unsigned char *Ptr = Start + Header->VTableNamesOffset;

1291

1292 uint64_t CompressedVTableNamesLen =

1294

1295

1296

1297 const char *VTableNamePtr = (const char *)Ptr;

1298 if (VTableNamePtr > DataBuffer->getBufferEnd())

1300

1301 VTableName = StringRef(VTableNamePtr, CompressedVTableNamesLen);

1302 }

1303

1304 if (Header->getIndexedProfileVersion() >= 10 &&

1306 const unsigned char *Ptr = Start + Header->TemporalProfTracesOffset;

1307 const auto *PtrEnd = (const unsigned char *)DataBuffer->getBufferEnd();

1308

1309 if (Ptr + 2 * sizeof(uint64_t) > PtrEnd)

1315 for (unsigned i = 0; i < NumTraces; i++) {

1316

1317 if (Ptr + 2 * sizeof(uint64_t) > PtrEnd)

1322 const uint64_t NumFunctions =

1324

1325 if (Ptr + NumFunctions * sizeof(uint64_t) > PtrEnd)

1327 for (unsigned j = 0; j < NumFunctions; j++) {

1330 Trace.FunctionNameRefs.push_back(NameRef);

1331 }

1333 }

1334 }

1335

1336

1337 if (RemappingBuffer) {

1338 Remapper =

1339 std::make_unique<InstrProfReaderItaniumRemapper>(

1340 std::move(RemappingBuffer), *IndexPtr);

1341 if (Error E = Remapper->populateRemappings())

1342 return E;

1343 } else {

1344 Remapper = std::make_unique(*IndexPtr);

1345 }

1346 Index = std::move(IndexPtr);

1347

1349}

1350

1354

1355 auto NewSymtab = std::make_unique();

1356

1357 if (Error E = NewSymtab->initVTableNamesFromCompressedStrings(VTableName)) {

1360 }

1361

1362

1363 if (Error E = Index->populateSymtab(*NewSymtab)) {

1366 }

1367

1368 Symtab = std::move(NewSymtab);

1370}

1371

1374 uint64_t *MismatchedFuncSum) {

1377 auto Err = Remapper->getRecords(FuncName, Data);

1378 if (Err) {

1379

1380

1381 auto Err2 =

1385 if (auto Err = Remapper->getRecords(DeprecatedFuncName, Data))

1386 return Err;

1388 });

1389 if (Err2)

1390 return std::move(Err2);

1391 }

1392

1393

1394

1395

1396 bool CSBitMatch = false;

1399 for (uint64_t CountValue : Counts) {

1400 if (CountValue == (uint64_t)-1)

1401 continue;

1402

1403 if (std::numeric_limits<uint64_t>::max() - CountValue <= ValueSum)

1404 return std::numeric_limits<uint64_t>::max();

1405 ValueSum += CountValue;

1406 }

1407 return ValueSum;

1408 };

1409

1411

1413 return std::move(I);

1416 CSBitMatch = true;

1417 if (MismatchedFuncSum == nullptr)

1418 continue;

1419 FuncSum = std::max(FuncSum, getFuncSum(I.Counts));

1420 }

1421 }

1422 if (CSBitMatch) {

1423 if (MismatchedFuncSum != nullptr)

1424 *MismatchedFuncSum = FuncSum;

1426 }

1428}

1429

1435 MemProfFrameTable);

1436

1438 MemProfCallStackTable, FrameIdConv);

1439

1441

1442

1446 "memprof call stack not found for call stack id " +

1448 }

1449

1450

1453 "memprof frame not found for frame id " +

1455 }

1456

1458}

1459

1462

1463 if (MemProfRecordTable == nullptr)

1465 "no memprof data available in profile");

1466 auto Iter = MemProfRecordTable->find(FuncNameHash);

1467 if (Iter == MemProfRecordTable->end())

1470 "memprof record not found for function hash " + Twine(FuncNameHash));

1471

1473 switch (Version) {

1475 assert(MemProfFrameTable && "MemProfFrameTable must be available");

1476 assert(MemProfCallStackTable && "MemProfCallStackTable must be available");

1478 *MemProfCallStackTable);

1479

1482 assert(!MemProfFrameTable && "MemProfFrameTable must not be available");

1483 assert(!MemProfCallStackTable &&

1484 "MemProfCallStackTable must not be available");

1485 assert(FrameBase && "FrameBase must be available");

1486 assert(CallStackBase && "CallStackBase must be available");

1487 {

1492 }

1493 }

1494

1497 formatv("MemProf version {} not supported; "

1498 "requires version between {} and {}, inclusive",

1501}

1502

1505 assert(MemProfRecordTable);

1507

1510 RadixTreeSize);

1511

1512

1513

1514 BitVector Worklist(RadixTreeSize);

1515

1516

1517

1518

1520 MemProfRecordTable->data()) {

1522 IndexedRecord.AllocSites)

1523 Worklist.set(IndexedAI.CSId);

1524 }

1525

1526

1527 for (unsigned CS : Worklist.set_bits())

1528 Extractor(CS);

1529

1531 std::move(Extractor.CallerCalleePairs);

1532

1533

1534 for (auto &[CallerGUID, CallList] : Pairs) {

1536 CallList.erase(llvm::unique(CallList), CallList.end());

1537 }

1538

1539 return Pairs;

1540}

1541

1545 MemProfRecordTable->getNumEntries());

1546 for (uint64_t Key : MemProfRecordTable->keys()) {

1548 if (Record.takeError())

1549 continue;

1554 }

1555

1556 if (DataAccessProfileData != nullptr) {

1557 for (const auto &[SymHandleRef, RecordRef] :

1558 DataAccessProfileData->getRecords())

1561 RecordRef.Locations));

1562 for (StringRef ColdSymbol : DataAccessProfileData->getKnownColdSymbols())

1564 ColdSymbol.str());

1565 for (uint64_t Hash : DataAccessProfileData->getKnownColdHashes())

1567 Hash);

1568 }

1569 return AllMemProfData;

1570}

1571

1574 std::vector<uint64_t> &Counts) {

1577 return error(std::move(E));

1578

1579 Counts = Record.get().Counts;

1581}

1582

1588 return error(std::move(E));

1589

1590 const auto &BitmapBytes = Record.get().BitmapBytes;

1591 size_t I = 0, E = BitmapBytes.size();

1592 Bitmap.resize(E * CHAR_BIT);

1594 [&](auto X) {

1595 using XTy = decltype(X);

1596 alignas(XTy) uint8_t W[sizeof(X)];

1597 size_t N = std::min(E - I, sizeof(W));

1598 std::memset(W, 0, sizeof(W));

1599 std::memcpy(W, &BitmapBytes[I], N);

1600 I += N;

1603 },

1604 Bitmap, Bitmap);

1606

1608}

1609

1612

1613 Error E = Index->getRecords(Data);

1614 if (E)

1615 return error(std::move(E));

1616

1618 if (RecordIndex >= Data.size()) {

1619 Index->advanceToNextKey();

1620 RecordIndex = 0;

1621 }

1623}

1624

1626 std::vectorllvm::object::BuildID &BinaryIds) {

1629}

1630

1632 std::vectorllvm::object::BuildID BinaryIds;

1634 return E;

1637}

1638

1641 for (const auto &Func : *this) {

1644 if (FuncIsCS != IsCS)

1645 continue;

1646 }

1647 Func.accumulateCounts(Sum);

1648 ++NumFuncs;

1649 }

1651}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

This file defines the DenseMap class.

Provides ErrorOr smart pointer.

InstrProfLookupTrait::offset_type offset_type

Definition InstrProfReader.cpp:921

static Error initializeReader(InstrProfReader &Reader)

Definition InstrProfReader.cpp:83

#define READ_NUM(Str, Dst)

#define CHECK_LINE_END(Line)

static Error readBinaryIdsInternal(const MemoryBuffer &DataBuffer, ArrayRef< uint8_t > BinaryIdsBuffer, std::vector< llvm::object::BuildID > &BinaryIds, const llvm::endianness Endian)

Read a list of binary ids from a profile that consist of a.

Definition InstrProfReader.cpp:96

#define VP_READ_ADVANCE(Val)

InstrProfLookupTrait::data_type data_type

Definition InstrProfReader.cpp:920

static InstrProfKind getProfileKindFromVersion(uint64_t Version)

Definition InstrProfReader.cpp:45

static Expected< memprof::MemProfRecord > getMemProfRecordV2(const memprof::IndexedMemProfRecord &IndexedRecord, MemProfFrameHashTable &MemProfFrameTable, MemProfCallStackHashTable &MemProfCallStackTable)

Definition InstrProfReader.cpp:1431

static void printBinaryIdsInternal(raw_ostream &OS, ArrayRef< llvm::object::BuildID > BinaryIds)

Definition InstrProfReader.cpp:146

#define VARIANT_MASK_CSIR_PROF

#define VARIANT_MASK_MEMPROF

#define VARIANT_MASK_TEMPORAL_PROF

#define VARIANT_MASK_IR_PROF

#define VARIANT_MASK_BYTE_COVERAGE

#define VARIANT_MASK_INSTR_ENTRY

#define VARIANT_MASK_FUNCTION_ENTRY_ONLY

#define VARIANT_MASK_INSTR_LOOP_ENTRIES

static StringRef getName(Value *V)

static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")

Defines the virtual file system interface vfs::FileSystem.

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

size_t size() const

size - Get the array size.

void resize(unsigned N, bool t=false)

resize - Grow or shrink the bitvector.

iterator_range< const_set_bits_iterator > set_bits() const

static BitVector & apply(F &&f, BitVector &Out, BitVector const &Arg, ArgTys const &...Args)

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

Reader for the indexed binary instrprof format.

Error readNextRecord(NamedInstrProfRecord &Record) override

Read a single record.

Definition InstrProfReader.cpp:1610

static Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const Twine &RemappingPath="")

Factory method to create an indexed reader.

Definition InstrProfReader.cpp:203

Error readHeader() override

Read the file header.

Definition InstrProfReader.cpp:1234

Error printBinaryIds(raw_ostream &OS) override

Print binary ids.

Definition InstrProfReader.cpp:1631

Error getFunctionBitmap(StringRef FuncName, uint64_t FuncHash, BitVector &Bitmap)

Fill Bitmap with the profile data for the given function name.

Definition InstrProfReader.cpp:1583

InstrProfSymtab & getSymtab() override

Return the PGO symtab.

Definition InstrProfReader.cpp:1351

static bool hasFormat(const MemoryBuffer &DataBuffer)

Return true if the given buffer is in an indexed instrprof format.

Definition InstrProfReader.cpp:1169

Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash, std::vector< uint64_t > &Counts)

Fill Counts with the profile data for the given function name.

Definition InstrProfReader.cpp:1572

Expected< NamedInstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash, StringRef DeprecatedFuncName="", uint64_t *MismatchedFuncSum=nullptr)

Return the NamedInstrProfRecord associated with FuncName and FuncHash.

Definition InstrProfReader.cpp:1372

Error readBinaryIds(std::vector< llvm::object::BuildID > &BinaryIds) override

Read a list of binary ids.

Definition InstrProfReader.cpp:1625

LLVM_ABI memprof::AllMemProfData getAllMemProfData() const

Definition InstrProfReader.cpp:1542

LLVM_ABI Expected< memprof::MemProfRecord > getMemProfRecord(const uint64_t FuncNameHash) const

Definition InstrProfReader.cpp:1461

LLVM_ABI DenseMap< uint64_t, SmallVector< memprof::CallEdgeTy, 0 > > getMemProfCallerCalleePairs() const

Definition InstrProfReader.cpp:1504

InstrProfCorrelatorImpl - A child of InstrProfCorrelator with a template pointer type so that the Pro...

const RawInstrProf::ProfileData< IntPtrT > * getDataPointer() const

Return a pointer to the underlying ProfileData vector that this class constructs.

size_t getDataSize() const

Return the number of ProfileData elements.

InstrProfCorrelator - A base class used to create raw instrumentation data to their functions.

const char * getNamesPointer() const

Return a pointer to the names string that this class constructs.

ProfCorrelatorKind

Indicate if we should use the debug info or profile metadata sections to correlate.

LLVM_ABI std::optional< size_t > getDataSize() const

Return the number of ProfileData elements.

static LLVM_ABI llvm::Expected< std::unique_ptr< InstrProfCorrelator > > get(StringRef Filename, ProfCorrelatorKind FileKind, const object::BuildIDFetcher *BIDFetcher=nullptr, const ArrayRef< llvm::object::BuildID > BIs={})

size_t getNamesSize() const

Return the number of bytes in the names string.

static std::pair< instrprof_error, std::string > take(Error E)

Consume an Error and return the raw enum value contained within it, and the optional error message.

LLVM_ABI data_type ReadData(StringRef K, const unsigned char *D, offset_type N)

Definition InstrProfReader.cpp:937

LLVM_ABI bool readValueProfilingData(const unsigned char *&D, const unsigned char *const End)

Definition InstrProfReader.cpp:923

LLVM_ABI hash_value_type ComputeHash(StringRef K)

Definition InstrProfReader.cpp:916

ArrayRef< NamedInstrProfRecord > data_type

InstrProfKind getProfileKind() const override

Definition InstrProfReader.cpp:1046

Error getRecords(ArrayRef< NamedInstrProfRecord > &Data) override

Definition InstrProfReader.cpp:1019

InstrProfReaderIndex(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, IndexedInstrProf::HashT HashType, uint64_t Version)

Definition InstrProfReader.cpp:1034

bool atEnd() const override

A remapper that applies remappings based on a symbol remapping file.

Definition InstrProfReader.cpp:1069

static StringRef extractName(StringRef Name)

Extract the original function name from a PGO function name.

Definition InstrProfReader.cpp:1078

InstrProfReaderItaniumRemapper(std::unique_ptr< MemoryBuffer > RemapBuffer, InstrProfReaderIndex< HashTableImpl > &Underlying)

Definition InstrProfReader.cpp:1071

Error populateRemappings() override

Definition InstrProfReader.cpp:1104

static void reconstituteName(StringRef OrigName, StringRef ExtractedName, StringRef Replacement, SmallVectorImpl< char > &Out)

Given a mangled name extracted from a PGO function name, and a new form for that mangled name,...

Definition InstrProfReader.cpp:1095

Error getRecords(StringRef FuncName, ArrayRef< NamedInstrProfRecord > &Data) override

Definition InstrProfReader.cpp:1119

Name matcher supporting fuzzy matching of symbol names to names in profiles.

Base class and interface for reading profiling data of any known instrprof format.

std::unique_ptr< InstrProfSymtab > Symtab

Error success()

Clear the current error and return a successful one.

SmallVector< TemporalProfTraceTy > TemporalProfTraces

A list of temporal profile traces.

uint64_t TemporalProfTraceStreamSize

The total number of temporal profile traces seen.

virtual bool isIRLevelProfile() const =0

virtual Error readHeader()=0

Read the header. Required before reading first record.

LLVM_ABI void accumulateCounts(CountSumOrPercent &Sum, bool IsCS)

Compute the sum of counts and return in Sum.

Definition InstrProfReader.cpp:1639

static LLVM_ABI Expected< std::unique_ptr< InstrProfReader > > create(const Twine &Path, vfs::FileSystem &FS, const InstrProfCorrelator *Correlator=nullptr, const object::BuildIDFetcher *BIDFetcher=nullptr, const InstrProfCorrelator::ProfCorrelatorKind BIDFetcherCorrelatorKind=InstrProfCorrelator::ProfCorrelatorKind::NONE, std::function< void(Error)> Warn=nullptr)

Factory method to create an appropriately typed reader for the given instrprof file.

Definition InstrProfReader.cpp:156

A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...

static bool isExternalSymbol(const StringRef &Symbol)

True if Symbol is the value used to represent external symbols.

void mapAddress(uint64_t Addr, uint64_t MD5Val)

Map a function address to its name's MD5 hash.

LLVM_ABI Error create(object::SectionRef &Section)

Create InstrProfSymtab from an object file section which contains function PGO names.

void mapVTableAddress(uint64_t StartAddr, uint64_t EndAddr, uint64_t MD5Val)

Map the address range (i.e., [start_address, end_address)) of a variable to its names' MD5 hash.

This interface provides simple read-only access to a block of memory, and provides simple methods for...

size_t getBufferSize() const

const char * getBufferEnd() const

static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()

Read all of stdin into a file buffer, and return it.

const char * getBufferStart() const

static LLVM_ABI const ArrayRef< uint32_t > DefaultCutoffs

A vector of useful cutoff values for detailed summary.

Reader for the raw instrprof binary format from runtime.

Error readHeader() override

Read the header. Required before reading first record.

Definition InstrProfReader.cpp:512

Error readNextRecord(NamedInstrProfRecord &Record) override

Read a single record.

Definition InstrProfReader.cpp:860

Error printBinaryIds(raw_ostream &OS) override

Print binary ids.

Definition InstrProfReader.cpp:902

static bool hasFormat(const MemoryBuffer &DataBuffer)

InstrProfKind getProfileKind() const override

Returns a BitsetEnum describing the attributes of the raw instr profile.

Definition InstrProfReader.cpp:478

Error readBinaryIds(std::vector< llvm::object::BuildID > &BinaryIds) override

Read a list of binary ids.

Definition InstrProfReader.cpp:894

SmallVector< TemporalProfTraceTy > & getTemporalProfTraces(std::optional< uint64_t > Weight={}) override

Definition InstrProfReader.cpp:484

SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void reserve(size_type N)

iterator insert(iterator I, T &&Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

constexpr StringRef substr(size_t Start, size_t N=npos) const

Return a reference to the substring from [Start, Start + N).

constexpr bool empty() const

empty - Check if the string is empty.

constexpr size_t size() const

size - Get the string size.

Reader for symbol remapping files.

Reader for the simple text based instrprof format.

static bool hasFormat(const MemoryBuffer &Buffer)

Return true if the given buffer is in text instrprof format.

Definition InstrProfReader.cpp:240

Error readNextRecord(NamedInstrProfRecord &Record) override

Read a single record.

Definition InstrProfReader.cpp:404

Error readHeader() override

Read the header.

Definition InstrProfReader.cpp:253

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

LLVM_ABI std::string str() const

Return the twine contents as a std::string.

BuildIDFetcher searches local cache directories for debug info.

This class implements an extremely fast bulk output stream that can only output to a stream.

The virtual file system interface.

std::unique_ptr< Summary > allocSummary(uint32_t TotalSize)

uint64_t ComputeHash(StringRef K)

constexpr uint64_t MaximumSupportedVersion

constexpr uint64_t MinimumSupportedVersion

SmallVector< uint8_t, 10 > BuildID

A build ID in binary form.

value_type byte_swap(value_type value, endianness endian)

value_type read(const void *memory, endianness endian)

Read a value of a particular endianness from memory.

value_type readNext(const CharT *&memory, endianness endian)

Read a value of a particular endianness from a buffer, and increment the buffer past that value.

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr CountersDelta

FunctionAddr VTableAddr Value

FunctionAddr NumBitmapBytes

RawInstrProfReader< uint64_t > RawInstrProfReader64

static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)

constexpr T byteswap(T V) noexcept

Reverses the bytes in the given integer value V.

Error handleErrors(Error E, HandlerTs &&... Hs)

Pass the ErrorInfo(s) contained in E to their respective handlers.

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

FunctionAddr VTableAddr uintptr_t uintptr_t DataSize

auto unique(Range &&R, Predicate P)

auto dyn_cast_or_null(const Y &Val)

FunctionAddr VTableAddr uintptr_t BitmapDelta

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

FunctionAddr VTableAddr uintptr_t uintptr_t Version

void sort(IteratorTy Start, IteratorTy End)

OnDiskIterableChainedHashTable< memprof::CallStackLookupTrait > MemProfCallStackHashTable

constexpr T alignToPowerOf2(U Value, V Align)

Will overflow only if result is not representable in T.

FunctionAddr NumValueSites[IPVK_Last+1]

OnDiskIterableChainedHashTable< memprof::FrameLookupTrait > MemProfFrameHashTable

FunctionAddr VTableAddr Count

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

@ raw_profile_version_mismatch

@ counter_value_too_large

@ unexpected_correlation_info

auto count(R &&Range, const E &Element)

Wrapper function around std::count to count the number of times an element Element occurs in the give...

constexpr char GlobalIdentifierDelimiter

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

std::vector< ProfileSummaryEntry > SummaryEntryVector

void consumeError(Error Err)

Consume a Error without doing anything.

InstrProfKind

An enum describing the attributes of an instrumented profile.

@ LoopEntriesInstrumentation

@ FunctionEntryInstrumentation

@ FrontendInstrumentation

RawInstrProfReader< uint32_t > RawInstrProfReader32

Implement std::hash so that hash_code can be used in STL containers.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

uint64_t Cutoff

The required percentile of total execution count.

uint64_t NumBlocks

Number of blocks >= the minumum execution count.

uint64_t MinBlockCount

The minimum execution count for this percentile.

static uint32_t getSize(uint32_t NumSumFields, uint32_t NumCutoffEntries)

uint64_t NumSummaryFields

uint64_t NumCutoffEntries

Profiling information for a single function.

LLVM_ABI void addValueData(uint32_t ValueKind, uint32_t Site, ArrayRef< InstrProfValueData > VData, InstrProfSymtab *SymTab)

Add ValueData for ValueKind at value Site.

void reserveSites(uint32_t ValueKind, uint32_t NumValueSites)

Reserve space for NumValueSites sites.

static bool hasCSFlagInHash(uint64_t FuncHash)

An ordered list of functions identified by their NameRef found in INSTR_PROF_DATA.

YamlDataAccessProfData YamlifiedDataAccessProfiles

std::vector< GUIDMemProfRecordPair > HeapProfileRecords

std::optional< CallStackId > LastUnmappedId

The data access profiles for a symbol.

std::optional< FrameId > LastUnmappedId

LLVM_ABI MemProfRecord toMemProfRecord(llvm::function_ref< std::vector< Frame >(const CallStackId)> Callback) const

std::vector< memprof::DataAccessProfRecord > Records

std::vector< uint64_t > KnownColdStrHashes

std::vector< std::string > KnownColdSymbols