tools/profiler/nsProfiler.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include <string>
michael@0 7 #include <sstream>
michael@0 8 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
michael@0 9 #include "EventTracer.h"
michael@0 10 #endif
michael@0 11 #include "GeckoProfiler.h"
michael@0 12 #include "nsProfiler.h"
michael@0 13 #include "nsMemory.h"
michael@0 14 #include "nsString.h"
michael@0 15 #include "mozilla/Services.h"
michael@0 16 #include "nsIObserverService.h"
michael@0 17 #include "nsIInterfaceRequestor.h"
michael@0 18 #include "nsILoadContext.h"
michael@0 19 #include "nsIWebNavigation.h"
michael@0 20 #include "nsIInterfaceRequestorUtils.h"
michael@0 21 #include "shared-libraries.h"
michael@0 22 #include "js/Value.h"
michael@0 23
michael@0 24 using std::string;
michael@0 25
michael@0 26 NS_IMPL_ISUPPORTS(nsProfiler, nsIProfiler)
michael@0 27
michael@0 28 nsProfiler::nsProfiler()
michael@0 29 : mLockedForPrivateBrowsing(false)
michael@0 30 {
michael@0 31 }
michael@0 32
michael@0 33 nsProfiler::~nsProfiler()
michael@0 34 {
michael@0 35 nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
michael@0 36 if (observerService) {
michael@0 37 observerService->RemoveObserver(this, "chrome-document-global-created");
michael@0 38 observerService->RemoveObserver(this, "last-pb-context-exited");
michael@0 39 }
michael@0 40 }
michael@0 41
michael@0 42 nsresult
michael@0 43 nsProfiler::Init() {
michael@0 44 nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
michael@0 45 if (observerService) {
michael@0 46 observerService->AddObserver(this, "chrome-document-global-created", false);
michael@0 47 observerService->AddObserver(this, "last-pb-context-exited", false);
michael@0 48 }
michael@0 49 return NS_OK;
michael@0 50 }
michael@0 51
michael@0 52 NS_IMETHODIMP
michael@0 53 nsProfiler::Observe(nsISupports *aSubject,
michael@0 54 const char *aTopic,
michael@0 55 const char16_t *aData)
michael@0 56 {
michael@0 57 if (strcmp(aTopic, "chrome-document-global-created") == 0) {
michael@0 58 nsCOMPtr<nsIInterfaceRequestor> requestor = do_QueryInterface(aSubject);
michael@0 59 nsCOMPtr<nsIWebNavigation> parentWebNav = do_GetInterface(requestor);
michael@0 60 nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(parentWebNav);
michael@0 61 if (loadContext && loadContext->UsePrivateBrowsing() && !mLockedForPrivateBrowsing) {
michael@0 62 mLockedForPrivateBrowsing = true;
michael@0 63 profiler_lock();
michael@0 64 }
michael@0 65 } else if (strcmp(aTopic, "last-pb-context-exited") == 0) {
michael@0 66 mLockedForPrivateBrowsing = false;
michael@0 67 profiler_unlock();
michael@0 68 }
michael@0 69 return NS_OK;
michael@0 70 }
michael@0 71
michael@0 72 NS_IMETHODIMP
michael@0 73 nsProfiler::StartProfiler(uint32_t aEntries, double aInterval,
michael@0 74 const char** aFeatures, uint32_t aFeatureCount,
michael@0 75 const char** aThreadNameFilters, uint32_t aFilterCount)
michael@0 76 {
michael@0 77 if (mLockedForPrivateBrowsing) {
michael@0 78 return NS_ERROR_NOT_AVAILABLE;
michael@0 79 }
michael@0 80
michael@0 81 profiler_start(aEntries, aInterval,
michael@0 82 aFeatures, aFeatureCount,
michael@0 83 aThreadNameFilters, aFilterCount);
michael@0 84 #ifdef MOZ_INSTRUMENT_EVENT_LOOP
michael@0 85 bool printToConsole = false;
michael@0 86 mozilla::InitEventTracing(printToConsole);
michael@0 87 #endif
michael@0 88 return NS_OK;
michael@0 89 }
michael@0 90
michael@0 91 NS_IMETHODIMP
michael@0 92 nsProfiler::StopProfiler()
michael@0 93 {
michael@0 94 profiler_stop();
michael@0 95 return NS_OK;
michael@0 96 }
michael@0 97
michael@0 98 NS_IMETHODIMP
michael@0 99 nsProfiler::IsPaused(bool *aIsPaused)
michael@0 100 {
michael@0 101 *aIsPaused = profiler_is_paused();
michael@0 102 return NS_OK;
michael@0 103 }
michael@0 104
michael@0 105 NS_IMETHODIMP
michael@0 106 nsProfiler::PauseSampling()
michael@0 107 {
michael@0 108 profiler_pause();
michael@0 109 return NS_OK;
michael@0 110 }
michael@0 111
michael@0 112 NS_IMETHODIMP
michael@0 113 nsProfiler::ResumeSampling()
michael@0 114 {
michael@0 115 profiler_resume();
michael@0 116 return NS_OK;
michael@0 117 }
michael@0 118
michael@0 119 NS_IMETHODIMP
michael@0 120 nsProfiler::AddMarker(const char *aMarker)
michael@0 121 {
michael@0 122 PROFILER_MARKER(aMarker);
michael@0 123 return NS_OK;
michael@0 124 }
michael@0 125
michael@0 126 NS_IMETHODIMP
michael@0 127 nsProfiler::GetProfile(char **aProfile)
michael@0 128 {
michael@0 129 char *profile = profiler_get_profile();
michael@0 130 if (profile) {
michael@0 131 size_t len = strlen(profile);
michael@0 132 char *profileStr = static_cast<char *>
michael@0 133 (nsMemory::Clone(profile, (len + 1) * sizeof(char)));
michael@0 134 profileStr[len] = '\0';
michael@0 135 *aProfile = profileStr;
michael@0 136 free(profile);
michael@0 137 }
michael@0 138 return NS_OK;
michael@0 139 }
michael@0 140
michael@0 141 static void
michael@0 142 AddSharedLibraryInfoToStream(std::ostream& aStream, const SharedLibrary& aLib)
michael@0 143 {
michael@0 144 aStream << "{";
michael@0 145 aStream << "\"start\":" << aLib.GetStart();
michael@0 146 aStream << ",\"end\":" << aLib.GetEnd();
michael@0 147 aStream << ",\"offset\":" << aLib.GetOffset();
michael@0 148 aStream << ",\"name\":\"" << aLib.GetName() << "\"";
michael@0 149 const std::string &breakpadId = aLib.GetBreakpadId();
michael@0 150 aStream << ",\"breakpadId\":\"" << breakpadId << "\"";
michael@0 151 #ifdef XP_WIN
michael@0 152 // FIXME: remove this XP_WIN code when the profiler plugin has switched to
michael@0 153 // using breakpadId.
michael@0 154 std::string pdbSignature = breakpadId.substr(0, 32);
michael@0 155 std::string pdbAgeStr = breakpadId.substr(32, breakpadId.size() - 1);
michael@0 156
michael@0 157 std::stringstream stream;
michael@0 158 stream << pdbAgeStr;
michael@0 159
michael@0 160 unsigned pdbAge;
michael@0 161 stream << std::hex;
michael@0 162 stream >> pdbAge;
michael@0 163
michael@0 164 #ifdef DEBUG
michael@0 165 std::ostringstream oStream;
michael@0 166 oStream << pdbSignature << std::hex << std::uppercase << pdbAge;
michael@0 167 MOZ_ASSERT(breakpadId == oStream.str());
michael@0 168 #endif
michael@0 169
michael@0 170 aStream << ",\"pdbSignature\":\"" << pdbSignature << "\"";
michael@0 171 aStream << ",\"pdbAge\":" << pdbAge;
michael@0 172 aStream << ",\"pdbName\":\"" << aLib.GetName() << "\"";
michael@0 173 #endif
michael@0 174 aStream << "}";
michael@0 175 }
michael@0 176
michael@0 177 std::string
michael@0 178 GetSharedLibraryInfoString()
michael@0 179 {
michael@0 180 SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
michael@0 181 if (info.GetSize() == 0)
michael@0 182 return "[]";
michael@0 183
michael@0 184 std::ostringstream os;
michael@0 185 os << "[";
michael@0 186 AddSharedLibraryInfoToStream(os, info.GetEntry(0));
michael@0 187
michael@0 188 for (size_t i = 1; i < info.GetSize(); i++) {
michael@0 189 os << ",";
michael@0 190 AddSharedLibraryInfoToStream(os, info.GetEntry(i));
michael@0 191 }
michael@0 192
michael@0 193 os << "]";
michael@0 194 return os.str();
michael@0 195 }
michael@0 196
michael@0 197 NS_IMETHODIMP
michael@0 198 nsProfiler::GetSharedLibraryInformation(nsAString& aOutString)
michael@0 199 {
michael@0 200 aOutString.Assign(NS_ConvertUTF8toUTF16(GetSharedLibraryInfoString().c_str()));
michael@0 201 return NS_OK;
michael@0 202 }
michael@0 203
michael@0 204 NS_IMETHODIMP nsProfiler::GetProfileData(JSContext* aCx,
michael@0 205 JS::MutableHandle<JS::Value> aResult)
michael@0 206 {
michael@0 207 JS::RootedObject obj(aCx, profiler_get_profile_jsobject(aCx));
michael@0 208 if (!obj) {
michael@0 209 return NS_ERROR_FAILURE;
michael@0 210 }
michael@0 211 aResult.setObject(*obj);
michael@0 212 return NS_OK;
michael@0 213 }
michael@0 214
michael@0 215 NS_IMETHODIMP
michael@0 216 nsProfiler::IsActive(bool *aIsActive)
michael@0 217 {
michael@0 218 *aIsActive = profiler_is_active();
michael@0 219 return NS_OK;
michael@0 220 }
michael@0 221
michael@0 222 NS_IMETHODIMP
michael@0 223 nsProfiler::GetResponsivenessTimes(uint32_t *aCount, double **aResult)
michael@0 224 {
michael@0 225 unsigned int len = 100;
michael@0 226 const double* times = profiler_get_responsiveness();
michael@0 227 if (!times) {
michael@0 228 *aCount = 0;
michael@0 229 *aResult = nullptr;
michael@0 230 return NS_OK;
michael@0 231 }
michael@0 232
michael@0 233 double *fs = static_cast<double *>
michael@0 234 (nsMemory::Clone(times, len * sizeof(double)));
michael@0 235
michael@0 236 *aCount = len;
michael@0 237 *aResult = fs;
michael@0 238
michael@0 239 return NS_OK;
michael@0 240 }
michael@0 241
michael@0 242 NS_IMETHODIMP
michael@0 243 nsProfiler::GetFeatures(uint32_t *aCount, char ***aFeatures)
michael@0 244 {
michael@0 245 uint32_t len = 0;
michael@0 246
michael@0 247 const char **features = profiler_get_features();
michael@0 248 if (!features) {
michael@0 249 *aCount = 0;
michael@0 250 *aFeatures = nullptr;
michael@0 251 return NS_OK;
michael@0 252 }
michael@0 253
michael@0 254 while (features[len]) {
michael@0 255 len++;
michael@0 256 }
michael@0 257
michael@0 258 char **featureList = static_cast<char **>
michael@0 259 (nsMemory::Alloc(len * sizeof(char*)));
michael@0 260
michael@0 261 for (size_t i = 0; i < len; i++) {
michael@0 262 size_t strLen = strlen(features[i]);
michael@0 263 featureList[i] = static_cast<char *>
michael@0 264 (nsMemory::Clone(features[i], (strLen + 1) * sizeof(char)));
michael@0 265 }
michael@0 266
michael@0 267 *aFeatures = featureList;
michael@0 268 *aCount = len;
michael@0 269 return NS_OK;
michael@0 270 }

mercurial