diff options
Diffstat (limited to 'tools/profiler/public')
-rw-r--r-- | tools/profiler/public/GeckoProfiler.h | 8 | ||||
-rw-r--r-- | tools/profiler/public/GeckoProfilerFunc.h | 125 | ||||
-rw-r--r-- | tools/profiler/public/GeckoProfilerImpl.h | 515 | ||||
-rw-r--r-- | tools/profiler/public/ProfileGatherer.h | 42 | ||||
-rw-r--r-- | tools/profiler/public/ProfilerBacktrace.h | 36 | ||||
-rw-r--r-- | tools/profiler/public/ProfilerMarkers.h | 193 | ||||
-rw-r--r-- | tools/profiler/public/PseudoStack.h | 469 | ||||
-rw-r--r-- | tools/profiler/public/shared-libraries.h | 137 |
8 files changed, 0 insertions, 1525 deletions
diff --git a/tools/profiler/public/GeckoProfiler.h b/tools/profiler/public/GeckoProfiler.h index bef017d11..92fc6e052 100644 --- a/tools/profiler/public/GeckoProfiler.h +++ b/tools/profiler/public/GeckoProfiler.h @@ -79,8 +79,6 @@ enum TracingMetadata { TRACING_TIMESTAMP }; -#if !defined(MOZ_ENABLE_PROFILER_SPS) - #include <stdint.h> #include <stdarg.h> @@ -248,12 +246,6 @@ static inline bool profiler_in_privacy_mode() { return false; } static inline void profiler_log(const char *str) {} static inline void profiler_log(const char *fmt, va_list args) {} -#else - -#include "GeckoProfilerImpl.h" - -#endif - class MOZ_RAII GeckoProfilerInitRAII { public: explicit GeckoProfilerInitRAII(void* stackTop) { diff --git a/tools/profiler/public/GeckoProfilerFunc.h b/tools/profiler/public/GeckoProfilerFunc.h deleted file mode 100644 index e0d27f593..000000000 --- a/tools/profiler/public/GeckoProfilerFunc.h +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef PROFILER_FUNCS_H -#define PROFILER_FUNCS_H - -#ifndef SPS_STANDALONE -#include "js/TypeDecls.h" -#endif -#include "js/ProfilingStack.h" -#include "mozilla/UniquePtr.h" -#include "mozilla/Vector.h" -#include <stdint.h> - -class nsISupports; - -namespace mozilla { -class TimeStamp; - -namespace dom { -class Promise; -} // namespace dom - -} // namespace mozilla - -class ProfilerBacktrace; -class ProfilerMarkerPayload; - -// Returns a handle to pass on exit. This can check that we are popping the -// correct callstack. -inline void* mozilla_sampler_call_enter(const char *aInfo, js::ProfileEntry::Category aCategory, - void *aFrameAddress = nullptr, bool aCopy = false, - uint32_t line = 0); - -inline void mozilla_sampler_call_exit(void* handle); - -void mozilla_sampler_add_marker(const char *aInfo, - ProfilerMarkerPayload *aPayload = nullptr); - -void mozilla_sampler_start(int aEntries, double aInterval, - const char** aFeatures, uint32_t aFeatureCount, - const char** aThreadNameFilters, uint32_t aFilterCount); - -void mozilla_sampler_stop(); - -bool mozilla_sampler_is_paused(); -void mozilla_sampler_pause(); -void mozilla_sampler_resume(); - -ProfilerBacktrace* mozilla_sampler_get_backtrace(); -void mozilla_sampler_free_backtrace(ProfilerBacktrace* aBacktrace); -void mozilla_sampler_get_backtrace_noalloc(char *output, size_t outputSize); - -bool mozilla_sampler_is_active(); - -bool mozilla_sampler_feature_active(const char* aName); - -void mozilla_sampler_responsiveness(const mozilla::TimeStamp& time); - -void mozilla_sampler_frame_number(int frameNumber); - -const double* mozilla_sampler_get_responsiveness(); - -void mozilla_sampler_save(); - -mozilla::UniquePtr<char[]> mozilla_sampler_get_profile(double aSinceTime); - -#ifndef SPS_STANDALONE -JSObject *mozilla_sampler_get_profile_data(JSContext* aCx, double aSinceTime); -void mozilla_sampler_get_profile_data_async(double aSinceTime, - mozilla::dom::Promise* aPromise); -void mozilla_sampler_get_profiler_start_params(int* aEntrySize, - double* aInterval, - mozilla::Vector<const char*>* aFilters, - mozilla::Vector<const char*>* aFeatures); -void mozilla_sampler_get_gatherer(nsISupports** aRetVal); -#endif - -// Make this function easily callable from a debugger in a build without -// debugging information (work around http://llvm.org/bugs/show_bug.cgi?id=22211) -extern "C" { - void mozilla_sampler_save_profile_to_file(const char* aFilename); -} - -const char** mozilla_sampler_get_features(); - -void mozilla_sampler_get_buffer_info(uint32_t *aCurrentPosition, uint32_t *aTotalSize, - uint32_t *aGeneration); - -void mozilla_sampler_init(void* stackTop); - -void mozilla_sampler_shutdown(); - -// Lock the profiler. When locked the profiler is (1) stopped, -// (2) profile data is cleared, (3) profiler-locked is fired. -// This is used to lock down the profiler during private browsing -void mozilla_sampler_lock(); - -// Unlock the profiler, leaving it stopped and fires profiler-unlocked. -void mozilla_sampler_unlock(); - -// Register/unregister threads with the profiler -bool mozilla_sampler_register_thread(const char* name, void* stackTop); -void mozilla_sampler_unregister_thread(); - -void mozilla_sampler_sleep_start(); -void mozilla_sampler_sleep_end(); -bool mozilla_sampler_is_sleeping(); - -double mozilla_sampler_time(); -double mozilla_sampler_time(const mozilla::TimeStamp& aTime); - -void mozilla_sampler_tracing(const char* aCategory, const char* aInfo, - TracingMetadata aMetaData); - -void mozilla_sampler_tracing(const char* aCategory, const char* aInfo, - ProfilerBacktrace* aCause, - TracingMetadata aMetaData); - -void mozilla_sampler_log(const char *fmt, va_list args); - -#endif - diff --git a/tools/profiler/public/GeckoProfilerImpl.h b/tools/profiler/public/GeckoProfilerImpl.h deleted file mode 100644 index 7011e5cdb..000000000 --- a/tools/profiler/public/GeckoProfilerImpl.h +++ /dev/null @@ -1,515 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// IWYU pragma: private, include "GeckoProfiler.h" - -#ifndef TOOLS_SPS_SAMPLER_H_ -#define TOOLS_SPS_SAMPLER_H_ - -#include <stdlib.h> -#include <signal.h> -#include <stdarg.h> -#include "mozilla/Assertions.h" -#include "mozilla/GuardObjects.h" -#include "mozilla/Sprintf.h" -#include "mozilla/ThreadLocal.h" -#include "mozilla/UniquePtr.h" -#ifndef SPS_STANDALONE -#include "nscore.h" -#include "nsISupports.h" -#endif -#include "GeckoProfilerFunc.h" -#include "PseudoStack.h" -#include "ProfilerBacktrace.h" - -// Make sure that we can use std::min here without the Windows headers messing with us. -#ifdef min -#undef min -#endif - -class GeckoSampler; - -namespace mozilla { -class TimeStamp; -} // namespace mozilla - -extern MOZ_THREAD_LOCAL(PseudoStack *) tlsPseudoStack; -extern MOZ_THREAD_LOCAL(GeckoSampler *) tlsTicker; -extern MOZ_THREAD_LOCAL(void *) tlsStackTop; -extern bool stack_key_initialized; - -#ifndef SAMPLE_FUNCTION_NAME -# ifdef __GNUC__ -# define SAMPLE_FUNCTION_NAME __FUNCTION__ -# elif defined(_MSC_VER) -# define SAMPLE_FUNCTION_NAME __FUNCTION__ -# else -# define SAMPLE_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name. -# endif -#endif - -static inline -void profiler_init(void* stackTop) -{ - mozilla_sampler_init(stackTop); -} - -static inline -void profiler_shutdown() -{ - mozilla_sampler_shutdown(); -} - -static inline -void profiler_start(int aProfileEntries, double aInterval, - const char** aFeatures, uint32_t aFeatureCount, - const char** aThreadNameFilters, uint32_t aFilterCount) -{ - mozilla_sampler_start(aProfileEntries, aInterval, aFeatures, aFeatureCount, aThreadNameFilters, aFilterCount); -} - -static inline -void profiler_stop() -{ - mozilla_sampler_stop(); -} - -static inline -bool profiler_is_paused() -{ - return mozilla_sampler_is_paused(); -} - -static inline -void profiler_pause() -{ - mozilla_sampler_pause(); -} - -static inline -void profiler_resume() -{ - mozilla_sampler_resume(); -} - -static inline -ProfilerBacktrace* profiler_get_backtrace() -{ - return mozilla_sampler_get_backtrace(); -} - -static inline -void profiler_free_backtrace(ProfilerBacktrace* aBacktrace) -{ - mozilla_sampler_free_backtrace(aBacktrace); -} - -static inline -void profiler_get_backtrace_noalloc(char *output, size_t outputSize) -{ - return mozilla_sampler_get_backtrace_noalloc(output, outputSize); -} - -static inline -bool profiler_is_active() -{ - return mozilla_sampler_is_active(); -} - -static inline -bool profiler_feature_active(const char* aName) -{ - return mozilla_sampler_feature_active(aName); -} - -static inline -void profiler_responsiveness(const mozilla::TimeStamp& aTime) -{ - mozilla_sampler_responsiveness(aTime); -} - -static inline -void profiler_set_frame_number(int frameNumber) -{ - return mozilla_sampler_frame_number(frameNumber); -} - -static inline -mozilla::UniquePtr<char[]> profiler_get_profile(double aSinceTime = 0) -{ - return mozilla_sampler_get_profile(aSinceTime); -} - -#ifndef SPS_STANDALONE -static inline -JSObject* profiler_get_profile_jsobject(JSContext* aCx, double aSinceTime = 0) -{ - return mozilla_sampler_get_profile_data(aCx, aSinceTime); -} - -static inline -void profiler_get_profile_jsobject_async(double aSinceTime = 0, - mozilla::dom::Promise* aPromise = 0) -{ - mozilla_sampler_get_profile_data_async(aSinceTime, aPromise); -} - -static inline -void profiler_get_start_params(int* aEntrySize, - double* aInterval, - mozilla::Vector<const char*>* aFilters, - mozilla::Vector<const char*>* aFeatures) -{ - mozilla_sampler_get_profiler_start_params(aEntrySize, aInterval, aFilters, aFeatures); -} - -static inline -void profiler_get_gatherer(nsISupports** aRetVal) -{ - mozilla_sampler_get_gatherer(aRetVal); -} - -#endif - -static inline -void profiler_save_profile_to_file(const char* aFilename) -{ - return mozilla_sampler_save_profile_to_file(aFilename); -} - -static inline -const char** profiler_get_features() -{ - return mozilla_sampler_get_features(); -} - -static inline -void profiler_get_buffer_info(uint32_t *aCurrentPosition, uint32_t *aTotalSize, - uint32_t *aGeneration) -{ - return mozilla_sampler_get_buffer_info(aCurrentPosition, aTotalSize, aGeneration); -} - -static inline -void profiler_lock() -{ - return mozilla_sampler_lock(); -} - -static inline -void profiler_unlock() -{ - return mozilla_sampler_unlock(); -} - -static inline -void profiler_register_thread(const char* name, void* guessStackTop) -{ - mozilla_sampler_register_thread(name, guessStackTop); -} - -static inline -void profiler_unregister_thread() -{ - mozilla_sampler_unregister_thread(); -} - -static inline -void profiler_sleep_start() -{ - mozilla_sampler_sleep_start(); -} - -static inline -void profiler_sleep_end() -{ - mozilla_sampler_sleep_end(); -} - -static inline -bool profiler_is_sleeping() -{ - return mozilla_sampler_is_sleeping(); -} - -#ifndef SPS_STANDALONE -static inline -void profiler_js_operation_callback() -{ - PseudoStack *stack = tlsPseudoStack.get(); - if (!stack) { - return; - } - - stack->jsOperationCallback(); -} -#endif - -static inline -double profiler_time() -{ - return mozilla_sampler_time(); -} - -static inline -double profiler_time(const mozilla::TimeStamp& aTime) -{ - return mozilla_sampler_time(aTime); -} - -static inline -bool profiler_in_privacy_mode() -{ - PseudoStack *stack = tlsPseudoStack.get(); - if (!stack) { - return false; - } - return stack->mPrivacyMode; -} - -static inline void profiler_tracing(const char* aCategory, const char* aInfo, - ProfilerBacktrace* aCause, - TracingMetadata aMetaData = TRACING_DEFAULT) -{ - // Don't insert a marker if we're not profiling to avoid - // the heap copy (malloc). - if (!stack_key_initialized || !profiler_is_active()) { - delete aCause; - return; - } - - mozilla_sampler_tracing(aCategory, aInfo, aCause, aMetaData); -} - -static inline void profiler_tracing(const char* aCategory, const char* aInfo, - TracingMetadata aMetaData = TRACING_DEFAULT) -{ - if (!stack_key_initialized) - return; - - // Don't insert a marker if we're not profiling to avoid - // the heap copy (malloc). - if (!profiler_is_active()) { - return; - } - - mozilla_sampler_tracing(aCategory, aInfo, aMetaData); -} - -#define SAMPLER_APPEND_LINE_NUMBER_PASTE(id, line) id ## line -#define SAMPLER_APPEND_LINE_NUMBER_EXPAND(id, line) SAMPLER_APPEND_LINE_NUMBER_PASTE(id, line) -#define SAMPLER_APPEND_LINE_NUMBER(id) SAMPLER_APPEND_LINE_NUMBER_EXPAND(id, __LINE__) - -// Uncomment this to turn on systrace or build with -// ac_add_options --enable-systace -//#define MOZ_USE_SYSTRACE -#ifdef MOZ_USE_SYSTRACE -#ifndef ATRACE_TAG -# define ATRACE_TAG ATRACE_TAG_ALWAYS -#endif -// We need HAVE_ANDROID_OS to be defined for Trace.h. -// If its not set we will set it temporary and remove it. -# ifndef HAVE_ANDROID_OS -# define HAVE_ANDROID_OS -# define REMOVE_HAVE_ANDROID_OS -# endif -// Android source code will include <cutils/trace.h> before this. There is no -// HAVE_ANDROID_OS defined in Firefox OS build at that time. Enabled it globally -// will cause other build break. So atrace_begin and atrace_end are not defined. -// It will cause a build-break when we include <utils/Trace.h>. Use undef -// _LIBS_CUTILS_TRACE_H will force <cutils/trace.h> to define atrace_begin and -// atrace_end with defined HAVE_ANDROID_OS again. Then there is no build-break. -# undef _LIBS_CUTILS_TRACE_H -# include <utils/Trace.h> -# define MOZ_PLATFORM_TRACING(name) android::ScopedTrace SAMPLER_APPEND_LINE_NUMBER(scopedTrace)(ATRACE_TAG, name); -# ifdef REMOVE_HAVE_ANDROID_OS -# undef HAVE_ANDROID_OS -# undef REMOVE_HAVE_ANDROID_OS -# endif -#else -# define MOZ_PLATFORM_TRACING(name) -#endif - -// we want the class and function name but can't easily get that using preprocessor macros -// __func__ doesn't have the class name and __PRETTY_FUNCTION__ has the parameters - -#define PROFILER_LABEL(name_space, info, category) MOZ_PLATFORM_TRACING(name_space "::" info) mozilla::SamplerStackFrameRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, category, __LINE__) -#define PROFILER_LABEL_FUNC(category) MOZ_PLATFORM_TRACING(SAMPLE_FUNCTION_NAME) mozilla::SamplerStackFrameRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(SAMPLE_FUNCTION_NAME, category, __LINE__) -#define PROFILER_LABEL_PRINTF(name_space, info, category, ...) MOZ_PLATFORM_TRACING(name_space "::" info) mozilla::SamplerStackFramePrintfRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, category, __LINE__, __VA_ARGS__) - -#define PROFILER_MARKER(info) mozilla_sampler_add_marker(info) -#define PROFILER_MARKER_PAYLOAD(info, payload) mozilla_sampler_add_marker(info, payload) -#define PROFILER_MAIN_THREAD_MARKER(info) MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread"); mozilla_sampler_add_marker(info) - -#define PROFILER_MAIN_THREAD_LABEL(name_space, info, category) MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread"); mozilla::SamplerStackFrameRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, category, __LINE__) -#define PROFILER_MAIN_THREAD_LABEL_PRINTF(name_space, info, category, ...) MOZ_ASSERT(NS_IsMainThread(), "This can only be called on the main thread"); mozilla::SamplerStackFramePrintfRAII SAMPLER_APPEND_LINE_NUMBER(sampler_raii)(name_space "::" info, category, __LINE__, __VA_ARGS__) - - -#if !defined(PLATFORM_LIKELY_MEMORY_CONSTRAINED) && !defined(ARCH_ARMV6) -# define PROFILE_DEFAULT_ENTRY 1000000 -#else -# define PROFILE_DEFAULT_ENTRY 100000 -#endif - -// In the case of profiler_get_backtrace we know that we only need enough space -// for a single backtrace. -#define GET_BACKTRACE_DEFAULT_ENTRY 1000 - -#if defined(PLATFORM_LIKELY_MEMORY_CONSTRAINED) -/* A 1ms sampling interval has been shown to be a large perf hit - * (10fps) on memory-contrained (low-end) platforms, and additionally - * to yield different results from the profiler. Where this is the - * important case, b2g, there are also many gecko processes which - * magnify these effects. */ -# define PROFILE_DEFAULT_INTERVAL 10 -#elif defined(ANDROID) -// We use a lower frequency on Android, in order to make things work -// more smoothly on phones. This value can be adjusted later with -// some libunwind optimizations. -// In one sample measurement on Galaxy Nexus, out of about 700 backtraces, -// 60 of them took more than 25ms, and the average and standard deviation -// were 6.17ms and 9.71ms respectively. - -// For now since we don't support stackwalking let's use 1ms since it's fast -// enough. -#define PROFILE_DEFAULT_INTERVAL 1 -#else -#define PROFILE_DEFAULT_INTERVAL 1 -#endif -#define PROFILE_DEFAULT_FEATURES NULL -#define PROFILE_DEFAULT_FEATURE_COUNT 0 - -namespace mozilla { - -class MOZ_RAII GeckoProfilerTracingRAII { -public: - GeckoProfilerTracingRAII(const char* aCategory, const char* aInfo, - mozilla::UniquePtr<ProfilerBacktrace> aBacktrace - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : mCategory(aCategory) - , mInfo(aInfo) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - profiler_tracing(mCategory, mInfo, aBacktrace.release(), TRACING_INTERVAL_START); - } - - ~GeckoProfilerTracingRAII() { - profiler_tracing(mCategory, mInfo, TRACING_INTERVAL_END); - } - -protected: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - const char* mCategory; - const char* mInfo; -}; - -class MOZ_RAII SamplerStackFrameRAII { -public: - // we only copy the strings at save time, so to take multiple parameters we'd need to copy them then. - SamplerStackFrameRAII(const char *aInfo, - js::ProfileEntry::Category aCategory, uint32_t line - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - mHandle = mozilla_sampler_call_enter(aInfo, aCategory, this, false, line); - } - ~SamplerStackFrameRAII() { - mozilla_sampler_call_exit(mHandle); - } -private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER - void* mHandle; -}; - -static const int SAMPLER_MAX_STRING = 128; -class MOZ_RAII SamplerStackFramePrintfRAII { -public: - // we only copy the strings at save time, so to take multiple parameters we'd need to copy them then. - SamplerStackFramePrintfRAII(const char *aInfo, - js::ProfileEntry::Category aCategory, uint32_t line, const char *aFormat, ...) - : mHandle(nullptr) - { - if (profiler_is_active() && !profiler_in_privacy_mode()) { - va_list args; - va_start(args, aFormat); - char buff[SAMPLER_MAX_STRING]; - - // We have to use seperate printf's because we're using - // the vargs. - VsprintfLiteral(buff, aFormat, args); - SprintfLiteral(mDest, "%s %s", aInfo, buff); - - mHandle = mozilla_sampler_call_enter(mDest, aCategory, this, true, line); - va_end(args); - } else { - mHandle = mozilla_sampler_call_enter(aInfo, aCategory, this, false, line); - } - } - ~SamplerStackFramePrintfRAII() { - mozilla_sampler_call_exit(mHandle); - } -private: - char mDest[SAMPLER_MAX_STRING]; - void* mHandle; -}; - -} // namespace mozilla - -inline PseudoStack* mozilla_get_pseudo_stack(void) -{ - if (!stack_key_initialized) - return nullptr; - return tlsPseudoStack.get(); -} - -inline void* mozilla_sampler_call_enter(const char *aInfo, - js::ProfileEntry::Category aCategory, void *aFrameAddress, bool aCopy, uint32_t line) -{ - // check if we've been initialized to avoid calling pthread_getspecific - // with a null tlsStack which will return undefined results. - if (!stack_key_initialized) - return nullptr; - - PseudoStack *stack = tlsPseudoStack.get(); - // we can't infer whether 'stack' has been initialized - // based on the value of stack_key_intiailized because - // 'stack' is only intialized when a thread is being - // profiled. - if (!stack) { - return stack; - } - stack->push(aInfo, aCategory, aFrameAddress, aCopy, line); - - // The handle is meant to support future changes - // but for now it is simply use to save a call to - // pthread_getspecific on exit. It also supports the - // case where the sampler is initialized between - // enter and exit. - return stack; -} - -inline void mozilla_sampler_call_exit(void *aHandle) -{ - if (!aHandle) - return; - - PseudoStack *stack = (PseudoStack*)aHandle; - stack->popAndMaybeDelete(); -} - -void mozilla_sampler_add_marker(const char *aMarker, ProfilerMarkerPayload *aPayload); - -static inline -void profiler_log(const char *str) -{ - profiler_tracing("log", str, TRACING_EVENT); -} - -static inline -void profiler_log(const char *fmt, va_list args) -{ - mozilla_sampler_log(fmt, args); -} - -#endif /* ndef TOOLS_SPS_SAMPLER_H_ */ diff --git a/tools/profiler/public/ProfileGatherer.h b/tools/profiler/public/ProfileGatherer.h deleted file mode 100644 index 4e39a4f5c..000000000 --- a/tools/profiler/public/ProfileGatherer.h +++ /dev/null @@ -1,42 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef MOZ_PROFILE_GATHERER_H -#define MOZ_PROFILE_GATHERER_H - -#include "mozilla/dom/Promise.h" - -class GeckoSampler; - -namespace mozilla { - -class ProfileGatherer final : public nsIObserver -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOBSERVER - - explicit ProfileGatherer(GeckoSampler* aTicker); - void WillGatherOOPProfile(); - void GatheredOOPProfile(); - void Start(double aSinceTime, mozilla::dom::Promise* aPromise); - void Cancel(); - void OOPExitProfile(const nsCString& aProfile); - -private: - ~ProfileGatherer() {}; - void Finish(); - void Reset(); - - nsTArray<nsCString> mExitProfiles; - RefPtr<mozilla::dom::Promise> mPromise; - GeckoSampler* mTicker; - double mSinceTime; - uint32_t mPendingProfiles; - bool mGathering; -}; - -} // namespace mozilla - -#endif diff --git a/tools/profiler/public/ProfilerBacktrace.h b/tools/profiler/public/ProfilerBacktrace.h deleted file mode 100644 index bcaab3563..000000000 --- a/tools/profiler/public/ProfilerBacktrace.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef __PROFILER_BACKTRACE_H -#define __PROFILER_BACKTRACE_H - -class SyncProfile; -class SpliceableJSONWriter; -class UniqueStacks; - -class ProfilerBacktrace -{ -public: - explicit ProfilerBacktrace(SyncProfile* aProfile); - ~ProfilerBacktrace(); - - // ProfilerBacktraces' stacks are deduplicated in the context of the - // profile that contains the backtrace as a marker payload. - // - // That is, markers that contain backtraces should not need their own stack, - // frame, and string tables. They should instead reuse their parent - // profile's tables. - void StreamJSON(SpliceableJSONWriter& aWriter, UniqueStacks& aUniqueStacks); - -private: - ProfilerBacktrace(const ProfilerBacktrace&); - ProfilerBacktrace& operator=(const ProfilerBacktrace&); - - SyncProfile* mProfile; -}; - -#endif // __PROFILER_BACKTRACE_H - diff --git a/tools/profiler/public/ProfilerMarkers.h b/tools/profiler/public/ProfilerMarkers.h deleted file mode 100644 index 29711f210..000000000 --- a/tools/profiler/public/ProfilerMarkers.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef PROFILER_MARKERS_H -#define PROFILER_MARKERS_H - -#include "mozilla/TimeStamp.h" -#include "mozilla/Attributes.h" - -namespace mozilla { -namespace layers { -class Layer; -} // namespace layers -} // namespace mozilla - -class SpliceableJSONWriter; -class UniqueStacks; - -/** - * This is an abstract object that can be implied to supply - * data to be attached with a profiler marker. Most data inserted - * into a profile is stored in a circular buffer. This buffer - * typically wraps around and overwrites most entries. Because - * of this, this structure is designed to defer the work of - * prepare the payload only when 'preparePayload' is called. - * - * Note when implementing that this object is typically constructed - * on a particular thread but 'preparePayload' and the destructor - * is called from the main thread. - */ -class ProfilerMarkerPayload -{ -public: - /** - * ProfilerMarkerPayload takes ownership of aStack - */ - explicit ProfilerMarkerPayload(ProfilerBacktrace* aStack = nullptr); - ProfilerMarkerPayload(const mozilla::TimeStamp& aStartTime, - const mozilla::TimeStamp& aEndTime, - ProfilerBacktrace* aStack = nullptr); - - /** - * Called from the main thread - */ - virtual ~ProfilerMarkerPayload(); - - /** - * Called from the main thread - */ - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks) = 0; - - mozilla::TimeStamp GetStartTime() const { return mStartTime; } - -protected: - /** - * Called from the main thread - */ - void streamCommonProps(const char* aMarkerType, SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks); - - void SetStack(ProfilerBacktrace* aStack) { mStack = aStack; } - -private: - mozilla::TimeStamp mStartTime; - mozilla::TimeStamp mEndTime; - ProfilerBacktrace* mStack; -}; - -class ProfilerMarkerTracing : public ProfilerMarkerPayload -{ -public: - ProfilerMarkerTracing(const char* aCategory, TracingMetadata aMetaData); - ProfilerMarkerTracing(const char* aCategory, TracingMetadata aMetaData, ProfilerBacktrace* aCause); - - const char *GetCategory() const { return mCategory; } - TracingMetadata GetMetaData() const { return mMetaData; } - - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks) override; - -private: - const char *mCategory; - TracingMetadata mMetaData; -}; - - -#ifndef SPS_STANDALONE -#include "gfxASurface.h" -class ProfilerMarkerImagePayload : public ProfilerMarkerPayload -{ -public: - explicit ProfilerMarkerImagePayload(gfxASurface *aImg); - - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks) override; - -private: - RefPtr<gfxASurface> mImg; -}; - -class IOMarkerPayload : public ProfilerMarkerPayload -{ -public: - IOMarkerPayload(const char* aSource, const char* aFilename, const mozilla::TimeStamp& aStartTime, - const mozilla::TimeStamp& aEndTime, - ProfilerBacktrace* aStack); - ~IOMarkerPayload(); - - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks) override; - -private: - const char* mSource; - char* mFilename; -}; - -/** - * Contains the translation applied to a 2d layer so we can - * track the layer position at each frame. - */ -class LayerTranslationPayload : public ProfilerMarkerPayload -{ -public: - LayerTranslationPayload(mozilla::layers::Layer* aLayer, - mozilla::gfx::Point aPoint); - - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks) override; - -private: - mozilla::layers::Layer* mLayer; - mozilla::gfx::Point mPoint; -}; - -#include "Units.h" // For ScreenIntPoint - -/** - * Tracks when touch events are processed by gecko, not when - * the touch actually occured in gonk/android. - */ -class TouchDataPayload : public ProfilerMarkerPayload -{ -public: - explicit TouchDataPayload(const mozilla::ScreenIntPoint& aPoint); - virtual ~TouchDataPayload() {} - - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks) override; - -private: - mozilla::ScreenIntPoint mPoint; -}; - -/** - * Tracks when a vsync occurs according to the HardwareComposer. - */ -class VsyncPayload : public ProfilerMarkerPayload -{ -public: - explicit VsyncPayload(mozilla::TimeStamp aVsyncTimestamp); - virtual ~VsyncPayload() {} - - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks) override; - -private: - mozilla::TimeStamp mVsyncTimestamp; -}; - -class GPUMarkerPayload : public ProfilerMarkerPayload -{ -public: - GPUMarkerPayload(const mozilla::TimeStamp& aCpuTimeStart, - const mozilla::TimeStamp& aCpuTimeEnd, - uint64_t aGpuTimeStart, - uint64_t aGpuTimeEnd); - ~GPUMarkerPayload() {} - - virtual void StreamPayload(SpliceableJSONWriter& aWriter, - UniqueStacks& aUniqueStacks) override; - -private: - mozilla::TimeStamp mCpuTimeStart; - mozilla::TimeStamp mCpuTimeEnd; - uint64_t mGpuTimeStart; - uint64_t mGpuTimeEnd; -}; -#endif - -#endif // PROFILER_MARKERS_H diff --git a/tools/profiler/public/PseudoStack.h b/tools/profiler/public/PseudoStack.h deleted file mode 100644 index f9e3836ea..000000000 --- a/tools/profiler/public/PseudoStack.h +++ /dev/null @@ -1,469 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef PROFILER_PSEUDO_STACK_H_ -#define PROFILER_PSEUDO_STACK_H_ - -#include "mozilla/ArrayUtils.h" -#include <stdint.h> -#include "js/ProfilingStack.h" -#include <stdlib.h> -#include "mozilla/Atomics.h" -#ifndef SPS_STANDALONE -#include "nsISupportsImpl.h" -#endif - -/* we duplicate this code here to avoid header dependencies - * which make it more difficult to include in other places */ -#if defined(_M_X64) || defined(__x86_64__) -#define V8_HOST_ARCH_X64 1 -#elif defined(_M_IX86) || defined(__i386__) || defined(__i386) -#define V8_HOST_ARCH_IA32 1 -#elif defined(__ARMEL__) -#define V8_HOST_ARCH_ARM 1 -#else -#warning Please add support for your architecture in chromium_types.h -#endif - -// STORE_SEQUENCER: Because signals can interrupt our profile modification -// we need to make stores are not re-ordered by the compiler -// or hardware to make sure the profile is consistent at -// every point the signal can fire. -#ifdef V8_HOST_ARCH_ARM -// TODO Is there something cheaper that will prevent -// memory stores from being reordered - -typedef void (*LinuxKernelMemoryBarrierFunc)(void); -LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) = - (LinuxKernelMemoryBarrierFunc) 0xffff0fa0; - -# define STORE_SEQUENCER() pLinuxKernelMemoryBarrier() -#elif defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64) -# if defined(_MSC_VER) -# include <intrin.h> -# define STORE_SEQUENCER() _ReadWriteBarrier(); -# elif defined(__INTEL_COMPILER) -# define STORE_SEQUENCER() __memory_barrier(); -# elif __GNUC__ -# define STORE_SEQUENCER() asm volatile("" ::: "memory"); -# else -# error "Memory clobber not supported for your compiler." -# endif -#else -# error "Memory clobber not supported for your platform." -#endif - -// We can't include <algorithm> because it causes issues on OS X, so we use -// our own min function. -static inline uint32_t sMin(uint32_t l, uint32_t r) { - return l < r ? l : r; -} - -// A stack entry exists to allow the JS engine to inform SPS of the current -// backtrace, but also to instrument particular points in C++ in case stack -// walking is not available on the platform we are running on. -// -// Each entry has a descriptive string, a relevant stack address, and some extra -// information the JS engine might want to inform SPS of. This class inherits -// from the JS engine's version of the entry to ensure that the size and layout -// of the two representations are consistent. -class StackEntry : public js::ProfileEntry -{ -}; - -class ProfilerMarkerPayload; -template<typename T> -class ProfilerLinkedList; -class SpliceableJSONWriter; -class UniqueStacks; - -class ProfilerMarker { - friend class ProfilerLinkedList<ProfilerMarker>; -public: - explicit ProfilerMarker(const char* aMarkerName, - ProfilerMarkerPayload* aPayload = nullptr, - double aTime = 0); - - ~ProfilerMarker(); - - const char* GetMarkerName() const { - return mMarkerName; - } - - void StreamJSON(SpliceableJSONWriter& aWriter, UniqueStacks& aUniqueStacks) const; - - void SetGeneration(uint32_t aGenID); - - bool HasExpired(uint32_t aGenID) const { - return mGenID + 2 <= aGenID; - } - - double GetTime() const; - -private: - char* mMarkerName; - ProfilerMarkerPayload* mPayload; - ProfilerMarker* mNext; - double mTime; - uint32_t mGenID; -}; - -template<typename T> -class ProfilerLinkedList { -public: - ProfilerLinkedList() - : mHead(nullptr) - , mTail(nullptr) - {} - - void insert(T* elem) - { - if (!mTail) { - mHead = elem; - mTail = elem; - } else { - mTail->mNext = elem; - mTail = elem; - } - elem->mNext = nullptr; - } - - T* popHead() - { - if (!mHead) { - MOZ_ASSERT(false); - return nullptr; - } - - T* head = mHead; - - mHead = head->mNext; - if (!mHead) { - mTail = nullptr; - } - - return head; - } - - const T* peek() { - return mHead; - } - -private: - T* mHead; - T* mTail; -}; - -typedef ProfilerLinkedList<ProfilerMarker> ProfilerMarkerLinkedList; - -template<typename T> -class ProfilerSignalSafeLinkedList { -public: - ProfilerSignalSafeLinkedList() - : mSignalLock(false) - {} - - ~ProfilerSignalSafeLinkedList() - { - if (mSignalLock) { - // Some thread is modifying the list. We should only be released on that - // thread. - abort(); - } - - while (mList.peek()) { - delete mList.popHead(); - } - } - - // Insert an item into the list. - // Must only be called from the owning thread. - // Must not be called while the list from accessList() is being accessed. - // In the profiler, we ensure that by interrupting the profiled thread - // (which is the one that owns this list and calls insert() on it) until - // we're done reading the list from the signal handler. - void insert(T* aElement) { - MOZ_ASSERT(aElement); - - mSignalLock = true; - STORE_SEQUENCER(); - - mList.insert(aElement); - - STORE_SEQUENCER(); - mSignalLock = false; - } - - // Called within signal, from any thread, possibly while insert() is in the - // middle of modifying the list (on the owning thread). Will return null if - // that is the case. - // Function must be reentrant. - ProfilerLinkedList<T>* accessList() - { - if (mSignalLock) { - return nullptr; - } - return &mList; - } - -private: - ProfilerLinkedList<T> mList; - - // If this is set, then it's not safe to read the list because its contents - // are being changed. - volatile bool mSignalLock; -}; - -// Stub eventMarker function for js-engine event generation. -void ProfilerJSEventMarker(const char *event); - -// the PseudoStack members are read by signal -// handlers, so the mutation of them needs to be signal-safe. -struct PseudoStack -{ -public: - // Create a new PseudoStack and acquire a reference to it. - static PseudoStack *create() - { - return new PseudoStack(); - } - - // This is called on every profiler restart. Put things that should happen at that time here. - void reinitializeOnResume() { - // This is needed to cause an initial sample to be taken from sleeping threads. Otherwise sleeping - // threads would not have any samples to copy forward while sleeping. - mSleepId++; - } - - void addMarker(const char* aMarkerStr, ProfilerMarkerPayload* aPayload, double aTime) - { - ProfilerMarker* marker = new ProfilerMarker(aMarkerStr, aPayload, aTime); - mPendingMarkers.insert(marker); - } - - // called within signal. Function must be reentrant - ProfilerMarkerLinkedList* getPendingMarkers() - { - // The profiled thread is interrupted, so we can access the list safely. - // Unless the profiled thread was in the middle of changing the list when - // we interrupted it - in that case, accessList() will return null. - return mPendingMarkers.accessList(); - } - - void push(const char *aName, js::ProfileEntry::Category aCategory, uint32_t line) - { - push(aName, aCategory, nullptr, false, line); - } - - void push(const char *aName, js::ProfileEntry::Category aCategory, - void *aStackAddress, bool aCopy, uint32_t line) - { - if (size_t(mStackPointer) >= mozilla::ArrayLength(mStack)) { - mStackPointer++; - return; - } - - // In order to ensure this object is kept alive while it is - // active, we acquire a reference at the outermost push. This is - // released by the corresponding pop. - if (mStackPointer == 0) { - ref(); - } - - volatile StackEntry &entry = mStack[mStackPointer]; - - // Make sure we increment the pointer after the name has - // been written such that mStack is always consistent. - entry.initCppFrame(aStackAddress, line); - entry.setLabel(aName); - MOZ_ASSERT(entry.flags() == js::ProfileEntry::IS_CPP_ENTRY); - entry.setCategory(aCategory); - - // Track if mLabel needs a copy. - if (aCopy) - entry.setFlag(js::ProfileEntry::FRAME_LABEL_COPY); - else - entry.unsetFlag(js::ProfileEntry::FRAME_LABEL_COPY); - - // Prevent the optimizer from re-ordering these instructions - STORE_SEQUENCER(); - mStackPointer++; - } - - // Pop the stack. If the stack is empty and all other references to - // this PseudoStack have been dropped, then the PseudoStack is - // deleted and "false" is returned. Otherwise "true" is returned. - bool popAndMaybeDelete() - { - mStackPointer--; - if (mStackPointer == 0) { - // Release our self-owned reference count. See 'push'. - deref(); - return false; - } else { - return true; - } - } - bool isEmpty() - { - return mStackPointer == 0; - } - uint32_t stackSize() const - { - return sMin(mStackPointer, mozilla::sig_safe_t(mozilla::ArrayLength(mStack))); - } - - void sampleContext(JSContext* context) { -#ifndef SPS_STANDALONE - if (mContext && !context) { - // On JS shut down, flush the current buffer as stringifying JIT samples - // requires a live JSContext. - flushSamplerOnJSShutdown(); - } - - mContext = context; - - if (!context) { - return; - } - - static_assert(sizeof(mStack[0]) == sizeof(js::ProfileEntry), - "mStack must be binary compatible with js::ProfileEntry."); - js::SetContextProfilingStack(context, - (js::ProfileEntry*) mStack, - (uint32_t*) &mStackPointer, - (uint32_t) mozilla::ArrayLength(mStack)); - if (mStartJSSampling) - enableJSSampling(); -#endif - } -#ifndef SPS_STANDALONE - void enableJSSampling() { - if (mContext) { - js::EnableContextProfilingStack(mContext, true); - js::RegisterContextProfilingEventMarker(mContext, &ProfilerJSEventMarker); - mStartJSSampling = false; - } else { - mStartJSSampling = true; - } - } - void jsOperationCallback() { - if (mStartJSSampling) - enableJSSampling(); - } - void disableJSSampling() { - mStartJSSampling = false; - if (mContext) - js::EnableContextProfilingStack(mContext, false); - } -#endif - - // Keep a list of active checkpoints - StackEntry volatile mStack[1024]; - private: - - // A PseudoStack can only be created via the "create" method. - PseudoStack() - : mStackPointer(0) - , mSleepId(0) - , mSleepIdObserved(0) - , mSleeping(false) - , mRefCnt(1) -#ifndef SPS_STANDALONE - , mContext(nullptr) -#endif - , mStartJSSampling(false) - , mPrivacyMode(false) - { - MOZ_COUNT_CTOR(PseudoStack); - } - - // A PseudoStack can only be deleted via deref. - ~PseudoStack() { - MOZ_COUNT_DTOR(PseudoStack); - if (mStackPointer != 0) { - // We're releasing the pseudostack while it's still in use. - // The label macros keep a non ref counted reference to the - // stack to avoid a TLS. If these are not all cleared we will - // get a use-after-free so better to crash now. - abort(); - } - } - - // No copying. - PseudoStack(const PseudoStack&) = delete; - void operator=(const PseudoStack&) = delete; - - void flushSamplerOnJSShutdown(); - - // Keep a list of pending markers that must be moved - // to the circular buffer - ProfilerSignalSafeLinkedList<ProfilerMarker> mPendingMarkers; - // This may exceed the length of mStack, so instead use the stackSize() method - // to determine the number of valid samples in mStack - mozilla::sig_safe_t mStackPointer; - // Incremented at every sleep/wake up of the thread - int mSleepId; - // Previous id observed. If this is not the same as mSleepId, this thread is not sleeping in the same place any more - mozilla::Atomic<int> mSleepIdObserved; - // Keeps tack of whether the thread is sleeping or not (1 when sleeping 0 when awake) - mozilla::Atomic<int> mSleeping; - // This class is reference counted because it must be kept alive by - // the ThreadInfo, by the reference from tlsPseudoStack, and by the - // current thread when callbacks are in progress. - mozilla::Atomic<int> mRefCnt; - - public: -#ifndef SPS_STANDALONE - // The context which is being sampled - JSContext *mContext; -#endif - // Start JS Profiling when possible - bool mStartJSSampling; - bool mPrivacyMode; - - enum SleepState {NOT_SLEEPING, SLEEPING_FIRST, SLEEPING_AGAIN}; - - // The first time this is called per sleep cycle we return SLEEPING_FIRST - // and any other subsequent call within the same sleep cycle we return SLEEPING_AGAIN - SleepState observeSleeping() { - if (mSleeping != 0) { - if (mSleepIdObserved == mSleepId) { - return SLEEPING_AGAIN; - } else { - mSleepIdObserved = mSleepId; - return SLEEPING_FIRST; - } - } else { - return NOT_SLEEPING; - } - } - - - // Call this whenever the current thread sleeps or wakes up - // Calling setSleeping with the same value twice in a row is an error - void setSleeping(int sleeping) { - MOZ_ASSERT(mSleeping != sleeping); - mSleepId++; - mSleeping = sleeping; - } - - bool isSleeping() { - return !!mSleeping; - } - - void ref() { - ++mRefCnt; - } - - void deref() { - int newValue = --mRefCnt; - if (newValue == 0) { - delete this; - } - } -}; - -#endif diff --git a/tools/profiler/public/shared-libraries.h b/tools/profiler/public/shared-libraries.h deleted file mode 100644 index b02a1fb08..000000000 --- a/tools/profiler/public/shared-libraries.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim:set ts=2 sw=2 sts=2 et cindent: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef SHARED_LIBRARIES_H_ -#define SHARED_LIBRARIES_H_ - -#ifndef MOZ_ENABLE_PROFILER_SPS -#error This header does not have a useful implementation on your platform! -#endif - -#include <algorithm> -#include <vector> -#include <string> -#include <stdlib.h> -#include <stdint.h> -#ifndef SPS_STANDALONE -#include <nsID.h> -#endif - -class SharedLibrary { -public: - - SharedLibrary(uintptr_t aStart, - uintptr_t aEnd, - uintptr_t aOffset, - const std::string& aBreakpadId, - const std::string& aName) - : mStart(aStart) - , mEnd(aEnd) - , mOffset(aOffset) - , mBreakpadId(aBreakpadId) - , mName(aName) - {} - - SharedLibrary(const SharedLibrary& aEntry) - : mStart(aEntry.mStart) - , mEnd(aEntry.mEnd) - , mOffset(aEntry.mOffset) - , mBreakpadId(aEntry.mBreakpadId) - , mName(aEntry.mName) - {} - - SharedLibrary& operator=(const SharedLibrary& aEntry) - { - // Gracefully handle self assignment - if (this == &aEntry) return *this; - - mStart = aEntry.mStart; - mEnd = aEntry.mEnd; - mOffset = aEntry.mOffset; - mBreakpadId = aEntry.mBreakpadId; - mName = aEntry.mName; - return *this; - } - - bool operator==(const SharedLibrary& other) const - { - return (mStart == other.mStart) && - (mEnd == other.mEnd) && - (mOffset == other.mOffset) && - (mName == other.mName) && - (mBreakpadId == other.mBreakpadId); - } - - uintptr_t GetStart() const { return mStart; } - uintptr_t GetEnd() const { return mEnd; } - uintptr_t GetOffset() const { return mOffset; } - const std::string &GetBreakpadId() const { return mBreakpadId; } - const std::string &GetName() const { return mName; } - -private: - SharedLibrary() {} - - uintptr_t mStart; - uintptr_t mEnd; - uintptr_t mOffset; - std::string mBreakpadId; - std::string mName; -}; - -static bool -CompareAddresses(const SharedLibrary& first, const SharedLibrary& second) -{ - return first.GetStart() < second.GetStart(); -} - -class SharedLibraryInfo { -public: - static SharedLibraryInfo GetInfoForSelf(); - SharedLibraryInfo() {} - - void AddSharedLibrary(SharedLibrary entry) - { - mEntries.push_back(entry); - } - - const SharedLibrary& GetEntry(size_t i) const - { - return mEntries[i]; - } - - // Removes items in the range [first, last) - // i.e. element at the "last" index is not removed - void RemoveEntries(size_t first, size_t last) - { - mEntries.erase(mEntries.begin() + first, mEntries.begin() + last); - } - - bool Contains(const SharedLibrary& searchItem) const - { - return (mEntries.end() != - std::find(mEntries.begin(), mEntries.end(), searchItem)); - } - - size_t GetSize() const - { - return mEntries.size(); - } - - void SortByAddress() - { - std::sort(mEntries.begin(), mEntries.end(), CompareAddresses); - } - - void Clear() - { - mEntries.clear(); - } - -private: - std::vector<SharedLibrary> mEntries; -}; - -#endif |