Bug 1352507 - Reset the profiling stack when the shell context owning it dies r=njn

This commit is contained in:
Jon Coppeard 2017-06-01 15:18:47 +01:00
Родитель 6d2f587da5
Коммит c0e306ba33
4 изменённых файлов: 62 добавлений и 8 удалений

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

@ -0,0 +1,3 @@
if (helperThreadCount() === 0)
quit();
evalInWorker("enableGeckoProfiling()");

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

@ -0,0 +1,3 @@
if (helperThreadCount() === 0)
quit();
evalInCooperativeThread("enableGeckoProfiling()");

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

@ -3430,6 +3430,11 @@ WorkerMain(void* arg)
KillWatchdog(cx);
JS_SetGrayGCRootsTracer(cx, nullptr, nullptr);
if (sc->geckoProfilingStack) {
MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
SetContextProfilingStack(cx, nullptr);
}
}
// Workers can spawn other workers, so we need a lock to access workerThreads.
@ -5205,6 +5210,29 @@ IsLatin1(JSContext* cx, unsigned argc, Value* vp)
return true;
}
static bool
EnsureGeckoProfilingStackInstalled(JSContext* cx, ShellContext* sc)
{
if (cx->runtime()->geckoProfiler().installed()) {
if (!sc->geckoProfilingStack) {
JS_ReportErrorASCII(cx, "Profiler already installed by another context");
return false;
}
return true;
}
MOZ_ASSERT(!sc->geckoProfilingStack);
sc->geckoProfilingStack = MakeUnique<PseudoStack>();
if (!sc->geckoProfilingStack) {
JS_ReportOutOfMemory(cx);
return false;
}
SetContextProfilingStack(cx, sc->geckoProfilingStack.get());
return true;
}
static bool
EnableGeckoProfiling(JSContext* cx, unsigned argc, Value* vp)
{
@ -5212,14 +5240,19 @@ EnableGeckoProfiling(JSContext* cx, unsigned argc, Value* vp)
ShellContext* sc = GetShellContext(cx);
// Disable before re-enabling; see the assertion in |GeckoProfiler::setProfilingStack|.
if (!EnsureGeckoProfilingStackInstalled(cx, sc))
return false;
// Disable before re-enabling; see the assertion in
// |GeckoProfiler::setProfilingStack|.
if (cx->runtime()->geckoProfiler().installed())
MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
SetContextProfilingStack(cx, &sc->geckoProfilingStack);
cx->runtime()->geckoProfiler().enableSlowAssertions(false);
if (!cx->runtime()->geckoProfiler().enable(true))
if (!cx->runtime()->geckoProfiler().enable(true)) {
JS_ReportErrorASCII(cx, "Cannot ensure single threaded execution in profiler");
return false;
}
args.rval().setUndefined();
return true;
@ -5233,6 +5266,9 @@ EnableGeckoProfilingWithSlowAssertions(JSContext* cx, unsigned argc, Value* vp)
ShellContext* sc = GetShellContext(cx);
if (!EnsureGeckoProfilingStackInstalled(cx, sc))
return false;
if (cx->runtime()->geckoProfiler().enabled()) {
// If profiling already enabled with slow assertions disabled,
// this is a no-op.
@ -5248,10 +5284,11 @@ EnableGeckoProfilingWithSlowAssertions(JSContext* cx, unsigned argc, Value* vp)
if (cx->runtime()->geckoProfiler().installed())
MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
SetContextProfilingStack(cx, &sc->geckoProfilingStack);
cx->runtime()->geckoProfiler().enableSlowAssertions(true);
if (!cx->runtime()->geckoProfiler().enable(true))
if (!cx->runtime()->geckoProfiler().enable(true)) {
JS_ReportErrorASCII(cx, "Cannot ensure single threaded execution in profiler");
return false;
}
return true;
}
@ -5260,9 +5297,19 @@ static bool
DisableGeckoProfiling(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (cx->runtime()->geckoProfiler().installed())
MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
args.rval().setUndefined();
ShellContext* sc = GetShellContext(cx);
if (!cx->runtime()->geckoProfiler().installed())
return true;
if (!sc->geckoProfilingStack) {
JS_ReportErrorASCII(cx, "Profiler was not installed by this context");
return false;
}
MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
return true;
}

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

@ -171,6 +171,7 @@ using StackChars = Vector<char16_t, 0, SystemAllocPolicy>;
struct ShellContext
{
explicit ShellContext(JSContext* cx);
bool isWorker;
double timeoutInterval;
double startTime;
@ -203,7 +204,7 @@ struct ShellContext
js::shell::RCFile** errFilePtr;
js::shell::RCFile** outFilePtr;
PseudoStack geckoProfilingStack;
UniquePtr<PseudoStack> geckoProfilingStack;
OffThreadState offThreadState;