Bug 1351963 (part 2, attempt 2) - Move StreamSamplesAndMarkers() out of ThreadInfo. r=mstange.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 04 Apr 2017 09:41:11 +1000
changeset 555412 d9b2934ac8606387e71e1f248613d4e32000cea7
parent 555411 a7e88ab4d4bd7b48e80383a1386a838b7915fee9
child 555413 6d446e9be0749c744f80370d63287e6316d15766
push id52236
push usercykesiopka.bmo@gmail.com
push dateTue, 04 Apr 2017 09:12:57 +0000
reviewersmstange
bugs1351963
milestone55.0a1
Bug 1351963 (part 2, attempt 2) - Move StreamSamplesAndMarkers() out of ThreadInfo. r=mstange.
tools/profiler/core/ProfileBufferEntry.cpp
tools/profiler/core/ProfilerBacktrace.cpp
tools/profiler/core/ProfilerBacktrace.h
tools/profiler/core/ThreadInfo.cpp
tools/profiler/core/ThreadInfo.h
--- a/tools/profiler/core/ProfileBufferEntry.cpp
+++ b/tools/profiler/core/ProfileBufferEntry.cpp
@@ -688,16 +688,17 @@ void ProfileBuffer::StreamSamplesToJSON(
               }
               stack.AppendFrame(frameKey);
             } else if (frame.isJitReturnAddr()) {
               // A JIT frame may expand to multiple frames due to inlining.
               void* pc = frame.mTagPtr;
               unsigned depth = aUniqueStacks.LookupJITFrameDepth(pc);
               if (depth == 0) {
                 StreamJSFramesOp framesOp(pc, stack);
+                MOZ_RELEASE_ASSERT(aContext);
                 JS::ForEachProfiledFrame(aContext, pc, framesOp);
                 aUniqueStacks.AddJITFrameDepth(pc, framesOp.depth());
               } else {
                 for (unsigned i = 0; i < depth; i++) {
                   UniqueStacks::OnStackFrameKey inlineFrameKey(pc, i);
                   stack.AppendFrame(inlineFrameKey);
                 }
               }
--- a/tools/profiler/core/ProfilerBacktrace.cpp
+++ b/tools/profiler/core/ProfilerBacktrace.cpp
@@ -25,11 +25,19 @@ ProfilerBacktrace::~ProfilerBacktrace()
   delete mThreadInfo;
 }
 
 void
 ProfilerBacktrace::StreamJSON(SpliceableJSONWriter& aWriter,
                               const TimeStamp& aStartTime,
                               UniqueStacks& aUniqueStacks)
 {
-  mThreadInfo->StreamSamplesAndMarkers(mBuffer, aWriter, aStartTime,
-                                       /* aSinceTime */ 0, aUniqueStacks);
+  // This call to StreamSamplesAndMarkers() can safely pass in a non-null
+  // JSContext. That's because StreamSamplesAndMarkers() only accesses the
+  // JSContext when streaming JitReturnAddress entries, and such entries
+  // never appear in synchronous samples.
+  StreamSamplesAndMarkers(mThreadInfo->Name(), mThreadInfo->ThreadId(),
+                          mBuffer, aWriter, aStartTime,
+                          /* aSinceTime */ 0, /* aContext */ nullptr,
+                          /* aSavedStreamedSamples */ nullptr,
+                          /* aSavedStreamedMarkers */ nullptr,
+                          aUniqueStacks);
 }
--- a/tools/profiler/core/ProfilerBacktrace.h
+++ b/tools/profiler/core/ProfilerBacktrace.h
@@ -7,16 +7,17 @@
 #ifndef __PROFILER_BACKTRACE_H
 #define __PROFILER_BACKTRACE_H
 
 class ProfileBuffer;
 class SpliceableJSONWriter;
 class ThreadInfo;
 class UniqueStacks;
 
