Bug 717059. Add suppport for optional features. r=ehsan
authorBenoit Girard <bgirard@mozilla.com>
Thu, 12 Jan 2012 13:33:32 -0500
changeset 84359 014f28a0543c2e76bc5da916a3e163c81788c453
parent 84358 2c1f1e307171886bf7b93074ef4dfaaf9aedbf09
child 84360 4b0fd441c9c70767a253f2b437b1d2aabb6840e0
push id21842
push usermak77@bonardo.net
push dateFri, 13 Jan 2012 08:56:37 +0000
treeherdermozilla-central@8d4638feec54 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs717059
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 717059. Add suppport for optional features. r=ehsan This will let us detect situations where we have different features in the profiler and choose to use them.
tools/profiler/nsProfiler.cpp
tools/profiler/public/nsIProfiler.idl
tools/profiler/sampler.h
tools/profiler/sps/TableTicker.cpp
tools/profiler/sps/sps_sampler.h
--- a/tools/profiler/nsProfiler.cpp
+++ b/tools/profiler/nsProfiler.cpp
@@ -48,19 +48,20 @@ NS_IMPL_ISUPPORTS1(nsProfiler, nsIProfil
 
 
 nsProfiler::nsProfiler()
 {
 }
 
 
 NS_IMETHODIMP
-nsProfiler::StartProfiler(PRUint32 aInterval, PRUint32 aEntries)
+nsProfiler::StartProfiler(PRUint32 aInterval, PRUint32 aEntries,
+                          const char** aFeatures, PRUint32 aFeatureCount)
 {
-  SAMPLER_START(aInterval, aEntries);
+  SAMPLER_START(aInterval, aEntries, aFeatures, aFeatureCount);
 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
   mozilla::InitEventTracing();
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsProfiler::StopProfiler()
@@ -106,8 +107,35 @@ nsProfiler::GetResponsivenessTimes(PRUin
                        (nsMemory::Clone(times, len * sizeof(double)));
 
   *aCount = len;
   *aResult = fs;
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsProfiler::GetFeatures(PRUint32 *aCount, char ***aFeatures)
+{
+  PRUint32 len = 0;
+
+  const char **features = SAMPLER_GET_FEATURES();
+  if (!features) {
+    *aCount = 0;
+    *aFeatures = nsnull;
+    return NS_OK;
+  }
+
+  while (features[++len]);
+
+  char **featureList = static_cast<char **>
+                       (nsMemory::Alloc(len * sizeof(char*)));
+
+  for (size_t i = 0; i < len; i++) {
+    PRUint32 strLen = strlen(features[i]);
+    featureList[i] = static_cast<char *>
+                         (nsMemory::Clone(features[i], (strLen + 1) * sizeof(char)));
+  }
+
+  *aFeatures = featureList;
+  *aCount = len;
+  return NS_OK;
+}
--- a/tools/profiler/public/nsIProfiler.idl
+++ b/tools/profiler/public/nsIProfiler.idl
@@ -30,18 +30,21 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
-[scriptable, uuid(97c34690-3ca8-4225-9f7d-bcdbb76f29ed)]
+[scriptable, uuid(e388fded-1321-41af-a988-861a2bc5cfc3)]
 interface nsIProfiler : nsISupports
 {
-  void StartProfiler(in PRUint32 aInterval, in PRUint32 aEntries);
+  void StartProfiler(in PRUint32 aInterval, in PRUint32 aEntries,
+                      [array, size_is(aFeatureCount)] in string aFeatures,
+                      in PRUint32 aFeatureCount);
   void StopProfiler();
   string GetProfile();
   boolean IsActive();
   void GetResponsivenessTimes(out PRUint32 aCount, [retval, array, size_is(aCount)] out double aResult);
+  void GetFeatures(out PRUint32 aCount, [retval, array, size_is(aCount)] out string aFeatures);
 };
 
--- a/tools/profiler/sampler.h
+++ b/tools/profiler/sampler.h
@@ -91,22 +91,23 @@
 #include "sps_sampler.h"
 
 #else
 
 // Initialize the sampler. Any other calls will be silently discarded
 // before the sampler has been initialized (i.e. early start-up code)
 #define SAMPLER_INIT()
 #define SAMPLER_DEINIT()
-#define SAMPLER_START(entries, interval)
+#define SAMPLER_START(entries, interval, features, featureCount)
 #define SAMPLER_STOP()
 #define SAMPLER_IS_ACTIVE() false
 #define SAMPLER_SAVE()
 // Returned string must be free'ed
 #define SAMPLER_GET_PROFILE() NULL
 #define SAMPLER_RESPONSIVENESS(time) NULL
 #define SAMPLER_GET_RESPONSIVENESS() NULL
+#define SAMPLER_GET_FEATURES() NULL
 #define SAMPLE_LABEL(name_space, info)
 #define SAMPLE_MARKER(info)
 
 #endif
 
 #endif // ifndef SAMPLER_H
--- a/tools/profiler/sps/TableTicker.cpp
+++ b/tools/profiler/sps/TableTicker.cpp
@@ -212,19 +212,29 @@ private:
   int mReadPos;  // points to the next entry we will read to
   int mEntrySize;
   bool mNeedsSharedLibraryInfo;
   SharedLibraryInfo mSharedLibraryInfo;
 };
 
 class SaveProfileTask;
 
+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;
+}
+
 class TableTicker: public Sampler {
  public:
-  explicit TableTicker(int aInterval, int aEntrySize, Stack *aStack)
+  TableTicker(int aInterval, int aEntrySize, Stack *aStack,
+              const char** aFeatures, uint32_t aFeatureCount)
     : Sampler(aInterval, true)
     , mProfile(aEntrySize)
     , mStack(aStack)
     , mSaveRequested(false)
   {
     mProfile.addTag(ProfileEntry('m', "Start"));
   }
 
@@ -437,16 +447,18 @@ string ProfileEntry::TagToString(Profile
     }
   }
 #endif
   return tag;
 }
 
 #define PROFILE_DEFAULT_ENTRY 100000
 #define PROFILE_DEFAULT_INTERVAL 10
