js/public/ProfilingStack.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial