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 197745 9dc9557dca8ef466ae6e2d82e9c4eeec15c1fe3e
parent 197744 ca9fa41e977c99f772995a5e0ad9e25327d90c89
child 197746 34df51f6221eb9a04d899fdc108a56a6e48a0c49
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersdougc
bugs1047010
milestone34.0a1
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;