@@ -1332,7 +1332,7 @@ PerfParser::PerfParser(QObject* parent)
13321332
13331333PerfParser::~PerfParser () = default ;
13341334
1335- void PerfParser::startParseFile (const QString& path)
1335+ void PerfParser::startParseFile (const QString& path, const QString& diffFile )
13361336{
13371337 Q_ASSERT (!m_isParsing);
13381338
@@ -1358,6 +1358,7 @@ void PerfParser::startParseFile(const QString& path)
13581358
13591359 auto parserArgs = [this ](const QString& filename) {
13601360 const auto settings = Settings::instance ();
1361+
13611362 QStringList parserArgs = {QStringLiteral (" --input" ), decompressIfNeeded (filename),
13621363 QStringLiteral (" --max-frames" ), QStringLiteral (" 1024" )};
13631364 const auto sysroot = settings->sysroot ();
@@ -1405,7 +1406,7 @@ void PerfParser::startParseFile(const QString& path)
14051406
14061407 emit parsingStarted ();
14071408 using namespace ThreadWeaver ;
1408- stream () << make_job ([path, parserBinary, parserArgs, env, this ]() {
1409+ stream () << make_job ([path, parserBinary, env, this ]() {
14091410 PerfParserPrivate d;
14101411 connect (&d, &PerfParserPrivate::progress, this , &PerfParser::progress);
14111412 connect (this , &PerfParser::stopRequested, &d, &PerfParserPrivate::stop);
@@ -1451,55 +1452,55 @@ void PerfParser::startParseFile(const QString& path)
14511452
14521453 d.setInput (&process);
14531454
1455+ const auto exitCodeHandler = [finalize, this ](int exitCode, QProcess::ExitStatus exitStatus) {
1456+ if (m_stopRequested) {
1457+ emit parsingFailed (tr (" Parsing stopped." ));
1458+ return ;
1459+ }
1460+ qCDebug (LOG_PERFPARSER) << exitCode << exitStatus;
1461+
1462+ enum ErrorCodes
1463+ {
1464+ NoError,
1465+ TcpSocketError,
1466+ CannotOpen,
1467+ BadMagic,
1468+ HeaderError,
1469+ DataError,
1470+ MissingData,
1471+ InvalidOption
1472+ };
1473+ switch (exitCode) {
1474+ case NoError:
1475+ finalize ();
1476+ break ;
1477+ case TcpSocketError:
1478+ emit parsingFailed (
1479+ tr (" The hotspot-perfparser binary exited with code %1 (TCP socket error)." ).arg (exitCode));
1480+ break ;
1481+ case CannotOpen:
1482+ emit parsingFailed (
1483+ tr (" The hotspot-perfparser binary exited with code %1 (file could not be opened)." ).arg (exitCode));
1484+ break ;
1485+ case BadMagic:
1486+ case HeaderError:
1487+ case DataError:
1488+ case MissingData:
1489+ emit parsingFailed (
1490+ tr (" The hotspot-perfparser binary exited with code %1 (invalid perf data file)." ).arg (exitCode));
1491+ break ;
1492+ case InvalidOption:
1493+ emit parsingFailed (
1494+ tr (" The hotspot-perfparser binary exited with code %1 (invalid option)." ).arg (exitCode));
1495+ break ;
1496+ default :
1497+ emit parsingFailed (tr (" The hotspot-perfparser binary exited with code %1." ).arg (exitCode));
1498+ break ;
1499+ }
1500+ };
1501+
14541502 connect (&process, static_cast <void (QProcess::*)(int , QProcess::ExitStatus)>(&QProcess::finished), &process,
1455- [finalize, this ](int exitCode, QProcess::ExitStatus exitStatus) {
1456- if (m_stopRequested) {
1457- emit parsingFailed (tr (" Parsing stopped." ));
1458- return ;
1459- }
1460- qCDebug (LOG_PERFPARSER) << exitCode << exitStatus;
1461-
1462- enum ErrorCodes
1463- {
1464- NoError,
1465- TcpSocketError,
1466- CannotOpen,
1467- BadMagic,
1468- HeaderError,
1469- DataError,
1470- MissingData,
1471- InvalidOption
1472- };
1473- switch (exitCode) {
1474- case NoError:
1475- finalize ();
1476- break ;
1477- case TcpSocketError:
1478- emit parsingFailed (
1479- tr (" The hotspot-perfparser binary exited with code %1 (TCP socket error)." ).arg (exitCode));
1480- break ;
1481- case CannotOpen:
1482- emit parsingFailed (
1483- tr (" The hotspot-perfparser binary exited with code %1 (file could not be opened)." )
1484- .arg (exitCode));
1485- break ;
1486- case BadMagic:
1487- case HeaderError:
1488- case DataError:
1489- case MissingData:
1490- emit parsingFailed (
1491- tr (" The hotspot-perfparser binary exited with code %1 (invalid perf data file)." )
1492- .arg (exitCode));
1493- break ;
1494- case InvalidOption:
1495- emit parsingFailed (
1496- tr (" The hotspot-perfparser binary exited with code %1 (invalid option)." ).arg (exitCode));
1497- break ;
1498- default :
1499- emit parsingFailed (tr (" The hotspot-perfparser binary exited with code %1." ).arg (exitCode));
1500- break ;
1501- }
1502- });
1503+ exitCodeHandler);
15031504
15041505 connect (&process, &QProcess::errorOccurred, &process, [&d, &process, this ](QProcess::ProcessError error) {
15051506 if (m_stopRequested) {
@@ -1523,6 +1524,52 @@ void PerfParser::startParseFile(const QString& path)
15231524 &QEventLoop::quit);
15241525 loop.exec ();
15251526 });
1527+
1528+ if (diffFile.isEmpty ()) {
1529+ return ;
1530+ }
1531+
1532+ PerfParser otherData;
1533+
1534+ otherData.startParseFile (diffFile);
1535+ QEventLoop loop;
1536+ connect (&otherData, &PerfParser::parsingFinished, &loop, &QEventLoop::quit);
1537+ connect (&otherData, &PerfParser::parsingFailed, &loop, &QEventLoop::quit);
1538+ connect (&otherData, &PerfParser::parsingFailed, this , [this ](const QString& error) { emit parsingFailed (error); });
1539+
1540+ connect (&otherData, &PerfParser::bottomUpDataAvailable, &otherData,
1541+ [this , &otherData](const Data::BottomUpResults& otherResults) {
1542+ if (m_bottomUpResults.root .children .size () > 0 ) {
1543+ this ->m_callerCalleeResults = {};
1544+
1545+ const auto diffResults =
1546+ Data::BottomUpResults::mergeBottomUpResults (m_bottomUpResults, otherResults);
1547+ m_bottomUpResults = diffResults;
1548+ const auto topDown = Data::TopDownResults::fromBottomUp (diffResults);
1549+ Data::CallerCalleeResults callerCalleeResults;
1550+ Data::callerCalleesFromBottomUpData (diffResults, &callerCalleeResults);
1551+ emit bottomUpDataAvailable (diffResults);
1552+ emit topDownDataAvailable (Data::TopDownResults::fromBottomUp (diffResults));
1553+ emit callerCalleeDataAvailable (callerCalleeResults);
1554+ } else {
1555+ connect (this , &PerfParser::bottomUpDataAvailable, &otherData,
1556+ [this , &otherData, otherResults](const Data::BottomUpResults& results) {
1557+ this ->m_bottomUpResults = {};
1558+ this ->m_callerCalleeResults = {};
1559+
1560+ const auto diffResults =
1561+ Data::BottomUpResults::mergeBottomUpResults (results, otherResults);
1562+ const auto topDown = Data::TopDownResults::fromBottomUp (diffResults);
1563+ Data::CallerCalleeResults callerCalleeResults;
1564+ Data::callerCalleesFromBottomUpData (diffResults, &callerCalleeResults);
1565+ emit bottomUpDataAvailable (diffResults);
1566+ emit topDownDataAvailable (Data::TopDownResults::fromBottomUp (diffResults));
1567+ emit callerCalleeDataAvailable (callerCalleeResults);
1568+ });
1569+ }
1570+ });
1571+
1572+ loop.exec ();
15261573}
15271574
15281575void PerfParser::filterResults (const Data::FilterAction& filter)
0 commit comments