1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_DEBUG_PROFILER_H_ 6*635a8641SAndroid Build Coastguard Worker #define BASE_DEBUG_PROFILER_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include <stddef.h> 9*635a8641SAndroid Build Coastguard Worker 10*635a8641SAndroid Build Coastguard Worker #include <string> 11*635a8641SAndroid Build Coastguard Worker 12*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 13*635a8641SAndroid Build Coastguard Worker 14*635a8641SAndroid Build Coastguard Worker // The Profiler functions allow usage of the underlying sampling based 15*635a8641SAndroid Build Coastguard Worker // profiler. If the application has not been built with the necessary 16*635a8641SAndroid Build Coastguard Worker // flags (-DENABLE_PROFILING and not -DNO_TCMALLOC) then these functions 17*635a8641SAndroid Build Coastguard Worker // are noops. 18*635a8641SAndroid Build Coastguard Worker namespace base { 19*635a8641SAndroid Build Coastguard Worker namespace debug { 20*635a8641SAndroid Build Coastguard Worker 21*635a8641SAndroid Build Coastguard Worker // Start profiling with the supplied name. 22*635a8641SAndroid Build Coastguard Worker // {pid} will be replaced by the process' pid and {count} will be replaced 23*635a8641SAndroid Build Coastguard Worker // by the count of the profile run (starts at 1 with each process). 24*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void StartProfiling(const std::string& name); 25*635a8641SAndroid Build Coastguard Worker 26*635a8641SAndroid Build Coastguard Worker // Stop profiling and write out data. 27*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void StopProfiling(); 28*635a8641SAndroid Build Coastguard Worker 29*635a8641SAndroid Build Coastguard Worker // Force data to be written to file. 30*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void FlushProfiling(); 31*635a8641SAndroid Build Coastguard Worker 32*635a8641SAndroid Build Coastguard Worker // Returns true if process is being profiled. 33*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool BeingProfiled(); 34*635a8641SAndroid Build Coastguard Worker 35*635a8641SAndroid Build Coastguard Worker // Reset profiling after a fork, which disables timers. 36*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void RestartProfilingAfterFork(); 37*635a8641SAndroid Build Coastguard Worker 38*635a8641SAndroid Build Coastguard Worker // Returns true iff this executable supports profiling. 39*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool IsProfilingSupported(); 40*635a8641SAndroid Build Coastguard Worker 41*635a8641SAndroid Build Coastguard Worker // There's a class of profilers that use "return address swizzling" to get a 42*635a8641SAndroid Build Coastguard Worker // hook on function exits. This class of profilers uses some form of entry hook, 43*635a8641SAndroid Build Coastguard Worker // like e.g. binary instrumentation, or a compiler flag, that calls a hook each 44*635a8641SAndroid Build Coastguard Worker // time a function is invoked. The hook then switches the return address on the 45*635a8641SAndroid Build Coastguard Worker // stack for the address of an exit hook function, and pushes the original 46*635a8641SAndroid Build Coastguard Worker // return address to a shadow stack of some type. When in due course the CPU 47*635a8641SAndroid Build Coastguard Worker // executes a return to the exit hook, the exit hook will do whatever work it 48*635a8641SAndroid Build Coastguard Worker // does on function exit, then arrange to return to the original return address. 49*635a8641SAndroid Build Coastguard Worker // This class of profiler does not play well with programs that look at the 50*635a8641SAndroid Build Coastguard Worker // return address, as does e.g. V8. V8 uses the return address to certain 51*635a8641SAndroid Build Coastguard Worker // runtime functions to find the JIT code that called it, and from there finds 52*635a8641SAndroid Build Coastguard Worker // the V8 data structures associated to the JS function involved. 53*635a8641SAndroid Build Coastguard Worker // A return address resolution function is used to fix this. It allows such 54*635a8641SAndroid Build Coastguard Worker // programs to resolve a location on stack where a return address originally 55*635a8641SAndroid Build Coastguard Worker // resided, to the shadow stack location where the profiler stashed it. 56*635a8641SAndroid Build Coastguard Worker typedef uintptr_t (*ReturnAddressLocationResolver)( 57*635a8641SAndroid Build Coastguard Worker uintptr_t return_addr_location); 58*635a8641SAndroid Build Coastguard Worker 59*635a8641SAndroid Build Coastguard Worker // This type declaration must match V8's FunctionEntryHook. 60*635a8641SAndroid Build Coastguard Worker typedef void (*DynamicFunctionEntryHook)(uintptr_t function, 61*635a8641SAndroid Build Coastguard Worker uintptr_t return_addr_location); 62*635a8641SAndroid Build Coastguard Worker 63*635a8641SAndroid Build Coastguard Worker // The functions below here are to support profiling V8-generated code. 64*635a8641SAndroid Build Coastguard Worker // V8 has provisions for generating a call to an entry hook for newly generated 65*635a8641SAndroid Build Coastguard Worker // JIT code, and it can push symbol information on code generation and advise 66*635a8641SAndroid Build Coastguard Worker // when the garbage collector moves code. The functions declarations below here 67*635a8641SAndroid Build Coastguard Worker // make glue between V8's facilities and a profiler. 68*635a8641SAndroid Build Coastguard Worker 69*635a8641SAndroid Build Coastguard Worker // This type declaration must match V8's FunctionEntryHook. 70*635a8641SAndroid Build Coastguard Worker typedef void (*DynamicFunctionEntryHook)(uintptr_t function, 71*635a8641SAndroid Build Coastguard Worker uintptr_t return_addr_location); 72*635a8641SAndroid Build Coastguard Worker 73*635a8641SAndroid Build Coastguard Worker typedef void (*AddDynamicSymbol)(const void* address, 74*635a8641SAndroid Build Coastguard Worker size_t length, 75*635a8641SAndroid Build Coastguard Worker const char* name, 76*635a8641SAndroid Build Coastguard Worker size_t name_len); 77*635a8641SAndroid Build Coastguard Worker typedef void (*MoveDynamicSymbol)(const void* address, const void* new_address); 78*635a8641SAndroid Build Coastguard Worker 79*635a8641SAndroid Build Coastguard Worker 80*635a8641SAndroid Build Coastguard Worker // If this binary is instrumented and the instrumentation supplies a function 81*635a8641SAndroid Build Coastguard Worker // for each of those purposes, find and return the function in question. 82*635a8641SAndroid Build Coastguard Worker // Otherwise returns NULL. 83*635a8641SAndroid Build Coastguard Worker BASE_EXPORT ReturnAddressLocationResolver GetProfilerReturnAddrResolutionFunc(); 84*635a8641SAndroid Build Coastguard Worker BASE_EXPORT DynamicFunctionEntryHook GetProfilerDynamicFunctionEntryHookFunc(); 85*635a8641SAndroid Build Coastguard Worker BASE_EXPORT AddDynamicSymbol GetProfilerAddDynamicSymbolFunc(); 86*635a8641SAndroid Build Coastguard Worker BASE_EXPORT MoveDynamicSymbol GetProfilerMoveDynamicSymbolFunc(); 87*635a8641SAndroid Build Coastguard Worker 88*635a8641SAndroid Build Coastguard Worker } // namespace debug 89*635a8641SAndroid Build Coastguard Worker } // namespace base 90*635a8641SAndroid Build Coastguard Worker 91*635a8641SAndroid Build Coastguard Worker #endif // BASE_DEBUG_PROFILER_H_ 92