js/public/ProfilingStack.h

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #ifndef js_ProfilingStack_h
     8 #define js_ProfilingStack_h
    10 #include "mozilla/NullPtr.h"
    12 #include "jsbytecode.h"
    13 #include "jstypes.h"
    15 #include "js/Utility.h"
    17 struct JSRuntime;
    19 namespace js {
    21 // A call stack can be specified to the JS engine such that all JS entry/exits
    22 // to functions push/pop an entry to/from the specified stack.
    23 //
    24 // For more detailed information, see vm/SPSProfiler.h.
    25 //
    26 class ProfileEntry
    27 {
    28     // All fields are marked volatile to prevent the compiler from re-ordering
    29     // instructions. Namely this sequence:
    30     //
    31     //    entry[size] = ...;
    32     //    size++;
    33     //
    34     // If the size modification were somehow reordered before the stores, then
    35     // if a sample were taken it would be examining bogus information.
    36     //
    37     // A ProfileEntry represents both a C++ profile entry and a JS one. Both use
    38     // the string as a description, but JS uses the sp as nullptr or (void*)1 to
    39     // indicate that it is a JS entry. The script_ is then only ever examined for
    40     // a JS entry, and the idx is used by both, but with different meanings.
    41     //
    42     const char * volatile string; // Descriptive string of this entry
    43     void * volatile sp;           // Relevant stack pointer for the entry,
    44                                   // less than or equal to SCRIPT_OPT_STACKPOINTER for js
    45                                   // script entries, greater for non-js entries.
    46     JSScript * volatile script_;  // if js(), non-null script which is running - low bit
    47                                   // indicates if script is optimized or not.
    48     int32_t volatile idx;         // if js(), idx of pc, otherwise line number
    50   public:
    51     static const uintptr_t SCRIPT_OPT_STACKPOINTER = 0x1;
    53     // All of these methods are marked with the 'volatile' keyword because SPS's
    54     // representation of the stack is stored such that all ProfileEntry
    55     // instances are volatile. These methods would not be available unless they
    56     // were marked as volatile as well.
    58     bool js() const volatile {
    59         MOZ_ASSERT_IF(uintptr_t(sp) <= SCRIPT_OPT_STACKPOINTER, script_ != nullptr);
    60         return uintptr_t(sp) <= SCRIPT_OPT_STACKPOINTER;
    61     }
    63     uint32_t line() const volatile { MOZ_ASSERT(!js()); return idx; }
    64     JSScript *script() const volatile { MOZ_ASSERT(js()); return script_; }
    65     bool scriptIsOptimized() const volatile {
    66         MOZ_ASSERT(js());
    67         return uintptr_t(sp) <= SCRIPT_OPT_STACKPOINTER;
    68     }
    69     void *stackAddress() const volatile {
    70         if (js())
    71             return nullptr;
    72         return sp;
    73     }
    74     const char *label() const volatile { return string; }
    76     void setLine(uint32_t aLine) volatile { MOZ_ASSERT(!js()); idx = aLine; }
    77     void setLabel(const char *aString) volatile { string = aString; }
    78     void setStackAddress(void *aSp) volatile { sp = aSp; }
    79     void setScript(JSScript *aScript) volatile { script_ = aScript; }
    81     // We can't know the layout of JSScript, so look in vm/SPSProfiler.cpp.
    82     JS_FRIEND_API(jsbytecode *) pc() const volatile;
    83     JS_FRIEND_API(void) setPC(jsbytecode *pc) volatile;
    85     static size_t offsetOfString() { return offsetof(ProfileEntry, string); }
    86     static size_t offsetOfStackAddress() { return offsetof(ProfileEntry, sp); }
    87     static size_t offsetOfPCIdx() { return offsetof(ProfileEntry, idx); }
    88     static size_t offsetOfScript() { return offsetof(ProfileEntry, script_); }
    90     // The index used in the entry can either be a line number or the offset of
    91     // a pc into a script's code. To signify a nullptr pc, use a -1 index. This
    92     // is checked against in pc() and setPC() to set/get the right pc.
    93     static const int32_t NullPCIndex = -1;
    95     // This bit is added to the stack address to indicate that copying the
    96     // frame label is not necessary when taking a sample of the pseudostack.
    97     static const uintptr_t NoCopyBit = 1;
    98 };
   100 JS_FRIEND_API(void)
   101 SetRuntimeProfilingStack(JSRuntime *rt, ProfileEntry *stack, uint32_t *size,
   102                          uint32_t max);
   104 JS_FRIEND_API(void)
   105 EnableRuntimeProfilingStack(JSRuntime *rt, bool enabled);
   107 JS_FRIEND_API(void)
   108 RegisterRuntimeProfilingEventMarker(JSRuntime *rt, void (*fn)(const char *));
   110 JS_FRIEND_API(jsbytecode*)
   111 ProfilingGetPC(JSRuntime *rt, JSScript *script, void *ip);
   113 } // namespace js
   115 #endif  /* js_ProfilingStack_h */

mercurial