Bug 992454 - Part 2: Integrate TaskTracer into GeckoProfiler. r=benwa.
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -31,16 +31,17 @@
#include "nsServiceManagerUtils.h"
#include "nsIXULRuntime.h"
#include "nsIXULAppInfo.h"
#include "nsDirectoryServiceUtils.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIObserverService.h"
#include "mozilla/Services.h"
#include "PlatformMacros.h"
+#include "nsTArray.h"
#if defined(SPS_OS_android) && !defined(MOZ_WIDGET_GONK)
#include "AndroidBridge.h"
#endif
// JS
#include "jsfriendapi.h"
#include "js/ProfilingFrameIterator.h"
@@ -101,16 +102,53 @@ void TableTicker::HandleSaveRequest()
mSaveRequested = false;
// TODO: Use use the ipc/chromium Tasks here to support processes
// without XPCOM.
nsCOMPtr<nsIRunnable> runnable = new SaveProfileTask();
NS_DispatchToMainThread(runnable);
}
+
+void TableTicker::StreamTaskTracer(JSStreamWriter& b)
+{
+ b.BeginObject();
+#ifdef MOZ_TASK_TRACER
+ b.Name("data");
+ b.BeginArray();
+ nsAutoPtr<nsTArray<nsCString>> data(
+ mozilla::tasktracer::GetLoggedData(sStartTime));
+ for (uint32_t i = 0; i < data->Length(); ++i) {
+ b.Value((data->ElementAt(i)).get());
+ }
+ mozilla::tasktracer::StartLogging();
+ b.EndArray();
+
+ b.Name("threads");
+ b.BeginArray();
+ mozilla::MutexAutoLock lock(*sRegisteredThreadsMutex);
+ for (size_t i = 0; i < sRegisteredThreads->size(); i++) {
+ // Thread meta data
+ ThreadInfo* info = sRegisteredThreads->at(i);
+ b.BeginObject();
+ if (XRE_GetProcessType() == GeckoProcessType_Plugin) {
+ // TODO Add the proper plugin name
+ b.NameValue("name", "Plugin");
+ } else {
+ b.NameValue("name", info->Name());
+ }
+ b.NameValue("tid", static_cast<int>(info->ThreadId()));
+ b.EndObject();
+ }
+ b.EndArray();
+#endif
+ b.EndObject();
+}
+
+
void TableTicker::StreamMetaJSCustomObject(JSStreamWriter& b)
{
b.BeginObject();
b.NameValue("version", 2);
b.NameValue("interval", interval());
b.NameValue("stackwalk", mUseStackWalk);
b.NameValue("jank", mJankOnly);
@@ -265,16 +303,22 @@ void TableTicker::StreamJSObject(JSStrea
b.BeginObject();
// Put shared library info
b.NameValue("libs", GetSharedLibraryInfoString().c_str());
// Put meta data
b.Name("meta");
StreamMetaJSCustomObject(b);
+ // Data of TaskTracer doesn't belong in the circular buffer.
+ if (TaskTracer()) {
+ b.Name("tasktracer");
+ StreamTaskTracer(b);
+ }
+
// Lists the samples for each ThreadProfile
b.Name("threads");
b.BeginArray();
SetPaused(true);
{
mozilla::MutexAutoLock lock(*sRegisteredThreadsMutex);
--- a/tools/profiler/TableTicker.h
+++ b/tools/profiler/TableTicker.h
@@ -5,16 +5,19 @@
#ifndef TableTicker_h
#define TableTicker_h
#include "platform.h"
#include "ProfileEntry.h"
#include "mozilla/Mutex.h"
#include "IntelPowerGadget.h"
+#ifdef MOZ_TASK_TRACER
+#include "GeckoTaskTracer.h"
+#endif
static bool
hasFeature(const char** aFeatures, uint32_t aFeatureCount, const char* aFeature) {
for(size_t i = 0; i < aFeatureCount; i++) {
if (strcmp(aFeatures[i], aFeature) == 0)
return true;
}
return false;
@@ -68,16 +71,17 @@ class TableTicker: public Sampler {
// Users sometimes ask to filter by a list of threads but forget to request
// profiling non main threads. Let's make it implificit if we have a filter
mProfileThreads = hasFeature(aFeatures, aFeatureCount, "threads") || aFilterCount > 0;
mUnwinderThread = hasFeature(aFeatures, aFeatureCount, "unwinder") || sps_version2();
mAddLeafAddresses = hasFeature(aFeatures, aFeatureCount, "leaf");
mPrivacyMode = hasFeature(aFeatures, aFeatureCount, "privacy");
mAddMainThreadIO = hasFeature(aFeatures, aFeatureCount, "mainthreadio");
mProfileMemory = hasFeature(aFeatures, aFeatureCount, "memory");
+ mTaskTracer = hasFeature(aFeatures, aFeatureCount, "tasktracer");
#if defined(XP_WIN)
if (mProfilePower) {
mIntelPowerGadget = new IntelPowerGadget();
mProfilePower = mIntelPowerGadget->Init();
}
#endif
@@ -96,16 +100,22 @@ class TableTicker: public Sampler {
for (uint32_t i = 0; i < sRegisteredThreads->size(); i++) {
ThreadInfo* info = sRegisteredThreads->at(i);
RegisterThread(info);
}
SetActiveSampler(this);
}
+
+#ifdef MOZ_TASK_TRACER
+ if (mTaskTracer) {
+ mozilla::tasktracer::StartLogging();
+ }
+#endif
}
~TableTicker() {
if (IsActive())
Stop();
SetActiveSampler(nullptr);
@@ -152,16 +162,21 @@ class TableTicker: public Sampler {
// Immediately captures the calling thread's call stack and returns it.
virtual SyncProfile* GetBacktrace();
// Called within a signal. This function must be reentrant
virtual void RequestSave()
{
mSaveRequested = true;
+#ifdef MOZ_TASK_TRACER
+ if (mTaskTracer) {
+ mozilla::tasktracer::StopLogging();
+ }
+#endif
}
virtual void HandleSaveRequest();
ThreadProfile* GetPrimaryThreadProfile()
{
if (!mPrimaryThreadProfile) {
mozilla::MutexAutoLock lock(*sRegisteredThreadsMutex);
@@ -176,24 +191,26 @@ class TableTicker: public Sampler {
}
return mPrimaryThreadProfile;
}
void ToStreamAsJSON(std::ostream& stream);
virtual JSObject *ToJSObject(JSContext *aCx);
void StreamMetaJSCustomObject(JSStreamWriter& b);
+ void StreamTaskTracer(JSStreamWriter& b);
bool HasUnwinderThread() const { return mUnwinderThread; }
bool ProfileJS() const { return mProfileJS; }
bool ProfileJava() const { return mProfileJava; }
bool ProfilePower() const { return mProfilePower; }
bool ProfileThreads() const { return mProfileThreads; }
bool InPrivacyMode() const { return mPrivacyMode; }
bool AddMainThreadIO() const { return mAddMainThreadIO; }
bool ProfileMemory() const { return mProfileMemory; }
+ bool TaskTracer() const { return mTaskTracer; }
protected:
// Called within a signal. This function must be reentrant
virtual void UnwinderTick(TickSample* sample);
// Called within a signal. This function must be reentrant
virtual void InplaceTick(TickSample* sample);
@@ -216,15 +233,16 @@ protected:
// Keep the thread filter to check against new thread that
// are started while profiling
char** mThreadNameFilters;
uint32_t mFilterCount;
bool mPrivacyMode;
bool mAddMainThreadIO;
bool mProfileMemory;
+ bool mTaskTracer;
#if defined(XP_WIN)
IntelPowerGadget* mIntelPowerGadget;
#endif
};
#endif
--- a/tools/profiler/platform.cpp
+++ b/tools/profiler/platform.cpp
@@ -684,16 +684,20 @@ const char** mozilla_sampler_get_feature
// Profile the registered secondary threads.
"threads",
// Do not include user-identifiable information
"privacy",
// Add main thread I/O to the profile
"mainthreadio",
// Add RSS collection
"memory",
+#ifdef MOZ_TASK_TRACER
+ // Start profiling with feature TaskTracer.
+ "tasktracer",
+#endif
#if defined(XP_WIN)
// Add power collection
"power",
#endif
nullptr
};
return features;