BaseProfilerLabels.h (8589B)
1 /* -*- Mode: C++; tab-width: 2; 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 // This header contains all definitions related to Base Profiler labels (outside 8 // of XUL). 9 // It is safe to include unconditionally, and only defines empty macros if 10 // MOZ_GECKO_PROFILER is not set. 11 12 #ifndef BaseProfilerLabels_h 13 #define BaseProfilerLabels_h 14 15 #ifndef MOZ_GECKO_PROFILER 16 17 # define AUTO_BASE_PROFILER_LABEL(label, categoryPair) 18 # define AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(categoryPair) 19 # define AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr) 20 # define AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(label, categoryPair, str) 21 # define AUTO_BASE_PROFILER_LABEL_FAST(label, categoryPair, ctx) 22 # define AUTO_BASE_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, \ 23 categoryPair, ctx, flags) 24 25 #else // !MOZ_GECKO_PROFILER 26 27 # include "BaseProfilingStack.h" 28 29 # include "mozilla/Attributes.h" 30 # include "mozilla/Maybe.h" 31 # include "mozilla/BaseProfilerRAIIMacro.h" 32 # include "mozilla/BaseProfilerState.h" 33 # include "mozilla/ThreadLocal.h" 34 35 # include <stdint.h> 36 # include <string> 37 38 namespace mozilla::baseprofiler { 39 40 // Insert an RAII object in this scope to enter a label stack frame. Any 41 // samples collected in this scope will contain this label in their stack. 42 // The label argument must be a static C string. It is usually of the 43 // form "ClassName::FunctionName". (Ideally we'd use the compiler to provide 44 // that for us, but __func__ gives us the function name without the class 45 // name.) If the label applies to only part of a function, you can qualify it 46 // like this: "ClassName::FunctionName:PartName". 47 // 48 // Use AUTO_BASE_PROFILER_LABEL_DYNAMIC_* if you want to add additional / 49 // dynamic information to the label stack frame. 50 # define AUTO_BASE_PROFILER_LABEL(label, categoryPair) \ 51 ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \ 52 label, nullptr, \ 53 ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair) 54 55 // Similar to AUTO_BASE_PROFILER_LABEL, but with only one argument: the category 56 // pair. The label string is taken from the category pair. This is convenient 57 // for labels like 58 // AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_LayerBuilding) which would 59 // otherwise just repeat the string. 60 # define AUTO_BASE_PROFILER_LABEL_CATEGORY_PAIR(categoryPair) \ 61 ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \ 62 "", nullptr, \ 63 ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, \ 64 uint32_t(::mozilla::baseprofiler::ProfilingStackFrame::Flags:: \ 65 LABEL_DETERMINED_BY_CATEGORY_PAIR)) 66 67 // Similar to AUTO_BASE_PROFILER_LABEL, but with an additional string. The 68 // inserted RAII object stores the cStr pointer in a field; it does not copy the 69 // string. 70 // 71 // WARNING: This means that the string you pass to this macro needs to live at 72 // least until the end of the current scope. Be careful using this macro with 73 // ns[C]String; the other AUTO_BASE_PROFILER_LABEL_DYNAMIC_* macros below are 74 // preferred because they avoid this problem. 75 // 76 // If the profiler samples the current thread and walks the label stack while 77 // this RAII object is on the stack, it will copy the supplied string into the 78 // profile buffer. So there's one string copy operation, and it happens at 79 // sample time. 80 // 81 // Compare this to the plain AUTO_BASE_PROFILER_LABEL macro, which only accepts 82 // literal strings: When the label stack frames generated by 83 // AUTO_BASE_PROFILER_LABEL are sampled, no string copy needs to be made because 84 // the profile buffer can just store the raw pointers to the literal strings. 85 // Consequently, AUTO_BASE_PROFILER_LABEL frames take up considerably less space 86 // in the profile buffer than AUTO_BASE_PROFILER_LABEL_DYNAMIC_* frames. 87 # define AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR(label, categoryPair, cStr) \ 88 ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \ 89 label, cStr, \ 90 ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair) 91 92 // Similar to AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR, but takes an std::string. 93 // 94 // Note: The use of the Maybe<>s ensures the scopes for the dynamic string and 95 // the AutoProfilerLabel are appropriate, while also not incurring the runtime 96 // cost of the string assignment unless the profiler is active. Therefore, 97 // unlike AUTO_BASE_PROFILER_LABEL and AUTO_BASE_PROFILER_LABEL_DYNAMIC_CSTR, 98 // this macro doesn't push/pop a label when the profiler is inactive. 99 # define AUTO_BASE_PROFILER_LABEL_DYNAMIC_STRING(label, categoryPair, str) \ 100 Maybe<std::string> autoStr; \ 101 Maybe<::mozilla::baseprofiler::AutoProfilerLabel> raiiObjectString; \ 102 if (::mozilla::baseprofiler::profiler_is_active()) { \ 103 autoStr.emplace(str); \ 104 raiiObjectString.emplace( \ 105 label, autoStr->c_str(), \ 106 ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair); \ 107 } 108 109 // Similar to AUTO_BASE_PROFILER_LABEL, but accepting a JSContext* parameter, 110 // and a no-op if the profiler is disabled. Used to annotate functions for which 111 // overhead in the range of nanoseconds is noticeable. It avoids overhead from 112 // the TLS lookup because it can get the ProfilingStack from the JS context, and 113 // avoids almost all overhead in the case where the profiler is disabled. 114 # define AUTO_BASE_PROFILER_LABEL_FAST(label, categoryPair, ctx) \ 115 ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \ 116 ctx, label, nullptr, \ 117 ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair) 118 119 // Similar to AUTO_BASE_PROFILER_LABEL_FAST, but also takes an extra string and 120 // an additional set of flags. The flags parameter should carry values from the 121 // ProfilingStackFrame::Flags enum. 122 # define AUTO_BASE_PROFILER_LABEL_DYNAMIC_FAST(label, dynamicString, \ 123 categoryPair, ctx, flags) \ 124 ::mozilla::baseprofiler::AutoProfilerLabel PROFILER_RAII( \ 125 ctx, label, dynamicString, \ 126 ::mozilla::baseprofiler::ProfilingCategoryPair::categoryPair, flags) 127 128 // This class creates a non-owning ProfilingStack reference. Objects of this 129 // class are stack-allocated, and so exist within a thread, and are thus bounded 130 // by the lifetime of the thread, which ensures that the references held can't 131 // be used after the ProfilingStack is destroyed. 132 class MOZ_RAII AutoProfilerLabel { 133 public: 134 // This is the AUTO_BASE_PROFILER_LABEL and AUTO_BASE_PROFILER_LABEL_DYNAMIC 135 // variant. 136 AutoProfilerLabel(const char* aLabel, const char* aDynamicString, 137 ProfilingCategoryPair aCategoryPair, uint32_t aFlags = 0) { 138 // Get the ProfilingStack from TLS. 139 Push(GetProfilingStack(), aLabel, aDynamicString, aCategoryPair, aFlags); 140 } 141 142 void Push(ProfilingStack* aProfilingStack, const char* aLabel, 143 const char* aDynamicString, ProfilingCategoryPair aCategoryPair, 144 uint32_t aFlags = 0) { 145 // This function runs both on and off the main thread. 146 147 mProfilingStack = aProfilingStack; 148 if (mProfilingStack) { 149 mProfilingStack->pushLabelFrame(aLabel, aDynamicString, this, 150 aCategoryPair, aFlags); 151 } 152 } 153 154 ~AutoProfilerLabel() { 155 // This function runs both on and off the main thread. 156 157 if (mProfilingStack) { 158 mProfilingStack->pop(); 159 } 160 } 161 162 MFBT_API static ProfilingStack* GetProfilingStack(); 163 164 private: 165 // We save a ProfilingStack pointer in the ctor so we don't have to redo the 166 // TLS lookup in the dtor. 167 ProfilingStack* mProfilingStack; 168 169 public: 170 // See the comment on the definition in platform.cpp for details about this. 171 static MOZ_THREAD_LOCAL(ProfilingStack*) sProfilingStack; 172 }; 173 174 } // namespace mozilla::baseprofiler 175 176 #endif // !MOZ_GECKO_PROFILER 177 178 #endif // BaseProfilerLabels_h