GeckoProfiler.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /* *************** SPS Sampler Information ****************
  6. *
  7. * SPS is an always on profiler that takes fast and low overheads samples
  8. * of the program execution using only userspace functionity for portability.
  9. * The goal of this module is to provide performance data in a generic
  10. * cross platform way without requiring custom tools or kernel support.
  11. *
  12. * Non goals: Support features that are platform specific or replace
  13. * platform specific profilers.
  14. *
  15. * Samples are collected to form a timeline with optional timeline event (markers)
  16. * used for filtering.
  17. *
  18. * SPS collects samples in a platform independant way by using a speudo stack abstraction
  19. * of the real program stack by using 'sample stack frames'. When a sample is collected
  20. * all active sample stack frames and the program counter are recorded.
  21. */
  22. /* *************** SPS Sampler File Format ****************
  23. *
  24. * Simple new line seperated tag format:
  25. * S -> BOF tags EOF
  26. * tags -> tag tags
  27. * tag -> CHAR - STRING
  28. *
  29. * Tags:
  30. * 's' - Sample tag followed by the first stack frame followed by 0 or more 'c' tags.
  31. * 'c' - Continue Sample tag gives remaining tag element. If a 'c' tag is seen without
  32. * a preceding 's' tag it should be ignored. This is to support the behavior
  33. * of circular buffers.
  34. * If the 'stackwalk' feature is enabled this tag will have the format
  35. * 'l-<library name>@<hex address>' and will expect an external tool to translate
  36. * the tag into something readable through a symbolication processing step.
  37. * 'm' - Timeline marker. Zero or more may appear before a 's' tag.
  38. * 'l' - Information about the program counter library and address. Post processing
  39. * can include function and source line. If built with leaf data enabled
  40. * this tag will describe the last 'c' tag.
  41. * 'r' - Responsiveness tag following an 's' tag. Gives an indication on how well the
  42. * application is responding to the event loop. Lower is better.
  43. * 't' - Elapse time since recording started.
  44. *
  45. */
  46. #ifndef SAMPLER_H
  47. #define SAMPLER_H
  48. #include "mozilla/Assertions.h"
  49. #include "mozilla/Attributes.h"
  50. #ifndef SPS_STANDALONE
  51. #include "js/TypeDecls.h"
  52. #endif
  53. #include "mozilla/UniquePtr.h"
  54. #include "mozilla/Vector.h"
  55. namespace mozilla {
  56. class TimeStamp;
  57. namespace dom {
  58. class Promise;
  59. } // namespace dom
  60. } // namespace mozilla
  61. #ifndef SPS_STANDALONE
  62. class nsIProfilerStartParams;
  63. #endif
  64. enum TracingMetadata {
  65. TRACING_DEFAULT,
  66. TRACING_INTERVAL_START,
  67. TRACING_INTERVAL_END,
  68. TRACING_EVENT,
  69. TRACING_EVENT_BACKTRACE,
  70. TRACING_TIMESTAMP
  71. };
  72. #include <stdint.h>
  73. #include <stdarg.h>
  74. // Insert a RAII in this scope to active a pseudo label. Any samples collected
  75. // in this scope will contain this annotation. For dynamic strings use
  76. // PROFILER_LABEL_PRINTF. Arguments must be string literals.
  77. #define PROFILER_LABEL(name_space, info, category) do {} while (0)
  78. // Similar to PROFILER_LABEL, PROFILER_LABEL_FUNC will push/pop the enclosing
  79. // functon name as the pseudostack label.
  80. #define PROFILER_LABEL_FUNC(category) do {} while (0)
  81. // Format a dynamic string as a pseudo label. These labels will a considerable
  82. // storage size in the circular buffer compared to regular labels. This function
  83. // can be used to annotate custom information such as URL for the resource being
  84. // decoded or the size of the paint.
  85. #define PROFILER_LABEL_PRINTF(name_space, info, category, format, ...) do {} while (0)
  86. // Insert a marker in the profile timeline. This is useful to delimit something
  87. // important happening such as the first paint. Unlike profiler_label that are
  88. // only recorded if a sample is collected while it is active, marker will always
  89. // be collected.
  90. #define PROFILER_MARKER(info) do {} while (0)
  91. #define PROFILER_MARKER_PAYLOAD(info, payload) do { mozilla::UniquePtr<ProfilerMarkerPayload> payloadDeletor(payload); } while (0)
  92. // Main thread specilization to avoid TLS lookup for performance critical use.
  93. #define PROFILER_MAIN_THREAD_LABEL(name_space, info, category) do {} while (0)
  94. #define PROFILER_MAIN_THREAD_LABEL_PRINTF(name_space, info, category, format, ...) do {} while (0)
  95. static inline void profiler_tracing(const char* aCategory, const char* aInfo,
  96. TracingMetadata metaData = TRACING_DEFAULT) {}
  97. class ProfilerBacktrace;
  98. static inline void profiler_tracing(const char* aCategory, const char* aInfo,
  99. ProfilerBacktrace* aCause,
  100. TracingMetadata metaData = TRACING_DEFAULT) {}
  101. // Initilize the profiler TLS, signal handlers on linux. If MOZ_PROFILER_STARTUP
  102. // is set the profiler will be started. This call must happen before any other
  103. // sampler calls. Particularly sampler_label/sampler_marker.
  104. static inline void profiler_init(void* stackTop) {};
  105. // Clean up the profiler module, stopping it if required. This function may
  106. // also save a shutdown profile if requested. No profiler calls should happen
  107. // after this point and all pseudo labels should have been popped.
  108. static inline void profiler_shutdown() {};
  109. // Start the profiler with the selected options. The samples will be
  110. // recorded in a circular buffer.
  111. // "aProfileEntries" is an abstract size indication of how big
  112. // the profile's circular buffer should be. Multiply by 4
  113. // words to get the cost.
  114. // "aInterval" the sampling interval. The profiler will do its
  115. // best to sample at this interval. The profiler visualization
  116. // should represent the actual sampling accuracy.
  117. static inline void profiler_start(int aProfileEntries, double aInterval,
  118. const char** aFeatures, uint32_t aFeatureCount,
  119. const char** aThreadNameFilters, uint32_t aFilterCount) {}
  120. // Stop the profiler and discard the profile. Call 'profiler_save' before this
  121. // to retrieve the profile.
  122. static inline void profiler_stop() {}
  123. // These functions pause and resume the profiler. While paused the profile will not
  124. // take any samples and will not record any data into its buffers. The profiler
  125. // remains fully initialized in this state. Timeline markers will still be stored.
  126. // This feature will keep javascript profiling enabled, thus allowing toggling the
  127. // profiler without invalidating the JIT.
  128. static inline bool profiler_is_paused() { return false; }
  129. static inline void profiler_pause() {}
  130. static inline void profiler_resume() {}
  131. // Immediately capture the current thread's call stack and return it
  132. static inline ProfilerBacktrace* profiler_get_backtrace() { return nullptr; }
  133. static inline void profiler_get_backtrace_noalloc(char *output, size_t outputSize) { return; }
  134. // Free a ProfilerBacktrace returned by profiler_get_backtrace()
  135. static inline void profiler_free_backtrace(ProfilerBacktrace* aBacktrace) {}
  136. static inline bool profiler_is_active() { return false; }
  137. // Check if an external profiler feature is active.
  138. // Supported:
  139. // * gpu
  140. static inline bool profiler_feature_active(const char*) { return false; }
  141. // Internal-only. Used by the event tracer.
  142. static inline void profiler_responsiveness(const mozilla::TimeStamp& aTime) {}
  143. // Internal-only.
  144. static inline void profiler_set_frame_number(int frameNumber) {}
  145. // Get the profile encoded as a JSON string.
  146. static inline mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0) {
  147. return nullptr;
  148. }
  149. // Get the profile encoded as a JSON object.
  150. static inline JSObject* profiler_get_profile_jsobject(JSContext* aCx,
  151. double aSinceTime = 0) {
  152. return nullptr;
  153. }
  154. #ifndef SPS_STANDALONE
  155. // Get the profile encoded as a JSON object.
  156. static inline void profiler_get_profile_jsobject_async(double aSinceTime = 0,
  157. mozilla::dom::Promise* = 0) {}
  158. static inline void profiler_get_start_params(int* aEntrySize,
  159. double* aInterval,
  160. mozilla::Vector<const char*>* aFilters,
  161. mozilla::Vector<const char*>* aFeatures) {}
  162. #endif
  163. // Get the profile and write it into a file
  164. static inline void profiler_save_profile_to_file(char* aFilename) { }
  165. // Get the features supported by the profiler that are accepted by profiler_init.
  166. // Returns a null terminated char* array.
  167. static inline char** profiler_get_features() { return nullptr; }
  168. // Get information about the current buffer status.
  169. // Retursn (using outparams) the current write position in the buffer,
  170. // the total size of the buffer, and the generation of the buffer.
  171. // This information may be useful to a user-interface displaying the
  172. // current status of the profiler, allowing the user to get a sense
  173. // for how fast the buffer is being written to, and how much
  174. // data is visible.
  175. static inline void profiler_get_buffer_info(uint32_t *aCurrentPosition,
  176. uint32_t *aTotalSize,
  177. uint32_t *aGeneration)
  178. {
  179. *aCurrentPosition = 0;
  180. *aTotalSize = 0;
  181. *aGeneration = 0;
  182. }
  183. // Discard the profile, throw away the profile and notify 'profiler-locked'.
  184. // This function is to be used when entering private browsing to prevent
  185. // the profiler from collecting sensitive data.
  186. static inline void profiler_lock() {}
  187. // Re-enable the profiler and notify 'profiler-unlocked'.
  188. static inline void profiler_unlock() {}
  189. static inline void profiler_register_thread(const char* name, void* guessStackTop) {}
  190. static inline void profiler_unregister_thread() {}
  191. // These functions tell the profiler that a thread went to sleep so that we can avoid
  192. // sampling it while it's sleeping. Calling profiler_sleep_start() twice without
  193. // profiler_sleep_end() is an error.
  194. static inline void profiler_sleep_start() {}
  195. static inline void profiler_sleep_end() {}
  196. static inline bool profiler_is_sleeping() { return false; }
  197. // Call by the JSRuntime's operation callback. This is used to enable
  198. // profiling on auxilerary threads.
  199. static inline void profiler_js_operation_callback() {}
  200. static inline double profiler_time() { return 0; }
  201. static inline double profiler_time(const mozilla::TimeStamp& aTime) { return 0; }
  202. static inline bool profiler_in_privacy_mode() { return false; }
  203. static inline void profiler_log(const char *str) {}
  204. static inline void profiler_log(const char *fmt, va_list args) {}
  205. class MOZ_RAII GeckoProfilerInitRAII {
  206. public:
  207. explicit GeckoProfilerInitRAII(void* stackTop) {
  208. profiler_init(stackTop);
  209. }
  210. ~GeckoProfilerInitRAII() {
  211. profiler_shutdown();
  212. }
  213. };
  214. class MOZ_RAII GeckoProfilerSleepRAII {
  215. public:
  216. GeckoProfilerSleepRAII() {
  217. profiler_sleep_start();
  218. }
  219. ~GeckoProfilerSleepRAII() {
  220. profiler_sleep_end();
  221. }
  222. };
  223. /**
  224. * Temporarily wake up the profiler while servicing events such as
  225. * Asynchronous Procedure Calls (APCs).
  226. */
  227. class MOZ_RAII GeckoProfilerWakeRAII {
  228. public:
  229. GeckoProfilerWakeRAII()
  230. : mIssuedWake(profiler_is_sleeping())
  231. {
  232. if (mIssuedWake) {
  233. profiler_sleep_end();
  234. }
  235. }
  236. ~GeckoProfilerWakeRAII() {
  237. if (mIssuedWake) {
  238. MOZ_ASSERT(!profiler_is_sleeping());
  239. profiler_sleep_start();
  240. }
  241. }
  242. private:
  243. bool mIssuedWake;
  244. };
  245. #endif // ifndef SAMPLER_H