示例#1
0
void
IOMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter, UniqueStacks& aUniqueStacks)
{
  streamCommonProps("io", aWriter, aUniqueStacks);
  aWriter.StringProperty("source", mSource);
  if (mFilename != nullptr) {
    aWriter.StringProperty("filename", mFilename);
  }
}
示例#2
0
void
GPUMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
                                UniqueStacks& aUniqueStacks)
{
  streamCommonProps("gpu_timer_query", aWriter, aUniqueStacks);

  aWriter.DoubleProperty("cpustart", profiler_time(mCpuTimeStart));
  aWriter.DoubleProperty("cpuend", profiler_time(mCpuTimeEnd));
  aWriter.IntProperty("gpustart", (int)mGpuTimeStart);
  aWriter.IntProperty("gpuend", (int)mGpuTimeEnd);
}
示例#3
0
void
LayerTranslationPayload::StreamPayload(SpliceableJSONWriter& aWriter,
                                       UniqueStacks& aUniqueStacks)
{
  const size_t bufferSize = 32;
  char buffer[bufferSize];
  PR_snprintf(buffer, bufferSize, "%p", mLayer);

  aWriter.StringProperty("layer", buffer);
  aWriter.IntProperty("x", mPoint.x);
  aWriter.IntProperty("y", mPoint.y);
  aWriter.StringProperty("category", "LayerTranslation");
}
示例#4
0
void
ProfilerMarkerTracing::StreamPayload(SpliceableJSONWriter& aWriter,
                                     UniqueStacks& aUniqueStacks)
{
  streamCommonProps("tracing", aWriter, aUniqueStacks);

  if (GetCategory()) {
    aWriter.StringProperty("category", GetCategory());
  }
  if (GetMetaData() != TRACING_DEFAULT) {
    if (GetMetaData() == TRACING_INTERVAL_START) {
      aWriter.StringProperty("interval", "start");
    } else if (GetMetaData() == TRACING_INTERVAL_END) {
      aWriter.StringProperty("interval", "end");
    }
  }
}
示例#5
0
void
ProfilerMarkerPayload::streamCommonProps(const char* aMarkerType,
                                         SpliceableJSONWriter& aWriter,
                                         UniqueStacks& aUniqueStacks)
{
  MOZ_ASSERT(aMarkerType);
  aWriter.StringProperty("type", aMarkerType);
  if (!mStartTime.IsNull()) {
    aWriter.DoubleProperty("startTime", profiler_time(mStartTime));
  }
  if (!mEndTime.IsNull()) {
    aWriter.DoubleProperty("endTime", profiler_time(mEndTime));
  }
  if (mStack) {
    aWriter.StartObjectProperty("stack");
    {
      mStack->StreamJSON(aWriter, aUniqueStacks);
    }
    aWriter.EndObject();
  }
}
示例#6
0
void ProfilerMarker::StreamJSON(SpliceableJSONWriter& aWriter,
                                UniqueStacks& aUniqueStacks) const
{
  // Schema:
  //   [name, time, data]

  aWriter.StartArrayElement();
  {
    aUniqueStacks.mUniqueStrings.WriteElement(aWriter, GetMarkerName());
    aWriter.DoubleElement(mTime);
    // TODO: Store the callsite for this marker if available:
    // if have location data
    //   b.NameValue(marker, "location", ...);
    if (mPayload) {
      aWriter.StartObjectElement();
      {
          mPayload->StreamPayload(aWriter, aUniqueStacks);
      }
      aWriter.EndObject();
    }
  }
  aWriter.EndArray();
}
示例#7
0
void GeckoSampler::StreamJSON(SpliceableJSONWriter& aWriter, double aSinceTime)
{
  aWriter.Start(SpliceableJSONWriter::SingleLineStyle);
  {
    // Put shared library info
    aWriter.StringProperty("libs", GetSharedLibraryInfoStringInternal().c_str());

    // Put meta data
    aWriter.StartObjectProperty("meta");
      StreamMetaJSCustomObject(aWriter);
    aWriter.EndObject();

    // Data of TaskTracer doesn't belong in the circular buffer.
    if (TaskTracer()) {
      aWriter.StartObjectProperty("tasktracer");
      StreamTaskTracer(aWriter);
    }

    // Lists the samples for each ThreadProfile
    aWriter.StartArrayProperty("threads");
    {
      SetPaused(true);

      {
        ::MutexAutoLock lock(*sRegisteredThreadsMutex);

        for (size_t i = 0; i < sRegisteredThreads->size(); i++) {
          // Thread not being profiled, skip it
          if (!sRegisteredThreads->at(i)->Profile())
            continue;

          // Note that we intentionally include ThreadProfile which
          // have been marked for pending delete.

          ::MutexAutoLock lock(sRegisteredThreads->at(i)->Profile()->GetMutex());

          sRegisteredThreads->at(i)->Profile()->StreamJSON(aWriter, aSinceTime);
        }
      }

#ifndef SPS_STANDALONE
      if (Sampler::CanNotifyObservers()) {
        // Send a event asking any subprocesses (plugins) to
        // give us their information
        SubprocessClosure closure(&aWriter);
        nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
        if (os) {
          RefPtr<ProfileSaveEvent> pse = new ProfileSaveEvent(SubProcessCallback, &closure);
          os->NotifyObservers(pse, "profiler-subprocess", nullptr);
        }
      }

  #if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
      if (ProfileJava()) {
        mozilla::widget::GeckoJavaSampler::PauseJavaProfiling();

        aWriter.Start();
        {
          BuildJavaThreadJSObject(aWriter);
        }
        aWriter.End();

        mozilla::widget::GeckoJavaSampler::UnpauseJavaProfiling();
      }
  #endif
#endif

      SetPaused(false);
    }
    aWriter.EndArray();
  }
  aWriter.End();
}
示例#8
0
static
void BuildJavaThreadJSObject(SpliceableJSONWriter& aWriter)
{
  aWriter.StringProperty("name", "Java Main Thread");

  aWriter.StartArrayProperty("samples");

    // for each sample
    for (int sampleId = 0; true; sampleId++) {
      bool firstRun = true;
      // for each frame
      for (int frameId = 0; true; frameId++) {
        nsCString result;
        bool hasFrame = AndroidBridge::Bridge()->GetFrameNameJavaProfiling(0, sampleId, frameId, result);
        // when we run out of frames, we stop looping
        if (!hasFrame) {
          // if we found at least one frame, we have objects to close
          if (!firstRun) {
              aWriter.EndArray();
            aWriter.EndObject();
          }
          break;
        }
        // the first time around, open the sample object and frames array
        if (firstRun) {
          firstRun = false;

          double sampleTime =
            mozilla::widget::GeckoJavaSampler::GetSampleTimeJavaProfiling(0, sampleId);

          aWriter.StartObjectElement();
            aWriter.DoubleProperty("time", sampleTime);

            aWriter.StartArrayProperty("frames");
        }
        // add a frame to the sample
        aWriter.StartObjectElement();
          aWriter.StringProperty("location", result.BeginReading());
        aWriter.EndObject();
      }
      // if we found no frames for this sample, we are done
      if (firstRun) {
        break;
      }
    }

  aWriter.EndArray();
}
示例#9
0
void GeckoSampler::StreamMetaJSCustomObject(SpliceableJSONWriter& aWriter)
{
  aWriter.IntProperty("version", 3);
  aWriter.DoubleProperty("interval", interval());
  aWriter.IntProperty("stackwalk", mUseStackWalk);

#ifndef SPS_STANDALONE
  mozilla::TimeDuration delta = mozilla::TimeStamp::Now() - sStartTime;
  aWriter.DoubleProperty("startTime", static_cast<double>(PR_Now()/1000.0 - delta.ToMilliseconds()));

  aWriter.IntProperty("processType", XRE_GetProcessType());

  nsresult res;
  nsCOMPtr<nsIHttpProtocolHandler> http = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &res);
  if (!NS_FAILED(res)) {
    nsAutoCString string;

    res = http->GetPlatform(string);
    if (!NS_FAILED(res))
      aWriter.StringProperty("platform", string.Data());

    res = http->GetOscpu(string);
    if (!NS_FAILED(res))
      aWriter.StringProperty("oscpu", string.Data());

    res = http->GetMisc(string);
    if (!NS_FAILED(res))
      aWriter.StringProperty("misc", string.Data());
  }

  nsCOMPtr<nsIXULRuntime> runtime = do_GetService("@mozilla.org/xre/runtime;1");
  if (runtime) {
    nsAutoCString string;

    res = runtime->GetXPCOMABI(string);
    if (!NS_FAILED(res))
      aWriter.StringProperty("abi", string.Data());

    res = runtime->GetWidgetToolkit(string);
    if (!NS_FAILED(res))
      aWriter.StringProperty("toolkit", string.Data());
  }

  nsCOMPtr<nsIXULAppInfo> appInfo = do_GetService("@mozilla.org/xre/app-info;1");
  if (appInfo) {
    nsAutoCString string;

    res = appInfo->GetName(string);
    if (!NS_FAILED(res))
      aWriter.StringProperty("product", string.Data());
  }
