Bumping manifests a=b2g-bump
[gecko.git] / tools / profiler / nsProfiler.cpp
blobe92bc0dca65fa2053538c0b7d388d8a81bf9d508
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/. */
6 #include <string>
7 #include <sstream>
8 #include "GeckoProfiler.h"
9 #include "nsProfiler.h"
10 #include "nsMemory.h"
11 #include "nsString.h"
12 #include "mozilla/Services.h"
13 #include "nsIObserverService.h"
14 #include "nsIInterfaceRequestor.h"
15 #include "nsILoadContext.h"
16 #include "nsIWebNavigation.h"
17 #include "nsIInterfaceRequestorUtils.h"
18 #include "shared-libraries.h"
19 #include "js/Value.h"
21 using std::string;
23 NS_IMPL_ISUPPORTS(nsProfiler, nsIProfiler)
25 nsProfiler::nsProfiler()
26 : mLockedForPrivateBrowsing(false)
30 nsProfiler::~nsProfiler()
32 nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
33 if (observerService) {
34 observerService->RemoveObserver(this, "chrome-document-global-created");
35 observerService->RemoveObserver(this, "last-pb-context-exited");
39 nsresult
40 nsProfiler::Init() {
41 nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
42 if (observerService) {
43 observerService->AddObserver(this, "chrome-document-global-created", false);
44 observerService->AddObserver(this, "last-pb-context-exited", false);
46 return NS_OK;
49 NS_IMETHODIMP
50 nsProfiler::Observe(nsISupports *aSubject,
51 const char *aTopic,
52 const char16_t *aData)
54 if (strcmp(aTopic, "chrome-document-global-created") == 0) {
55 nsCOMPtr<nsIInterfaceRequestor> requestor = do_QueryInterface(aSubject);
56 nsCOMPtr<nsIWebNavigation> parentWebNav = do_GetInterface(requestor);
57 nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(parentWebNav);
58 if (loadContext && loadContext->UsePrivateBrowsing() && !mLockedForPrivateBrowsing) {
59 mLockedForPrivateBrowsing = true;
60 profiler_lock();
62 } else if (strcmp(aTopic, "last-pb-context-exited") == 0) {
63 mLockedForPrivateBrowsing = false;
64 profiler_unlock();
66 return NS_OK;
69 NS_IMETHODIMP
70 nsProfiler::StartProfiler(uint32_t aEntries, double aInterval,
71 const char** aFeatures, uint32_t aFeatureCount,
72 const char** aThreadNameFilters, uint32_t aFilterCount)
74 if (mLockedForPrivateBrowsing) {
75 return NS_ERROR_NOT_AVAILABLE;
78 profiler_start(aEntries, aInterval,
79 aFeatures, aFeatureCount,
80 aThreadNameFilters, aFilterCount);
81 return NS_OK;
84 NS_IMETHODIMP
85 nsProfiler::StopProfiler()
87 profiler_stop();
88 return NS_OK;
91 NS_IMETHODIMP
92 nsProfiler::IsPaused(bool *aIsPaused)
94 *aIsPaused = profiler_is_paused();
95 return NS_OK;
98 NS_IMETHODIMP
99 nsProfiler::PauseSampling()
101 profiler_pause();
102 return NS_OK;
105 NS_IMETHODIMP
106 nsProfiler::ResumeSampling()
108 profiler_resume();
109 return NS_OK;
112 NS_IMETHODIMP
113 nsProfiler::AddMarker(const char *aMarker)
115 PROFILER_MARKER(aMarker);
116 return NS_OK;
119 NS_IMETHODIMP
120 nsProfiler::GetProfile(char **aProfile)
122 char *profile = profiler_get_profile();
123 if (profile) {
124 size_t len = strlen(profile);
125 char *profileStr = static_cast<char *>
126 (nsMemory::Clone(profile, (len + 1) * sizeof(char)));
127 profileStr[len] = '\0';
128 *aProfile = profileStr;
129 free(profile);
131 return NS_OK;
134 static void
135 AddSharedLibraryInfoToStream(std::ostream& aStream, const SharedLibrary& aLib)
137 aStream << "{";
138 aStream << "\"start\":" << aLib.GetStart();
139 aStream << ",\"end\":" << aLib.GetEnd();
140 aStream << ",\"offset\":" << aLib.GetOffset();
141 aStream << ",\"name\":\"" << aLib.GetName() << "\"";
142 const std::string &breakpadId = aLib.GetBreakpadId();
143 aStream << ",\"breakpadId\":\"" << breakpadId << "\"";
144 #ifdef XP_WIN
145 // FIXME: remove this XP_WIN code when the profiler plugin has switched to
146 // using breakpadId.
147 std::string pdbSignature = breakpadId.substr(0, 32);
148 std::string pdbAgeStr = breakpadId.substr(32, breakpadId.size() - 1);
150 std::stringstream stream;
151 stream << pdbAgeStr;
153 unsigned pdbAge;
154 stream << std::hex;
155 stream >> pdbAge;
157 #ifdef DEBUG
158 std::ostringstream oStream;
159 oStream << pdbSignature << std::hex << std::uppercase << pdbAge;
160 MOZ_ASSERT(breakpadId == oStream.str());
161 #endif
163 aStream << ",\"pdbSignature\":\"" << pdbSignature << "\"";
164 aStream << ",\"pdbAge\":" << pdbAge;
165 aStream << ",\"pdbName\":\"" << aLib.GetName() << "\"";
166 #endif
167 aStream << "}";
170 std::string
171 GetSharedLibraryInfoString()
173 SharedLibraryInfo info = SharedLibraryInfo::GetInfoForSelf();
174 if (info.GetSize() == 0)
175 return "[]";
177 std::ostringstream os;
178 os << "[";
179 AddSharedLibraryInfoToStream(os, info.GetEntry(0));
181 for (size_t i = 1; i < info.GetSize(); i++) {
182 os << ",";
183 AddSharedLibraryInfoToStream(os, info.GetEntry(i));
186 os << "]";
187 return os.str();
190 NS_IMETHODIMP
191 nsProfiler::GetSharedLibraryInformation(nsAString& aOutString)
193 aOutString.Assign(NS_ConvertUTF8toUTF16(GetSharedLibraryInfoString().c_str()));
194 return NS_OK;
197 NS_IMETHODIMP nsProfiler::GetProfileData(JSContext* aCx,
198 JS::MutableHandle<JS::Value> aResult)
200 JS::RootedObject obj(aCx, profiler_get_profile_jsobject(aCx));
201 if (!obj) {
202 return NS_ERROR_FAILURE;
204 aResult.setObject(*obj);
205 return NS_OK;
208 NS_IMETHODIMP
209 nsProfiler::IsActive(bool *aIsActive)
211 *aIsActive = profiler_is_active();
212 return NS_OK;
215 NS_IMETHODIMP
216 nsProfiler::GetFeatures(uint32_t *aCount, char ***aFeatures)
218 uint32_t len = 0;
220 const char **features = profiler_get_features();
221 if (!features) {
222 *aCount = 0;
223 *aFeatures = nullptr;
224 return NS_OK;
227 while (features[len]) {
228 len++;
231 char **featureList = static_cast<char **>
232 (nsMemory::Alloc(len * sizeof(char*)));
234 for (size_t i = 0; i < len; i++) {
235 size_t strLen = strlen(features[i]);
236 featureList[i] = static_cast<char *>
237 (nsMemory::Clone(features[i], (strLen + 1) * sizeof(char)));
240 *aFeatures = featureList;
241 *aCount = len;
242 return NS_OK;