aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit/qv4assembler.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-03-16 17:27:38 +0100
committerUlf Hermann <ulf.hermann@qt.io>2018-03-19 07:25:24 +0000
commitd5c7229339a916b2f1f004ec4ea9de89995c003d (patch)
tree6994773be946a8f9a95c5f2cf6a1d40191955e1f /src/qml/jit/qv4assembler.cpp
parent61447075954aab99b3abc9c78294e5966ae3b6ce (diff)
Restore the QV4_WRITE_PERF_MAP feature
We want to be able to generate perf map files for JITed code. Task-number: QTBUG-67056 Change-Id: I56899e1dbf184083d94efe926d21fca4f9ea1e18 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jit/qv4assembler.cpp')
-rw-r--r--src/qml/jit/qv4assembler.cpp47
1 files changed, 41 insertions, 6 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index 186e5952da..72b057b2bc 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include <QBuffer>
+#include <QFile>
#include "qv4engine_p.h"
#include "qv4assembler_p.h"
@@ -1367,6 +1368,17 @@ static void printDisassembledOutputWithCalls(QByteArray processedOutput,
qDebug("%s", processedOutput.constData());
}
+static QByteArray functionName(Function *function)
+{
+ QByteArray name = function->name()->toQString().toUtf8();
+ if (name.isEmpty()) {
+ name = QByteArray::number(reinterpret_cast<quintptr>(function), 16);
+ name.prepend("QV4::Function(0x");
+ name.append(')');
+ }
+ return name;
+}
+
void Assembler::link(Function *function)
{
for (const auto &jumpTarget : pasm()->patches)
@@ -1388,12 +1400,7 @@ void Assembler::link(Function *function)
buf.open(QIODevice::WriteOnly);
WTF::setDataFile(new QIODevicePrintStream(&buf));
- QByteArray name = function->name()->toQString().toUtf8();
- if (name.isEmpty()) {
- name = QByteArray::number(quintptr(function), 16);
- name.prepend("QV4::Function(0x");
- name.append(')');
- }
+ QByteArray name = functionName(function);
codeRef = linkBuffer.finalizeCodeWithDisassembly("%s", name.data());
WTF::setDataFile(stderr);
@@ -1404,6 +1411,34 @@ void Assembler::link(Function *function)
function->codeRef = new JSC::MacroAssemblerCodeRef(codeRef);
function->jittedCode = reinterpret_cast<Function::JittedCode>(function->codeRef->code().executableAddress());
+
+#if defined(Q_OS_LINUX)
+ // This implements writing of JIT'd addresses so that perf can find the
+ // symbol names.
+ //
+ // Perf expects the mapping to be in a certain place and have certain
+ // content, for more information, see:
+ // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/jit-interface.txt
+ static bool doProfile = !qEnvironmentVariableIsEmpty("QV4_PROFILE_WRITE_PERF_MAP");
+ if (doProfile) {
+ static QFile perfMapFile(QString::fromLatin1("/tmp/perf-%1.map")
+ .arg(QCoreApplication::applicationPid()));
+ static const bool isOpen = perfMapFile.open(QIODevice::WriteOnly);
+ if (!isOpen) {
+ qWarning("QV4::JIT::Assembler: Cannot write perf map file.");
+ doProfile = false;
+ } else {
+ perfMapFile.write(QByteArray::number(reinterpret_cast<quintptr>(
+ codeRef.code().executableAddress()), 16));
+ perfMapFile.putChar(' ');
+ perfMapFile.write(QByteArray::number(static_cast<qsizetype>(codeRef.size()), 16));
+ perfMapFile.putChar(' ');
+ perfMapFile.write(functionName(function));
+ perfMapFile.putChar('\n');
+ perfMapFile.flush();
+ }
+ }
+#endif
}
void Assembler::addLabel(int offset)