Example #1
0
static
typename Builder::Object BuildJavaThreadJSObject(Builder& b)
{
  typename Builder::RootedObject javaThread(b.context(), b.CreateObject());
  b.DefineProperty(javaThread, "name", "Java Main Thread");

  typename Builder::RootedArray samples(b.context(), b.CreateArray());
  b.DefineProperty(javaThread, "samples", samples);

  int sampleId = 0;
  while (true) {
    int frameId = 0;
    typename Builder::RootedObject sample(b.context());
    typename Builder::RootedArray frames(b.context());
    while (true) {
      nsCString result;
      bool hasFrame = AndroidBridge::Bridge()->GetFrameNameJavaProfiling(0, sampleId, frameId, result);
      if (!hasFrame) {
        if (frames) {
          b.DefineProperty(sample, "frames", frames);
        }
        break;
      }
      if (!sample) {
        sample = b.CreateObject();
        frames = b.CreateArray();
        b.DefineProperty(sample, "frames", frames);
        b.ArrayPush(samples, sample);

        double sampleTime = AndroidBridge::Bridge()->GetSampleTimeJavaProfiling(0, sampleId);
        b.DefineProperty(sample, "time", sampleTime);
      }
      typename Builder::RootedObject frame(b.context(), b.CreateObject());
      b.DefineProperty(frame, "location", result.BeginReading());
      b.ArrayPush(frames, frame);
      frameId++;
    }
    if (frameId == 0) {
      break;
    }
    sampleId++;
  }

  return javaThread;
}
Example #2
0
typename Builder::Object
ProfilerMarkerImagePayload::preparePayloadImp(Builder& b)
{
  typename Builder::RootedObject data(b.context(), b.CreateObject());
  prepareCommonProps("innerHTML", b, data);
  // TODO: Finish me
  //b.DefineProperty(data, "innerHTML", "<img src=''/>");
  return data;
}
Example #3
0
template<typename Builder> typename Builder::Object
IOMarkerPayload::preparePayloadImp(Builder& b)
{
  typename Builder::RootedObject data(b.context(), b.CreateObject());
  prepareCommonProps("io", b, data);
  b.DefineProperty(data, "source", mSource);

  return data;
}
Example #4
0
typename Builder::Object TableTicker::GetMetaJSCustomObject(Builder& b)
{
  typename Builder::RootedObject meta(b.context(), b.CreateObject());

  b.DefineProperty(meta, "version", 2);
  b.DefineProperty(meta, "interval", interval());
  b.DefineProperty(meta, "stackwalk", mUseStackWalk);
  b.DefineProperty(meta, "jank", mJankOnly);
  b.DefineProperty(meta, "processType", XRE_GetProcessType());

  TimeDuration delta = TimeStamp::Now() - sStartTime;
  b.DefineProperty(meta, "startTime", PR_Now()/1000.0 - delta.ToMilliseconds());

  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))
      b.DefineProperty(meta, "platform", string.Data());

    res = http->GetOscpu(string);
    if (!NS_FAILED(res))
      b.DefineProperty(meta, "oscpu", string.Data());

    res = http->GetMisc(string);
    if (!NS_FAILED(res))
      b.DefineProperty(meta, "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))
      b.DefineProperty(meta, "abi", string.Data());

    res = runtime->GetWidgetToolkit(string);
    if (!NS_FAILED(res))
      b.DefineProperty(meta, "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))
      b.DefineProperty(meta, "product", string.Data());
  }

  return meta;
}
Example #5
0
void TableTicker::BuildJSObject(Builder& b, typename Builder::ObjectHandle profile)
{
  // Put shared library info
  b.DefineProperty(profile, "libs", GetSharedLibraryInfoString().c_str());

  // Put meta data
  typename Builder::RootedObject meta(b.context(), GetMetaJSCustomObject(b));
  b.DefineProperty(profile, "meta", meta);

  // Lists the samples for each ThreadProfile
  typename Builder::RootedArray threads(b.context(), b.CreateArray());
  b.DefineProperty(profile, "threads", threads);

  SetPaused(true);

  {
    mozilla::MutexAutoLock lock(*sRegisteredThreadsMutex);

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

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

      typename Builder::RootedObject threadSamples(b.context(), b.CreateObject());
      sRegisteredThreads->at(i)->Profile()->BuildJSObject(b, threadSamples);
      b.ArrayPush(threads, threadSamples);
    }
  }

#if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
  if (ProfileJava()) {
    AndroidBridge::Bridge()->PauseJavaProfiling();

    typename Builder::RootedObject javaThread(b.context(), BuildJavaThreadJSObject(b));
    b.ArrayPush(threads, javaThread);

    AndroidBridge::Bridge()->UnpauseJavaProfiling();
  }