+// ProfilerBacktrace encapsulates a synchronous sample.
 class ProfilerBacktrace
 {
 public:
   explicit ProfilerBacktrace(ProfileBuffer* aBuffer, ThreadInfo* aThreadInfo);
   ~ProfilerBacktrace();
 
   // ProfilerBacktraces' stacks are deduplicated in the context of the
   // profile that contains the backtrace as a marker payload.
--- a/tools/profiler/core/ThreadInfo.cpp
+++ b/tools/profiler/core/ThreadInfo.cpp
@@ -67,18 +67,22 @@ ThreadInfo::StreamJSON(ProfileBuffer* aB
 {
   // mUniqueStacks may already be emplaced from FlushSamplesAndMarkers.
   if (!mUniqueStacks.isSome()) {
     mUniqueStacks.emplace(mPseudoStack->mContext);
   }
 
   aWriter.Start(SpliceableJSONWriter::SingleLineStyle);
   {
-    StreamSamplesAndMarkers(aBuffer, aWriter, aStartTime, aSinceTime,
-                            *mUniqueStacks);
+    StreamSamplesAndMarkers(Name(), ThreadId(), aBuffer, aWriter, aStartTime,
+                            aSinceTime, mPseudoStack->mContext,
+                            mSavedStreamedSamples.get(),
+                            mSavedStreamedMarkers.get(), *mUniqueStacks);
+    mSavedStreamedSamples.reset();
+    mSavedStreamedMarkers.reset();
 
     aWriter.StartObjectProperty("stackTable");
     {
       {
         JSONSchemaWriter schema(aWriter);
         schema.WriteField("prefix");
         schema.WriteField("frame");
       }
@@ -117,75 +121,78 @@ ThreadInfo::StreamJSON(ProfileBuffer* aB
     aWriter.EndArray();
   }
   aWriter.End();
 
   mUniqueStacks.reset();
 }
 
 void
-ThreadInfo::StreamSamplesAndMarkers(ProfileBuffer* aBuffer,
-                                    SpliceableJSONWriter& aWriter,
-                                    const TimeStamp& aStartTime,
-                                    double aSinceTime,
-                                    UniqueStacks& aUniqueStacks)
+StreamSamplesAndMarkers(const char* aName,
+                        int aThreadId,
+                        ProfileBuffer* aBuffer,
+                        SpliceableJSONWriter& aWriter,
+                        const TimeStamp& aStartTime,
+                        double aSinceTime,
+                        JSContext* aContext,
+                        char* aSavedStreamedSamples,
+                        char* aSavedStreamedMarkers,
+                        UniqueStacks& aUniqueStacks)
 {
   aWriter.StringProperty("processType",
                          XRE_ChildProcessTypeToString(XRE_GetProcessType()));
 
-  aWriter.StringProperty("name", Name());
-  aWriter.IntProperty("tid", static_cast<int64_t>(mThreadId));
+  aWriter.StringProperty("name", aName);
+  aWriter.IntProperty("tid", static_cast<int64_t>(aThreadId));
   aWriter.IntProperty("pid", static_cast<int64_t>(getpid()));
 
   aWriter.StartObjectProperty("samples");
   {
     {
       JSONSchemaWriter schema(aWriter);
       schema.WriteField("stack");
       schema.WriteField("time");
       schema.WriteField("responsiveness");
       schema.WriteField("rss");
       schema.WriteField("uss");
       schema.WriteField("frameNumber");
     }
 
     aWriter.StartArrayProperty("data");
     {
-      if (mSavedStreamedSamples) {
+      if (aSavedStreamedSamples) {
         // We would only have saved streamed samples during shutdown
         // streaming, which cares about dumping the entire buffer, and thus
         // should have passed in 0 for aSinceTime.
         MOZ_ASSERT(aSinceTime == 0);
-        aWriter.Splice(mSavedStreamedSamples.get());
-        mSavedStreamedSamples.reset();
+        aWriter.Splice(aSavedStreamedSamples);
       }
-      aBuffer->StreamSamplesToJSON(aWriter, mThreadId, aSinceTime,
-                                   mPseudoStack->mContext, aUniqueStacks);
+      aBuffer->StreamSamplesToJSON(aWriter, aThreadId, aSinceTime, aContext,
+                                   aUniqueStacks);
     }
     aWriter.EndArray();
   }
   aWriter.EndObject();
 
   aWriter.StartObjectProperty("markers");
   {
     {
       JSONSchemaWriter schema(aWriter);
       schema.WriteField("name");
       schema.WriteField("time");
       schema.WriteField("data");
     }
 
     aWriter.StartArrayProperty("data");
     {
-      if (mSavedStreamedMarkers) {
+      if (aSavedStreamedMarkers) {
         MOZ_ASSERT(aSinceTime == 0);
-        aWriter.Splice(mSavedStreamedMarkers.get());
-        mSavedStreamedMarkers.reset();
+        aWriter.Splice(aSavedStreamedMarkers);
       }
-      aBuffer->StreamMarkersToJSON(aWriter, mThreadId, aStartTime, aSinceTime,
+      aBuffer->StreamMarkersToJSON(aWriter, aThreadId, aStartTime, aSinceTime,
                                    aUniqueStacks);
     }
     aWriter.EndArray();
   }
   aWriter.EndObject();
 }
 
 void
--- a/tools/profiler/core/ThreadInfo.h
+++ b/tools/profiler/core/ThreadInfo.h
@@ -76,22 +76,16 @@ public:
                               const mozilla::TimeStamp& aStartTime);
 
   ThreadResponsiveness* GetThreadResponsiveness() { return &mRespInfo; }
 
   void UpdateThreadResponsiveness() {
     mRespInfo.Update(mIsMainThread, mThread);
   }
 
-  void StreamSamplesAndMarkers(ProfileBuffer* aBuffer,
-                               SpliceableJSONWriter& aWriter,
-                               const mozilla::TimeStamp& aStartTime,
-                               double aSinceTime,
-                               UniqueStacks& aUniqueStacks);
-
 private:
   bool mHasProfile;
 
   // JS frames in the buffer may require a live JSRuntime to stream (e.g.,
   // stringifying JIT frames). In the case of JSRuntime destruction,
   // FlushSamplesAndMarkers should be called to save them. These are spliced
   // into the final stream.
   mozilla::UniquePtr<char[]> mSavedStreamedSamples;
@@ -102,9 +96,20 @@ private:
 
   // When sampling, this holds the generation number and offset in the
   // ProfileBuffer of the most recent sample for this thread.
   // mLastSample.mThreadId duplicates mThreadId in this structure, which
   // simplifies some uses of mLastSample.
   ProfileBuffer::LastSample mLastSample;
 };
 
+void
+StreamSamplesAndMarkers(const char* aName, int aThreadId,
+                        ProfileBuffer* aBuffer,
+                        SpliceableJSONWriter& aWriter,
+                        const mozilla::TimeStamp& aStartTime,
+                        double aSinceTime,
+                        JSContext* aContext,
+                        char* aSavedStreamedSamples,
+                        char* aSavedStreamedMarkers,
+                        UniqueStacks& aUniqueStacks);
+
 #endif