1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/profiler/GeckoProfiler.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,218 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* *************** SPS Sampler Information **************** 1.10 + * 1.11 + * SPS is an always on profiler that takes fast and low overheads samples 1.12 + * of the program execution using only userspace functionity for portability. 1.13 + * The goal of this module is to provide performance data in a generic 1.14 + * cross platform way without requiring custom tools or kernel support. 1.15 + * 1.16 + * Non goals: Support features that are platform specific or replace 1.17 + * platform specific profilers. 1.18 + * 1.19 + * Samples are collected to form a timeline with optional timeline event (markers) 1.20 + * used for filtering. 1.21 + * 1.22 + * SPS collects samples in a platform independant way by using a speudo stack abstraction 1.23 + * of the real program stack by using 'sample stack frames'. When a sample is collected 1.24 + * all active sample stack frames and the program counter are recorded. 1.25 + */ 1.26 + 1.27 +/* *************** SPS Sampler File Format **************** 1.28 + * 1.29 + * Simple new line seperated tag format: 1.30 + * S -> BOF tags EOF 1.31 + * tags -> tag tags 1.32 + * tag -> CHAR - STRING 1.33 + * 1.34 + * Tags: 1.35 + * 's' - Sample tag followed by the first stack frame followed by 0 or more 'c' tags. 1.36 + * 'c' - Continue Sample tag gives remaining tag element. If a 'c' tag is seen without 1.37 + * a preceding 's' tag it should be ignored. This is to support the behavior 1.38 + * of circular buffers. 1.39 + * If the 'stackwalk' feature is enabled this tag will have the format 1.40 + * 'l-<library name>@<hex address>' and will expect an external tool to translate 1.41 + * the tag into something readable through a symbolication processing step. 1.42 + * 'm' - Timeline marker. Zero or more may appear before a 's' tag. 1.43 + * 'l' - Information about the program counter library and address. Post processing 1.44 + * can include function and source line. If built with leaf data enabled 1.45 + * this tag will describe the last 'c' tag. 1.46 + * 'r' - Responsiveness tag following an 's' tag. Gives an indication on how well the 1.47 + * application is responding to the event loop. Lower is better. 1.48 + * 't' - Elapse time since recording started. 1.49 + * 1.50 + */ 1.51 + 1.52 +#ifndef SAMPLER_H 1.53 +#define SAMPLER_H 1.54 + 1.55 +#include "mozilla/NullPtr.h" 1.56 +#include "js/TypeDecls.h" 1.57 + 1.58 +namespace mozilla { 1.59 +class TimeStamp; 1.60 +} 1.61 + 1.62 +enum TracingMetadata { 1.63 + TRACING_DEFAULT, 1.64 + TRACING_INTERVAL_START, 1.65 + TRACING_INTERVAL_END 1.66 +}; 1.67 + 1.68 +#ifndef MOZ_ENABLE_PROFILER_SPS 1.69 + 1.70 +#include <stdint.h> 1.71 + 1.72 +// Insert a RAII in this scope to active a pseudo label. Any samples collected 1.73 +// in this scope will contain this annotation. For dynamic strings use 1.74 +// PROFILER_LABEL_PRINTF. Arguments must be string literals. 1.75 +#define PROFILER_LABEL(name_space, info) do {} while (0) 1.76 + 1.77 +// Format a dynamic string as a pseudo label. These labels will a considerable 1.78 +// storage size in the circular buffer compared to regular labels. This function 1.79 +// can be used to annotate custom information such as URL for the resource being 1.80 +// decoded or the size of the paint. 1.81 +#define PROFILER_LABEL_PRINTF(name_space, info, format, ...) do {} while (0) 1.82 + 1.83 +// Insert a marker in the profile timeline. This is useful to delimit something 1.84 +// important happening such as the first paint. Unlike profiler_label that are 1.85 +// only recorded if a sample is collected while it is active, marker will always 1.86 +// be collected. 1.87 +#define PROFILER_MARKER(info) do {} while (0) 1.88 +#define PROFILER_MARKER_PAYLOAD(info, payload) do {} while (0) 1.89 + 1.90 +// Main thread specilization to avoid TLS lookup for performance critical use. 1.91 +#define PROFILER_MAIN_THREAD_LABEL(name_space, info) do {} while (0) 1.92 +#define PROFILER_MAIN_THREAD_LABEL_PRINTF(name_space, info, format, ...) do {} while (0) 1.93 + 1.94 +static inline void profiler_tracing(const char* aCategory, const char* aInfo, 1.95 + TracingMetadata metaData = TRACING_DEFAULT) {} 1.96 + 1.97 +// Initilize the profiler TLS, signal handlers on linux. If MOZ_PROFILER_STARTUP 1.98 +// is set the profiler will be started. This call must happen before any other 1.99 +// sampler calls. Particularly sampler_label/sampler_marker. 1.100 +static inline void profiler_init(void* stackTop) {}; 1.101 + 1.102 +// Clean up the profiler module, stopping it if required. This function may 1.103 +// also save a shutdown profile if requested. No profiler calls should happen 1.104 +// after this point and all pseudo labels should have been popped. 1.105 +static inline void profiler_shutdown() {}; 1.106 + 1.107 +// Start the profiler with the selected options. The samples will be 1.108 +// recorded in a circular buffer. 1.109 +// "aProfileEntries" is an abstract size indication of how big 1.110 +// the profile's circular buffer should be. Multiply by 4 1.111 +// words to get the cost. 1.112 +// "aInterval" the sampling interval. The profiler will do its 1.113 +// best to sample at this interval. The profiler visualization 1.114 +// should represent the actual sampling accuracy. 1.115 +static inline void profiler_start(int aProfileEntries, double aInterval, 1.116 + const char** aFeatures, uint32_t aFeatureCount, 1.117 + const char** aThreadNameFilters, uint32_t aFilterCount) {} 1.118 + 1.119 +// Stop the profiler and discard the profile. Call 'profiler_save' before this 1.120 +// to retrieve the profile. 1.121 +static inline void profiler_stop() {} 1.122 + 1.123 +// These functions pause and resume the profiler. While paused the profile will not 1.124 +// take any samples and will not record any data into its buffers. The profiler 1.125 +// remains fully initialized in this state. Timeline markers will still be stored. 1.126 +// This feature will keep javascript profiling enabled, thus allowing toggling the 1.127 +// profiler without invalidating the JIT. 1.128 +static inline bool profiler_is_paused() { return false; } 1.129 +static inline void profiler_pause() {} 1.130 +static inline void profiler_resume() {} 1.131 + 1.132 +class ProfilerBacktrace; 1.133 + 1.134 +// Immediately capture the current thread's call stack and return it 1.135 +static inline ProfilerBacktrace* profiler_get_backtrace() { return nullptr; } 1.136 + 1.137 +// Free a ProfilerBacktrace returned by profiler_get_backtrace() 1.138 +static inline void profiler_free_backtrace(ProfilerBacktrace* aBacktrace) {} 1.139 + 1.140 +static inline bool profiler_is_active() { return false; } 1.141 + 1.142 +// Internal-only. Used by the event tracer. 1.143 +static inline void profiler_responsiveness(const mozilla::TimeStamp& aTime) {} 1.144 + 1.145 +// Internal-only. Used by the event tracer. 1.146 +static inline double* profiler_get_responsiveness() { return nullptr; } 1.147 + 1.148 +// Internal-only. 1.149 +static inline void profiler_set_frame_number(int frameNumber) {} 1.150 + 1.151 +// Get the profile encoded as a JSON string. 1.152 +static inline char* profiler_get_profile() { return nullptr; } 1.153 + 1.154 +// Get the profile encoded as a JSON object. 1.155 +static inline JSObject* profiler_get_profile_jsobject(JSContext* aCx) { return nullptr; } 1.156 + 1.157 +// Get the profile and write it into a file 1.158 +static inline void profiler_save_profile_to_file(char* aFilename) { } 1.159 + 1.160 +// Get the features supported by the profiler that are accepted by profiler_init. 1.161 +// Returns a null terminated char* array. 1.162 +static inline char** profiler_get_features() { return nullptr; } 1.163 + 1.164 +// Print the current location to the console. This functill will do it best effort 1.165 +// to show the profiler's combined js/c++ if the profiler is running. Note that 1.166 +// printing the location require symbolicating which is very slow. 1.167 +static inline void profiler_print_location() {} 1.168 + 1.169 +// Discard the profile, throw away the profile and notify 'profiler-locked'. 1.170 +// This function is to be used when entering private browsing to prevent 1.171 +// the profiler from collecting sensitive data. 1.172 +static inline void profiler_lock() {} 1.173 + 1.174 +// Re-enable the profiler and notify 'profiler-unlocked'. 1.175 +static inline void profiler_unlock() {} 1.176 + 1.177 +static inline void profiler_register_thread(const char* name, void* stackTop) {} 1.178 +static inline void profiler_unregister_thread() {} 1.179 + 1.180 +// These functions tell the profiler that a thread went to sleep so that we can avoid 1.181 +// sampling it while it's sleeping. Calling profiler_sleep_start() twice without 1.182 +// profiler_sleep_end() is an error. 1.183 +static inline void profiler_sleep_start() {} 1.184 +static inline void profiler_sleep_end() {} 1.185 + 1.186 +// Call by the JSRuntime's operation callback. This is used to enable 1.187 +// profiling on auxilerary threads. 1.188 +static inline void profiler_js_operation_callback() {} 1.189 + 1.190 +static inline double profiler_time() { return 0; } 1.191 +static inline double profiler_time(const mozilla::TimeStamp& aTime) { return 0; } 1.192 + 1.193 +static inline bool profiler_in_privacy_mode() { return false; } 1.194 + 1.195 +#else 1.196 + 1.197 +#include "GeckoProfilerImpl.h" 1.198 + 1.199 +#endif 1.200 + 1.201 +class GeckoProfilerInitRAII { 1.202 +public: 1.203 + GeckoProfilerInitRAII(void* stackTop) { 1.204 + profiler_init(stackTop); 1.205 + } 1.206 + ~GeckoProfilerInitRAII() { 1.207 + profiler_shutdown(); 1.208 + } 1.209 +}; 1.210 + 1.211 +class GeckoProfilerSleepRAII { 1.212 +public: 1.213 + GeckoProfilerSleepRAII() { 1.214 + profiler_sleep_start(); 1.215 + } 1.216 + ~GeckoProfilerSleepRAII() { 1.217 + profiler_sleep_end(); 1.218 + } 1.219 +}; 1.220 + 1.221 +#endif // ifndef SAMPLER_H