зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1436353: Fix and enhance perf support in the jits; r=campbell
MozReview-Commit-ID: IKyJf5jRIZu --HG-- extra : rebase_source : 56ba6731e9918b03e47441673d0eb37d8a8a5387 extra : histedit_source : cce41f271385a436d93289b576ccf0f47ade4f9d
This commit is contained in:
Родитель
6fd86afdb4
Коммит
d68b7067f1
|
@ -5505,7 +5505,8 @@ CodeGenerator::generateBody()
|
|||
TrackedOptimizations* last = nullptr;
|
||||
|
||||
#if defined(JS_ION_PERF)
|
||||
perfSpewer->startBasicBlock(current->mir(), masm);
|
||||
if (!perfSpewer->startBasicBlock(current->mir(), masm))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
for (LInstructionIterator iter = current->begin(); iter != current->end(); iter++) {
|
||||
|
|
|
@ -129,24 +129,21 @@ js::jit::PerfFuncEnabled() {
|
|||
return PerfMode == PERF_MODE_FUNC;
|
||||
}
|
||||
|
||||
static bool
|
||||
lockPerfMap(void)
|
||||
{
|
||||
if (!PerfEnabled())
|
||||
return false;
|
||||
|
||||
PerfMutex->lock();
|
||||
|
||||
MOZ_ASSERT(PerfFilePtr);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
unlockPerfMap()
|
||||
{
|
||||
MOZ_ASSERT(PerfFilePtr);
|
||||
fflush(PerfFilePtr);
|
||||
PerfMutex->unlock();
|
||||
namespace {
|
||||
struct MOZ_RAII AutoLockPerfMap
|
||||
{
|
||||
AutoLockPerfMap() {
|
||||
if (!PerfEnabled())
|
||||
return;
|
||||
PerfMutex->lock();
|
||||
MOZ_ASSERT(PerfFilePtr);
|
||||
}
|
||||
~AutoLockPerfMap() {
|
||||
MOZ_ASSERT(PerfFilePtr);
|
||||
fflush(PerfFilePtr);
|
||||
PerfMutex->unlock();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
uint32_t PerfSpewer::nextFunctionIndex = 0;
|
||||
|
@ -173,24 +170,36 @@ PerfSpewer::startBasicBlock(MBasicBlock* blk,
|
|||
return basicBlocks_.append(r);
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
PerfSpewer::endBasicBlock(MacroAssembler& masm)
|
||||
{
|
||||
if (!PerfBlockEnabled())
|
||||
return true;
|
||||
|
||||
return;
|
||||
masm.bind(&basicBlocks_.back().end);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
PerfSpewer::noteEndInlineCode(MacroAssembler& masm)
|
||||
{
|
||||
if (!PerfBlockEnabled())
|
||||
return true;
|
||||
|
||||
return;
|
||||
masm.bind(&endInlineCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PerfSpewer::WriteEntry(const AutoLockPerfMap&, uintptr_t address, size_t size,
|
||||
const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
|
||||
auto result = mozilla::Vsmprintf<js::SystemAllocPolicy>(fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
fprintf(PerfFilePtr, "%" PRIxPTR " %zx %s\n",
|
||||
address,
|
||||
size,
|
||||
result.get());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -198,29 +207,19 @@ PerfSpewer::writeProfile(JSScript* script,
|
|||
JitCode* code,
|
||||
MacroAssembler& masm)
|
||||
{
|
||||
AutoLockPerfMap lock;
|
||||
|
||||
if (PerfFuncEnabled()) {
|
||||
if (!lockPerfMap())
|
||||
return;
|
||||
|
||||
uint32_t thisFunctionIndex = nextFunctionIndex++;
|
||||
|
||||
size_t size = code->instructionsSize();
|
||||
if (size > 0) {
|
||||
fprintf(PerfFilePtr, "%p %zx %s:%zu: Func%02d\n",
|
||||
code->raw(),
|
||||
size,
|
||||
script->filename(),
|
||||
script->lineno(),
|
||||
thisFunctionIndex);
|
||||
WriteEntry(lock, reinterpret_cast<uintptr_t>(code->raw()), size, "%s:%zu: Func%02" PRIu32,
|
||||
script->filename(), script->lineno(), thisFunctionIndex);
|
||||
}
|
||||
unlockPerfMap();
|
||||
return;
|
||||
}
|
||||
|
||||
if (PerfBlockEnabled() && basicBlocks_.length() > 0) {
|
||||
if (!lockPerfMap())
|
||||
return;
|
||||
|
||||
uint32_t thisFunctionIndex = nextFunctionIndex++;
|
||||
uintptr_t funcStart = uintptr_t(code->raw());
|
||||
uintptr_t funcEndInlineCode = funcStart + endInlineCode.offset();
|
||||
|
@ -230,8 +229,8 @@ PerfSpewer::writeProfile(JSScript* script,
|
|||
size_t prologueSize = basicBlocks_[0].start.offset();
|
||||
|
||||
if (prologueSize > 0) {
|
||||
fprintf(PerfFilePtr, "%zx %zx %s:%zu: Func%02d-Prologue\n",
|
||||
funcStart, prologueSize, script->filename(), script->lineno(), thisFunctionIndex);
|
||||
WriteEntry(lock, funcStart, prologueSize, "%s:%zu: Func%02" PRIu32 "-Prologue",
|
||||
script->filename(), script->lineno(), thisFunctionIndex);
|
||||
}
|
||||
|
||||
uintptr_t cur = funcStart + prologueSize;
|
||||
|
@ -243,41 +242,31 @@ PerfSpewer::writeProfile(JSScript* script,
|
|||
|
||||
MOZ_ASSERT(cur <= blockStart);
|
||||
if (cur < blockStart) {
|
||||
fprintf(PerfFilePtr, "%" PRIxPTR " %" PRIxPTR " %s:%zu: Func%02d-Block?\n",
|
||||
cur, blockStart - cur,
|
||||
script->filename(), script->lineno(),
|
||||
thisFunctionIndex);
|
||||
WriteEntry(lock, cur, blockStart - cur, "%s:%zu: Func%02" PRIu32 "-Block?",
|
||||
script->filename(), script->lineno(), thisFunctionIndex);
|
||||
}
|
||||
cur = blockEnd;
|
||||
|
||||
size_t size = blockEnd - blockStart;
|
||||
|
||||
if (size > 0) {
|
||||
fprintf(PerfFilePtr, "%" PRIxPTR " %zx %s:%d:%d: Func%02d-Block%d\n",
|
||||
blockStart, size,
|
||||
r.filename, r.lineNumber, r.columnNumber,
|
||||
thisFunctionIndex, r.id);
|
||||
WriteEntry(lock, blockStart, size, "%s:%u:%u: Func%02" PRIu32 "d-Block%" PRIu32,
|
||||
r.filename, r.lineNumber, r.columnNumber, thisFunctionIndex, r.id);
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(cur <= funcEndInlineCode);
|
||||
if (cur < funcEndInlineCode) {
|
||||
fprintf(PerfFilePtr, "%" PRIxPTR " %" PRIxPTR " %s:%zu: Func%02d-Epilogue\n",
|
||||
cur, funcEndInlineCode - cur,
|
||||
script->filename(), script->lineno(),
|
||||
thisFunctionIndex);
|
||||
WriteEntry(lock, cur, funcEndInlineCode - cur, "%s:%zu: Func%02" PRIu32 "-Epilogue",
|
||||
script->filename(), script->lineno(), thisFunctionIndex);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(funcEndInlineCode <= funcEnd);
|
||||
if (funcEndInlineCode < funcEnd) {
|
||||
fprintf(PerfFilePtr, "%" PRIxPTR " %" PRIxPTR " %s:%zu: Func%02d-OOL\n",
|
||||
funcEndInlineCode, funcEnd - funcEndInlineCode,
|
||||
script->filename(), script->lineno(),
|
||||
thisFunctionIndex);
|
||||
WriteEntry(lock, funcEndInlineCode, funcEnd - funcEndInlineCode,
|
||||
"%s:%zu: Func%02" PRIu32 "-OOL",
|
||||
script->filename(), script->lineno(), thisFunctionIndex);
|
||||
}
|
||||
|
||||
unlockPerfMap();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,17 +276,12 @@ js::jit::writePerfSpewerBaselineProfile(JSScript* script, JitCode* code)
|
|||
if (!PerfEnabled())
|
||||
return;
|
||||
|
||||
if (!lockPerfMap())
|
||||
return;
|
||||
|
||||
size_t size = code->instructionsSize();
|
||||
if (size > 0) {
|
||||
fprintf(PerfFilePtr, "%" PRIxPTR " %zx %s:%zu: Baseline\n",
|
||||
reinterpret_cast<uintptr_t>(code->raw()),
|
||||
size, script->filename(), script->lineno());
|
||||
AutoLockPerfMap lock;
|
||||
PerfSpewer::WriteEntry(lock, reinterpret_cast<uintptr_t>(code->raw()), size,
|
||||
"%s:%zu: Baseline", script->filename(), script->lineno());
|
||||
}
|
||||
|
||||
unlockPerfMap();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -306,17 +290,13 @@ js::jit::writePerfSpewerJitCodeProfile(JitCode* code, const char* msg)
|
|||
if (!code || !PerfEnabled())
|
||||
return;
|
||||
|
||||
if (!lockPerfMap())
|
||||
return;
|
||||
|
||||
size_t size = code->instructionsSize();
|
||||
if (size > 0) {
|
||||
fprintf(PerfFilePtr, "%" PRIxPTR " %zx %s (%p 0x%zx)\n",
|
||||
reinterpret_cast<uintptr_t>(code->raw()),
|
||||
size, msg, code->raw(), size);
|
||||
AutoLockPerfMap lock;
|
||||
PerfSpewer::WriteEntry(lock, reinterpret_cast<uintptr_t>(code->raw()), size,
|
||||
"%s (%p 0x%zx)", msg, code->raw(), size);
|
||||
}
|
||||
|
||||
unlockPerfMap();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -327,13 +307,8 @@ js::jit::writePerfSpewerWasmFunctionMap(uintptr_t base, uintptr_t size,
|
|||
if (!PerfFuncEnabled() || size == 0U)
|
||||
return;
|
||||
|
||||
if (!lockPerfMap())
|
||||
return;
|
||||
|
||||
fprintf(PerfFilePtr, "%" PRIxPTR " %" PRIxPTR " %s:%u:%u: Function %s\n",
|
||||
base, size, filename, lineno, colIndex, funcName);
|
||||
|
||||
unlockPerfMap();
|
||||
AutoLockPerfMap lock;
|
||||
PerfSpewer::WriteEntry(lock, base, size, "%s:%u: Function %s", filename, lineno, funcName);
|
||||
}
|
||||
|
||||
#endif // defined (JS_ION_PERF)
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
# include "jit/MacroAssembler.h"
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
struct MOZ_RAII AutoLockPerfMap;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
|
@ -67,10 +71,14 @@ class PerfSpewer
|
|||
|
||||
public:
|
||||
virtual MOZ_MUST_USE bool startBasicBlock(MBasicBlock* blk, MacroAssembler& masm);
|
||||
virtual MOZ_MUST_USE bool endBasicBlock(MacroAssembler& masm);
|
||||
MOZ_MUST_USE bool noteEndInlineCode(MacroAssembler& masm);
|
||||
virtual void endBasicBlock(MacroAssembler& masm);
|
||||
void noteEndInlineCode(MacroAssembler& masm);
|
||||
|
||||
void writeProfile(JSScript* script, JitCode* code, MacroAssembler& masm);
|
||||
|
||||
static void WriteEntry(const AutoLockPerfMap&, uintptr_t address, size_t size,
|
||||
const char* fmt, ...)
|
||||
MOZ_FORMAT_PRINTF(4, 5);
|
||||
};
|
||||
|
||||
void writePerfSpewerBaselineProfile(JSScript* script, JitCode* code);
|
||||
|
@ -81,7 +89,7 @@ class WasmPerfSpewer : public PerfSpewer
|
|||
{
|
||||
public:
|
||||
MOZ_MUST_USE bool startBasicBlock(MBasicBlock* blk, MacroAssembler& masm) { return true; }
|
||||
MOZ_MUST_USE bool endBasicBlock(MacroAssembler& masm) { return true; }
|
||||
void endBasicBlock(MacroAssembler& masm) { }
|
||||
};
|
||||
|
||||
void writePerfSpewerWasmFunctionMap(uintptr_t base, uintptr_t size, const char* filename,
|
||||
|
|
Загрузка…
Ссылка в новой задаче