forked from qt-creator/qt-creator
Valgrind: Dismantle Parser class
Replace it with parseDataFile() function. Change-Id: I21ee1e5ffa2dba94501c7d8e258ac2c5478af633 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -110,17 +110,10 @@ static int parseNameShorthand(const char **current, const char *end)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Parser::Private
|
class ParserPrivate
|
||||||
{
|
{
|
||||||
Parser *const q;
|
|
||||||
public:
|
public:
|
||||||
|
ParseDataPtr parse(const FilePath &filePath);
|
||||||
explicit Private(Parser *qq)
|
|
||||||
: q(qq)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse(const FilePath &filePath);
|
|
||||||
void parseHeader(QIODevice *device);
|
void parseHeader(QIODevice *device);
|
||||||
|
|
||||||
using NamePair = QPair<qint64, QString>;
|
using NamePair = QPair<qint64, QString>;
|
||||||
@@ -167,7 +160,7 @@ public:
|
|||||||
QSet<Function *> recursiveFunctions;
|
QSet<Function *> recursiveFunctions;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Parser::Private::parse(const FilePath &filePath)
|
ParseDataPtr ParserPrivate::parse(const FilePath &filePath)
|
||||||
{
|
{
|
||||||
const QString path = filePath.path(); // FIXME: Works only accidentally for docker
|
const QString path = filePath.path(); // FIXME: Works only accidentally for docker
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
@@ -233,8 +226,7 @@ void Parser::Private::parse(const FilePath &filePath)
|
|||||||
// now accumulate callees
|
// now accumulate callees
|
||||||
for (Function *func : std::as_const(pendingFunctions))
|
for (Function *func : std::as_const(pendingFunctions))
|
||||||
func->finalize();
|
func->finalize();
|
||||||
|
return data;
|
||||||
emit q->parserDataReady();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QString getValue(const QByteArray &line, const int prefixLength)
|
inline QString getValue(const QByteArray &line, const int prefixLength)
|
||||||
@@ -244,7 +236,7 @@ inline QString getValue(const QByteArray &line, const int prefixLength)
|
|||||||
return QString::fromLatin1(line.mid(prefixLength, line.length() - 1 - prefixLength).constData());
|
return QString::fromLatin1(line.mid(prefixLength, line.length() - 1 - prefixLength).constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseHeader(QIODevice *device)
|
void ParserPrivate::parseHeader(QIODevice *device)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(device->isOpen(), return);
|
QTC_ASSERT(device->isOpen(), return);
|
||||||
QTC_ASSERT(device->isReadable(), return);
|
QTC_ASSERT(device->isReadable(), return);
|
||||||
@@ -301,7 +293,7 @@ void Parser::Private::parseHeader(QIODevice *device)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Private::NamePair Parser::Private::parseName(const char *begin, const char *end)
|
ParserPrivate::NamePair ParserPrivate::parseName(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
const char *current = begin;
|
const char *current = begin;
|
||||||
qint64 nameShorthand = -1;
|
qint64 nameShorthand = -1;
|
||||||
@@ -325,7 +317,7 @@ Parser::Private::NamePair Parser::Private::parseName(const char *begin, const ch
|
|||||||
* cfn means called function
|
* cfn means called function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Parser::Private::dispatchLine(const QByteArray &line)
|
void ParserPrivate::dispatchLine(const QByteArray &line)
|
||||||
{
|
{
|
||||||
int lineEnding = line.endsWith("\r\n") ? 2 : 1;
|
int lineEnding = line.endsWith("\r\n") ? 2 : 1;
|
||||||
const char *const begin = line.constData();
|
const char *const begin = line.constData();
|
||||||
@@ -408,7 +400,7 @@ void Parser::Private::dispatchLine(const QByteArray &line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseCostItem(const char *begin, const char *end)
|
void ParserPrivate::parseCostItem(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(currentFunction, return);
|
QTC_ASSERT(currentFunction, return);
|
||||||
|
|
||||||
@@ -504,7 +496,7 @@ void Parser::Private::parseCostItem(const char *begin, const char *end)
|
|||||||
currentFunction->addCostItem(costItem);
|
currentFunction->addCostItem(costItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseSourceFile(const char *begin, const char *end)
|
void ParserPrivate::parseSourceFile(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
NamePair name = parseName(begin, end);
|
NamePair name = parseName(begin, end);
|
||||||
|
|
||||||
@@ -518,7 +510,7 @@ void Parser::Private::parseSourceFile(const char *begin, const char *end)
|
|||||||
currentDifferingFile = -1;
|
currentDifferingFile = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseFunction(const char *begin, const char *end)
|
void ParserPrivate::parseFunction(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
currentFunction = new Function(data.get());
|
currentFunction = new Function(data.get());
|
||||||
currentFunction->setFile(lastFile);
|
currentFunction->setFile(lastFile);
|
||||||
@@ -534,7 +526,7 @@ void Parser::Private::parseFunction(const char *begin, const char *end)
|
|||||||
currentFunction->setName(name.first);
|
currentFunction->setName(name.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseDifferingSourceFile(const char *begin, const char *end)
|
void ParserPrivate::parseDifferingSourceFile(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
NamePair name = parseName(begin, end);
|
NamePair name = parseName(begin, end);
|
||||||
|
|
||||||
@@ -550,7 +542,7 @@ void Parser::Private::parseDifferingSourceFile(const char *begin, const char *en
|
|||||||
currentDifferingFile = name.first;
|
currentDifferingFile = name.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseObjectFile(const char *begin, const char *end)
|
void ParserPrivate::parseObjectFile(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
NamePair name = parseName(begin, end);
|
NamePair name = parseName(begin, end);
|
||||||
if (!name.second.isEmpty())
|
if (!name.second.isEmpty())
|
||||||
@@ -559,7 +551,7 @@ void Parser::Private::parseObjectFile(const char *begin, const char *end)
|
|||||||
lastObject = name.first;
|
lastObject = name.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseCalls(const char *begin, const char *end)
|
void ParserPrivate::parseCalls(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
const char *current = begin;
|
const char *current = begin;
|
||||||
bool ok;
|
bool ok;
|
||||||
@@ -577,7 +569,7 @@ void Parser::Private::parseCalls(const char *begin, const char *end)
|
|||||||
isParsingFunctionCall = true;
|
isParsingFunctionCall = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseCalledFunction(const char *begin, const char *end)
|
void ParserPrivate::parseCalledFunction(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
NamePair name = parseName(begin, end);
|
NamePair name = parseName(begin, end);
|
||||||
if (!name.second.isEmpty())
|
if (!name.second.isEmpty())
|
||||||
@@ -586,7 +578,7 @@ void Parser::Private::parseCalledFunction(const char *begin, const char *end)
|
|||||||
currentCallData.calledFunction = name.first;
|
currentCallData.calledFunction = name.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseCalledSourceFile(const char *begin, const char *end)
|
void ParserPrivate::parseCalledSourceFile(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
NamePair name = parseName(begin, end);
|
NamePair name = parseName(begin, end);
|
||||||
if (!name.second.isEmpty()) {
|
if (!name.second.isEmpty()) {
|
||||||
@@ -598,7 +590,7 @@ void Parser::Private::parseCalledSourceFile(const char *begin, const char *end)
|
|||||||
currentCallData.calledFile = name.first;
|
currentCallData.calledFile = name.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::Private::parseCalledObjectFile(const char *begin, const char *end)
|
void ParserPrivate::parseCalledObjectFile(const char *begin, const char *end)
|
||||||
{
|
{
|
||||||
NamePair name = parseName(begin, end);
|
NamePair name = parseName(begin, end);
|
||||||
if (!name.second.isEmpty())
|
if (!name.second.isEmpty())
|
||||||
@@ -609,24 +601,10 @@ void Parser::Private::parseCalledObjectFile(const char *begin, const char *end)
|
|||||||
|
|
||||||
//BEGIN Parser
|
//BEGIN Parser
|
||||||
|
|
||||||
void Parser::parse(const Utils::FilePath &filePath)
|
ParseDataPtr parseDataFile(const Utils::FilePath &filePath)
|
||||||
{
|
{
|
||||||
d->parse(filePath);
|
ParserPrivate parser;
|
||||||
}
|
return parser.parse(filePath);
|
||||||
|
|
||||||
Parser::Parser()
|
|
||||||
: d(new Private(this))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Parser::~Parser()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseDataPtr Parser::parserData() const
|
|
||||||
{
|
|
||||||
return d->data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Valgrind::Callgrind
|
} // namespace Valgrind::Callgrind
|
||||||
|
@@ -11,8 +11,6 @@ namespace Utils { class FilePath; }
|
|||||||
|
|
||||||
namespace Valgrind::Callgrind {
|
namespace Valgrind::Callgrind {
|
||||||
|
|
||||||
class ParseData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parser for Valgrind --tool=callgrind output
|
* Parser for Valgrind --tool=callgrind output
|
||||||
* most of the format is documented at http://kcachegrind.sourceforge.net/html/CallgrindFormat.html
|
* most of the format is documented at http://kcachegrind.sourceforge.net/html/CallgrindFormat.html
|
||||||
@@ -22,25 +20,7 @@ class ParseData;
|
|||||||
* the rest is assumed to be zero."
|
* the rest is assumed to be zero."
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Parser : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
ParseDataPtr parseDataFile(const Utils::FilePath &filePath);
|
||||||
Parser();
|
|
||||||
~Parser() override;
|
|
||||||
|
|
||||||
// get and take ownership of the parsing results. If this function is not called the repository
|
|
||||||
// will be destroyed when the parser is destroyed. Subsequent calls return null.
|
|
||||||
ParseDataPtr parserData() const;
|
|
||||||
void parse(const Utils::FilePath &filePath);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void parserDataReady();
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Private;
|
|
||||||
Private *const d;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Valgrind::Callgrind
|
} // namespace Valgrind::Callgrind
|
||||||
|
@@ -34,13 +34,7 @@ CallgrindToolRunner::CallgrindToolRunner(RunControl *runControl)
|
|||||||
connect(&m_runner, &ValgrindProcess::valgrindStarted, this, [this](qint64 pid) {
|
connect(&m_runner, &ValgrindProcess::valgrindStarted, this, [this](qint64 pid) {
|
||||||
m_pid = pid;
|
m_pid = pid;
|
||||||
});
|
});
|
||||||
connect(&m_runner, &ValgrindProcess::done, this, [this] {
|
connect(&m_runner, &ValgrindProcess::done, this, &CallgrindToolRunner::triggerParse);
|
||||||
triggerParse();
|
|
||||||
emit parserDataReady(this);
|
|
||||||
});
|
|
||||||
connect(&m_parser, &Callgrind::Parser::parserDataReady, this, [this] {
|
|
||||||
emit parserDataReady(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_valgrindRunnable = runControl->runnable();
|
m_valgrindRunnable = runControl->runnable();
|
||||||
|
|
||||||
@@ -117,11 +111,6 @@ void CallgrindToolRunner::setToggleCollectFunction(const QString &toggleCollectF
|
|||||||
m_argumentForToggleCollect = "--toggle-collect=" + toggleCollectFunction;
|
m_argumentForToggleCollect = "--toggle-collect=" + toggleCollectFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
Callgrind::ParseDataPtr CallgrindToolRunner::parserData() const
|
|
||||||
{
|
|
||||||
return m_parser.parserData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CallgrindToolRunner::showStatusMessage(const QString &message)
|
void CallgrindToolRunner::showStatusMessage(const QString &message)
|
||||||
{
|
{
|
||||||
Debugger::showPermanentStatusMessage(message);
|
Debugger::showPermanentStatusMessage(message);
|
||||||
@@ -253,7 +242,7 @@ void CallgrindToolRunner::triggerParse()
|
|||||||
if (!res) // failed to run callgrind
|
if (!res) // failed to run callgrind
|
||||||
return;
|
return;
|
||||||
showStatusMessage(Tr::tr("Parsing Profile Data..."));
|
showStatusMessage(Tr::tr("Parsing Profile Data..."));
|
||||||
m_parser.parse(m_hostOutputFile);
|
emit parserDataReady(parseDataFile(m_hostOutputFile));
|
||||||
};
|
};
|
||||||
// TODO: Store the handle and cancel on CallgrindToolRunner destructor?
|
// TODO: Store the handle and cancel on CallgrindToolRunner destructor?
|
||||||
// TODO: Should d'tor of context object cancel the running task?
|
// TODO: Should d'tor of context object cancel the running task?
|
||||||
|
@@ -23,8 +23,6 @@ public:
|
|||||||
|
|
||||||
void start() override;
|
void start() override;
|
||||||
|
|
||||||
Callgrind::ParseDataPtr parserData() const;
|
|
||||||
|
|
||||||
/// controller actions
|
/// controller actions
|
||||||
void dump() { run(Dump); }
|
void dump() { run(Dump); }
|
||||||
void reset() { run(ResetEventCounters); }
|
void reset() { run(ResetEventCounters); }
|
||||||
@@ -52,7 +50,7 @@ protected:
|
|||||||
QString progressTitle() const override;
|
QString progressTitle() const override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void parserDataReady(CallgrindToolRunner *engine);
|
void parserDataReady(const Callgrind::ParseDataPtr &data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void showStatusMessage(const QString &message);
|
void showStatusMessage(const QString &message);
|
||||||
@@ -83,7 +81,6 @@ private:
|
|||||||
Utils::FilePath m_valgrindOutputFile; // On the device that runs valgrind
|
Utils::FilePath m_valgrindOutputFile; // On the device that runs valgrind
|
||||||
Utils::FilePath m_hostOutputFile; // On the device that runs creator
|
Utils::FilePath m_hostOutputFile; // On the device that runs creator
|
||||||
|
|
||||||
Callgrind::Parser m_parser;
|
|
||||||
bool m_paused = false;
|
bool m_paused = false;
|
||||||
|
|
||||||
QString m_argumentForToggleCollect;
|
QString m_argumentForToggleCollect;
|
||||||
|
@@ -137,7 +137,6 @@ public:
|
|||||||
void visualisationFunctionSelected(const Function *function);
|
void visualisationFunctionSelected(const Function *function);
|
||||||
void showParserResults(const ParseDataPtr &data);
|
void showParserResults(const ParseDataPtr &data);
|
||||||
|
|
||||||
void takeParserDataFromRunControl(CallgrindToolRunner *rc);
|
|
||||||
void setParserData(const ParseDataPtr &data);
|
void setParserData(const ParseDataPtr &data);
|
||||||
void doSetParseData(const ParseDataPtr &data);
|
void doSetParseData(const ParseDataPtr &data);
|
||||||
void engineFinished();
|
void engineFinished();
|
||||||
@@ -710,7 +709,7 @@ void CallgrindTool::setupRunner(CallgrindToolRunner *toolRunner)
|
|||||||
{
|
{
|
||||||
RunControl *runControl = toolRunner->runControl();
|
RunControl *runControl = toolRunner->runControl();
|
||||||
|
|
||||||
connect(toolRunner, &CallgrindToolRunner::parserDataReady, this, &CallgrindTool::takeParserDataFromRunControl);
|
connect(toolRunner, &CallgrindToolRunner::parserDataReady, this, &CallgrindTool::setParserData);
|
||||||
connect(runControl, &RunControl::stopped, this, &CallgrindTool::engineFinished);
|
connect(runControl, &RunControl::stopped, this, &CallgrindTool::engineFinished);
|
||||||
|
|
||||||
connect(this, &CallgrindTool::dumpRequested, toolRunner, &CallgrindToolRunner::dump);
|
connect(this, &CallgrindTool::dumpRequested, toolRunner, &CallgrindToolRunner::dump);
|
||||||
@@ -870,14 +869,7 @@ void CallgrindTool::loadExternalLogFile()
|
|||||||
Debugger::showPermanentStatusMessage(Tr::tr("Parsing Profile Data..."));
|
Debugger::showPermanentStatusMessage(Tr::tr("Parsing Profile Data..."));
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
|
|
||||||
Parser parser;
|
setParserData(parseDataFile(filePath));
|
||||||
parser.parse(filePath);
|
|
||||||
setParserData(parser.parserData());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CallgrindTool::takeParserDataFromRunControl(CallgrindToolRunner *rc)
|
|
||||||
{
|
|
||||||
setParserData(rc->parserData());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallgrindTool::setParserData(const ParseDataPtr &data)
|
void CallgrindTool::setParserData(const ParseDataPtr &data)
|
||||||
|
@@ -21,9 +21,10 @@ using namespace Valgrind::Callgrind;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static QString dataFile(const char *file)
|
static Utils::FilePath dataFile(const char *file)
|
||||||
{
|
{
|
||||||
return QLatin1String(PARSERTESTS_DATA_DIR) + QLatin1String("/") + QLatin1String(file);
|
return Utils::FilePath::fromString(
|
||||||
|
QLatin1String(PARSERTESTS_DATA_DIR) + QLatin1String("/") + QLatin1String(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
void testCostItem(const CostItem *item, quint64 expectedPosition, quint64 expectedCost)
|
void testCostItem(const CostItem *item, quint64 expectedPosition, quint64 expectedCost)
|
||||||
@@ -80,13 +81,6 @@ void CallgrindParserTests::cleanup()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseDataPtr parseDataFile(const QString &dataFile)
|
|
||||||
{
|
|
||||||
Parser p;
|
|
||||||
p.parse(Utils::FilePath::fromString(dataFile));
|
|
||||||
return p.parserData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CallgrindParserTests::testHeaderData()
|
void CallgrindParserTests::testHeaderData()
|
||||||
{
|
{
|
||||||
const ParseDataPtr data(parseDataFile(dataFile("simpleFunction.out")));
|
const ParseDataPtr data(parseDataFile(dataFile("simpleFunction.out")));
|
||||||
|
Reference in New Issue
Block a user