Bug 1204167 - Create the js::AutoSPSEntry RAII class for defining psuedo frame entries; r=djvj
authorNick Fitzgerald <fitzgen@gmail.com>
Mon, 14 Sep 2015 12:15:12 -0700
changeset 295026 e49720fee5a534ee671d9ea68773a2437b7f7ce1
parent 295025 7e587a5822420e7a018b96830eff1059720b0654
child 295027 cd96a343381a64b663d16684a9c0a1aefdceca18
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs1204167
milestone43.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 1204167 - Create the js::AutoSPSEntry RAII class for defining psuedo frame entries; r=djvj
js/src/vm/SPSProfiler.cpp
js/src/vm/SPSProfiler.h
--- a/js/src/vm/SPSProfiler.cpp
+++ b/js/src/vm/SPSProfiler.cpp
@@ -255,30 +255,32 @@ SPSProfiler::beginPseudoJS(const char* s
         stack[current].setLabel(string);
         stack[current].setCppFrame(sp, 0);
         stack[current].setFlag(ProfileEntry::BEGIN_PSEUDO_JS);
     }
     *size = current + 1;
 }
 
 void
-SPSProfiler::push(const char* string, void* sp, JSScript* script, jsbytecode* pc, bool copy)
+SPSProfiler::push(const char* string, void* sp, JSScript* script, jsbytecode* pc, bool copy,
+                  ProfileEntry::Category category)
 {
     MOZ_ASSERT_IF(sp != nullptr, script == nullptr && pc == nullptr);
     MOZ_ASSERT_IF(sp == nullptr, script != nullptr && pc != nullptr);
 
     /* these operations cannot be re-ordered, so volatile-ize operations */
     volatile ProfileEntry* stack = stack_;
     volatile uint32_t* size = size_;
     uint32_t current = *size;
 
     MOZ_ASSERT(installed());
     if (current < max_) {
         volatile ProfileEntry& entry = stack[current];
         entry.setLabel(string);
+        entry.setCategory(category);
 
         if (sp != nullptr) {
             entry.setCppFrame(sp, 0);
             MOZ_ASSERT(entry.flags() == js::ProfileEntry::IS_CPP_ENTRY);
         }
         else {
             entry.setJsFrame(script, pc);
             MOZ_ASSERT(entry.flags() == 0);
@@ -379,16 +381,40 @@ SPSEntryMarker::~SPSEntryMarker()
     if (profiler == nullptr)
         return;
 
     profiler->pop();
     profiler->endPseudoJS();
     MOZ_ASSERT(size_before == *profiler->size_);
 }
 
+AutoSPSEntry::AutoSPSEntry(JSRuntime* rt, const char* label, ProfileEntry::Category category
+                           MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+    : profiler_(&rt->spsProfiler)
+{
+    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+    if (!profiler_->installed()) {
+        profiler_ = nullptr;
+        return;
+    }
+    sizeBefore_ = *profiler_->size_;
+    profiler_->beginPseudoJS(label, this);
+    profiler_->push(label, this, nullptr, nullptr, /* copy = */ false, category);
+}
+
+AutoSPSEntry::~AutoSPSEntry()
+{
+    if (!profiler_)
+        return;
+
+    profiler_->pop();
+    profiler_->endPseudoJS();
+    MOZ_ASSERT(sizeBefore_ == *profiler_->size_);
+}
+
 SPSBaselineOSRMarker::SPSBaselineOSRMarker(JSRuntime* rt, bool hasSPSFrame
                                            MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
     : profiler(&rt->spsProfiler)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     if (!hasSPSFrame || !profiler->enabled() ||
         profiler->size() >= profiler->maxSize())
     {
--- a/js/src/vm/SPSProfiler.h
+++ b/js/src/vm/SPSProfiler.h
@@ -101,41 +101,42 @@
  * this in place, only the top entry of the stack can ever have nullptr as its
  * pc. Additionally with this invariant, it is possible to maintain mappings of
  * JIT code to pc which can be accessed safely because they will only be
  * accessed from a signal handler when the JIT code is executing.
  */
 
 namespace js {
 
-class ProfileEntry;
-
 typedef HashMap<JSScript*, const char*, DefaultHasher<JSScript*>, SystemAllocPolicy>
         ProfileStringMap;
 
+class AutoSPSEntry;
 class SPSEntryMarker;
 class SPSBaselineOSRMarker;
 
 class SPSProfiler
 {
+    friend class AutoSPSEntry;
     friend class SPSEntryMarker;
     friend class SPSBaselineOSRMarker;
 
     JSRuntime*           rt;
     ProfileStringMap     strings;
     ProfileEntry*        stack_;
     uint32_t*            size_;
     uint32_t             max_;
     bool                 slowAssertions;
     uint32_t             enabled_;
     PRLock*              lock_;
     void                (*eventMarker_)(const char*);
 
     const char* allocProfileString(JSScript* script, JSFunction* function);
-    void push(const char* string, void* sp, JSScript* script, jsbytecode* pc, bool copy);
+    void push(const char* string, void* sp, JSScript* script, jsbytecode* pc, bool copy,
+              ProfileEntry::Category category = ProfileEntry::Category::JS);
     void pop();
 
   public:
     explicit SPSProfiler(JSRuntime* rt);
     ~SPSProfiler();
 
     bool init();
 
@@ -270,16 +271,35 @@ class MOZ_RAII SPSEntryMarker
 
   private:
     SPSProfiler* profiler;
     mozilla::DebugOnly<uint32_t> size_before;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 /*
+ * RAII class to automatically add SPS psuedo frame entries.
+ *
+ * NB: The `label` string must be statically allocated.
+ */
+class MOZ_NONHEAP_CLASS AutoSPSEntry
+{
+  public:
+    explicit AutoSPSEntry(JSRuntime* rt, const char* label,
+                          ProfileEntry::Category category = ProfileEntry::Category::JS
+                          MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+    ~AutoSPSEntry();
+
+  private:
+    SPSProfiler* profiler_;
+    mozilla::DebugOnly<uint32_t> sizeBefore_;
+    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
+};
+
+/*
  * This class is used in the interpreter to bound regions where the baseline JIT
  * being entered via OSR.  It marks the current top pseudostack entry as
  * OSR-ed
  */
 class MOZ_RAII SPSBaselineOSRMarker
 {
   public:
     explicit SPSBaselineOSRMarker(JSRuntime* rt, bool hasSPSFrame