GeckoProfiler-inl.h (4273B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 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/. */ 6 7 #ifndef vm_GeckoProfiler_inl_h 8 #define vm_GeckoProfiler_inl_h 9 10 #include "vm/GeckoProfiler.h" 11 12 #include "js/ProfilingStack.h" 13 #include "vm/JSContext.h" 14 #include "vm/Realm.h" 15 #include "vm/Runtime.h" 16 17 namespace js { 18 19 inline void GeckoProfilerThread::updatePC(JSContext* cx, JSScript* script, 20 jsbytecode* pc) { 21 if (!cx->runtime()->geckoProfiler().enabled()) { 22 return; 23 } 24 25 uint32_t sp = profilingStack_->stackPointer; 26 if (sp - 1 < profilingStack_->stackCapacity()) { 27 MOZ_ASSERT(sp > 0); 28 MOZ_ASSERT(profilingStack_->frames[sp - 1].rawScript() == script); 29 profilingStack_->frames[sp - 1].setPC(pc); 30 } 31 } 32 33 /* 34 * This class is used to suppress profiler sampling during 35 * critical sections where stack state is not valid. 36 */ 37 class MOZ_RAII AutoSuppressProfilerSampling { 38 public: 39 explicit AutoSuppressProfilerSampling(JSContext* cx); 40 41 ~AutoSuppressProfilerSampling(); 42 43 private: 44 JSContext* cx_; 45 bool previouslyEnabled_; 46 }; 47 48 MOZ_ALWAYS_INLINE 49 GeckoProfilerEntryMarker::GeckoProfilerEntryMarker(JSContext* cx, 50 JSScript* script) 51 : profiler_(&cx->geckoProfiler()) { 52 if (MOZ_LIKELY(!profiler_->infraInstalled())) { 53 profiler_ = nullptr; 54 #ifdef DEBUG 55 spBefore_ = 0; 56 #endif 57 return; 58 } 59 #ifdef DEBUG 60 spBefore_ = profiler_->stackPointer(); 61 #endif 62 63 // Push an sp marker frame so the profiler can correctly order JS and native 64 // stacks. 65 profiler_->profilingStack_->pushSpMarkerFrame(this); 66 67 profiler_->profilingStack_->pushJsFrame( 68 "js::RunScript", 69 /* dynamicString = */ nullptr, script, script->code(), 70 script->realm()->creationOptions().profilerRealmID()); 71 } 72 73 MOZ_ALWAYS_INLINE 74 GeckoProfilerEntryMarker::~GeckoProfilerEntryMarker() { 75 if (MOZ_LIKELY(profiler_ == nullptr)) { 76 return; 77 } 78 79 profiler_->profilingStack_->pop(); // the JS frame 80 profiler_->profilingStack_->pop(); // the SP_MARKER frame 81 MOZ_ASSERT(spBefore_ == profiler_->stackPointer()); 82 } 83 84 MOZ_ALWAYS_INLINE 85 AutoGeckoProfilerEntry::AutoGeckoProfilerEntry( 86 JSContext* cx, const char* label, const char* dynamicString, 87 JS::ProfilingCategoryPair categoryPair, uint32_t flags) { 88 profilingStack_ = GetContextProfilingStackIfEnabled(cx); 89 if (MOZ_LIKELY(!profilingStack_)) { 90 #ifdef DEBUG 91 profiler_ = nullptr; 92 spBefore_ = 0; 93 #endif 94 return; 95 } 96 97 #ifdef DEBUG 98 profiler_ = &cx->geckoProfiler(); 99 spBefore_ = profiler_->stackPointer(); 100 #endif 101 102 profilingStack_->pushLabelFrame(label, dynamicString, 103 /* sp = */ this, categoryPair, flags); 104 } 105 106 MOZ_ALWAYS_INLINE 107 AutoGeckoProfilerEntry::~AutoGeckoProfilerEntry() { 108 if (MOZ_LIKELY(!profilingStack_)) { 109 return; 110 } 111 112 profilingStack_->pop(); 113 MOZ_ASSERT(spBefore_ == profiler_->stackPointer()); 114 } 115 116 MOZ_ALWAYS_INLINE 117 AutoGeckoProfilerEntry::AutoGeckoProfilerEntry( 118 JSContext* cx, const char* label, JS::ProfilingCategoryPair categoryPair, 119 uint32_t flags) 120 : AutoGeckoProfilerEntry(cx, label, /* dynamicString */ nullptr, 121 categoryPair, flags) {} 122 123 MOZ_ALWAYS_INLINE 124 AutoJSMethodProfilerEntry::AutoJSMethodProfilerEntry(JSContext* cx, 125 const char* label, 126 const char* dynamicString) 127 : AutoGeckoProfilerEntry( 128 cx, label, dynamicString, JS::ProfilingCategoryPair::JS_Builtin, 129 uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS) | 130 uint32_t(ProfilingStackFrame::Flags::STRING_TEMPLATE_METHOD)) {} 131 132 MOZ_ALWAYS_INLINE 133 AutoJSConstructorProfilerEntry::AutoJSConstructorProfilerEntry( 134 JSContext* cx, const char* label) 135 : AutoGeckoProfilerEntry( 136 cx, label, "constructor", JS::ProfilingCategoryPair::JS_Builtin, 137 uint32_t(ProfilingStackFrame::Flags::RELEVANT_FOR_JS)) {} 138 139 } // namespace js 140 141 #endif // vm_GeckoProfiler_inl_h