michael@0: // Check that the EnterJIT frame, added by the JIT trampoline and michael@0: // usable by a native unwinder to resume unwinding after encountering michael@0: // JIT code, is pushed as expected. michael@0: function run_test() { michael@0: let p = Cc["@mozilla.org/tools/profiler;1"]; michael@0: // Just skip the test if the profiler component isn't present. michael@0: if (!p) michael@0: return; michael@0: p = p.getService(Ci.nsIProfiler); michael@0: if (!p) michael@0: return; michael@0: michael@0: // This test assumes that it's starting on an empty SPS stack. michael@0: // (Note that the other profiler tests also assume the profiler michael@0: // isn't already started.) michael@0: do_check_true(!p.IsActive()); michael@0: michael@0: const ms = 5; michael@0: p.StartProfiler(100, ms, ["js"], 1); michael@0: let profile = (function arbitrary_name(){ michael@0: // A frame for |arbitrary_name| has been pushed. michael@0: let then = Date.now(); michael@0: do { michael@0: let n = 10000; michael@0: while (--n); // OSR happens here michael@0: // Spin until we're sure we have a sample. michael@0: } while (Date.now() - then < ms * 2.5); michael@0: return p.getProfileData().threads[0].samples; michael@0: })(); michael@0: do_check_neq(profile.length, 0); michael@0: let stack = profile[profile.length - 1].frames.map(f => f.location); michael@0: stack = stack.slice(stack.indexOf("js::RunScript") + 1); michael@0: michael@0: do_print(stack); michael@0: // This test needs to not break on platforms and configurations michael@0: // where IonMonkey isn't available / enabled. michael@0: if (stack.length < 2 || stack[1] != "EnterJIT") { michael@0: do_print("No JIT?"); michael@0: // Try to check what we can.... michael@0: do_check_eq(Math.min(stack.length, 1), 1); michael@0: let thisInterp = stack[0]; michael@0: do_check_eq(thisInterp.split(" ")[0], "arbitrary_name"); michael@0: if (stack.length >= 2) { michael@0: let nextFrame = stack[1]; michael@0: do_check_neq(nextFrame.split(" ")[0], "arbitrary_name"); michael@0: } michael@0: } else { michael@0: do_check_eq(Math.min(stack.length, 3), 3); michael@0: let thisInterp = stack[0]; michael@0: let enterJit = stack[1]; michael@0: let thisBC = stack[2]; michael@0: do_check_eq(thisInterp.split(" ")[0], "arbitrary_name"); michael@0: do_check_eq(enterJit, "EnterJIT"); michael@0: do_check_eq(thisBC.split(" ")[0], "arbitrary_name"); michael@0: } michael@0: michael@0: p.StopProfiler(); michael@0: }