#endif
}
示例#10
0
void GeckoSampler::StreamTaskTracer(SpliceableJSONWriter& aWriter)
{
#ifdef MOZ_TASK_TRACER
  aWriter.StartArrayProperty("data");
    nsAutoPtr<nsTArray<nsCString>> data(mozilla::tasktracer::GetLoggedData(sStartTime));
    for (uint32_t i = 0; i < data->Length(); ++i) {
      aWriter.StringElement((data->ElementAt(i)).get());
    }
  aWriter.EndArray();

  aWriter.StartArrayProperty("threads");
    ::MutexAutoLock lock(*sRegisteredThreadsMutex);
    for (size_t i = 0; i < sRegisteredThreads->size(); i++) {
      // Thread meta data
      ThreadInfo* info = sRegisteredThreads->at(i);
      aWriter.StartObjectElement();
        if (XRE_GetProcessType() == GeckoProcessType_Plugin) {
          // TODO Add the proper plugin name
          aWriter.StringProperty("name", "Plugin");
        } else {
          aWriter.StringProperty("name", info->Name());
        }
        aWriter.IntProperty("tid", static_cast<int>(info->ThreadId()));
      aWriter.EndObject();
    }
  aWriter.EndArray();

  aWriter.DoubleProperty("start", static_cast<double>(mozilla::tasktracer::GetStartTime()));
#endif
}
示例#11
0
void
VsyncPayload::StreamPayload(SpliceableJSONWriter& aWriter, UniqueStacks& aUniqueStacks)
{
  aWriter.DoubleProperty("vsync", profiler_time(mVsyncTimestamp));
  aWriter.StringProperty("category", "VsyncTimestamp");
}
示例#12
0
void
TouchDataPayload::StreamPayload(SpliceableJSONWriter& aWriter, UniqueStacks& aUniqueStacks)
{
  aWriter.IntProperty("x", mPoint.x);
  aWriter.IntProperty("y", mPoint.y);
}
示例#13
0
void UniqueStacks::SpliceStackTableElements(SpliceableJSONWriter& aWriter)
{
  mStackTableWriter.EndBareList();
  aWriter.TakeAndSplice(mStackTableWriter.WriteFunc());
}
示例#14
0
void ThreadProfile::StreamSamplesAndMarkers(SpliceableJSONWriter& aWriter, float aSinceTime,
                                            UniqueStacks& aUniqueStacks)
{
  // Thread meta data
  if (XRE_GetProcessType() == GeckoProcessType_Plugin) {
    // TODO Add the proper plugin name
    aWriter.StringProperty("name", "Plugin");
  } else if (XRE_GetProcessType() == GeckoProcessType_Content) {
    // This isn't going to really help once we have multiple content
    // processes, but it'll do for now.
    aWriter.StringProperty("name", "Content");
  } else {
    aWriter.StringProperty("name", Name());
  }
  aWriter.IntProperty("tid", static_cast<int>(mThreadId));

  aWriter.StartObjectProperty("samples");
  {
    {
      JSONSchemaWriter schema(aWriter);
      schema.WriteField("stack");
      schema.WriteField("time");
      schema.WriteField("responsiveness");
      schema.WriteField("rss");
      schema.WriteField("uss");
      schema.WriteField("frameNumber");
      schema.WriteField("power");
    }

    aWriter.StartArrayProperty("data");
    {
      if (mSavedStreamedSamples) {
        // 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();
      }
      mBuffer->StreamSamplesToJSON(aWriter, mThreadId, aSinceTime,
                                   mPseudoStack->mRuntime, 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) {
        MOZ_ASSERT(aSinceTime == 0);
        aWriter.Splice(mSavedStreamedMarkers.get());
        mSavedStreamedMarkers.reset();
      }
      mBuffer->StreamMarkersToJSON(aWriter, mThreadId, aSinceTime, aUniqueStacks);
    }
    aWriter.EndArray();
  }
  aWriter.EndObject();
}
示例#15
0
void ThreadProfile::StreamJSON(SpliceableJSONWriter& aWriter, float aSinceTime)
{
  // mUniqueStacks may already be emplaced from FlushSamplesAndMarkers.
  if (!mUniqueStacks.isSome()) {
    mUniqueStacks.emplace(mPseudoStack->mRuntime);
  }

  aWriter.Start(SpliceableJSONWriter::SingleLineStyle);
  {
    StreamSamplesAndMarkers(aWriter, aSinceTime, *mUniqueStacks);

    aWriter.StartObjectProperty("stackTable");
    {
      {
        JSONSchemaWriter schema(aWriter);
        schema.WriteField("prefix");
        schema.WriteField("frame");
      }

      aWriter.StartArrayProperty("data");
      {
        mUniqueStacks->SpliceStackTableElements(aWriter);
      }
      aWriter.EndArray();
    }
    aWriter.EndObject();

    aWriter.StartObjectProperty("frameTable");
    {
      {
        JSONSchemaWriter schema(aWriter);
        schema.WriteField("location");
        schema.WriteField("implementation");
        schema.WriteField("optimizations");
        schema.WriteField("line");
        schema.WriteField("category");
      }

      aWriter.StartArrayProperty("data");
      {
        mUniqueStacks->SpliceFrameTableElements(aWriter);
      }
      aWriter.EndArray();
    }
    aWriter.EndObject();

    aWriter.StartArrayProperty("stringTable");
    {
      mUniqueStacks->mUniqueStrings.SpliceStringTableElements(aWriter);
    }
    aWriter.EndArray();
  }
  aWriter.End();

  mUniqueStacks.reset();
}
示例#16
0
static void WriteSample(SpliceableJSONWriter& aWriter, ProfileSample& aSample)
{
  // Schema:
  //   [stack, time, responsiveness, rss, uss, frameNumber, power]

  aWriter.StartArrayElement();
  {
    // The last non-null index is tracked to save space in the JSON by avoid
    // emitting 'null's at the end of the array, as they're only needed if
    // followed by non-null elements.
    uint32_t index = 0;
    uint32_t lastNonNullIndex = 0;

    aWriter.IntElement(aSample.mStack);
    index++;

    if (aSample.mTime.isSome()) {
      lastNonNullIndex = index;
      aWriter.DoubleElement(*aSample.mTime);
    }
    index++;

    if (aSample.mResponsiveness.isSome()) {
      aWriter.NullElements(index - lastNonNullIndex - 1);
      lastNonNullIndex = index;
      aWriter.DoubleElement(*aSample.mResponsiveness);
    }
    index++;

    if (aSample.mRSS.isSome()) {
      aWriter.NullElements(index - lastNonNullIndex - 1);
      lastNonNullIndex = index;
      aWriter.DoubleElement(*aSample.mRSS);
    }
    index++;

    if (aSample.mUSS.isSome()) {
      aWriter.NullElements(index - lastNonNullIndex - 1);
      lastNonNullIndex = index;
      aWriter.DoubleElement(*aSample.mUSS);
    }
    index++;

    if (aSample.mFrameNumber.isSome()) {
      aWriter.NullElements(index - lastNonNullIndex - 1);
      lastNonNullIndex = index;
      aWriter.IntElement(*aSample.mFrameNumber);
    }
    index++;

    if (aSample.mPower.isSome()) {
      aWriter.NullElements(index - lastNonNullIndex - 1);
      lastNonNullIndex = index;
      aWriter.DoubleElement(*aSample.mPower);
    }
    index++;
  }
  aWriter.EndArray();
}