#endif

  SetPaused(false);

  // Send a event asking any subprocesses (plugins) to
  // give us their information
  SubprocessClosure<Builder> closure(&b, threads);
  nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
  if (os) {
    nsRefPtr<ProfileSaveEvent> pse = new ProfileSaveEvent(SubProcessCallback<Builder>, &closure);
    os->NotifyObservers(pse, "profiler-subprocess", nullptr);
  }
}
Example #6
0
template<typename Builder> void
ProfilerMarker::BuildJSObject(Builder& b, typename Builder::ArrayHandle markers) const {
  typename Builder::RootedObject marker(b.context(), b.CreateObject());
  b.DefineProperty(marker, "name", GetMarkerName());
  // TODO: Store the callsite for this marker if available:
  // if have location data
  //   b.DefineProperty(marker, "location", ...);
  if (mPayload) {
    typename Builder::RootedObject markerData(b.context(),
                                              mPayload->PreparePayload(b));
    b.DefineProperty(marker, "data", markerData);
  }
  b.ArrayPush(markers, marker);
}
Example #7
0
typename Builder::Object
ProfilerMarkerTracing::preparePayloadImp(Builder& b)
{
  typename Builder::RootedObject data(b.context(), b.CreateObject());
  prepareCommonProps("tracing", b, data);

  if (GetCategory()) {
    b.DefineProperty(data, "category", GetCategory());
  }
  if (GetMetaData() != TRACING_DEFAULT) {
    if (GetMetaData() == TRACING_INTERVAL_START) {
      b.DefineProperty(data, "interval", "start");
    } else if (GetMetaData() == TRACING_INTERVAL_END) {
      b.DefineProperty(data, "interval", "end");
    }
  }

  return data;
}
Example #8
0
template<typename Builder> void
ProfilerMarkerPayload::prepareCommonProps(const char* aMarkerType,
                                          Builder& aBuilder,
                                          typename Builder::ObjectHandle aObject)
{
  MOZ_ASSERT(aMarkerType);
  aBuilder.DefineProperty(aObject, "type", aMarkerType);
  if (!mStartTime.IsNull()) {
    aBuilder.DefineProperty(aObject, "startTime", profiler_time(mStartTime));
  }
  if (!mEndTime.IsNull()) {
    aBuilder.DefineProperty(aObject, "endTime", profiler_time(mEndTime));
  }
  if (mStack) {
    typename Builder::RootedObject stack(aBuilder.context(),
                                         aBuilder.CreateObject());
    aBuilder.DefineProperty(aObject, "stack", stack);
    mStack->BuildJSObject(aBuilder, stack);
  }
}
Example #9
0
void ThreadProfile::BuildJSObject(Builder& b,
                                  typename Builder::ObjectHandle profile)
{
  // Thread meta data
  if (XRE_GetProcessType() == GeckoProcessType_Plugin) {
    // TODO Add the proper plugin name
    b.DefineProperty(profile, "name", "Plugin");
  } else {
    b.DefineProperty(profile, "name", mName);
  }

  b.DefineProperty(profile, "tid", static_cast<int>(mThreadId));

  typename Builder::RootedArray samples(b.context(), b.CreateArray());
  b.DefineProperty(profile, "samples", samples);

  typename Builder::RootedObject sample(b.context());
  typename Builder::RootedArray frames(b.context());
  typename Builder::RootedArray markers(b.context());

  int readPos = mReadPos;
  while (readPos != mLastFlushPos) {
    // Number of tag consumed
    int incBy = 1;
    ProfileEntry entry = mEntries[readPos];

    // Read ahead to the next tag, if it's a 'd' tag process it now
    const char* tagStringData = entry.mTagData;
    int readAheadPos = (readPos + 1) % mEntrySize;
    char tagBuff[DYNAMIC_MAX_STRING];
    // Make sure the string is always null terminated if it fills up
    // DYNAMIC_MAX_STRING-2
    tagBuff[DYNAMIC_MAX_STRING-1] = '\0';

    if (readAheadPos != mLastFlushPos && mEntries[readAheadPos].mTagName == 'd') {
      tagStringData = processDynamicTag(readPos, &incBy, tagBuff);
    }

    switch (entry.mTagName) {
      case 'm':
        {
          if (sample) {
            if (!markers) {
              markers = b.CreateArray();
              b.DefineProperty(sample, "marker", markers);
            }
            entry.getMarker()->BuildJSObject(b, markers);
          }
        }
        break;
      case 'r':
        {
          if (sample) {
            b.DefineProperty(sample, "responsiveness", entry.mTagFloat);
          }
        }
        break;
      case 'p':
        {
          if (sample) {
            b.DefineProperty(sample, "power", entry.mTagFloat);
          }
        }
        break;
      case 'f':
        {
          if (sample) {
            b.DefineProperty(sample, "frameNumber", entry.mTagLine);
          }
        }
        break;
      case 't':
        {
          if (sample) {
            b.DefineProperty(sample, "time", entry.mTagFloat);
          }
        }
        break;
      case 's':
        sample = b.CreateObject();
        b.DefineProperty(sample, "name", tagStringData);
        frames = b.CreateArray();
        b.DefineProperty(sample, "frames", frames);
        b.ArrayPush(samples, sample);
        // Created lazily
        markers = nullptr;
        // Fall though to create a label for the 's' tag
      case 'c':
      case 'l':
        {
          if (sample) {
            typename Builder::RootedObject frame(b.context(), b.CreateObject());
            if (entry.mTagName == 'l') {
              // Bug 753041
              // We need a double cast here to tell GCC that we don't want to sign
              // extend 32-bit addresses starting with 0xFXXXXXX.
              unsigned long long pc = (unsigned long long)(uintptr_t)entry.mTagPtr;
              snprintf(tagBuff, DYNAMIC_MAX_STRING, "%#llx", pc);
              b.DefineProperty(frame, "location", tagBuff);
            } else {
              b.DefineProperty(frame, "location", tagStringData);
              readAheadPos = (readPos + incBy) % mEntrySize;
              if (readAheadPos != mLastFlushPos &&
                  mEntries[readAheadPos].mTagName == 'n') {
                b.DefineProperty(frame, "line",
                                 mEntries[readAheadPos].mTagLine);
                incBy++;
              }
            }
            b.ArrayPush(frames, frame);
          }
        }
    }
    readPos = (readPos + incBy) % mEntrySize;
  }
}