зеркало из https://github.com/mozilla/gecko-dev.git
Bug 884473: Integrate perf with Odinmonkey: functions profiling; r=sstangl
This commit is contained in:
Родитель
9c55104e5e
Коммит
fedb281b89
|
@ -1363,6 +1363,18 @@ class MOZ_STACK_CLASS ModuleCompiler
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef JS_ION_PERF
|
||||
bool trackPerfProfiledFunction(const Func &func, unsigned endCodeOffset) {
|
||||
JSAtom *name = FunctionName(func.fn());
|
||||
|
||||
unsigned lineno = 0U, columnIndex = 0U;
|
||||
tokenStream_.srcCoords.lineNumAndColumnIndex(func.fn()->pn_pos.begin, &lineno, &columnIndex);
|
||||
|
||||
unsigned startCodeOffset = func.codeLabel()->offset();
|
||||
return module_->trackPerfProfiledFunction(name, startCodeOffset, endCodeOffset, lineno, columnIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
void setFirstPassComplete() {
|
||||
JS_ASSERT(currentPass_ == 1);
|
||||
currentPass_ = 2;
|
||||
|
@ -4701,6 +4713,13 @@ GenerateAsmJSCode(ModuleCompiler &m, ModuleCompiler::Func &func,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef JS_ION_PERF
|
||||
if (PerfFuncEnabled()) {
|
||||
if (!m.trackPerfProfiledFunction(func, m.masm().size()))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// A single MacroAssembler is reused for all function compilations so
|
||||
// that there is a single linear code segment for each module. To avoid
|
||||
// spiking memory, a LifoAllocScope in the caller frees all MIR/LIR
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
#include "ion/AsmJSModule.h"
|
||||
#include "frontend/BytecodeCompiler.h"
|
||||
|
||||
#ifdef JS_ION_PERF
|
||||
# include "ion/PerfSpewer.h"
|
||||
#endif
|
||||
|
||||
#include "ion/Ion.h"
|
||||
|
||||
#include "jsfuninlines.h"
|
||||
|
@ -465,6 +469,44 @@ SendFunctionsToVTune(JSContext *cx, AsmJSModule &module)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef JS_ION_PERF
|
||||
static bool
|
||||
SendFunctionsToPerf(JSContext *cx, AsmJSModule &module)
|
||||
{
|
||||
if (!PerfFuncEnabled())
|
||||
return true;
|
||||
|
||||
PerfSpewer perfSpewer;
|
||||
|
||||
unsigned long base = (unsigned long) module.functionCode();
|
||||
|
||||
const AsmJSModule::PostLinkFailureInfo &info = module.postLinkFailureInfo();
|
||||
const char *filename = const_cast<char *>(info.scriptSource_->filename());
|
||||
|
||||
for (unsigned i = 0; i < module.numPerfFunctions(); i++) {
|
||||
const AsmJSModule::ProfiledFunction &func = module.perfProfiledFunction(i);
|
||||
|
||||
unsigned long start = base + (unsigned long) func.startCodeOffset;
|
||||
unsigned long end = base + (unsigned long) func.endCodeOffset;
|
||||
JS_ASSERT(end >= start);
|
||||
|
||||
unsigned long size = (end - start);
|
||||
|
||||
JSAutoByteString bytes;
|
||||
const char *method_name = js_AtomToPrintableString(cx, func.name, &bytes);
|
||||
if (!method_name)
|
||||
return false;
|
||||
|
||||
unsigned lineno = func.lineno;
|
||||
unsigned columnIndex = func.columnIndex;
|
||||
|
||||
perfSpewer.writeAsmJSProfile(start, size, filename, lineno, columnIndex, method_name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
JSBool
|
||||
js::LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||
{
|
||||
|
@ -485,6 +527,11 @@ js::LinkAsmJS(JSContext *cx, unsigned argc, JS::Value *vp)
|
|||
return false;
|
||||
#endif
|
||||
|
||||
#if defined(JS_ION_PERF)
|
||||
if (!SendFunctionsToPerf(cx, module))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
if (module.numExportedFunctions() == 1) {
|
||||
const AsmJSModule::ExportedFunction &func = module.exportedFunction(0);
|
||||
if (!func.maybeFieldName()) {
|
||||
|
|
|
@ -280,16 +280,23 @@ class AsmJSModule
|
|||
}
|
||||
};
|
||||
|
||||
#if defined(MOZ_VTUNE)
|
||||
#if defined(MOZ_VTUNE) or defined(JS_ION_PERF)
|
||||
// Function information to add to the VTune JIT profiler following linking.
|
||||
struct ProfiledFunction
|
||||
{
|
||||
JSAtom *name;
|
||||
unsigned startCodeOffset;
|
||||
unsigned endCodeOffset;
|
||||
unsigned lineno;
|
||||
unsigned columnIndex;
|
||||
|
||||
ProfiledFunction(JSAtom *name, unsigned start, unsigned end)
|
||||
: name(name), startCodeOffset(start), endCodeOffset(end)
|
||||
ProfiledFunction(JSAtom *name, unsigned start, unsigned end,
|
||||
unsigned line = 0U, unsigned column = 0U)
|
||||
: name(name),
|
||||
startCodeOffset(start),
|
||||
endCodeOffset(end),
|
||||
lineno(line),
|
||||
columnIndex(column)
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
@ -336,7 +343,7 @@ class AsmJSModule
|
|||
typedef Vector<ion::AsmJSBoundsCheck, 0, SystemAllocPolicy> BoundsCheckVector;
|
||||
#endif
|
||||
typedef Vector<ion::IonScriptCounts *, 0, SystemAllocPolicy> FunctionCountsVector;
|
||||
#if defined(MOZ_VTUNE)
|
||||
#if defined(MOZ_VTUNE) or defined(JS_ION_PERF)
|
||||
typedef Vector<ProfiledFunction, 0, SystemAllocPolicy> ProfiledFunctionVector;
|
||||
#endif
|
||||
|
||||
|
@ -350,6 +357,9 @@ class AsmJSModule
|
|||
#if defined(MOZ_VTUNE)
|
||||
ProfiledFunctionVector profiledFunctions_;
|
||||
#endif
|
||||
#if defined(JS_ION_PERF)
|
||||
ProfiledFunctionVector perfProfiledFunctions_;
|
||||
#endif
|
||||
|
||||
uint32_t numGlobalVars_;
|
||||
uint32_t numFFIs_;
|
||||
|
@ -497,6 +507,20 @@ class AsmJSModule
|
|||
const ProfiledFunction &profiledFunction(unsigned i) const {
|
||||
return profiledFunctions_[i];
|
||||
}
|
||||
#endif
|
||||
#ifdef JS_ION_PERF
|
||||
bool trackPerfProfiledFunction(JSAtom *name, unsigned startCodeOffset, unsigned endCodeOffset,
|
||||
unsigned line, unsigned column)
|
||||
{
|
||||
ProfiledFunction func(name, startCodeOffset, endCodeOffset, line, column);
|
||||
return perfProfiledFunctions_.append(func);
|
||||
}
|
||||
unsigned numPerfFunctions() const {
|
||||
return perfProfiledFunctions_.length();
|
||||
}
|
||||
const ProfiledFunction &perfProfiledFunction(unsigned i) const {
|
||||
return perfProfiledFunctions_[i];
|
||||
}
|
||||
#endif
|
||||
bool hasArrayView() const {
|
||||
return hasArrayView_;
|
||||
|
|
|
@ -127,6 +127,19 @@ PerfSpewer::endBasicBlock(MacroAssembler &masm)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PerfSpewer::writeAsmJSProfile(unsigned long base, unsigned long size, const char *filename,
|
||||
unsigned lineno, unsigned colIndex, const char *funcName)
|
||||
{
|
||||
if (!fp_ || !PerfFuncEnabled() || size == 0U)
|
||||
return;
|
||||
|
||||
fprintf(fp_,
|
||||
"%lx %lx %s:%d:%d: Function %s\n",
|
||||
base, size,
|
||||
filename, lineno, colIndex, funcName);
|
||||
}
|
||||
|
||||
void
|
||||
PerfSpewer::writeProfile(JSScript *script,
|
||||
IonCode *code,
|
||||
|
|
|
@ -68,6 +68,8 @@ class PerfSpewer
|
|||
void writeProfile(JSScript *script,
|
||||
IonCode *code,
|
||||
MacroAssembler &masm);
|
||||
void writeAsmJSProfile(unsigned long base, unsigned long size, const char *filename,
|
||||
unsigned lineno, unsigned colIndex, const char *funcName);
|
||||
};
|
||||
|
||||
} // namespace ion
|
||||
|
|
Загрузка…
Ссылка в новой задаче