зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1486731: wasm profiling: Don't look at FP's tagged bit in non-function call situations; r=luke
--HG-- extra : rebase_source : 7a7665b41ad3332aee4c4b7c9d9c8b8c1e677654 extra : amend_source : 06705b2fdab5e489f8c472ea41869e190042553f
This commit is contained in:
Родитель
b42fd5e8a5
Коммит
f6e6cc5fcc
|
@ -0,0 +1,28 @@
|
|||
var lfModule = new WebAssembly.Module(wasmTextToBinary(`
|
||||
(module
|
||||
(import "global" "func" (result i32))
|
||||
(func (export "func_0") (result i32)
|
||||
call 0 ;; calls the import, which is func #0
|
||||
)
|
||||
)
|
||||
`));
|
||||
|
||||
enableGeckoProfiling();
|
||||
enableSingleStepProfiling();
|
||||
setJitCompilerOption("ion.warmup.trigger", 20);
|
||||
|
||||
Object.prototype[3] = 3;
|
||||
|
||||
var imports = {
|
||||
global: {
|
||||
func: function() {}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < 100; ++i) {
|
||||
for (dmod in imports)
|
||||
for (dname in imports[dmod])
|
||||
if (imports[dmod][dname] == undefined) {}
|
||||
instance = new WebAssembly.Instance(lfModule, imports);
|
||||
print(i, instance.exports.func_0());
|
||||
}
|
|
@ -910,6 +910,7 @@ js::wasm::StartUnwinding(const RegisterState& registers, UnwindState* unwindStat
|
|||
// - in the process of tagging/untagging when calling into the JITs;
|
||||
// make sure it's untagged.
|
||||
// - tagged by an direct JIT call.
|
||||
// - unreliable if it's not been set yet, in prologues.
|
||||
DebugOnly<bool> fpWasTagged = uintptr_t(registers.fp) & ExitOrJitEntryFPTag;
|
||||
Frame* const fp = (Frame*) (intptr_t(registers.fp) & ~ExitOrJitEntryFPTag);
|
||||
|
||||
|
@ -1109,7 +1110,8 @@ js::wasm::StartUnwinding(const RegisterState& registers, UnwindState* unwindStat
|
|||
fixedFP = offsetFromEntry < SetJitEntryFP ? (Frame*) sp : fp;
|
||||
fixedPC = nullptr;
|
||||
|
||||
// On the error return path, FP might be set to FailFP. Ignore these transient frames.
|
||||
// On the error return path, FP might be set to FailFP. Ignore these
|
||||
// transient frames.
|
||||
if (intptr_t(fixedFP) == (FailFP & ~ExitOrJitEntryFPTag))
|
||||
return false;
|
||||
break;
|
||||
|
@ -1156,18 +1158,26 @@ ProfilingFrameIterator::ProfilingFrameIterator(const JitActivation& activation,
|
|||
if (unwoundCaller) {
|
||||
callerFP_ = unwindState.fp;
|
||||
callerPC_ = unwindState.pc;
|
||||
// If the original FP value is tagged, then we're being called through
|
||||
// a direct JIT call. We can't observe transient tagged values of FP
|
||||
// (during wasm::SetExitFP) here because StartUnwinding would not have
|
||||
// unwound for us in this case.
|
||||
if ((uintptr_t(state.fp) & ExitOrJitEntryFPTag))
|
||||
// In the case of a function call, if the original FP value is tagged,
|
||||
// then we're being called through a direct JIT call (the interpreter
|
||||
// and the jit entry don't set FP's low bit). We can't observe
|
||||
// transient tagged values of FP (during wasm::SetExitFP) here because
|
||||
// StartUnwinding would not have unwound then.
|
||||
if (unwindState.codeRange &&
|
||||
unwindState.codeRange->isFunction() &&
|
||||
(uintptr_t(state.fp) & ExitOrJitEntryFPTag))
|
||||
{
|
||||
unwoundIonCallerFP_ = (uint8_t*) callerFP_;
|
||||
}
|
||||
} else {
|
||||
callerFP_ = unwindState.fp->callerFP;
|
||||
callerPC_ = unwindState.fp->returnAddress;
|
||||
// See comment above.
|
||||
if ((uintptr_t(callerFP_) & ExitOrJitEntryFPTag))
|
||||
// See comment above. The only way to get a tagged FP here means that
|
||||
// the caller is a fast JIT caller which called into a wasm function.
|
||||
if ((uintptr_t(callerFP_) & ExitOrJitEntryFPTag)) {
|
||||
MOZ_ASSERT(unwindState.codeRange->isFunction());
|
||||
unwoundIonCallerFP_ = (uint8_t*)(uintptr_t(callerFP_) & ~ExitOrJitEntryFPTag);
|
||||
}
|
||||
}
|
||||
|
||||
if (unwindState.codeRange->isJitEntry()) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче