Bug 974980 - Always push a js:RunScript frame in pseudostack; r=BenWa
authorJim Chen <nchen@mozilla.com>
Mon, 24 Feb 2014 12:27:58 -0500
changeset 170562 33f11ad7ef1ee565f40af4ed1ad289bc8ef0f437
parent 170561 ba82c75ac11c978784adc5cea92890cf255eb7b8
child 170563 5609571991994bbc2c55e5430b53b23378b87def
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersBenWa
bugs974980
milestone30.0a1
Bug 974980 - Always push a js:RunScript frame in pseudostack; r=BenWa
js/public/ProfilingStack.h
js/src/vm/SPSProfiler.cpp
js/src/vm/SPSProfiler.h
tools/profiler/PseudoStack.h
--- a/js/public/ProfilingStack.h
+++ b/js/public/ProfilingStack.h
@@ -73,16 +73,20 @@ class ProfileEntry
     static size_t offsetOfStackAddress() { return offsetof(ProfileEntry, sp); }
     static size_t offsetOfPCIdx() { return offsetof(ProfileEntry, idx); }
     static size_t offsetOfScript() { return offsetof(ProfileEntry, script_); }
 
     // The index used in the entry can either be a line number or the offset of
     // a pc into a script's code. To signify a nullptr pc, use a -1 index. This
     // is checked against in pc() and setPC() to set/get the right pc.
     static const int32_t NullPCIndex = -1;
+
+    // This bit is added to the stack address to indicate that copying the
+    // frame label is not necessary when taking a sample of the pseudostack.
+    static const uintptr_t NoCopyBit = 1;
 };
 
 JS_FRIEND_API(void)
 SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size,
                          uint32_t max);
 
 JS_FRIEND_API(void)
 EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled);
--- a/js/src/vm/SPSProfiler.cpp
+++ b/js/src/vm/SPSProfiler.cpp
@@ -207,17 +207,17 @@ SPSProfiler::enterNative(const char *str
 void
 SPSProfiler::push(const char *string, void *sp, JSScript *script, jsbytecode *pc)
 {
     /* these operations cannot be re-ordered, so volatile-ize operations */
     volatile ProfileEntry *stack = stack_;
     volatile uint32_t *size = size_;
     uint32_t current = *size;
 
-    JS_ASSERT(enabled());
+    JS_ASSERT(installed());
     if (current < max_) {
         stack[current].setLabel(string);
         stack[current].setStackAddress(sp);
         stack[current].setScript(script);
         stack[current].setPC(pc);
     }
     *size = current + 1;
 }
@@ -286,22 +286,22 @@ SPSProfiler::allocProfileString(JSScript
     return cstr;
 }
 
 SPSEntryMarker::SPSEntryMarker(JSRuntime *rt
                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
     : profiler(&rt->spsProfiler)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    if (!profiler->enabled()) {
+    if (!profiler->installed()) {
         profiler = nullptr;
         return;
     }
     size_before = *profiler->size_;
-    profiler->push("js::RunScript", this, nullptr, nullptr);
+    profiler->pushNoCopy("js::RunScript", this, nullptr, nullptr);
 }
 
 SPSEntryMarker::~SPSEntryMarker()
 {
     if (profiler != nullptr) {
         profiler->pop();
         JS_ASSERT(size_before == *profiler->size_);
     }
--- a/js/src/vm/SPSProfiler.h
+++ b/js/src/vm/SPSProfiler.h
@@ -123,16 +123,22 @@ class SPSProfiler
     uint32_t             *size_;
     uint32_t             max_;
     bool                 slowAssertions;
     uint32_t             enabled_;
     PRLock               *lock_;
 
     const char *allocProfileString(JSScript *script, JSFunction *function);
     void push(const char *string, void *sp, JSScript *script, jsbytecode *pc);
+    void pushNoCopy(const char *string, void *sp,
+                    JSScript *script, jsbytecode *pc) {
+        push(string, reinterpret_cast<void*>(
+            reinterpret_cast<uintptr_t>(sp) | ProfileEntry::NoCopyBit),
+            script, pc);
+    }
     void pop();
 
   public:
     SPSProfiler(JSRuntime *rt);
     ~SPSProfiler();
 
     bool init();
 
--- a/tools/profiler/PseudoStack.h
+++ b/tools/profiler/PseudoStack.h
@@ -88,20 +88,20 @@ public:
   void setStackAddressCopy(void *sparg, bool copy) volatile {
     // Tagged pointer. Less significant bit used to track if mLabel needs a
     // copy. Note that we don't need the last bit of the stack address for
     // proper ordering. This is optimized for encoding within the JS engine's
     // instrumentation, so we do the extra work here of encoding a bit.
     // Last bit 1 = Don't copy, Last bit 0 = Copy.
     if (copy) {
       setStackAddress(reinterpret_cast<void*>(
-                        reinterpret_cast<uintptr_t>(sparg) & ~0x1));
+                        reinterpret_cast<uintptr_t>(sparg) & ~NoCopyBit));
     } else {
       setStackAddress(reinterpret_cast<void*>(
-                        reinterpret_cast<uintptr_t>(sparg) | 0x1));
+                        reinterpret_cast<uintptr_t>(sparg) | NoCopyBit));
     }
   }
 };
 
 class ProfilerMarkerPayload;
 template<typename T>
 class ProfilerLinkedList;
 class JSAObjectBuilder;