Commit 81f27884 authored by Jan de Mooij's avatar Jan de Mooij
Browse files

Bug 1782003 - Set lastProfilingFrame correctly in GeckoProfilerRuntime::enable. r=iain

If the top activation is a C++ interpreter activation, the code would incorrectly use
`nullptr` as `lastProfilingFrame` for the first `JitActivation`.

Differential Revision: https://phabricator.services.mozilla.com/D153061
parent 9e84990d
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
function getStack() {
    enableGeckoProfiling();
    let stack = readGeckoProfilingStack();
    // The number of frames depends on JIT flags, but there must be at least
    // one frame for the caller and at most 3 total (the global script, 'testFun'
    // and 'getStack').
    assertEq(stack.length > 0, true);
    assertEq(stack.length <= 3, true);
    assertEq(JSON.stringify(stack).includes('"testFun ('), true);
    disableGeckoProfiling();
}
function testFun() {
    // Loop until this is a JIT frame.
    while (true) {
        let isJitFrame = inJit();
        if (typeof isJitFrame === "string") {
            return; // JIT disabled.
        }
        if (isJitFrame) {
            break;
        }
    }

    // Now call getStack to check this frame is on the profiler's JIT stack.
    getStack();
    getStack();
}
testFun();
+4 −14
Original line number Diff line number Diff line
@@ -51,20 +51,14 @@ void GeckoProfilerRuntime::setEventMarker(void (*fn)(const char*,
}

// Get a pointer to the top-most profiling frame, given the exit frame pointer.
static jit::JitFrameLayout* GetTopProfilingJitFrame(Activation* act) {
  if (!act || !act->isJit()) {
    return nullptr;
  }

  jit::JitActivation* jitActivation = act->asJit();

static jit::JitFrameLayout* GetTopProfilingJitFrame(jit::JitActivation* act) {
  // If there is no exit frame set, just return.
  if (!jitActivation->hasExitFP()) {
  if (!act->hasExitFP()) {
    return nullptr;
  }

  // Skip wasm frames that might be in the way.
  OnlyJSJitFrameIter iter(jitActivation);
  OnlyJSJitFrameIter iter(act);
  if (iter.done()) {
    return nullptr;
  }
@@ -118,16 +112,12 @@ void GeckoProfilerRuntime::enable(bool enabled) {
    // Walk through all activations, and set their lastProfilingFrame
    // appropriately.
    if (enabled) {
      Activation* act = cx->activation();
      auto* lastProfilingFrame = GetTopProfilingJitFrame(act);

      jit::JitActivation* jitActivation = cx->jitActivation;
      while (jitActivation) {
        auto* lastProfilingFrame = GetTopProfilingJitFrame(jitActivation);
        jitActivation->setLastProfilingFrame(lastProfilingFrame);
        jitActivation->setLastProfilingCallSite(nullptr);

        jitActivation = jitActivation->prevJitActivation();
        lastProfilingFrame = GetTopProfilingJitFrame(jitActivation);
      }
    } else {
      jit::JitActivation* jitActivation = cx->jitActivation;