Bug 884473: Integrate perf with Odinmonkey: functions profiling; r=sstangl

This commit is contained in:
Benjamin Bouvier 2013-07-01 16:35:22 -07:00
Родитель 9c55104e5e
Коммит fedb281b89
5 изменённых файлов: 109 добавлений и 4 удалений

Просмотреть файл

@ -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