mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1047010 - OdinMonkey: provide better profiling info for FFI calls (r=dougc)
--HG-- extra : rebase_source : 9ab49294fc688bec90a9d211ad0ad03ab4c6a2e0
This commit is contained in:
parent
f605107f86
commit
103cade597
@ -79,7 +79,8 @@ AsmJSFrameIterator::settle()
|
||||
fp_ = nullptr;
|
||||
JS_ASSERT(done());
|
||||
break;
|
||||
case AsmJSModule::CodeRange::FFI:
|
||||
case AsmJSModule::CodeRange::IonFFI:
|
||||
case AsmJSModule::CodeRange::SlowFFI:
|
||||
case AsmJSModule::CodeRange::Interrupt:
|
||||
case AsmJSModule::CodeRange::Inline:
|
||||
case AsmJSModule::CodeRange::Thunk:
|
||||
@ -462,7 +463,8 @@ AsmJSProfilingFrameIterator::initFromFP(const AsmJSActivation &activation)
|
||||
callerFP_ = CallerFPFromFP(fp);
|
||||
AssertMatchesCallSite(*module_, codeRange, callerPC_, callerFP_, fp);
|
||||
break;
|
||||
case AsmJSModule::CodeRange::FFI:
|
||||
case AsmJSModule::CodeRange::IonFFI:
|
||||
case AsmJSModule::CodeRange::SlowFFI:
|
||||
case AsmJSModule::CodeRange::Interrupt:
|
||||
case AsmJSModule::CodeRange::Inline:
|
||||
case AsmJSModule::CodeRange::Thunk:
|
||||
@ -505,7 +507,8 @@ AsmJSProfilingFrameIterator::AsmJSProfilingFrameIterator(const AsmJSActivation &
|
||||
const AsmJSModule::CodeRange *codeRange = module_->lookupCodeRange(state.pc);
|
||||
switch (codeRange->kind()) {
|
||||
case AsmJSModule::CodeRange::Function:
|
||||
case AsmJSModule::CodeRange::FFI:
|
||||
case AsmJSModule::CodeRange::IonFFI:
|
||||
case AsmJSModule::CodeRange::SlowFFI:
|
||||
case AsmJSModule::CodeRange::Interrupt:
|
||||
case AsmJSModule::CodeRange::Thunk: {
|
||||
// While codeRange describes the *current* frame, the fp/pc state stored in
|
||||
@ -606,7 +609,8 @@ AsmJSProfilingFrameIterator::operator++()
|
||||
callerPC_ = nullptr;
|
||||
break;
|
||||
case AsmJSModule::CodeRange::Function:
|
||||
case AsmJSModule::CodeRange::FFI:
|
||||
case AsmJSModule::CodeRange::IonFFI:
|
||||
case AsmJSModule::CodeRange::SlowFFI:
|
||||
case AsmJSModule::CodeRange::Interrupt:
|
||||
case AsmJSModule::CodeRange::Inline:
|
||||
case AsmJSModule::CodeRange::Thunk:
|
||||
@ -657,19 +661,22 @@ AsmJSProfilingFrameIterator::label() const
|
||||
{
|
||||
JS_ASSERT(!done());
|
||||
|
||||
// Note: this label is regexp-matched by
|
||||
// browser/devtools/profiler/cleopatra/js/parserWorker.js.
|
||||
|
||||
// Use the same string for both time inside and under so that the two
|
||||
// entries will be coalesced by the profiler.
|
||||
const char *ffiDescription = "FFI trampoline (in asm.js)";
|
||||
//
|
||||
// NB: these labels are regexp-matched by
|
||||
// browser/devtools/profiler/cleopatra/js/parserWorker.js.
|
||||
const char *ionFFIDescription = "fast FFI trampoline (in asm.js)";
|
||||
const char *slowFFIDescription = "slow FFI trampoline (in asm.js)";
|
||||
const char *interruptDescription = "slow script interrupt trampoline (in asm.js)";
|
||||
|
||||
switch (AsmJSExit::ExtractReasonKind(exitReason_)) {
|
||||
case AsmJSExit::Reason_None:
|
||||
break;
|
||||
case AsmJSExit::Reason_FFI:
|
||||
return ffiDescription;
|
||||
case AsmJSExit::Reason_IonFFI:
|
||||
return ionFFIDescription;
|
||||
case AsmJSExit::Reason_SlowFFI:
|
||||
return slowFFIDescription;
|
||||
case AsmJSExit::Reason_Interrupt:
|
||||
return interruptDescription;
|
||||
case AsmJSExit::Reason_Builtin:
|
||||
@ -680,7 +687,8 @@ AsmJSProfilingFrameIterator::label() const
|
||||
switch (codeRange->kind()) {
|
||||
case AsmJSModule::CodeRange::Function: return codeRange->functionProfilingLabel(*module_);
|
||||
case AsmJSModule::CodeRange::Entry: return "entry trampoline (in asm.js)";
|
||||
case AsmJSModule::CodeRange::FFI: return ffiDescription;
|
||||
case AsmJSModule::CodeRange::IonFFI: return ionFFIDescription;
|
||||
case AsmJSModule::CodeRange::SlowFFI: return slowFFIDescription;
|
||||
case AsmJSModule::CodeRange::Interrupt: return interruptDescription;
|
||||
case AsmJSModule::CodeRange::Inline: return "inline stub (in asm.js)";
|
||||
case AsmJSModule::CodeRange::Thunk: return BuiltinToName(codeRange->thunkTarget());
|
||||
|
@ -69,7 +69,8 @@ namespace AsmJSExit
|
||||
// handler).
|
||||
enum ReasonKind {
|
||||
Reason_None,
|
||||
Reason_FFI,
|
||||
Reason_IonFFI,
|
||||
Reason_SlowFFI,
|
||||
Reason_Interrupt,
|
||||
Reason_Builtin
|
||||
};
|
||||
@ -105,7 +106,8 @@ namespace AsmJSExit
|
||||
typedef uint32_t Reason;
|
||||
|
||||
static const uint32_t None = Reason_None;
|
||||
static const uint32_t FFI = Reason_FFI;
|
||||
static const uint32_t IonFFI = Reason_IonFFI;
|
||||
static const uint32_t SlowFFI = Reason_SlowFFI;
|
||||
static const uint32_t Interrupt = Reason_Interrupt;
|
||||
static inline Reason Builtin(BuiltinKind builtin) {
|
||||
return uint16_t(Reason_Builtin) | (uint16_t(builtin) << 16);
|
||||
|
@ -1235,6 +1235,7 @@ AsmJSModule::CodeRange::CodeRange(Kind kind, uint32_t begin, uint32_t profilingR
|
||||
|
||||
JS_ASSERT(begin_ < profilingReturn_);
|
||||
JS_ASSERT(profilingReturn_ < end_);
|
||||
JS_ASSERT(u.kind_ == IonFFI || u.kind_ == SlowFFI || u.kind_ == Interrupt);
|
||||
}
|
||||
|
||||
AsmJSModule::CodeRange::CodeRange(AsmJSExit::BuiltinKind builtin, uint32_t begin,
|
||||
|
@ -366,7 +366,7 @@ class AsmJSModule
|
||||
void setDeltas(uint32_t entry, uint32_t profilingJump, uint32_t profilingEpilogue);
|
||||
|
||||
public:
|
||||
enum Kind { Function, Entry, FFI, Interrupt, Thunk, Inline };
|
||||
enum Kind { Function, Entry, IonFFI, SlowFFI, Interrupt, Thunk, Inline };
|
||||
|
||||
CodeRange() {}
|
||||
CodeRange(uint32_t nameIndex, uint32_t lineNumber, const AsmJSFunctionLabels &l);
|
||||
@ -378,7 +378,7 @@ class AsmJSModule
|
||||
Kind kind() const { return Kind(u.kind_); }
|
||||
bool isFunction() const { return kind() == Function; }
|
||||
bool isEntry() const { return kind() == Entry; }
|
||||
bool isFFI() const { return kind() == FFI; }
|
||||
bool isFFI() const { return kind() == IonFFI || kind() == SlowFFI; }
|
||||
bool isInterrupt() const { return kind() == Interrupt; }
|
||||
bool isThunk() const { return kind() == Thunk; }
|
||||
|
||||
@ -827,6 +827,12 @@ class AsmJSModule
|
||||
if (len > pod.minHeapLength_)
|
||||
pod.minHeapLength_ = len;
|
||||
}
|
||||
bool addCodeRange(CodeRange::Kind kind, uint32_t begin, uint32_t end) {
|
||||
return codeRanges_.append(CodeRange(kind, begin, end));
|
||||
}
|
||||
bool addCodeRange(CodeRange::Kind kind, uint32_t begin, uint32_t pret, uint32_t end) {
|
||||
return codeRanges_.append(CodeRange(kind, begin, pret, end));
|
||||
}
|
||||
bool addFunctionCodeRange(PropertyName *name, uint32_t lineNumber,
|
||||
const AsmJSFunctionLabels &labels)
|
||||
{
|
||||
@ -837,24 +843,12 @@ class AsmJSModule
|
||||
uint32_t nameIndex = names_.length();
|
||||
return names_.append(name) && codeRanges_.append(CodeRange(nameIndex, lineNumber, labels));
|
||||
}
|
||||
bool addEntryCodeRange(uint32_t begin, uint32_t end) {
|
||||
return codeRanges_.append(CodeRange(CodeRange::Entry, begin, end));
|
||||
}
|
||||
bool addFFICodeRange(uint32_t begin, uint32_t pret, uint32_t end) {
|
||||
return codeRanges_.append(CodeRange(CodeRange::FFI, begin, pret, end));
|
||||
}
|
||||
bool addInterruptCodeRange(uint32_t begin, uint32_t pret, uint32_t end) {
|
||||
return codeRanges_.append(CodeRange(CodeRange::Interrupt, begin, pret, end));
|
||||
}
|
||||
bool addBuiltinThunkCodeRange(AsmJSExit::BuiltinKind builtin, uint32_t begin,
|
||||
uint32_t profilingReturn, uint32_t end)
|
||||
{
|
||||
return builtinThunkOffsets_.append(begin) &&
|
||||
codeRanges_.append(CodeRange(builtin, begin, profilingReturn, end));
|
||||
}
|
||||
bool addInlineCodeRange(uint32_t begin, uint32_t end) {
|
||||
return codeRanges_.append(CodeRange(CodeRange::Inline, begin, end));
|
||||
}
|
||||
bool addExit(unsigned ffiIndex, unsigned *exitIndex) {
|
||||
JS_ASSERT(isFinishedWithModulePrologue() && !isFinishedWithFunctionBodies());
|
||||
if (SIZE_MAX - pod.funcPtrTableAndExitBytes_ < sizeof(ExitDatum))
|
||||
|
@ -1491,32 +1491,35 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
JS_ASSERT(finishedFunctionBodies_);
|
||||
module_->exportedFunction(exportIndex).initCodeOffset(begin->offset());
|
||||
uint32_t end = masm_.currentOffset();
|
||||
return module_->addEntryCodeRange(begin->offset(), end);
|
||||
}
|
||||
bool finishGeneratingFFI(Label *begin, Label *profilingReturn) {
|
||||
JS_ASSERT(finishedFunctionBodies_);
|
||||
uint32_t end = masm_.currentOffset();
|
||||
return module_->addFFICodeRange(begin->offset(), profilingReturn->offset(), end);
|
||||
return module_->addCodeRange(AsmJSModule::CodeRange::Entry, begin->offset(), end);
|
||||
}
|
||||
bool finishGeneratingInterpExit(unsigned exitIndex, Label *begin, Label *profilingReturn) {
|
||||
JS_ASSERT(finishedFunctionBodies_);
|
||||
module_->exit(exitIndex).initInterpOffset(begin->offset());
|
||||
return finishGeneratingFFI(begin, profilingReturn);
|
||||
uint32_t beg = begin->offset();
|
||||
module_->exit(exitIndex).initInterpOffset(beg);
|
||||
uint32_t pret = profilingReturn->offset();
|
||||
uint32_t end = masm_.currentOffset();
|
||||
return module_->addCodeRange(AsmJSModule::CodeRange::SlowFFI, beg, pret, end);
|
||||
}
|
||||
bool finishGeneratingIonExit(unsigned exitIndex, Label *begin, Label *profilingReturn) {
|
||||
JS_ASSERT(finishedFunctionBodies_);
|
||||
module_->exit(exitIndex).initIonOffset(begin->offset());
|
||||
return finishGeneratingFFI(begin, profilingReturn);
|
||||
uint32_t beg = begin->offset();
|
||||
module_->exit(exitIndex).initIonOffset(beg);
|
||||
uint32_t pret = profilingReturn->offset();
|
||||
uint32_t end = masm_.currentOffset();
|
||||
return module_->addCodeRange(AsmJSModule::CodeRange::IonFFI, beg, pret, end);
|
||||
}
|
||||
bool finishGeneratingInterrupt(Label *begin, Label *profilingReturn) {
|
||||
JS_ASSERT(finishedFunctionBodies_);
|
||||
uint32_t beg = begin->offset();
|
||||
uint32_t pret = profilingReturn->offset();
|
||||
uint32_t end = masm_.currentOffset();
|
||||
return module_->addInterruptCodeRange(begin->offset(), profilingReturn->offset(), end);
|
||||
return module_->addCodeRange(AsmJSModule::CodeRange::Interrupt, beg, pret, end);
|
||||
}
|
||||
bool finishGeneratingInlineStub(Label *begin) {
|
||||
JS_ASSERT(finishedFunctionBodies_);
|
||||
uint32_t end = masm_.currentOffset();
|
||||
return module_->addInlineCodeRange(begin->offset(), end);
|
||||
return module_->addCodeRange(AsmJSModule::CodeRange::Inline, begin->offset(), end);
|
||||
}
|
||||
bool finishGeneratingBuiltinThunk(AsmJSExit::BuiltinKind builtin, Label *begin, Label *pret) {
|
||||
JS_ASSERT(finishedFunctionBodies_);
|
||||
@ -6141,7 +6144,7 @@ GenerateFFIInterpExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &e
|
||||
unsigned framePushed = StackDecrementForCall(masm, offsetToArgv + argvBytes);
|
||||
|
||||
Label begin;
|
||||
GenerateAsmJSExitPrologue(masm, framePushed, AsmJSExit::FFI, &begin);
|
||||
GenerateAsmJSExitPrologue(masm, framePushed, AsmJSExit::SlowFFI, &begin);
|
||||
|
||||
// Fill the argument array.
|
||||
unsigned offsetToCallerStackArgs = sizeof(AsmJSFrame) + masm.framePushed();
|
||||
@ -6200,7 +6203,7 @@ GenerateFFIInterpExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &e
|
||||
}
|
||||
|
||||
Label profilingReturn;
|
||||
GenerateAsmJSExitEpilogue(masm, framePushed, AsmJSExit::FFI, &profilingReturn);
|
||||
GenerateAsmJSExitEpilogue(masm, framePushed, AsmJSExit::SlowFFI, &profilingReturn);
|
||||
return m.finishGeneratingInterpExit(exitIndex, &begin, &profilingReturn) && !masm.oom();
|
||||
}
|
||||
|
||||
@ -6255,7 +6258,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
unsigned framePushed = Max(ionFrameSize, coerceFrameSize);
|
||||
|
||||
Label begin;
|
||||
GenerateAsmJSExitPrologue(masm, framePushed, AsmJSExit::FFI, &begin);
|
||||
GenerateAsmJSExitPrologue(masm, framePushed, AsmJSExit::IonFFI, &begin);
|
||||
|
||||
// 1. Descriptor
|
||||
size_t argOffset = offsetToIonArgs;
|
||||
@ -6415,7 +6418,7 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
masm.bind(&done);
|
||||
|
||||
Label profilingReturn;
|
||||
GenerateAsmJSExitEpilogue(masm, framePushed, AsmJSExit::FFI, &profilingReturn);
|
||||
GenerateAsmJSExitEpilogue(masm, framePushed, AsmJSExit::IonFFI, &profilingReturn);
|
||||
|
||||
if (oolConvert.used()) {
|
||||
masm.bind(&oolConvert);
|
||||
|
@ -10,7 +10,7 @@ function assertEqualStacks(got, expect)
|
||||
got = String(got).replace(/ \([^\)]*\)/g, "");
|
||||
|
||||
// Shorten FFI/entry trampolines
|
||||
got = got.replace(/FFI trampoline/g, "<").replace(/entry trampoline/g, ">");
|
||||
got = got.replace(/(fast|slow) FFI trampoline/g, "<").replace(/entry trampoline/g, ">");
|
||||
|
||||
assertEq(got, expect);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user