1818#include " llvm/Support/Process.h"
1919#include " llvm/Support/ToolOutputFile.h"
2020
21- #include < regex>
22-
2321#define DEBUG_TYPE " perf-reader"
2422
2523cl::opt<bool > SkipSymbolization (" skip-symbolization" ,
@@ -377,15 +375,24 @@ PerfReaderBase::create(ProfiledBinary *Binary, PerfInputFile &PerfInput,
377375 return PerfReader;
378376}
379377
380- void PerfReaderBase::parseDataAccessPerfTraces (
378+ Error PerfReaderBase::parseDataAccessPerfTraces (
381379 StringRef DataAccessPerfTraceFile, std::optional<int32_t > PIDFilter) {
382- std::regex logRegex (
383- R"( ^.*?PERF_RECORD_SAMPLE\(.*?\):\s*(\d+)\/(\d+):\s*(0x[0-9a-fA-F]+)\s+period:\s*\d+\s+addr:\s*(0x[0-9a-fA-F]+)$)" );
380+ // A perf_record_sample line is like
381+ // . 1282514022939813 0x87b0 [0x60]: PERF_RECORD_SAMPLE(IP, 0x4002):
382+ // 3446532/3446532: 0x2608a2 period: 233 addr: 0x3b3fb0
383+ constexpr static const char *const DataAccessSamplePattern =
384+ " PERF_RECORD_SAMPLE\\ ([A-Za-z]+, 0x[0-9a-fA-F]+\\ ): "
385+ " ([0-9]+)\\ /[0-9]+: (0x[0-9a-fA-F]+) period: [0-9]+ addr: "
386+ " (0x[0-9a-fA-F]+)" ;
387+
388+ llvm::Regex logRegex (DataAccessSamplePattern);
384389
385390 auto BufferOrErr = MemoryBuffer::getFile (DataAccessPerfTraceFile);
386391 std::error_code EC = BufferOrErr.getError ();
387392 if (EC)
388- exitWithError (" Failed to open perf trace file: " + DataAccessPerfTraceFile);
393+ return make_error<StringError>(" Failed to open perf trace file: " +
394+ DataAccessPerfTraceFile,
395+ inconvertibleErrorCode ());
389396
390397 assert (!SampleCounters.empty () && " Sample counters should not be empty!" );
391398 SampleCounter &Counter = SampleCounters.begin ()->second ;
@@ -403,33 +410,28 @@ void PerfReaderBase::parseDataAccessPerfTraces(
403410 continue ;
404411 }
405412
406- // Skip lines that do not contain "PERF_RECORD_SAMPLE".
407- if (!Line.contains (" PERF_RECORD_SAMPLE" )) {
408- continue ;
409- }
410-
411- std::smatch matches;
412- const std::string LineStr = Line.str ();
413-
414- if (std::regex_search (LineStr.begin (), LineStr.end (), matches, logRegex)) {
415- if (matches.size () != 5 )
416- continue ;
417-
418- const int32_t PID = std::stoi (matches[1 ].str ());
419- if (PIDFilter && *PIDFilter != PID) {
413+ SmallVector<StringRef> Fields;
414+ if (logRegex.match (Line, &Fields)) {
415+ int32_t PID = 0 ;
416+ Fields[1 ].getAsInteger (0 , PID);
417+ if (PIDFilter.has_value () && *PIDFilter != PID) {
420418 continue ;
421419 }
422420
423- const uint64_t DataAddress = std::stoull (matches[4 ].str (), nullptr , 16 );
421+ uint64_t DataAddress = 0 ;
422+ Fields[3 ].getAsInteger (0 , DataAddress);
423+
424424 StringRef DataSymbol = Binary->symbolizeDataAddress (
425425 Binary->CanonicalizeNonTextAddress (DataAddress));
426426 if (DataSymbol.starts_with (" _ZTV" )) {
427- const uint64_t IP = std::stoull (matches[3 ].str (), nullptr , 16 );
427+ uint64_t IP = 0 ;
428+ Fields[2 ].getAsInteger (0 , IP);
428429 Counter.recordDataAccessCount (Binary->canonicalizeVirtualAddress (IP),
429430 DataSymbol, 1 );
430431 }
431432 }
432433 }
434+ return Error::success ();
433435}
434436
435437PerfInputFile
0 commit comments