Bug 1047010 - OdinMonkey: provide better profiling info for signal handlers (r=dougc)
authorLuke Wagner <luke@mozilla.com>
Mon, 04 Aug 2014 12:59:31 -0500
changeset 219371 9dc9557dca8ef466ae6e2d82e9c4eeec15c1fe3e
parent 219370 ca9fa41e977c99f772995a5e0ad9e25327d90c89
child 219372 34df51f6221eb9a04d899fdc108a56a6e48a0c49
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdougc
bugs1047010
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1047010 - OdinMonkey: provide better profiling info for signal handlers (r=dougc)
js/src/asmjs/AsmJSFrameIterator.cpp
--- a/js/src/asmjs/AsmJSFrameIterator.cpp
+++ b/js/src/asmjs/AsmJSFrameIterator.cpp
@@ -436,21 +436,16 @@ AsmJSProfilingFrameIterator::initFromFP(
     // Since we don't have the pc for fp, start unwinding at the caller of fp,
     // whose pc we do have via fp->returnAddress. This means that the innermost
     // frame is skipped but this is fine because:
     //  - for FFI calls, the innermost frame is a thunk, so the first frame that
     //    shows up is the function calling the FFI;
     //  - for Math and other builtin calls, when profiling is activated, we
     //    patch all call sites to instead call through a thunk; and
     //  - for interrupts, we just accept that we'll lose the innermost frame.
-    // However, we do want FFI trampolines to show up in callstacks (so that
-    // they properly accumulate self-time) and for this we use the exitReason.
-
-    exitReason_ = activation.exitReason();
-
     void *pc = ReturnAddressFromFP(fp);
     const AsmJSModule::CodeRange *codeRange = module_->lookupCodeRange(pc);
     JS_ASSERT(codeRange);
     codeRange_ = codeRange;
     stackAddress_ = fp;
 
     switch (codeRange->kind()) {
       case AsmJSModule::CodeRange::Entry:
@@ -466,16 +461,27 @@ AsmJSProfilingFrameIterator::initFromFP(
       case AsmJSModule::CodeRange::IonFFI:
       case AsmJSModule::CodeRange::SlowFFI:
       case AsmJSModule::CodeRange::Interrupt:
       case AsmJSModule::CodeRange::Inline:
       case AsmJSModule::CodeRange::Thunk:
         MOZ_CRASH("Unexpected CodeRange kind");
     }
 
+    // Since, despite the above reasoning for skipping a frame, we do want FFI
+    // trampolines and interrupts to show up in the profile (so they can
+    // accumulate self time and explain performance faults), an "exit reason" is
+    // stored on all the paths leaving asm.js and the iterator logic treats this
+    // reason as its own frame. If we have exited asm.js code without setting an
+    // exit reason, the reason will be None and this means the code was
+    // asynchronously interrupted.
+    exitReason_ = activation.exitReason();
+    if (exitReason_ == AsmJSExit::None)
+        exitReason_ = AsmJSExit::Interrupt;
+
     JS_ASSERT(!done());
 }
 
 typedef JS::ProfilingFrameIterator::RegisterState RegisterState;
 
 AsmJSProfilingFrameIterator::AsmJSProfilingFrameIterator(const AsmJSActivation &activation,
                                                          const RegisterState &state)
   : module_(&activation.module()),
@@ -663,17 +669,17 @@ AsmJSProfilingFrameIterator::label() con
 
     // Use the same string for both time inside and under so that the two
     // entries will be coalesced by the profiler.
     //
     // 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)";
+    const char *interruptDescription = "interrupt due to out-of-bounds or long execution (in asm.js)";
 
     switch (AsmJSExit::ExtractReasonKind(exitReason_)) {
       case AsmJSExit::Reason_None:
         break;
       case AsmJSExit::Reason_IonFFI:
         return ionFFIDescription;
       case AsmJSExit::Reason_SlowFFI:
         return slowFFIDescription;