+#define PROFILE_DEFAULT_FEATURES NULL
+#define PROFILE_DEFAULT_FEATURE_COUNT 0
 
 void mozilla_sampler_init()
 {
   // TODO linux port: Use TLS with ifdefs
   if (!mozilla::tls::create(&pkey_stack) ||
       !mozilla::tls::create(&pkey_ticker)) {
     LOG("Failed to init.");
     return;
@@ -459,65 +471,77 @@ void mozilla_sampler_init()
   // We can't open pref so we use an environment variable
   // to know if we should trigger the profiler on startup
   // NOTE: Default
   const char *val = PR_GetEnv("MOZ_PROFILER_STARTUP");
   if (!val || !*val) {
     return;
   }
 
-  mozilla_sampler_start(PROFILE_DEFAULT_ENTRY, PROFILE_DEFAULT_INTERVAL);
+  mozilla_sampler_start(PROFILE_DEFAULT_ENTRY, PROFILE_DEFAULT_INTERVAL,
+                        PROFILE_DEFAULT_FEATURES, PROFILE_DEFAULT_FEATURE_COUNT);
 }
 
 void mozilla_sampler_deinit()
 {
   mozilla_sampler_stop();
   // We can't delete the Stack because we can be between a
   // sampler call_enter/call_exit point.
   // TODO Need to find a safe time to delete Stack
 }
 
-void mozilla_sampler_save() {
+void mozilla_sampler_save()
+{
   TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker);
   if (!t) {
     return;
   }
 
   t->RequestSave();
   // We're on the main thread already so we don't
   // have to wait to handle the save request.
   t->HandleSaveRequest();
 }
 
-char* mozilla_sampler_get_profile() {
+char* mozilla_sampler_get_profile()
+{
   TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker);
   if (!t) {
     return NULL;
   }
 
   StringBuilder profile;
   t->GetProfile()->ToString(profile);
 
   char *rtn = (char*)malloc( (profile.Length()+1) * sizeof(char) );
   strcpy(rtn, profile.Buffer());
   return rtn;
 }
 
+const char** mozilla_sampler_get_features()
+{
+  static const char* features[] = {""};
+
+  return features;
+}
+
 // Values are only honored on the first start
-void mozilla_sampler_start(int aProfileEntries, int aInterval)
+void mozilla_sampler_start(int aProfileEntries, int aInterval,
+                           const char** aFeatures, uint32_t aFeatureCount)
 {
   Stack *stack = mozilla::tls::get<Stack>(pkey_stack);
   if (!stack) {
     ASSERT(false);
     return;
   }
 
   mozilla_sampler_stop();
 
-  TableTicker *t = new TableTicker(aInterval, aProfileEntries, stack);
+  TableTicker *t = new TableTicker(aInterval, aProfileEntries, stack,
+                                   aFeatures, aFeatureCount);
   mozilla::tls::set(pkey_ticker, t);
   t->Start();
 }
 
 void mozilla_sampler_stop()
 {
   TableTicker *t = mozilla::tls::get<TableTicker>(pkey_ticker);
   if (!t) {
--- a/tools/profiler/sps/sps_sampler.h
+++ b/tools/profiler/sps/sps_sampler.h
@@ -46,23 +46,24 @@ using mozilla::TimeStamp;
 using mozilla::TimeDuration;
 
 extern mozilla::tls::key pkey_stack;
 extern mozilla::tls::key pkey_ticker;
 extern bool stack_key_initialized;
 
 #define SAMPLER_INIT() mozilla_sampler_init()
 #define SAMPLER_DEINIT() mozilla_sampler_deinit()
-#define SAMPLER_START(entries, interval) mozilla_sampler_start(entries, interval)
+#define SAMPLER_START(entries, interval, features, featureCount) mozilla_sampler_start(entries, interval, features, featureCount)
 #define SAMPLER_STOP() mozilla_sampler_stop()
 #define SAMPLER_IS_ACTIVE() mozilla_sampler_is_active()
 #define SAMPLER_RESPONSIVENESS(time) mozilla_sampler_responsiveness(time)
 #define SAMPLER_GET_RESPONSIVENESS() mozilla_sampler_get_responsiveness()
 #define SAMPLER_SAVE() mozilla_sampler_save()
 #define SAMPLER_GET_PROFILE() mozilla_sampler_get_profile()
+#define SAMPLER_GET_FEATURES() mozilla_sampler_get_features()
 #define SAMPLE_LABEL(name_space, info) mozilla::SamplerStackFrameRAII only_one_sampleraii_per_scope(FULLFUNCTION, name_space "::" info)
 #define SAMPLE_MARKER(info) mozilla_sampler_add_marker(info)
 
 /* we duplicate this code here to avoid header dependencies
  * which make it more difficult to include in other places */
 #if defined(_M_X64) || defined(__x86_64__)
 #define V8_HOST_ARCH_X64 1
 #elif defined(_M_IX86) || defined(__i386__) || defined(__i386)
@@ -109,23 +110,24 @@ LinuxKernelMemoryBarrierFunc pLinuxKerne
 #endif
 
 // Returns a handdle to pass on exit. This can check that we are popping the
 // correct callstack.
 inline void* mozilla_sampler_call_enter(const char *aInfo);
 inline void  mozilla_sampler_call_exit(void* handle);
 inline void  mozilla_sampler_add_marker(const char *aInfo);
 
-void mozilla_sampler_start(int aEntries, int aInterval);
+void mozilla_sampler_start(int aEntries, int aInterval, const char** aFeatures, uint32_t aFeatureCount);
 void mozilla_sampler_stop();
 bool mozilla_sampler_is_active();
 void mozilla_sampler_responsiveness(TimeStamp time);
 const double* mozilla_sampler_get_responsiveness();
 void mozilla_sampler_save();
 char* mozilla_sampler_get_profile();
+const char** mozilla_sampler_get_features();
 void mozilla_sampler_init();
 
 namespace mozilla {
 
 class NS_STACK_CLASS SamplerStackFrameRAII {
 public:
   SamplerStackFrameRAII(const char *aFuncName, const char *aInfo) {
     mHandle = mozilla_sampler_call_enter(aInfo);