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/. */
8 #include "GeckoProfiler.h"
9 #include "nsProfiler.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"
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");
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);
50 nsProfiler::Observe(nsISupports
*aSubject
,
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;
62 } else if (strcmp(aTopic
, "last-pb-context-exited") == 0) {
63 mLockedForPrivateBrowsing
= false;
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
);
85 nsProfiler::StopProfiler()
92 nsProfiler::IsPaused(bool *aIsPaused
)
94 *aIsPaused
= profiler_is_paused();
99 nsProfiler::PauseSampling()
106 nsProfiler::ResumeSampling()
113 nsProfiler::AddMarker(const char *aMarker
)
115 PROFILER_MARKER(aMarker
);
120 nsProfiler::GetProfile(char **aProfile
)
122 char *profile
= profiler_get_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
;
135 AddSharedLibraryInfoToStream(std::ostream
& aStream
, const SharedLibrary
& aLib
)
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
<< "\"";
145 // FIXME: remove this XP_WIN code when the profiler plugin has switched to
147 std::string pdbSignature
= breakpadId
.substr(0, 32);
148 std::string pdbAgeStr
= breakpadId
.substr(32, breakpadId
.size() - 1);
150 std::stringstream stream
;
158 std::ostringstream oStream
;
159 oStream
<< pdbSignature
<< std::hex
<< std::uppercase
<< pdbAge
;
160 MOZ_ASSERT(breakpadId
== oStream
.str());
163 aStream
<< ",\"pdbSignature\":\"" << pdbSignature
<< "\"";
164 aStream
<< ",\"pdbAge\":" << pdbAge
;
165 aStream
<< ",\"pdbName\":\"" << aLib
.GetName() << "\"";
171 GetSharedLibraryInfoString()
173 SharedLibraryInfo info
= SharedLibraryInfo::GetInfoForSelf();
174 if (info
.GetSize() == 0)
177 std::ostringstream os
;
179 AddSharedLibraryInfoToStream(os
, info
.GetEntry(0));
181 for (size_t i
= 1; i
< info
.GetSize(); i
++) {
183 AddSharedLibraryInfoToStream(os
, info
.GetEntry(i
));
191 nsProfiler::GetSharedLibraryInformation(nsAString
& aOutString
)
193 aOutString
.Assign(NS_ConvertUTF8toUTF16(GetSharedLibraryInfoString().c_str()));
197 NS_IMETHODIMP
nsProfiler::GetProfileData(JSContext
* aCx
,
198 JS::MutableHandle
<JS::Value
> aResult
)
200 JS::RootedObject
obj(aCx
, profiler_get_profile_jsobject(aCx
));
202 return NS_ERROR_FAILURE
;
204 aResult
.setObject(*obj
);
209 nsProfiler::IsActive(bool *aIsActive
)
211 *aIsActive
= profiler_is_active();
216 nsProfiler::GetFeatures(uint32_t *aCount
, char ***aFeatures
)
220 const char **features
= profiler_get_features();
223 *aFeatures
= nullptr;
227 while (features
[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
;