Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp
Warning:line 2907, column 12
Although the value stored to 'bytesAllocated' is used in the enclosing expression, the value is never actually read from 'bytesAllocated'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_js_xpconnect_src0.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=all -relaxed-aliasing -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -D DEBUG=1 -D OS_POSIX=1 -D OS_LINUX=1 -D STATIC_EXPORTABLE_JS_API -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -I /var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/xpconnect/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/glue -I /var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/loader -I /var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/caps -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/bindings -I /var/lib/jenkins/workspace/firefox-scan-build/dom/html -I /var/lib/jenkins/workspace/firefox-scan-build/dom/svg -I /var/lib/jenkins/workspace/firefox-scan-build/layout/base -I /var/lib/jenkins/workspace/firefox-scan-build/layout/style -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Os -Wwrite-strings -Wno-invalid-offsetof -Wno-error=maybe-uninitialized -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=coverage-mismatch -Wno-error=free-nonheap-object -Wno-shadow -fdeprecated-macro -fdebug-compilation-dir /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/xpconnect/src -ferror-limit 19 -fmessage-length 0 -stack-protector 2 -fno-rtti -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-checker optin.cplusplus.UninitializedObject -analyzer-checker alpha.cplusplus.IteratorRange -analyzer-checker alpha.core.BoolAssignment -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2019-10-12-015329-15167-1 -x c++ Unified_cpp_js_xpconnect_src0.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/* Per JSRuntime object */
8
9#include "mozilla/ArrayUtils.h"
10#include "mozilla/MemoryReporting.h"
11#include "mozilla/UniquePtr.h"
12
13#include "xpcprivate.h"
14#include "xpcpublic.h"
15#include "XPCWrapper.h"
16#include "XPCJSMemoryReporter.h"
17#include "XPCJSThreadPool.h"
18#include "XrayWrapper.h"
19#include "WrapperFactory.h"
20#include "mozJSComponentLoader.h"
21#include "nsAutoPtr.h"
22#include "nsNetUtil.h"
23
24#include "nsExceptionHandler.h"
25#include "nsIMemoryInfoDumper.h"
26#include "nsIMemoryReporter.h"
27#include "nsIObserverService.h"
28#include "nsIDebug2.h"
29#include "nsIDocShell.h"
30#include "mozilla/dom/Document.h"
31#include "nsIRunnable.h"
32#include "nsIPlatformInfo.h"
33#include "nsPIDOMWindow.h"
34#include "nsPrintfCString.h"
35#include "nsThreadPool.h"
36#include "nsWindowSizes.h"
37#include "mozilla/Preferences.h"
38#include "mozilla/Telemetry.h"
39#include "mozilla/Services.h"
40#include "mozilla/dom/ScriptLoader.h"
41#include "mozilla/dom/ScriptSettings.h"
42
43#include "nsContentUtils.h"
44#include "nsCCUncollectableMarker.h"
45#include "nsCycleCollectionNoteRootCallback.h"
46#include "nsCycleCollector.h"
47#include "jsapi.h"
48#include "js/BuildId.h" // JS::BuildIdCharVector, JS::SetProcessBuildIdOp
49#include "js/experimental/SourceHook.h" // js::{,Set}SourceHook
50#include "js/GCAPI.h"
51#include "js/MemoryFunctions.h"
52#include "js/MemoryMetrics.h"
53#include "js/UbiNode.h"
54#include "js/UbiNodeUtils.h"
55#include "mozilla/dom/GeneratedAtomList.h"
56#include "mozilla/dom/BindingUtils.h"
57#include "mozilla/dom/Element.h"
58#include "mozilla/dom/WindowBinding.h"
59#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
60#include "mozilla/Atomics.h"
61#include "mozilla/Attributes.h"
62#include "mozilla/ProcessHangMonitor.h"
63#include "mozilla/Sprintf.h"
64#include "mozilla/UniquePtrExtensions.h"
65#include "mozilla/Unused.h"
66#include "AccessCheck.h"
67#include "nsGlobalWindow.h"
68#include "nsAboutProtocolUtils.h"
69
70#include "GeckoProfiler.h"
71#include "NodeUbiReporting.h"
72#include "nsIInputStream.h"
73#include "nsIXULRuntime.h"
74#include "nsJSPrincipals.h"
75
76#ifdef XP_WIN
77# include <windows.h>
78#endif
79
80using namespace mozilla;
81using namespace xpc;
82using namespace JS;
83using mozilla::dom::AutoEntryScript;
84using mozilla::dom::PerThreadAtomCache;
85
86/***************************************************************************/
87
88const char* const XPCJSRuntime::mStrings[] = {
89 "constructor", // IDX_CONSTRUCTOR
90 "toString", // IDX_TO_STRING
91 "toSource", // IDX_TO_SOURCE
92 "lastResult", // IDX_LAST_RESULT
93 "returnCode", // IDX_RETURN_CODE
94 "value", // IDX_VALUE
95 "QueryInterface", // IDX_QUERY_INTERFACE
96 "Components", // IDX_COMPONENTS
97 "Cc", // IDX_CC
98 "Ci", // IDX_CI
99 "Cr", // IDX_CR
100 "Cu", // IDX_CU
101 "wrappedJSObject", // IDX_WRAPPED_JSOBJECT
102 "Object", // IDX_OBJECT
103 "Function", // IDX_FUNCTION
104 "prototype", // IDX_PROTOTYPE
105 "createInstance", // IDX_CREATE_INSTANCE
106 "item", // IDX_ITEM
107 "__proto__", // IDX_PROTO
108 "eval", // IDX_EVAL
109 "controllers", // IDX_CONTROLLERS
110 "Controllers", // IDX_CONTROLLERS_CLASS
111 "realFrameElement", // IDX_REALFRAMEELEMENT
112 "length", // IDX_LENGTH
113 "name", // IDX_NAME
114 "undefined", // IDX_UNDEFINED
115 "", // IDX_EMPTYSTRING
116 "fileName", // IDX_FILENAME
117 "lineNumber", // IDX_LINENUMBER
118 "columnNumber", // IDX_COLUMNNUMBER
119 "stack", // IDX_STACK
120 "message", // IDX_MESSAGE
121 "lastIndex", // IDX_LASTINDEX
122 "then", // IDX_THEN
123 "isInstance", // IDX_ISINSTANCE
124 "Infinity", // IDX_INFINITY
125 "NaN", // IDX_NAN
126 "classId", // IDX_CLASS_ID
127 "interfaceId", // IDX_INTERFACE_ID
128 "initializer", // IDX_INITIALIZER
129};
130
131/***************************************************************************/
132
133// *Some* NativeSets are referenced from mClassInfo2NativeSetMap.
134// *All* NativeSets are referenced from mNativeSetMap.
135// So, in mClassInfo2NativeSetMap we just clear references to the unmarked.
136// In mNativeSetMap we clear the references to the unmarked *and* delete them.
137
138class AsyncFreeSnowWhite : public Runnable {
139 public:
140 NS_IMETHODvirtual nsresult Run() override {
141 AUTO_PROFILER_LABEL("AsyncFreeSnowWhite::Run", GCCC)mozilla::AutoProfilerLabel raiiObject141( "AsyncFreeSnowWhite::Run"
, nullptr, JS::ProfilingCategoryPair::GCCC)
;
142
143 TimeStamp start = TimeStamp::Now();
144 // 2 ms budget, given that kICCSliceBudget is only 3 ms
145 js::SliceBudget budget = js::SliceBudget(js::TimeBudget(2));
146 bool hadSnowWhiteObjects =
147 nsCycleCollector_doDeferredDeletionWithBudget(budget);
148 Telemetry::Accumulate(
149 Telemetry::CYCLE_COLLECTOR_ASYNC_SNOW_WHITE_FREEING,
150 uint32_t((TimeStamp::Now() - start).ToMilliseconds()));
151 if (hadSnowWhiteObjects && !mContinuation) {
152 mContinuation = true;
153 if (NS_FAILED(Dispatch())((bool)(__builtin_expect(!!(NS_FAILED_impl(Dispatch())), 0)))) {
154 mActive = false;
155 }
156 } else {
157 mActive = false;
158 }
159 return NS_OK;
160 }
161
162 nsresult Dispatch() {
163 nsCOMPtr<nsIRunnable> self(this);
164 return NS_DispatchToCurrentThreadQueue(self.forget(), 500,
165 EventQueuePriority::Idle);
166 }
167
168 void Start(bool aContinuation = false, bool aPurge = false) {
169 if (mContinuation) {
170 mContinuation = aContinuation;
171 }
172 mPurge = aPurge;
173 if (!mActive && NS_SUCCEEDED(Dispatch())((bool)(__builtin_expect(!!(!NS_FAILED_impl(Dispatch())), 1))
)
) {
174 mActive = true;
175 }
176 }
177
178 AsyncFreeSnowWhite()
179 : Runnable("AsyncFreeSnowWhite"),
180 mContinuation(false),
181 mActive(false),
182 mPurge(false) {}
183
184 public:
185 bool mContinuation;
186 bool mActive;
187 bool mPurge;
188};
189
190namespace xpc {
191
192CompartmentPrivate::CompartmentPrivate(
193 JS::Compartment* c, mozilla::UniquePtr<XPCWrappedNativeScope> scope,
194 mozilla::BasePrincipal* origin, const SiteIdentifier& site)
195 : originInfo(origin, site),
196 wantXrays(false),
197 allowWaivers(true),
198 isWebExtensionContentScript(false),
199 allowCPOWs(false),
200 isContentXBLCompartment(false),
201 isUAWidgetCompartment(false),
202 hasExclusiveExpandos(false),
203 universalXPConnectEnabled(false),
204 wasShutdown(false),
205 mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH32)),
206 mScope(std::move(scope)) {
207 MOZ_COUNT_CTOR(xpc::CompartmentPrivate)do { static_assert(mozilla::IsClass<xpc::CompartmentPrivate
>::value, "Token '" "xpc::CompartmentPrivate" "' is not a class type."
); static_assert(!mozilla::IsBaseOf<nsISupports, xpc::CompartmentPrivate
>::value, "nsISupports classes don't need to call MOZ_COUNT_CTOR or "
"MOZ_COUNT_DTOR");; NS_LogCtor((void*)this, "xpc::CompartmentPrivate"
, sizeof(*this)); } while (0)
;
208}
209
210CompartmentPrivate::~CompartmentPrivate() {
211 MOZ_COUNT_DTOR(xpc::CompartmentPrivate)do { static_assert(mozilla::IsClass<xpc::CompartmentPrivate
>::value, "Token '" "xpc::CompartmentPrivate" "' is not a class type."
); static_assert(!mozilla::IsBaseOf<nsISupports, xpc::CompartmentPrivate
>::value, "nsISupports classes don't need to call MOZ_COUNT_CTOR or "
"MOZ_COUNT_DTOR");; NS_LogDtor((void*)this, "xpc::CompartmentPrivate"
, sizeof(*this)); } while (0)
;
212 delete mWrappedJSMap;
213}
214
215void CompartmentPrivate::SystemIsBeingShutDown() {
216 // We may call this multiple times when the compartment contains more than one
217 // realm.
218 if (!wasShutdown) {
219 mWrappedJSMap->ShutdownMarker();
220 wasShutdown = true;
221 }
222}
223
224RealmPrivate::RealmPrivate(JS::Realm* realm) : scriptability(realm) {
225 mozilla::PodArrayZero(wrapperDenialWarnings);
226}
227
228/* static */
229void RealmPrivate::Init(HandleObject aGlobal, const SiteIdentifier& aSite) {
230 MOZ_ASSERT(aGlobal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aGlobal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aGlobal))), 0))) { MOZ_ReportAssertionFailure
("aGlobal", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 230); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aGlobal" ")"
); do { *((volatile int*)__null) = 230; ::abort(); } while (false
); } } while (false)
;
231 DebugOnly<const JSClass*> clasp = js::GetObjectClass(aGlobal);
232 MOZ_ASSERT(clasp->flags &do { static_assert( mozilla::detail::AssertionConditionType<
decltype(clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS
| JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE
) || dom::IsDOMClass(clasp)))), 0))) { MOZ_ReportAssertionFailure
("clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 234); AnnotateMozCrashReason("MOZ_ASSERT" "(" "clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp)"
")"); do { *((volatile int*)__null) = 234; ::abort(); } while
(false); } } while (false)
233 (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS
| JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE
) || dom::IsDOMClass(clasp)))), 0))) { MOZ_ReportAssertionFailure
("clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 234); AnnotateMozCrashReason("MOZ_ASSERT" "(" "clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp)"
")"); do { *((volatile int*)__null) = 234; ::abort(); } while
(false); } } while (false)
234 dom::IsDOMClass(clasp))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS
| JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE
) || dom::IsDOMClass(clasp)))), 0))) { MOZ_ReportAssertionFailure
("clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 234); AnnotateMozCrashReason("MOZ_ASSERT" "(" "clasp->flags & (JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_HAS_PRIVATE) || dom::IsDOMClass(clasp)"
")"); do { *((volatile int*)__null) = 234; ::abort(); } while
(false); } } while (false)
;
235
236 Realm* realm = GetObjectRealmOrNull(aGlobal);
237
238 // Create the realm private.
239 RealmPrivate* realmPriv = new RealmPrivate(realm);
240 MOZ_ASSERT(!GetRealmPrivate(realm))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!GetRealmPrivate(realm))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!GetRealmPrivate(realm)))), 0
))) { MOZ_ReportAssertionFailure("!GetRealmPrivate(realm)", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 240); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!GetRealmPrivate(realm)"
")"); do { *((volatile int*)__null) = 240; ::abort(); } while
(false); } } while (false)
;
241 SetRealmPrivate(realm, realmPriv);
242
243 nsIPrincipal* principal = GetRealmPrincipal(realm);
244 Compartment* c = js::GetObjectCompartment(aGlobal);
245
246 // Create the compartment private if needed.
247 if (CompartmentPrivate* priv = CompartmentPrivate::Get(c)) {
248 MOZ_ASSERT(priv->originInfo.IsSameOrigin(principal))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(priv->originInfo.IsSameOrigin(principal))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(priv->originInfo.IsSameOrigin(principal)))), 0))) { MOZ_ReportAssertionFailure
("priv->originInfo.IsSameOrigin(principal)", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 248); AnnotateMozCrashReason("MOZ_ASSERT" "(" "priv->originInfo.IsSameOrigin(principal)"
")"); do { *((volatile int*)__null) = 248; ::abort(); } while
(false); } } while (false)
;
249 } else {
250 auto scope = mozilla::MakeUnique<XPCWrappedNativeScope>(c, aGlobal);
251 priv = new CompartmentPrivate(c, std::move(scope),
252 BasePrincipal::Cast(principal), aSite);
253 JS_SetCompartmentPrivate(c, priv);
254 }
255}
256
257static bool TryParseLocationURICandidate(
258 const nsACString& uristr, RealmPrivate::LocationHint aLocationHint,
259 nsIURI** aURI) {
260 static NS_NAMED_LITERAL_CSTRING(kGRE, "resource://gre/")const nsLiteralCString kGRE("" "resource://gre/");
261 static NS_NAMED_LITERAL_CSTRING(kToolkit, "chrome://global/")const nsLiteralCString kToolkit("" "chrome://global/");
262 static NS_NAMED_LITERAL_CSTRING(kBrowser, "chrome://browser/")const nsLiteralCString kBrowser("" "chrome://browser/");
263
264 if (aLocationHint == RealmPrivate::LocationHintAddon) {
265 // Blacklist some known locations which are clearly not add-on related.
266 if (StringBeginsWith(uristr, kGRE) || StringBeginsWith(uristr, kToolkit) ||
267 StringBeginsWith(uristr, kBrowser))
268 return false;
269
270 // -- GROSS HACK ALERT --
271 // The Yandex Elements 8.10.2 extension implements its own "xb://" URL
272 // scheme. If we call NS_NewURI() on an "xb://..." URL, we'll end up
273 // calling into the extension's own JS-implemented nsIProtocolHandler
274 // object, which we can't allow while we're iterating over the JS heap.
275 // So just skip any such URL.
276 // -- GROSS HACK ALERT --
277 if (StringBeginsWith(uristr, NS_LITERAL_CSTRING("xb")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "xb"))
)) {
278 return false;
279 }
280 }
281
282 nsCOMPtr<nsIURI> uri;
283 if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), uristr))((bool)(__builtin_expect(!!(NS_FAILED_impl(NS_NewURI(getter_AddRefs
(uri), uristr))), 0)))
) {
284 return false;
285 }
286
287 nsAutoCString scheme;
288 if (NS_FAILED(uri->GetScheme(scheme))((bool)(__builtin_expect(!!(NS_FAILED_impl(uri->GetScheme(
scheme))), 0)))
) {
289 return false;
290 }
291
292 // Cannot really map data: and blob:.
293 // Also, data: URIs are pretty memory hungry, which is kinda bad
294 // for memory reporter use.
295 if (scheme.EqualsLiteral("data") || scheme.EqualsLiteral("blob")) {
296 return false;
297 }
298
299 uri.forget(aURI);
300 return true;
301}
302
303bool RealmPrivate::TryParseLocationURI(RealmPrivate::LocationHint aLocationHint,
304 nsIURI** aURI) {
305 if (!aURI) {
306 return false;
307 }
308
309 // Need to parse the URI.
310 if (location.IsEmpty()) {
311 return false;
312 }
313
314 // Handle Sandbox location strings.
315 // A sandbox string looks like this, for anonymous sandboxes, and builds
316 // where Sandbox location tagging is enabled:
317 //
318 // <sandboxName> (from: <js-stack-frame-filename>:<lineno>)
319 //
320 // where <sandboxName> is user-provided via Cu.Sandbox()
321 // and <js-stack-frame-filename> and <lineno> is the stack frame location
322 // from where Cu.Sandbox was called.
323 //
324 // Otherwise, it is simply the caller-provided name, which is usually a URI.
325 //
326 // <js-stack-frame-filename> furthermore is "free form", often using a
327 // "uri -> uri -> ..." chain. The following code will and must handle this
328 // common case.
329 //
330 // It should be noted that other parts of the code may already rely on the
331 // "format" of these strings.
332
333 static const nsDependentCString from("(from: ");
334 static const nsDependentCString arrow(" -> ");
335 static const size_t fromLength = from.Length();
336 static const size_t arrowLength = arrow.Length();
337
338 // See: XPCComponents.cpp#AssembleSandboxMemoryReporterName
339 int32_t idx = location.Find(from);
340 if (idx < 0) {
341 return TryParseLocationURICandidate(location, aLocationHint, aURI);
342 }
343
344 // When parsing we're looking for the right-most URI. This URI may be in
345 // <sandboxName>, so we try this first.
346 if (TryParseLocationURICandidate(Substring(location, 0, idx), aLocationHint,
347 aURI))
348 return true;
349
350 // Not in <sandboxName> so we need to inspect <js-stack-frame-filename> and
351 // the chain that is potentially contained within and grab the rightmost
352 // item that is actually a URI.
353
354 // First, hack off the :<lineno>) part as well
355 int32_t ridx = location.RFind(NS_LITERAL_CSTRING(":")static_cast<const nsLiteralCString&>(nsLiteralCString
("" ":"))
);
356 nsAutoCString chain(
357 Substring(location, idx + fromLength, ridx - idx - fromLength));
358
359 // Loop over the "->" chain. This loop also works for non-chains, or more
360 // correctly chains with only one item.
361 for (;;) {
362 idx = chain.RFind(arrow);
363 if (idx < 0) {
364 // This is the last chain item. Try to parse what is left.
365 return TryParseLocationURICandidate(chain, aLocationHint, aURI);
366 }
367
368 // Try to parse current chain item
369 if (TryParseLocationURICandidate(Substring(chain, idx + arrowLength),
370 aLocationHint, aURI))
371 return true;
372
373 // Current chain item couldn't be parsed.
374 // Strip current item and continue.
375 chain = Substring(chain, 0, idx);
376 }
377
378 MOZ_CRASH("Chain parser loop does not terminate")do { MOZ_ReportCrash("" "Chain parser loop does not terminate"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 378); AnnotateMozCrashReason("MOZ_CRASH(" "Chain parser loop does not terminate"
")"); do { *((volatile int*)__null) = 378; ::abort(); } while
(false); } while (false)
;
379}
380
381static bool PrincipalImmuneToScriptPolicy(nsIPrincipal* aPrincipal) {
382 // System principal gets a free pass.
383 if (aPrincipal->IsSystemPrincipal()) {
384 return true;
385 }
386
387 auto principal = BasePrincipal::Cast(aPrincipal);
388
389 // ExpandedPrincipal gets a free pass.
390 if (principal->Is<ExpandedPrincipal>()) {
391 return true;
392 }
393
394 // WebExtension principals get a free pass.
395 if (principal->AddonPolicy()) {
396 return true;
397 }
398
399 // Check whether our URI is an "about:" URI that allows scripts. If it is,
400 // we need to allow JS to run.
401 if (aPrincipal->SchemeIs("about")) {
402 nsCOMPtr<nsIURI> principalURI;
403 aPrincipal->GetURI(getter_AddRefs(principalURI));
404 MOZ_ASSERT(principalURI)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(principalURI)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(principalURI))), 0))) { MOZ_ReportAssertionFailure
("principalURI", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 404); AnnotateMozCrashReason("MOZ_ASSERT" "(" "principalURI"
")"); do { *((volatile int*)__null) = 404; ::abort(); } while
(false); } } while (false)
;
405 nsCOMPtr<nsIAboutModule> module;
406 nsresult rv = NS_GetAboutModule(principalURI, getter_AddRefs(module));
407 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
408 uint32_t flags;
409 rv = module->GetURIFlags(principalURI, &flags);
410 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && (flags & nsIAboutModule::ALLOW_SCRIPT)) {
411 return true;
412 }
413 }
414 }
415
416 return false;
417}
418
419void RealmPrivate::RegisterStackFrame(JSStackFrameBase* aFrame) {
420 mJSStackFrames.PutEntry(aFrame);
421}
422
423void RealmPrivate::UnregisterStackFrame(JSStackFrameBase* aFrame) {
424 mJSStackFrames.RemoveEntry(aFrame);
425}
426
427void RealmPrivate::NukeJSStackFrames() {
428 for (auto iter = mJSStackFrames.Iter(); !iter.Done(); iter.Next()) {
429 iter.Get()->GetKey()->Clear();
430 }
431
432 mJSStackFrames.Clear();
433}
434
435void RegisterJSStackFrame(JS::Realm* aRealm, JSStackFrameBase* aStackFrame) {
436 RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm);
437 if (!realmPrivate) {
438 return;
439 }
440
441 realmPrivate->RegisterStackFrame(aStackFrame);
442}
443
444void UnregisterJSStackFrame(JS::Realm* aRealm, JSStackFrameBase* aStackFrame) {
445 RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm);
446 if (!realmPrivate) {
447 return;
448 }
449
450 realmPrivate->UnregisterStackFrame(aStackFrame);
451}
452
453void NukeJSStackFrames(JS::Realm* aRealm) {
454 RealmPrivate* realmPrivate = RealmPrivate::Get(aRealm);
455 if (!realmPrivate) {
456 return;
457 }
458
459 realmPrivate->NukeJSStackFrames();
460}
461
462Scriptability::Scriptability(JS::Realm* realm)
463 : mScriptBlocks(0),
464 mDocShellAllowsScript(true),
465 mScriptBlockedByPolicy(false) {
466 nsIPrincipal* prin = nsJSPrincipals::get(JS::GetRealmPrincipals(realm));
467 mImmuneToScriptPolicy = PrincipalImmuneToScriptPolicy(prin);
468
469 // If we're not immune, we should have a real principal with a URI.
470 // Check the URI against the new-style domain policy.
471 if (!mImmuneToScriptPolicy) {
472 nsCOMPtr<nsIURI> codebase;
473 nsresult rv = prin->GetURI(getter_AddRefs(codebase));
474 bool policyAllows;
475 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && codebase &&
476 NS_SUCCEEDED(nsXPConnect::SecurityManager()->PolicyAllowsScript(((bool)(__builtin_expect(!!(!NS_FAILED_impl(nsXPConnect::SecurityManager
()->PolicyAllowsScript( codebase, &policyAllows))), 1)
))
477 codebase, &policyAllows))((bool)(__builtin_expect(!!(!NS_FAILED_impl(nsXPConnect::SecurityManager
()->PolicyAllowsScript( codebase, &policyAllows))), 1)
))
) {
478 mScriptBlockedByPolicy = !policyAllows;
479 } else {
480 // Something went wrong - be safe and block script.
481 mScriptBlockedByPolicy = true;
482 }
483 }
484}
485
486bool Scriptability::Allowed() {
487 return mDocShellAllowsScript && !mScriptBlockedByPolicy && mScriptBlocks == 0;
488}
489
490bool Scriptability::IsImmuneToScriptPolicy() { return mImmuneToScriptPolicy; }
491
492void Scriptability::Block() { ++mScriptBlocks; }
493
494void Scriptability::Unblock() {
495 MOZ_ASSERT(mScriptBlocks > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mScriptBlocks > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mScriptBlocks > 0))), 0))
) { MOZ_ReportAssertionFailure("mScriptBlocks > 0", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 495); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mScriptBlocks > 0"
")"); do { *((volatile int*)__null) = 495; ::abort(); } while
(false); } } while (false)
;
496 --mScriptBlocks;
497}
498
499void Scriptability::SetDocShellAllowsScript(bool aAllowed) {
500 mDocShellAllowsScript = aAllowed || mImmuneToScriptPolicy;
501}
502
503/* static */
504Scriptability& Scriptability::Get(JSObject* aScope) {
505 return RealmPrivate::Get(aScope)->scriptability;
506}
507
508bool IsContentXBLCompartment(JS::Compartment* compartment) {
509 // We always eagerly create compartment privates for content XBL compartments.
510 CompartmentPrivate* priv = CompartmentPrivate::Get(compartment);
511 return priv && priv->isContentXBLCompartment;
512}
513
514bool IsContentXBLScope(JS::Realm* realm) {
515 return IsContentXBLCompartment(JS::GetCompartmentForRealm(realm));
516}
517
518bool IsInContentXBLScope(JSObject* obj) {
519 return IsContentXBLCompartment(js::GetObjectCompartment(obj));
520}
521
522bool IsUAWidgetCompartment(JS::Compartment* compartment) {
523 // We always eagerly create compartment privates for UA Widget compartments.
524 CompartmentPrivate* priv = CompartmentPrivate::Get(compartment);
525 return priv && priv->isUAWidgetCompartment;
526}
527
528bool IsUAWidgetScope(JS::Realm* realm) {
529 return IsUAWidgetCompartment(JS::GetCompartmentForRealm(realm));
530}
531
532bool IsInUAWidgetScope(JSObject* obj) {
533 return IsUAWidgetCompartment(js::GetObjectCompartment(obj));
534}
535
536bool CompartmentOriginInfo::MightBeWebContent() const {
537 // Compartments with principals that are either the system principal or an
538 // expanded principal are definitely not web content.
539 return !nsContentUtils::IsSystemOrExpandedPrincipal(mOrigin);
540}
541
542bool MightBeWebContentCompartment(JS::Compartment* compartment) {
543 if (CompartmentPrivate* priv = CompartmentPrivate::Get(compartment)) {
544 return priv->originInfo.MightBeWebContent();
545 }
546
547 // No CompartmentPrivate; try IsSystemCompartment.
548 return !js::IsSystemCompartment(compartment);
549}
550
551bool IsUniversalXPConnectEnabled(JS::Compartment* compartment) {
552 CompartmentPrivate* priv = CompartmentPrivate::Get(compartment);
553 if (!priv) {
554 return false;
555 }
556 return priv->universalXPConnectEnabled;
557}
558
559bool IsUniversalXPConnectEnabled(JSContext* cx) {
560 JS::Compartment* compartment = js::GetContextCompartment(cx);
561 if (!compartment) {
562 return false;
563 }
564 return IsUniversalXPConnectEnabled(compartment);
565}
566
567bool EnableUniversalXPConnect(JSContext* cx) {
568 JS::Compartment* compartment = js::GetContextCompartment(cx);
569 if (!compartment) {
570 return true;
571 }
572 // Never set universalXPConnectEnabled on a chrome compartment - it confuses
573 // the security wrapping code.
574 if (AccessCheck::isChrome(compartment)) {
575 return true;
576 }
577 CompartmentPrivate* priv = CompartmentPrivate::Get(compartment);
578 if (!priv) {
579 return true;
580 }
581 if (priv->universalXPConnectEnabled) {
582 return true;
583 }
584 priv->universalXPConnectEnabled = true;
585
586 // Recompute all the cross-compartment wrappers leaving the newly-privileged
587 // compartment.
588 bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
589 js::AllCompartments());
590 NS_ENSURE_TRUE(ok, false)do { if ((__builtin_expect(!!(!(ok)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "ok" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 590); return false; } } while (false)
;
591
592 // The Components object normally isn't defined for unprivileged web content,
593 // but we define it when UniversalXPConnect is enabled to support legacy
594 // tests.
595 Compartment* comp = js::GetContextCompartment(cx);
596 XPCWrappedNativeScope* scope = CompartmentPrivate::Get(comp)->GetScope();
597 MOZ_ASSERT(scope)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(scope)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(scope))), 0))) { MOZ_ReportAssertionFailure
("scope", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 597); AnnotateMozCrashReason("MOZ_ASSERT" "(" "scope" ")");
do { *((volatile int*)__null) = 597; ::abort(); } while (false
); } } while (false)
;
598 scope->ForcePrivilegedComponents();
599 return scope->AttachComponentsObject(cx);
600}
601
602bool CompartmentOriginInfo::IsSameOrigin(nsIPrincipal* aOther) const {
603 return mOrigin->FastEquals(aOther);
604}
605
606/* static */
607bool CompartmentOriginInfo::Subsumes(JS::Compartment* aCompA,
608 JS::Compartment* aCompB) {
609 CompartmentPrivate* apriv = CompartmentPrivate::Get(aCompA);
610 CompartmentPrivate* bpriv = CompartmentPrivate::Get(aCompB);
611 MOZ_ASSERT(apriv)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(apriv)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(apriv))), 0))) { MOZ_ReportAssertionFailure
("apriv", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 611); AnnotateMozCrashReason("MOZ_ASSERT" "(" "apriv" ")");
do { *((volatile int*)__null) = 611; ::abort(); } while (false
); } } while (false)
;
612 MOZ_ASSERT(bpriv)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bpriv)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(bpriv))), 0))) { MOZ_ReportAssertionFailure
("bpriv", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 612); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bpriv" ")");
do { *((volatile int*)__null) = 612; ::abort(); } while (false
); } } while (false)
;
613 return apriv->originInfo.mOrigin->FastSubsumes(bpriv->originInfo.mOrigin);
614}
615
616/* static */
617bool CompartmentOriginInfo::SubsumesIgnoringFPD(JS::Compartment* aCompA,
618 JS::Compartment* aCompB) {
619 CompartmentPrivate* apriv = CompartmentPrivate::Get(aCompA);
620 CompartmentPrivate* bpriv = CompartmentPrivate::Get(aCompB);
621 MOZ_ASSERT(apriv)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(apriv)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(apriv))), 0))) { MOZ_ReportAssertionFailure
("apriv", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 621); AnnotateMozCrashReason("MOZ_ASSERT" "(" "apriv" ")");
do { *((volatile int*)__null) = 621; ::abort(); } while (false
); } } while (false)
;
622 MOZ_ASSERT(bpriv)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bpriv)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(bpriv))), 0))) { MOZ_ReportAssertionFailure
("bpriv", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 622); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bpriv" ")");
do { *((volatile int*)__null) = 622; ::abort(); } while (false
); } } while (false)
;
623 return apriv->originInfo.mOrigin->FastSubsumesIgnoringFPD(
624 bpriv->originInfo.mOrigin);
625}
626
627void SetCompartmentChangedDocumentDomain(JS::Compartment* compartment) {
628 // Note: we call this for all compartments that contain realms with a
629 // particular principal. Not all of these compartments have a
630 // CompartmentPrivate (for instance the temporary compartment/realm
631 // created by the JS engine for off-thread parsing).
632 if (CompartmentPrivate* priv = CompartmentPrivate::Get(compartment)) {
633 priv->originInfo.SetChangedDocumentDomain();
634 }
635}
636
637JSObject* UnprivilegedJunkScope() {
638 return XPCJSRuntime::Get()->UnprivilegedJunkScope();
639}
640
641JSObject* NACScope(JSObject* global) {
642 // If we're a chrome global, just use ourselves.
643 if (AccessCheck::isChrome(global)) {
644 return global;
645 }
646
647 JSObject* scope = UnprivilegedJunkScope();
648 JS::ExposeObjectToActiveJS(scope);
649 return scope;
650}
651
652JSObject* PrivilegedJunkScope() { return XPCJSRuntime::Get()->LoaderGlobal(); }
653
654JSObject* CompilationScope() { return XPCJSRuntime::Get()->LoaderGlobal(); }
655
656nsGlobalWindowInner* WindowOrNull(JSObject* aObj) {
657 MOZ_ASSERT(aObj)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aObj)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aObj))), 0))) { MOZ_ReportAssertionFailure
("aObj", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 657); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aObj" ")"); do
{ *((volatile int*)__null) = 657; ::abort(); } while (false)
; } } while (false)
;
658 MOZ_ASSERT(!js::IsWrapper(aObj))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!js::IsWrapper(aObj))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!js::IsWrapper(aObj)))), 0))
) { MOZ_ReportAssertionFailure("!js::IsWrapper(aObj)", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 658); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!js::IsWrapper(aObj)"
")"); do { *((volatile int*)__null) = 658; ::abort(); } while
(false); } } while (false)
;
659
660 nsGlobalWindowInner* win = nullptr;
661 UNWRAP_NON_WRAPPER_OBJECT(Window, aObj, win)mozilla::dom::UnwrapNonWrapperObject< mozilla::dom::prototypes
::id::Window, mozilla::dom::Window_Binding::NativeType>(aObj
, win)
;
662 return win;
663}
664
665nsGlobalWindowInner* WindowGlobalOrNull(JSObject* aObj) {
666 MOZ_ASSERT(aObj)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aObj)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aObj))), 0))) { MOZ_ReportAssertionFailure
("aObj", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 666); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aObj" ")"); do
{ *((volatile int*)__null) = 666; ::abort(); } while (false)
; } } while (false)
;
667 JSObject* glob = JS::GetNonCCWObjectGlobal(aObj);
668
669 return WindowOrNull(glob);
670}
671
672nsGlobalWindowInner* CurrentWindowOrNull(JSContext* cx) {
673 JSObject* glob = JS::CurrentGlobalOrNull(cx);
674 return glob ? WindowOrNull(glob) : nullptr;
675}
676
677// Nukes all wrappers into or out of the given realm, and prevents new
678// wrappers from being created. Additionally marks the realm as
679// unscriptable after wrappers have been nuked.
680//
681// Note: This should *only* be called for browser or extension realms.
682// Wrappers between web compartments must never be cut in web-observable
683// ways.
684void NukeAllWrappersForRealm(
685 JSContext* cx, JS::Realm* realm,
686 js::NukeReferencesToWindow nukeReferencesToWindow) {
687 // We do the following:
688 // * Nuke all wrappers into the realm.
689 // * Nuke all wrappers out of the realm's compartment, once we have nuked all
690 // realms in it.
691 js::NukeCrossCompartmentWrappers(cx, js::AllCompartments(), realm,
692 nukeReferencesToWindow,
693 js::NukeAllReferences);
694
695 // Mark the realm as unscriptable.
696 xpc::RealmPrivate::Get(realm)->scriptability.Block();
697}
698
699} // namespace xpc
700
701static void CompartmentDestroyedCallback(JSFreeOp* fop,
702 JS::Compartment* compartment) {
703 // NB - This callback may be called in JS_DestroyContext, which happens
704 // after the XPCJSRuntime has been torn down.
705
706 // Get the current compartment private into an AutoPtr (which will do the
707 // cleanup for us), and null out the private (which may already be null).
708 nsAutoPtr<CompartmentPrivate> priv(CompartmentPrivate::Get(compartment));
709 JS_SetCompartmentPrivate(compartment, nullptr);
710}
711
712static size_t CompartmentSizeOfIncludingThisCallback(
713 MallocSizeOf mallocSizeOf, JS::Compartment* compartment) {
714 CompartmentPrivate* priv = CompartmentPrivate::Get(compartment);
715 return priv ? priv->SizeOfIncludingThis(mallocSizeOf) : 0;
716}
717
718/*
719 * Return true if there exists a non-system inner window which is a current
720 * inner window and whose reflector is gray. We don't merge system
721 * compartments, so we don't use them to trigger merging CCs.
722 */
723bool XPCJSRuntime::UsefulToMergeZones() const {
724 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
MOZ_ReportAssertionFailure("NS_IsMainThread()", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 724); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 724; ::abort(); } while
(false); } } while (false)
;
725
726 // Turns out, actually making this return true often enough makes Windows
727 // mochitest-gl OOM a lot. Need to figure out what's going on there; see
728 // bug 1277036.
729
730 return false;
731}
732
733void XPCJSRuntime::TraceNativeBlackRoots(JSTracer* trc) {
734 for (CycleCollectedJSContext* ccx : Contexts()) {
735 auto* cx = static_cast<const XPCJSContext*>(ccx);
736 if (AutoMarkingPtr* roots = cx->mAutoRoots) {
737 roots->TraceJSAll(trc);
738 }
739 }
740
741 dom::TraceBlackJS(trc, nsIXPConnect::XPConnect()->GetIsShuttingDown());
742}
743
744void XPCJSRuntime::TraceAdditionalNativeGrayRoots(JSTracer* trc) {
745 XPCWrappedNativeScope::TraceWrappedNativesInAllScopes(this, trc);
746
747 for (XPCRootSetElem* e = mVariantRoots; e; e = e->GetNextRoot()) {
748 static_cast<XPCTraceableVariant*>(e)->TraceJS(trc);
749 }
750
751 for (XPCRootSetElem* e = mWrappedJSRoots; e; e = e->GetNextRoot()) {
752 static_cast<nsXPCWrappedJS*>(e)->TraceJS(trc);
753 }
754}
755
756void XPCJSRuntime::TraverseAdditionalNativeRoots(
757 nsCycleCollectionNoteRootCallback& cb) {
758 XPCWrappedNativeScope::SuspectAllWrappers(cb);
759
760 for (XPCRootSetElem* e = mVariantRoots; e; e = e->GetNextRoot()) {
761 XPCTraceableVariant* v = static_cast<XPCTraceableVariant*>(e);
762 cb.NoteXPCOMRoot(
763 v,
764 XPCTraceableVariant::NS_CYCLE_COLLECTION_INNERCLASScycleCollection::GetParticipant());
765 }
766
767 for (XPCRootSetElem* e = mWrappedJSRoots; e; e = e->GetNextRoot()) {
768 cb.NoteXPCOMRoot(
769 ToSupports(static_cast<nsXPCWrappedJS*>(e)),
770 nsXPCWrappedJS::NS_CYCLE_COLLECTION_INNERCLASScycleCollection::GetParticipant());
771 }
772}
773
774void XPCJSRuntime::UnmarkSkippableJSHolders() {
775 CycleCollectedJSRuntime::UnmarkSkippableJSHolders();
776}
777
778void XPCJSRuntime::PrepareForForgetSkippable() {
779 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
780 if (obs) {
781 obs->NotifyObservers(nullptr, "cycle-collector-forget-skippable", nullptr);
782 }
783}
784
785void XPCJSRuntime::BeginCycleCollectionCallback() {
786 nsJSContext::BeginCycleCollectionCallback();
787
788 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
789 if (obs) {
790 obs->NotifyObservers(nullptr, "cycle-collector-begin", nullptr);
791 }
792}
793
794void XPCJSRuntime::EndCycleCollectionCallback(CycleCollectorResults& aResults) {
795 nsJSContext::EndCycleCollectionCallback(aResults);
796
797 nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
798 if (obs) {
799 obs->NotifyObservers(nullptr, "cycle-collector-end", nullptr);
800 }
801}
802
803void XPCJSRuntime::DispatchDeferredDeletion(bool aContinuation, bool aPurge) {
804 mAsyncSnowWhiteFreer->Start(aContinuation, aPurge);
805}
806
807void xpc_UnmarkSkippableJSHolders() {
808 if (nsXPConnect::GetRuntimeInstance()) {
809 nsXPConnect::GetRuntimeInstance()->UnmarkSkippableJSHolders();
810 }
811}
812
813/* static */
814void XPCJSRuntime::GCSliceCallback(JSContext* cx, JS::GCProgress progress,
815 const JS::GCDescription& desc) {
816 XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
817 if (!self) {
818 return;
819 }
820
821 CrashReporter::SetGarbageCollecting(progress == JS::GC_CYCLE_BEGIN);
822
823 if (self->mPrevGCSliceCallback) {
824 (*self->mPrevGCSliceCallback)(cx, progress, desc);
825 }
826}
827
828/* static */
829void XPCJSRuntime::DoCycleCollectionCallback(JSContext* cx) {
830 // The GC has detected that a CC at this point would collect a tremendous
831 // amount of garbage that is being revivified unnecessarily.
832 NS_DispatchToCurrentThread(
833 NS_NewRunnableFunction("XPCJSRuntime::DoCycleCollectionCallback",
834 []() { nsJSContext::CycleCollectNow(nullptr); }));
835
836 XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
837 if (!self) {
838 return;
839 }
840
841 if (self->mPrevDoCycleCollectionCallback) {
842 (*self->mPrevDoCycleCollectionCallback)(cx);
843 }
844}
845
846void XPCJSRuntime::CustomGCCallback(JSGCStatus status) {
847 nsTArray<xpcGCCallback> callbacks(extraGCCallbacks);
848 for (uint32_t i = 0; i < callbacks.Length(); ++i) {
849 callbacks[i](status);
850 }
851}
852
853/* static */
854void XPCJSRuntime::FinalizeCallback(JSFreeOp* fop, JSFinalizeStatus status,
855 void* data) {
856 XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance();
857 if (!self) {
858 return;
859 }
860
861 switch (status) {
862 case JSFINALIZE_GROUP_PREPARE: {
863 MOZ_ASSERT(!self->mDoingFinalization, "bad state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!self->mDoingFinalization)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!self->mDoingFinalization
))), 0))) { MOZ_ReportAssertionFailure("!self->mDoingFinalization"
" (" "bad state" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 863); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!self->mDoingFinalization"
") (" "bad state" ")"); do { *((volatile int*)__null) = 863;
::abort(); } while (false); } } while (false)
;
864
865 MOZ_ASSERT(!self->mGCIsRunning, "bad state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!self->mGCIsRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!self->mGCIsRunning))), 0
))) { MOZ_ReportAssertionFailure("!self->mGCIsRunning" " ("
"bad state" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!self->mGCIsRunning"
") (" "bad state" ")"); do { *((volatile int*)__null) = 865;
::abort(); } while (false); } } while (false)
;
866 self->mGCIsRunning = true;
867
868 self->mDoingFinalization = true;
869
870 break;
871 }
872 case JSFINALIZE_GROUP_START: {
873 MOZ_ASSERT(self->mDoingFinalization, "bad state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->mDoingFinalization)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->mDoingFinalization)
)), 0))) { MOZ_ReportAssertionFailure("self->mDoingFinalization"
" (" "bad state" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 873); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->mDoingFinalization"
") (" "bad state" ")"); do { *((volatile int*)__null) = 873;
::abort(); } while (false); } } while (false)
;
874
875 MOZ_ASSERT(self->mGCIsRunning, "bad state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->mGCIsRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->mGCIsRunning))), 0)
)) { MOZ_ReportAssertionFailure("self->mGCIsRunning" " (" "bad state"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 875); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->mGCIsRunning"
") (" "bad state" ")"); do { *((volatile int*)__null) = 875;
::abort(); } while (false); } } while (false)
;
876 self->mGCIsRunning = false;
877
878 break;
879 }
880 case JSFINALIZE_GROUP_END: {
881 MOZ_ASSERT(self->mDoingFinalization, "bad state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->mDoingFinalization)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->mDoingFinalization)
)), 0))) { MOZ_ReportAssertionFailure("self->mDoingFinalization"
" (" "bad state" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 881); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->mDoingFinalization"
") (" "bad state" ")"); do { *((volatile int*)__null) = 881;
::abort(); } while (false); } } while (false)
;
882 self->mDoingFinalization = false;
883
884 break;
885 }
886 case JSFINALIZE_COLLECTION_END: {
887 MOZ_ASSERT(!self->mGCIsRunning, "bad state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!self->mGCIsRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!self->mGCIsRunning))), 0
))) { MOZ_ReportAssertionFailure("!self->mGCIsRunning" " ("
"bad state" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 887); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!self->mGCIsRunning"
") (" "bad state" ")"); do { *((volatile int*)__null) = 887;
::abort(); } while (false); } } while (false)
;
888 self->mGCIsRunning = true;
889
890 for (CycleCollectedJSContext* ccx : self->Contexts()) {
891 auto* cx = static_cast<const XPCJSContext*>(ccx);
892 if (AutoMarkingPtr* roots = cx->mAutoRoots) {
893 roots->MarkAfterJSFinalizeAll();
894 }
895
896 // Now we are going to recycle any unused WrappedNativeTearoffs.
897 // We do this by iterating all the live callcontexts
898 // and marking the tearoffs in use. And then we
899 // iterate over all the WrappedNative wrappers and sweep their
900 // tearoffs.
901 //
902 // This allows us to perhaps minimize the growth of the
903 // tearoffs. And also makes us not hold references to interfaces
904 // on our wrapped natives that we are not actually using.
905 //
906 // XXX We may decide to not do this on *every* gc cycle.
907
908 XPCCallContext* ccxp = cx->GetCallContext();
909 while (ccxp) {
910 // Deal with the strictness of callcontext that
911 // complains if you ask for a tearoff when
912 // it is in a state where the tearoff could not
913 // possibly be valid.
914 if (ccxp->CanGetTearOff()) {
915 XPCWrappedNativeTearOff* to = ccxp->GetTearOff();
916 if (to) {
917 to->Mark();
918 }
919 }
920 ccxp = ccxp->GetPrevCallContext();
921 }
922 }
923
924 XPCWrappedNativeScope::SweepAllWrappedNativeTearOffs();
925
926 // Now we need to kill the 'Dying' XPCWrappedNativeProtos.
927 // We transfered these native objects to this table when their
928 // JSObject's were finalized. We did not destroy them immediately
929 // at that point because the ordering of JS finalization is not
930 // deterministic and we did not yet know if any wrappers that
931 // might still be referencing the protos where still yet to be
932 // finalized and destroyed. We *do* know that the protos'
933 // JSObjects would not have been finalized if there were any
934 // wrappers that referenced the proto but where not themselves
935 // slated for finalization in this gc cycle. So... at this point
936 // we know that any and all wrappers that might have been
937 // referencing the protos in the dying list are themselves dead.
938 // So, we can safely delete all the protos in the list.
939
940 for (auto i = self->mDyingWrappedNativeProtoMap->Iter(); !i.Done();
941 i.Next()) {
942 auto entry = static_cast<XPCWrappedNativeProtoMap::Entry*>(i.Get());
943 delete static_cast<const XPCWrappedNativeProto*>(entry->key);
944 i.Remove();
945 }
946
947 MOZ_ASSERT(self->mGCIsRunning, "bad state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->mGCIsRunning)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->mGCIsRunning))), 0)
)) { MOZ_ReportAssertionFailure("self->mGCIsRunning" " (" "bad state"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 947); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->mGCIsRunning"
") (" "bad state" ")"); do { *((volatile int*)__null) = 947;
::abort(); } while (false); } } while (false)
;
948 self->mGCIsRunning = false;
949
950 break;
951 }
952 }
953}
954
955/* static */
956void XPCJSRuntime::WeakPointerZonesCallback(JSContext* cx, void* data) {
957 // Called before each sweeping slice -- after processing any final marking
958 // triggered by barriers -- to clear out any references to things that are
959 // about to be finalized and update any pointers to moved GC things.
960 XPCJSRuntime* self = static_cast<XPCJSRuntime*>(data);
961
962 self->mWrappedJSMap->UpdateWeakPointersAfterGC();
963 self->mUAWidgetScopeMap.sweep();
964}
965
966/* static */
967void XPCJSRuntime::WeakPointerCompartmentCallback(JSContext* cx,
968 JS::Compartment* comp,
969 void* data) {
970 // Called immediately after the ZoneGroup weak pointer callback, but only
971 // once for each compartment that is being swept.
972 CompartmentPrivate* xpcComp = CompartmentPrivate::Get(comp);
973 if (xpcComp) {
974 xpcComp->UpdateWeakPointersAfterGC();
975 }
976}
977
978void CompartmentPrivate::UpdateWeakPointersAfterGC() {
979 mRemoteProxies.sweep();
980 mWrappedJSMap->UpdateWeakPointersAfterGC();
981 mScope->UpdateWeakPointersAfterGC();
982}
983
984void XPCJSRuntime::CustomOutOfMemoryCallback() {
985 if (!Preferences::GetBool("memory.dump_reports_on_oom")) {
986 return;
987 }
988
989 nsCOMPtr<nsIMemoryInfoDumper> dumper =
990 do_GetService("@mozilla.org/memory-info-dumper;1");
991 if (!dumper) {
992 return;
993 }
994
995 // If this fails, it fails silently.
996 dumper->DumpMemoryInfoToTempDir(NS_LITERAL_STRING("due-to-JS-OOM")static_cast<const nsLiteralString&>(nsLiteralString
(u"" "due-to-JS-OOM"))
,
997 /* anonymize = */ false,
998 /* minimizeMemoryUsage = */ false);
999}
1000
1001void XPCJSRuntime::OnLargeAllocationFailure() {
1002 CycleCollectedJSRuntime::SetLargeAllocationFailure(OOMState::Reporting);
1003
1004 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
1005 if (os) {
1006 os->NotifyObservers(nullptr, "memory-pressure", u"heap-minimize");
1007 }
1008
1009 CycleCollectedJSRuntime::SetLargeAllocationFailure(OOMState::Reported);
1010}
1011
1012class LargeAllocationFailureRunnable final : public Runnable {
1013 Mutex mMutex;
1014 CondVar mCondVar;
1015 bool mWaiting;
1016
1017 virtual ~LargeAllocationFailureRunnable() { MOZ_ASSERT(!mWaiting)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mWaiting)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mWaiting))), 0))) { MOZ_ReportAssertionFailure
("!mWaiting", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1017); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mWaiting" ")"
); do { *((volatile int*)__null) = 1017; ::abort(); } while (
false); } } while (false)
; }
1018
1019 protected:
1020 NS_IMETHODvirtual nsresult Run() override {
1021 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
MOZ_ReportAssertionFailure("NS_IsMainThread()", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1021); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1021; ::abort(); } while
(false); } } while (false)
;
1022
1023 XPCJSRuntime::Get()->OnLargeAllocationFailure();
1024
1025 MutexAutoLock lock(mMutex);
1026 MOZ_ASSERT(mWaiting)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mWaiting)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mWaiting))), 0))) { MOZ_ReportAssertionFailure
("mWaiting", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1026); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mWaiting" ")"
); do { *((volatile int*)__null) = 1026; ::abort(); } while (
false); } } while (false)
;
1027
1028 mWaiting = false;
1029 mCondVar.Notify();
1030 return NS_OK;
1031 }
1032
1033 public:
1034 LargeAllocationFailureRunnable()
1035 : mozilla::Runnable("LargeAllocationFailureRunnable"),
1036 mMutex("LargeAllocationFailureRunnable::mMutex"),
1037 mCondVar(mMutex, "LargeAllocationFailureRunnable::mCondVar"),
1038 mWaiting(true) {
1039 MOZ_ASSERT(!NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!NS_IsMainThread()))), 0))) {
MOZ_ReportAssertionFailure("!NS_IsMainThread()", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1039); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1039; ::abort(); } while
(false); } } while (false)
;
1040 }
1041
1042 void BlockUntilDone() {
1043 MOZ_ASSERT(!NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!NS_IsMainThread()))), 0))) {
MOZ_ReportAssertionFailure("!NS_IsMainThread()", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1043); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1043; ::abort(); } while
(false); } } while (false)
;
1044
1045 MutexAutoLock lock(mMutex);
1046 while (mWaiting) {
1047 mCondVar.Wait();
1048 }
1049 }
1050};
1051
1052static void OnLargeAllocationFailureCallback() {
1053 // This callback can be called from any thread, including internal JS helper
1054 // and DOM worker threads. We need to send the low-memory event via the
1055 // observer service which can only be called on the main thread, so proxy to
1056 // the main thread if we're not there already. The purpose of this callback
1057 // is to synchronously free some memory so the caller can retry a failed
1058 // allocation, so block on the completion.
1059
1060 if (NS_IsMainThread()) {
1061 XPCJSRuntime::Get()->OnLargeAllocationFailure();
1062 return;
1063 }
1064
1065 RefPtr<LargeAllocationFailureRunnable> r = new LargeAllocationFailureRunnable;
1066 if (NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(r)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(NS_DispatchToMainThread
(r))), 0))), "NS_FAILED(NS_DispatchToMainThread(r))", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1066)
) {
1067 return;
1068 }
1069
1070 r->BlockUntilDone();
1071}
1072
1073bool mozilla::GetBuildId(JS::BuildIdCharVector* aBuildID) {
1074 nsCOMPtr<nsIPlatformInfo> info = do_GetService("@mozilla.org/xre/app-info;1");
1075 if (!info) {
1076 return false;
1077 }
1078
1079 nsCString buildID;
1080 nsresult rv = info->GetPlatformBuildID(buildID);
1081 NS_ENSURE_SUCCESS(rv, false)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "false", static_cast<uint32_t>(__rv)); NS_DebugBreak(
NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1081); return false; } } while (false)
;
1082
1083 if (!aBuildID->resize(buildID.Length())) {
1084 return false;
1085 }
1086
1087 for (size_t i = 0; i < buildID.Length(); i++) {
1088 (*aBuildID)[i] = buildID[i];
1089 }
1090
1091 return true;
1092}
1093
1094size_t XPCJSRuntime::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) {
1095 size_t n = 0;
1096 n += mallocSizeOf(this);
1097 n += mWrappedJSMap->SizeOfIncludingThis(mallocSizeOf);
1098 n += mIID2NativeInterfaceMap->SizeOfIncludingThis(mallocSizeOf);
1099 n += mClassInfo2NativeSetMap->ShallowSizeOfIncludingThis(mallocSizeOf);
1100 n += mNativeSetMap->SizeOfIncludingThis(mallocSizeOf);
1101
1102 n += CycleCollectedJSRuntime::SizeOfExcludingThis(mallocSizeOf);
1103
1104 // There are other XPCJSRuntime members that could be measured; the above
1105 // ones have been seen by DMD to be worth measuring. More stuff may be
1106 // added later.
1107
1108 return n;
1109}
1110
1111size_t CompartmentPrivate::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) {
1112 size_t n = mallocSizeOf(this);
1113 n += mWrappedJSMap->SizeOfIncludingThis(mallocSizeOf);
1114 n += mWrappedJSMap->SizeOfWrappedJS(mallocSizeOf);
1115 return n;
1116}
1117
1118/***************************************************************************/
1119
1120void XPCJSRuntime::SystemIsBeingShutDown() {
1121 // We don't want to track wrapped JS roots after this point since we're
1122 // making them !IsValid anyway through SystemIsBeingShutDown.
1123 mWrappedJSRoots = nullptr;
1124}
1125
1126StaticAutoPtr<HelperThreadPool> gHelperThreads;
1127
1128void InitializeHelperThreadPool() { gHelperThreads = new HelperThreadPool(); }
1129
1130void DispatchOffThreadTask(RunnableTask* task) {
1131 gHelperThreads->Dispatch(MakeAndAddRef<HelperThreadTaskHandler>(task));
1132}
1133
1134void XPCJSRuntime::Shutdown(JSContext* cx) {
1135 // This destructor runs before ~CycleCollectedJSContext, which does the actual
1136 // JS_DestroyContext() call. But destroying the context triggers one final GC,
1137 // which can call back into the context with various callbacks if we aren't
1138 // careful. Remove the relevant callbacks, but leave the weak pointer
1139 // callbacks to clear out any remaining table entries.
1140 JS_RemoveFinalizeCallback(cx, FinalizeCallback);
1141 xpc_DelocalizeRuntime(JS_GetRuntime(cx));
1142
1143 JS::SetGCSliceCallback(cx, mPrevGCSliceCallback);
1144
1145 // Shut down the helper threads
1146 gHelperThreads->Shutdown();
1147 gHelperThreads = nullptr;
1148
1149 // Clean up and destroy maps. Any remaining entries in mWrappedJSMap will be
1150 // cleaned up by the weak pointer callbacks.
1151 delete mIID2NativeInterfaceMap;
1152 mIID2NativeInterfaceMap = nullptr;
1153
1154 delete mClassInfo2NativeSetMap;
1155 mClassInfo2NativeSetMap = nullptr;
1156
1157 delete mNativeSetMap;
1158 mNativeSetMap = nullptr;
1159
1160 delete mDyingWrappedNativeProtoMap;
1161 mDyingWrappedNativeProtoMap = nullptr;
1162
1163 // Prevent ~LinkedList assertion failures if we leaked things.
1164 mWrappedNativeScopes.clear();
1165
1166 CycleCollectedJSRuntime::Shutdown(cx);
1167}
1168
1169XPCJSRuntime::~XPCJSRuntime() {
1170 MOZ_COUNT_DTOR_INHERITED(XPCJSRuntime, CycleCollectedJSRuntime)do { static_assert(mozilla::IsClass<XPCJSRuntime>::value
, "Token '" "XPCJSRuntime" "' is not a class type."); static_assert
(mozilla::IsClass<CycleCollectedJSRuntime>::value, "Token '"
"CycleCollectedJSRuntime" "' is not a class type."); static_assert
(!mozilla::IsBaseOf<nsISupports, XPCJSRuntime>::value, "nsISupports classes don't need to call MOZ_COUNT_CTOR or "
"MOZ_COUNT_DTOR");; NS_LogDtor((void*)this, "XPCJSRuntime", sizeof
(*this) - sizeof(CycleCollectedJSRuntime)); } while (0)
;
1171 delete mWrappedJSMap;
1172}
1173
1174// If |*anonymizeID| is non-zero and this is a user realm, the name will
1175// be anonymized.
1176static void GetRealmName(JS::Realm* realm, nsCString& name, int* anonymizeID,
1177 bool replaceSlashes) {
1178 if (*anonymizeID && !js::IsSystemRealm(realm)) {
1179 name.AppendPrintf("<anonymized-%d>", *anonymizeID);
1180 *anonymizeID += 1;
1181 } else if (JSPrincipals* principals = JS::GetRealmPrincipals(realm)) {
1182 nsresult rv = nsJSPrincipals::get(principals)->GetScriptLocation(name);
1183 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1184 name.AssignLiteral("(unknown)");
1185 }
1186
1187 // If the realm's location (name) differs from the principal's script
1188 // location, append the realm's location to allow differentiation of
1189 // multiple realms owned by the same principal (e.g. components owned
1190 // by the system or null principal).
1191 RealmPrivate* realmPrivate = RealmPrivate::Get(realm);
1192 if (realmPrivate) {
1193 const nsACString& location = realmPrivate->GetLocation();
1194 if (!location.IsEmpty() && !location.Equals(name)) {
1195 name.AppendLiteral(", ");
1196 name.Append(location);
1197 }
1198 }
1199
1200 if (*anonymizeID) {
1201 // We might have a file:// URL that includes a path from the local
1202 // filesystem, which should be omitted if we're anonymizing.
1203 static const char* filePrefix = "file://";
1204 int filePos = name.Find(filePrefix);
1205 if (filePos >= 0) {
1206 int pathPos = filePos + strlen(filePrefix);
1207 int lastSlashPos = -1;
1208 for (int i = pathPos; i < int(name.Length()); i++) {
1209 if (name[i] == '/' || name[i] == '\\') {
1210 lastSlashPos = i;
1211 }
1212 }
1213 if (lastSlashPos != -1) {
1214 name.ReplaceASCII(pathPos, lastSlashPos - pathPos, "<anonymized>");
1215 } else {
1216 // Something went wrong. Anonymize the entire path to be
1217 // safe.
1218 name.Truncate(pathPos);
1219 name += "<anonymized?!>";
1220 }
1221 }
1222
1223 // We might have a location like this:
1224 // inProcessBrowserChildGlobal?ownedBy=http://www.example.com/
1225 // The owner should be omitted if it's not a chrome: URI and we're
1226 // anonymizing.
1227 static const char* ownedByPrefix = "inProcessBrowserChildGlobal?ownedBy=";
1228 int ownedByPos = name.Find(ownedByPrefix);
1229 if (ownedByPos >= 0) {
1230 const char* chrome = "chrome:";
1231 int ownerPos = ownedByPos + strlen(ownedByPrefix);
1232 const nsDependentCSubstring& ownerFirstPart =
1233 Substring(name, ownerPos, strlen(chrome));
1234 if (!ownerFirstPart.EqualsASCII(chrome)) {
1235 name.Truncate(ownerPos);
1236 name += "<anonymized>";
1237 }
1238 }
1239 }
1240
1241 // A hack: replace forward slashes with '\\' so they aren't
1242 // treated as path separators. Users of the reporters
1243 // (such as about:memory) have to undo this change.
1244 if (replaceSlashes) {
1245 name.ReplaceChar('/', '\\');
1246 }
1247 } else {
1248 name.AssignLiteral("null-principal");
1249 }
1250}
1251
1252extern void xpc::GetCurrentRealmName(JSContext* cx, nsCString& name) {
1253 RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
1254 if (!global) {
1255 name.AssignLiteral("no global");
1256 return;
1257 }
1258
1259 JS::Realm* realm = GetNonCCWObjectRealm(global);
1260 int anonymizeID = 0;
1261 GetRealmName(realm, name, &anonymizeID, false);
1262}
1263
1264void xpc::AddGCCallback(xpcGCCallback cb) {
1265 XPCJSRuntime::Get()->AddGCCallback(cb);
1266}
1267
1268void xpc::RemoveGCCallback(xpcGCCallback cb) {
1269 XPCJSRuntime::Get()->RemoveGCCallback(cb);
1270}
1271
1272static int64_t JSMainRuntimeGCHeapDistinguishedAmount() {
1273 JSContext* cx = danger::GetJSContext();
1274 return int64_t(JS_GetGCParameter(cx, JSGC_TOTAL_CHUNKS)) * js::gc::ChunkSize;
1275}
1276
1277static int64_t JSMainRuntimeTemporaryPeakDistinguishedAmount() {
1278 JSContext* cx = danger::GetJSContext();
1279 return JS::PeakSizeOfTemporary(cx);
1280}
1281
1282static int64_t JSMainRuntimeCompartmentsSystemDistinguishedAmount() {
1283 JSContext* cx = danger::GetJSContext();
1284 return JS::SystemCompartmentCount(cx);
1285}
1286
1287static int64_t JSMainRuntimeCompartmentsUserDistinguishedAmount() {
1288 JSContext* cx = XPCJSContext::Get()->Context();
1289 return JS::UserCompartmentCount(cx);
1290}
1291
1292static int64_t JSMainRuntimeRealmsSystemDistinguishedAmount() {
1293 JSContext* cx = danger::GetJSContext();
1294 return JS::SystemRealmCount(cx);
1295}
1296
1297static int64_t JSMainRuntimeRealmsUserDistinguishedAmount() {
1298 JSContext* cx = XPCJSContext::Get()->Context();
1299 return JS::UserRealmCount(cx);
1300}
1301
1302class JSMainRuntimeTemporaryPeakReporter final : public nsIMemoryReporter {
1303 ~JSMainRuntimeTemporaryPeakReporter() {}
1304
1305 public:
1306 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; typedef mozilla::FalseType HasThreadSafeRefCnt
; protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
1307
1308 NS_IMETHODvirtual nsresult CollectReports(nsIHandleReportCallback* aHandleReport,
1309 nsISupports* aData, bool aAnonymize) override {
1310 MOZ_COLLECT_REPORT((void)aHandleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-temporary-peak"
)), KIND_OTHER, UNITS_BYTES, JSMainRuntimeTemporaryPeakDistinguishedAmount
(), static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Peak transient data size in the main JSRuntime (the current size "
"of which is reported as " "'explicit/js-non-window/runtime/temporary')."
)), aData)
1311 "js-main-runtime-temporary-peak", KIND_OTHER, UNITS_BYTES,(void)aHandleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-temporary-peak"
)), KIND_OTHER, UNITS_BYTES, JSMainRuntimeTemporaryPeakDistinguishedAmount
(), static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Peak transient data size in the main JSRuntime (the current size "
"of which is reported as " "'explicit/js-non-window/runtime/temporary')."
)), aData)
1312 JSMainRuntimeTemporaryPeakDistinguishedAmount(),(void)aHandleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-temporary-peak"
)), KIND_OTHER, UNITS_BYTES, JSMainRuntimeTemporaryPeakDistinguishedAmount
(), static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Peak transient data size in the main JSRuntime (the current size "
"of which is reported as " "'explicit/js-non-window/runtime/temporary')."
)), aData)
1313 "Peak transient data size in the main JSRuntime (the current size "(void)aHandleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-temporary-peak"
)), KIND_OTHER, UNITS_BYTES, JSMainRuntimeTemporaryPeakDistinguishedAmount
(), static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Peak transient data size in the main JSRuntime (the current size "
"of which is reported as " "'explicit/js-non-window/runtime/temporary')."
)), aData)
1314 "of which is reported as "(void)aHandleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-temporary-peak"
)), KIND_OTHER, UNITS_BYTES, JSMainRuntimeTemporaryPeakDistinguishedAmount
(), static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Peak transient data size in the main JSRuntime (the current size "
"of which is reported as " "'explicit/js-non-window/runtime/temporary')."
)), aData)
1315 "'explicit/js-non-window/runtime/temporary').")(void)aHandleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-temporary-peak"
)), KIND_OTHER, UNITS_BYTES, JSMainRuntimeTemporaryPeakDistinguishedAmount
(), static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Peak transient data size in the main JSRuntime (the current size "
"of which is reported as " "'explicit/js-non-window/runtime/temporary')."
)), aData)
;
1316
1317 return NS_OK;
1318 }
1319};
1320
1321NS_IMPL_ISUPPORTS(JSMainRuntimeTemporaryPeakReporter, nsIMemoryReporter)MozExternalRefCountType JSMainRuntimeTemporaryPeakReporter::AddRef
(void) { static_assert(!mozilla::IsDestructible<JSMainRuntimeTemporaryPeakReporter
>::value, "Reference-counted class " "JSMainRuntimeTemporaryPeakReporter"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1321); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1321; ::abort(); } while (false); } } while (false); do { static_assert
( mozilla::detail::AssertionConditionType<decltype("JSMainRuntimeTemporaryPeakReporter"
!= nullptr)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!("JSMainRuntimeTemporaryPeakReporter"
!= nullptr))), 0))) { MOZ_ReportAssertionFailure("\"JSMainRuntimeTemporaryPeakReporter\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1321); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"JSMainRuntimeTemporaryPeakReporter\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1321; ::abort(); } while (false); } } while (false); if (
!mRefCnt.isThreadSafe) this->_mOwningThread.AssertOwnership
("JSMainRuntimeTemporaryPeakReporter" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("JSMainRuntimeTemporaryPeakReporter"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
JSMainRuntimeTemporaryPeakReporter::Release(void) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " ("
"dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1321); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1321
; ::abort(); } while (false); } } while (false); do { static_assert
( mozilla::detail::AssertionConditionType<decltype("JSMainRuntimeTemporaryPeakReporter"
!= nullptr)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!("JSMainRuntimeTemporaryPeakReporter"
!= nullptr))), 0))) { MOZ_ReportAssertionFailure("\"JSMainRuntimeTemporaryPeakReporter\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1321); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"JSMainRuntimeTemporaryPeakReporter\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1321; ::abort(); } while (false); } } while (false); if (
!mRefCnt.isThreadSafe) this->_mOwningThread.AssertOwnership
("JSMainRuntimeTemporaryPeakReporter" " not thread-safe"); const
char* const nametmp = "JSMainRuntimeTemporaryPeakReporter"; nsrefcnt
count = --mRefCnt; NS_LogRelease((this), (count), (nametmp))
; if (count == 0) { mRefCnt = 1; delete (this); return 0; } return
count; } nsresult JSMainRuntimeTemporaryPeakReporter::QueryInterface
(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1321); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&(nsIMemoryReporter
::COMTypeInfo<nsIMemoryReporter, void>::kIID), int32_t(
reinterpret_cast<char*>(static_cast<nsIMemoryReporter
*>((JSMainRuntimeTemporaryPeakReporter*)0x1000)) - reinterpret_cast
<char*>((JSMainRuntimeTemporaryPeakReporter*)0x1000))},
{&(nsISupports::COMTypeInfo<nsISupports, void>::kIID
), int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIMemoryReporter*>((JSMainRuntimeTemporaryPeakReporter
*)0x1000))) - reinterpret_cast<char*>((JSMainRuntimeTemporaryPeakReporter
*)0x1000))}, { nullptr, 0 } } ; static_assert((sizeof(table) /
sizeof(table[0])) > 1, "need at least 1 interface"); rv =
NS_TableDrivenQI(static_cast<void*>(this), aIID, aInstancePtr
, table); return rv; }
1322
1323// The REPORT* macros do an unconditional report. The ZRREPORT* macros are for
1324// realms and zones; they aggregate any entries smaller than
1325// SUNDRIES_THRESHOLD into the "sundries/gc-heap" and "sundries/malloc-heap"
1326// entries for the realm.
1327
1328#define SUNDRIES_THRESHOLDjs::MemoryReportingSundriesThreshold() js::MemoryReportingSundriesThreshold()
1329
1330#define REPORT(_path, _kind, _units, _amount, _desc)handleReport->Callback(EmptyCString(), _path, nsIMemoryReporter
::_kind, nsIMemoryReporter::_units, _amount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" _desc)), data)
;
\
1331 handleReport->Callback(EmptyCString(), _path, nsIMemoryReporter::_kind, \
1332 nsIMemoryReporter::_units, _amount, \
1333 NS_LITERAL_CSTRING(_desc)static_cast<const nsLiteralCString&>(nsLiteralCString
("" _desc))
, data);
1334
1335#define REPORT_BYTES(_path, _kind, _amount, _desc)handleReport->Callback(EmptyCString(), _path, nsIMemoryReporter
::_kind, nsIMemoryReporter::UNITS_BYTES, _amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" _desc
)), data);;
\
1336 REPORT(_path, _kind, UNITS_BYTES, _amount, _desc)handleReport->Callback(EmptyCString(), _path, nsIMemoryReporter
::_kind, nsIMemoryReporter::UNITS_BYTES, _amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" _desc
)), data);
;
1337
1338#define REPORT_GC_BYTES(_path, _amount, _desc)do { size_t amount = _amount; handleReport->Callback(EmptyCString
(), _path, nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter
::UNITS_BYTES, amount, static_cast<const nsLiteralCString&
>(nsLiteralCString("" _desc)), data); gcTotal += amount; }
while (0)
\
1339 do { \
1340 size_t amount = _amount; /* evaluate _amount only once */ \
1341 handleReport->Callback(EmptyCString(), _path, \
1342 nsIMemoryReporter::KIND_NONHEAP, \
1343 nsIMemoryReporter::UNITS_BYTES, amount, \
1344 NS_LITERAL_CSTRING(_desc)static_cast<const nsLiteralCString&>(nsLiteralCString
("" _desc))
, data); \
1345 gcTotal += amount; \
1346 } while (0)
1347
1348// Report realm/zone non-GC (KIND_HEAP) bytes.
1349#define ZRREPORT_BYTES(_path, _amount, _desc)do { size_t amount = _amount; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), _path, nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" _desc
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
\
1350 do { \
1351 /* Assign _descLiteral plus "" into a char* to prove that it's */ \
1352 /* actually a literal. */ \
1353 size_t amount = _amount; /* evaluate _amount only once */ \
1354 if (amount >= SUNDRIES_THRESHOLDjs::MemoryReportingSundriesThreshold()) { \
1355 handleReport->Callback(EmptyCString(), _path, \
1356 nsIMemoryReporter::KIND_HEAP, \
1357 nsIMemoryReporter::UNITS_BYTES, amount, \
1358 NS_LITERAL_CSTRING(_desc)static_cast<const nsLiteralCString&>(nsLiteralCString
("" _desc))
, data); \
1359 } else { \
1360 sundriesMallocHeap += amount; \
1361 } \
1362 } while (0)
1363
1364// Report realm/zone GC bytes.
1365#define ZRREPORT_GC_BYTES(_path, _amount, _desc)do { size_t amount = _amount; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), _path, nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" _desc
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
\
1366 do { \
1367 size_t amount = _amount; /* evaluate _amount only once */ \
1368 if (amount >= SUNDRIES_THRESHOLDjs::MemoryReportingSundriesThreshold()) { \
1369 handleReport->Callback(EmptyCString(), _path, \
1370 nsIMemoryReporter::KIND_NONHEAP, \
1371 nsIMemoryReporter::UNITS_BYTES, amount, \
1372 NS_LITERAL_CSTRING(_desc)static_cast<const nsLiteralCString&>(nsLiteralCString
("" _desc))
, data); \
1373 gcTotal += amount; \
1374 } else { \
1375 sundriesGCHeap += amount; \
1376 } \
1377 } while (0)
1378
1379// Report runtime bytes.
1380#define RREPORT_BYTES(_path, _kind, _amount, _desc)do { size_t amount = _amount; handleReport->Callback(EmptyCString
(), _path, nsIMemoryReporter::_kind, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" _desc)), data); rtTotal += amount; } while (0)
\
1381 do { \
1382 size_t amount = _amount; /* evaluate _amount only once */ \
1383 handleReport->Callback(EmptyCString(), _path, nsIMemoryReporter::_kind, \
1384 nsIMemoryReporter::UNITS_BYTES, amount, \
1385 NS_LITERAL_CSTRING(_desc)static_cast<const nsLiteralCString&>(nsLiteralCString
("" _desc))
, data); \
1386 rtTotal += amount; \
1387 } while (0)
1388
1389// Report GC thing bytes.
1390#define MREPORT_BYTES(_path, _kind, _amount, _desc)do { size_t amount = _amount; handleReport->Callback(EmptyCString
(), _path, nsIMemoryReporter::_kind, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" _desc)), data); gcThingTotal += amount; } while (0)
\
1391 do { \
1392 size_t amount = _amount; /* evaluate _amount only once */ \
1393 handleReport->Callback(EmptyCString(), _path, nsIMemoryReporter::_kind, \
1394 nsIMemoryReporter::UNITS_BYTES, amount, \
1395 NS_LITERAL_CSTRING(_desc)static_cast<const nsLiteralCString&>(nsLiteralCString
("" _desc))
, data); \
1396 gcThingTotal += amount; \
1397 } while (0)
1398
1399MOZ_DEFINE_MALLOC_SIZE_OF(JSMallocSizeOf)static size_t JSMallocSizeOf(const void* aPtr) { mozilla::dmd
::Report(aPtr); return moz_malloc_size_of(aPtr); }
1400
1401namespace xpc {
1402
1403static void ReportZoneStats(const JS::ZoneStats& zStats,
1404 const xpc::ZoneStatsExtras& extras,
1405 nsIHandleReportCallback* handleReport,
1406 nsISupports* data, bool anonymize,
1407 size_t* gcTotalOut = nullptr) {
1408 const nsCString& pathPrefix = extras.pathPrefix;
1409 size_t gcTotal = 0, sundriesGCHeap = 0, sundriesMallocHeap = 0;
1410
1411 MOZ_ASSERT(!gcTotalOut == zStats.isTotals)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!gcTotalOut == zStats.isTotals)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!gcTotalOut == zStats.isTotals
))), 0))) { MOZ_ReportAssertionFailure("!gcTotalOut == zStats.isTotals"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1411); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!gcTotalOut == zStats.isTotals"
")"); do { *((volatile int*)__null) = 1411; ::abort(); } while
(false); } } while (false)
;
1412
1413 ZRREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("symbols/gc-heap"),do { size_t amount = zStats.symbolsGCHeap; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "symbols/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Symbols."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1414 zStats.symbolsGCHeap, "Symbols.")do { size_t amount = zStats.symbolsGCHeap; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "symbols/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Symbols."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
;
1415
1416 ZRREPORT_GC_BYTES(do { size_t amount = zStats.gcHeapArenaAdmin; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap-arena-admin")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Bookkeeping information and alignment padding within GC arenas."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1417 pathPrefix + NS_LITERAL_CSTRING("gc-heap-arena-admin"),do { size_t amount = zStats.gcHeapArenaAdmin; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap-arena-admin")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Bookkeeping information and alignment padding within GC arenas."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1418 zStats.gcHeapArenaAdmin,do { size_t amount = zStats.gcHeapArenaAdmin; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap-arena-admin")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Bookkeeping information and alignment padding within GC arenas."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1419 "Bookkeeping information and alignment padding within GC arenas.")do { size_t amount = zStats.gcHeapArenaAdmin; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap-arena-admin")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Bookkeeping information and alignment padding within GC arenas."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
;
1420
1421 ZRREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("unused-gc-things"),do { size_t amount = zStats.unusedGCThings.totalSize(); if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "unused-gc-things"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Unused GC thing cells within non-empty arenas.")), data)
; gcTotal += amount; } else { sundriesGCHeap += amount; } } while
(0)
1422 zStats.unusedGCThings.totalSize(),do { size_t amount = zStats.unusedGCThings.totalSize(); if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "unused-gc-things"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Unused GC thing cells within non-empty arenas.")), data)
; gcTotal += amount; } else { sundriesGCHeap += amount; } } while
(0)
1423 "Unused GC thing cells within non-empty arenas.")do { size_t amount = zStats.unusedGCThings.totalSize(); if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "unused-gc-things"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Unused GC thing cells within non-empty arenas.")), data)
; gcTotal += amount; } else { sundriesGCHeap += amount; } } while
(0)
;
1424
1425 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("unique-id-map"),do { size_t amount = zStats.uniqueIdMap; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "unique-id-map")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Address-independent cell identities."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1426 zStats.uniqueIdMap, "Address-independent cell identities.")do { size_t amount = zStats.uniqueIdMap; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "unique-id-map")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Address-independent cell identities."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1427
1428 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("shape-tables"),do { size_t amount = zStats.shapeTables; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "shape-tables")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Tables storing shape information."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1429 zStats.shapeTables, "Tables storing shape information.")do { size_t amount = zStats.shapeTables; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "shape-tables")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Tables storing shape information."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1430
1431 ZRREPORT_BYTES(do { size_t amount = zStats.compartmentObjects; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "compartments/compartment-objects"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The JS::Compartment objects in this zone.")), data); } else
{ sundriesMallocHeap += amount; } } while (0)
1432 pathPrefix + NS_LITERAL_CSTRING("compartments/compartment-objects"),do { size_t amount = zStats.compartmentObjects; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "compartments/compartment-objects"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The JS::Compartment objects in this zone.")), data); } else
{ sundriesMallocHeap += amount; } } while (0)
1433 zStats.compartmentObjects, "The JS::Compartment objects in this zone.")do { size_t amount = zStats.compartmentObjects; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "compartments/compartment-objects"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The JS::Compartment objects in this zone.")), data); } else
{ sundriesMallocHeap += amount; } } while (0)
;
1434
1435 ZRREPORT_BYTES(do { size_t amount = zStats.crossCompartmentWrappersTables; if
(amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/cross-compartment-wrapper-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The cross-compartment wrapper tables.")), data); } else {
sundriesMallocHeap += amount; } } while (0)
1436 pathPrefix +do { size_t amount = zStats.crossCompartmentWrappersTables; if
(amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/cross-compartment-wrapper-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The cross-compartment wrapper tables.")), data); } else {
sundriesMallocHeap += amount; } } while (0)
1437 NS_LITERAL_CSTRING("compartments/cross-compartment-wrapper-tables"),do { size_t amount = zStats.crossCompartmentWrappersTables; if
(amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/cross-compartment-wrapper-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The cross-compartment wrapper tables.")), data); } else {
sundriesMallocHeap += amount; } } while (0)
1438 zStats.crossCompartmentWrappersTables,do { size_t amount = zStats.crossCompartmentWrappersTables; if
(amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/cross-compartment-wrapper-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The cross-compartment wrapper tables.")), data); } else {
sundriesMallocHeap += amount; } } while (0)
1439 "The cross-compartment wrapper tables.")do { size_t amount = zStats.crossCompartmentWrappersTables; if
(amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/cross-compartment-wrapper-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The cross-compartment wrapper tables.")), data); } else {
sundriesMallocHeap += amount; } } while (0)
;
1440
1441 ZRREPORT_BYTES(do { size_t amount = zStats.compartmentsPrivateData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/private-data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Extra data attached to each compartment by XPConnect, including "
"its wrapped-js.")), data); } else { sundriesMallocHeap += amount
; } } while (0)
1442 pathPrefix + NS_LITERAL_CSTRING("compartments/private-data"),do { size_t amount = zStats.compartmentsPrivateData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/private-data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Extra data attached to each compartment by XPConnect, including "
"its wrapped-js.")), data); } else { sundriesMallocHeap += amount
; } } while (0)
1443 zStats.compartmentsPrivateData,do { size_t amount = zStats.compartmentsPrivateData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/private-data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Extra data attached to each compartment by XPConnect, including "
"its wrapped-js.")), data); } else { sundriesMallocHeap += amount
; } } while (0)
1444 "Extra data attached to each compartment by XPConnect, including "do { size_t amount = zStats.compartmentsPrivateData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/private-data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Extra data attached to each compartment by XPConnect, including "
"its wrapped-js.")), data); } else { sundriesMallocHeap += amount
; } } while (0)
1445 "its wrapped-js.")do { size_t amount = zStats.compartmentsPrivateData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "compartments/private-data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Extra data attached to each compartment by XPConnect, including "
"its wrapped-js.")), data); } else { sundriesMallocHeap += amount
; } } while (0)
;
1446
1447 ZRREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("lazy-scripts/gc-heap"),do { size_t amount = zStats.lazyScriptsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "lazy-scripts/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Scripts that haven't executed yet."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1448 zStats.lazyScriptsGCHeap,do { size_t amount = zStats.lazyScriptsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "lazy-scripts/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Scripts that haven't executed yet."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1449 "Scripts that haven't executed yet.")do { size_t amount = zStats.lazyScriptsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "lazy-scripts/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Scripts that haven't executed yet."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
;
1450
1451 ZRREPORT_BYTES(do { size_t amount = zStats.lazyScriptsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "lazy-scripts/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Lazy script tables containing closed-over bindings or inner functions."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1452 pathPrefix + NS_LITERAL_CSTRING("lazy-scripts/malloc-heap"),do { size_t amount = zStats.lazyScriptsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "lazy-scripts/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Lazy script tables containing closed-over bindings or inner functions."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1453 zStats.lazyScriptsMallocHeap,do { size_t amount = zStats.lazyScriptsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "lazy-scripts/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Lazy script tables containing closed-over bindings or inner functions."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1454 "Lazy script tables containing closed-over bindings or inner functions.")do { size_t amount = zStats.lazyScriptsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "lazy-scripts/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Lazy script tables containing closed-over bindings or inner functions."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1455
1456 ZRREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("jit-codes-gc-heap"),do { size_t amount = zStats.jitCodesGCHeap; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "jit-codes-gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "References to executable code pools used by the JITs."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1457 zStats.jitCodesGCHeap,do { size_t amount = zStats.jitCodesGCHeap; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "jit-codes-gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "References to executable code pools used by the JITs."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1458 "References to executable code pools used by the JITs.")do { size_t amount = zStats.jitCodesGCHeap; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "jit-codes-gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "References to executable code pools used by the JITs."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
;
1459
1460 ZRREPORT_GC_BYTES(do { size_t amount = zStats.objectGroupsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "object-groups/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Classification and type inference information about objects."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1461 pathPrefix + NS_LITERAL_CSTRING("object-groups/gc-heap"),do { size_t amount = zStats.objectGroupsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "object-groups/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Classification and type inference information about objects."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1462 zStats.objectGroupsGCHeap,do { size_t amount = zStats.objectGroupsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "object-groups/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Classification and type inference information about objects."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1463 "Classification and type inference information about objects.")do { size_t amount = zStats.objectGroupsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "object-groups/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Classification and type inference information about objects."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
;
1464
1465 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("object-groups/malloc-heap"),do { size_t amount = zStats.objectGroupsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "object-groups/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Object group addenda.")), data); } else { sundriesMallocHeap
+= amount; } } while (0)
1466 zStats.objectGroupsMallocHeap, "Object group addenda.")do { size_t amount = zStats.objectGroupsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "object-groups/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Object group addenda.")), data); } else { sundriesMallocHeap
+= amount; } } while (0)
;
1467
1468 ZRREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("scopes/gc-heap"),do { size_t amount = zStats.scopesGCHeap; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scopes/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Scope information for scripts."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1469 zStats.scopesGCHeap, "Scope information for scripts.")do { size_t amount = zStats.scopesGCHeap; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scopes/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Scope information for scripts."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
;
1470
1471 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("scopes/malloc-heap"),do { size_t amount = zStats.scopesMallocHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scopes/malloc-heap")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Arrays of binding names and other binding-related data."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1472 zStats.scopesMallocHeap,do { size_t amount = zStats.scopesMallocHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scopes/malloc-heap")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Arrays of binding names and other binding-related data."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1473 "Arrays of binding names and other binding-related data.")do { size_t amount = zStats.scopesMallocHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scopes/malloc-heap")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Arrays of binding names and other binding-related data."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1474
1475 ZRREPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("regexp-shareds/gc-heap"),do { size_t amount = zStats.regExpSharedsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "regexp-shareds/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Shared compiled regexp data."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
1476 zStats.regExpSharedsGCHeap, "Shared compiled regexp data.")do { size_t amount = zStats.regExpSharedsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "regexp-shareds/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Shared compiled regexp data."
)), data); gcTotal += amount; } else { sundriesGCHeap += amount
; } } while (0)
;
1477
1478 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("regexp-shareds/malloc-heap"),do { size_t amount = zStats.regExpSharedsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "regexp-shareds/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Shared compiled regexp data.")), data); } else { sundriesMallocHeap
+= amount; } } while (0)
1479 zStats.regExpSharedsMallocHeap,do { size_t amount = zStats.regExpSharedsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "regexp-shareds/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Shared compiled regexp data.")), data); } else { sundriesMallocHeap
+= amount; } } while (0)
1480 "Shared compiled regexp data.")do { size_t amount = zStats.regExpSharedsMallocHeap; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "regexp-shareds/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Shared compiled regexp data.")), data); } else { sundriesMallocHeap
+= amount; } } while (0)
;
1481
1482 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("type-pool"), zStats.typePool,do { size_t amount = zStats.typePool; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-pool"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Type sets and related data.")), data); } else { sundriesMallocHeap
+= amount; } } while (0)
1483 "Type sets and related data.")do { size_t amount = zStats.typePool; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-pool"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Type sets and related data.")), data); } else { sundriesMallocHeap
+= amount; } } while (0)
;
1484
1485 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("regexp-zone"),do { size_t amount = zStats.regexpZone; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "regexp-zone")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The regexp zone and regexp data."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1486 zStats.regexpZone, "The regexp zone and regexp data.")do { size_t amount = zStats.regexpZone; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "regexp-zone")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The regexp zone and regexp data."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1487
1488 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("jit-zone"), zStats.jitZone,do { size_t amount = zStats.jitZone; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "jit-zone"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The JIT zone.")), data); } else { sundriesMallocHeap += amount
; } } while (0)
1489 "The JIT zone.")do { size_t amount = zStats.jitZone; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "jit-zone"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The JIT zone.")), data); } else { sundriesMallocHeap += amount
; } } while (0)
;
1490
1491 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("baseline/optimized-stubs"),do { size_t amount = zStats.baselineStubsOptimized; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "baseline/optimized-stubs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The Baseline JIT's optimized IC stubs (excluding code)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1492 zStats.baselineStubsOptimized,do { size_t amount = zStats.baselineStubsOptimized; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "baseline/optimized-stubs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The Baseline JIT's optimized IC stubs (excluding code)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1493 "The Baseline JIT's optimized IC stubs (excluding code).")do { size_t amount = zStats.baselineStubsOptimized; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "baseline/optimized-stubs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The Baseline JIT's optimized IC stubs (excluding code)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1494
1495 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("jit-cached-cfg"),do { size_t amount = zStats.cachedCFG; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "jit-cached-cfg"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The cached CFG to construct Ion code out of it.")), data
); } else { sundriesMallocHeap += amount; } } while (0)
1496 zStats.cachedCFG,do { size_t amount = zStats.cachedCFG; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "jit-cached-cfg"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The cached CFG to construct Ion code out of it.")), data
); } else { sundriesMallocHeap += amount; } } while (0)
1497 "The cached CFG to construct Ion code out of it.")do { size_t amount = zStats.cachedCFG; if (amount >= js::MemoryReportingSundriesThreshold
()) { handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "jit-cached-cfg"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The cached CFG to construct Ion code out of it.")), data
); } else { sundriesMallocHeap += amount; } } while (0)
;
1498
1499 ZRREPORT_BYTES(pathPrefix + NS_LITERAL_CSTRING("script-counts-map"),do { size_t amount = zStats.scriptCountsMap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "script-counts-map")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Profiling-related information for scripts."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1500 zStats.scriptCountsMap,do { size_t amount = zStats.scriptCountsMap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "script-counts-map")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Profiling-related information for scripts."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1501 "Profiling-related information for scripts.")do { size_t amount = zStats.scriptCountsMap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "script-counts-map")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Profiling-related information for scripts."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1502
1503 size_t stringsNotableAboutMemoryGCHeap = 0;
1504 size_t stringsNotableAboutMemoryMallocHeap = 0;
1505
1506#define MAYBE_INLINE"The characters may be inline or on the malloc heap." "The characters may be inline or on the malloc heap."
1507#define MAYBE_OVERALLOCATED"Sometimes over-allocated to simplify string concatenation." \
1508 "Sometimes over-allocated to simplify string concatenation."
1509
1510 for (size_t i = 0; i < zStats.notableStrings.length(); i++) {
1511 const JS::NotableStringInfo& info = zStats.notableStrings[i];
1512
1513 MOZ_ASSERT(!zStats.isTotals)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!zStats.isTotals)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!zStats.isTotals))), 0))) { MOZ_ReportAssertionFailure
("!zStats.isTotals", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1513); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!zStats.isTotals"
")"); do { *((volatile int*)__null) = 1513; ::abort(); } while
(false); } } while (false)
;
1514
1515 // We don't do notable string detection when anonymizing, because
1516 // there's a good chance its for crash submission, and the memory
1517 // required for notable string detection is high.
1518 MOZ_ASSERT(!anonymize)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!anonymize)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!anonymize))), 0))) { MOZ_ReportAssertionFailure
("!anonymize", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1518); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!anonymize"
")"); do { *((volatile int*)__null) = 1518; ::abort(); } while
(false); } } while (false)
;
1519
1520 nsDependentCString notableString(info.buffer.get());
1521
1522 // Viewing about:memory generates many notable strings which contain
1523 // "string(length=". If we report these as notable, then we'll create
1524 // even more notable strings the next time we open about:memory (unless
1525 // there's a GC in the meantime), and so on ad infinitum.
1526 //
1527 // To avoid cluttering up about:memory like this, we stick notable
1528 // strings which contain "string(length=" into their own bucket.
1529#define STRING_LENGTH "string(length="
1530 if (FindInReadable(NS_LITERAL_CSTRING(STRING_LENGTH)static_cast<const nsLiteralCString&>(nsLiteralCString
("" STRING_LENGTH))
, notableString)) {
1531 stringsNotableAboutMemoryGCHeap += info.gcHeapLatin1;
1532 stringsNotableAboutMemoryGCHeap += info.gcHeapTwoByte;
1533 stringsNotableAboutMemoryMallocHeap += info.mallocHeapLatin1;
1534 stringsNotableAboutMemoryMallocHeap += info.mallocHeapTwoByte;
1535 continue;
1536 }
1537
1538 // Escape / to \ before we put notableString into the memory reporter
1539 // path, because we don't want any forward slashes in the string to
1540 // count as path separators.
1541 nsCString escapedString(notableString);
1542 escapedString.ReplaceSubstring("/", "\\");
1543
1544 bool truncated = notableString.Length() < info.length;
1545
1546 nsCString path =
1547 pathPrefix +
1548 nsPrintfCString("strings/" STRING_LENGTH "%zu, copies=%d, \"%s\"%s)/",
1549 info.length, info.numCopies, escapedString.get(),
1550 truncated ? " (truncated)" : "");
1551
1552 if (info.gcHeapLatin1 > 0) {
1553 REPORT_GC_BYTES(path + NS_LITERAL_CSTRING("gc-heap/latin1"),do { size_t amount = info.gcHeapLatin1; handleReport->Callback
(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/latin1")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Latin1 strings. "
"The characters may be inline or on the malloc heap.")), data
); gcTotal += amount; } while (0)
1554 info.gcHeapLatin1, "Latin1 strings. " MAYBE_INLINE)do { size_t amount = info.gcHeapLatin1; handleReport->Callback
(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/latin1")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Latin1 strings. "
"The characters may be inline or on the malloc heap.")), data
); gcTotal += amount; } while (0)
;
1555 }
1556
1557 if (info.gcHeapTwoByte > 0) {
1558 REPORT_GC_BYTES(path + NS_LITERAL_CSTRING("gc-heap/two-byte"),do { size_t amount = info.gcHeapTwoByte; handleReport->Callback
(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/two-byte")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "TwoByte strings. "
"The characters may be inline or on the malloc heap.")), data
); gcTotal += amount; } while (0)
1559 info.gcHeapTwoByte, "TwoByte strings. " MAYBE_INLINE)do { size_t amount = info.gcHeapTwoByte; handleReport->Callback
(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/two-byte")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "TwoByte strings. "
"The characters may be inline or on the malloc heap.")), data
); gcTotal += amount; } while (0)
;
1560 }
1561
1562 if (info.mallocHeapLatin1 > 0) {
1563 REPORT_BYTES(path + NS_LITERAL_CSTRING("malloc-heap/latin1"), KIND_HEAP,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/latin1"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, info.mallocHeapLatin1, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline Latin1 string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1564 info.mallocHeapLatin1,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/latin1"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, info.mallocHeapLatin1, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline Latin1 string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1565 "Non-inline Latin1 string characters. " MAYBE_OVERALLOCATED)handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/latin1"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, info.mallocHeapLatin1, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline Latin1 string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
;
1566 }
1567
1568 if (info.mallocHeapTwoByte > 0) {
1569 REPORT_BYTES(handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/two-byte"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, info.mallocHeapTwoByte, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline TwoByte string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1570 path + NS_LITERAL_CSTRING("malloc-heap/two-byte"), KIND_HEAP,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/two-byte"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, info.mallocHeapTwoByte, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline TwoByte string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1571 info.mallocHeapTwoByte,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/two-byte"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, info.mallocHeapTwoByte, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline TwoByte string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1572 "Non-inline TwoByte string characters. " MAYBE_OVERALLOCATED)handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/two-byte"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, info.mallocHeapTwoByte, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline TwoByte string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
;
1573 }
1574 }
1575
1576 nsCString nonNotablePath = pathPrefix;
1577 nonNotablePath +=
1578 (zStats.isTotals || anonymize)
1579 ? NS_LITERAL_CSTRING("strings/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "strings/"))
1580 : NS_LITERAL_CSTRING("strings/string(<non-notable strings>)/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "strings/string(<non-notable strings>)/"))
;
1581
1582 if (zStats.stringInfo.gcHeapLatin1 > 0) {
1583 REPORT_GC_BYTES(nonNotablePath + NS_LITERAL_CSTRING("gc-heap/latin1"),do { size_t amount = zStats.stringInfo.gcHeapLatin1; handleReport
->Callback(EmptyCString(), nonNotablePath + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "gc-heap/latin1"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Latin1 strings. " "The characters may be inline or on the malloc heap."
)), data); gcTotal += amount; } while (0)
1584 zStats.stringInfo.gcHeapLatin1,do { size_t amount = zStats.stringInfo.gcHeapLatin1; handleReport
->Callback(EmptyCString(), nonNotablePath + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "gc-heap/latin1"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Latin1 strings. " "The characters may be inline or on the malloc heap."
)), data); gcTotal += amount; } while (0)
1585 "Latin1 strings. " MAYBE_INLINE)do { size_t amount = zStats.stringInfo.gcHeapLatin1; handleReport
->Callback(EmptyCString(), nonNotablePath + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "gc-heap/latin1"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Latin1 strings. " "The characters may be inline or on the malloc heap."
)), data); gcTotal += amount; } while (0)
;
1586 }
1587
1588 if (zStats.stringInfo.gcHeapTwoByte > 0) {
1589 REPORT_GC_BYTES(nonNotablePath + NS_LITERAL_CSTRING("gc-heap/two-byte"),do { size_t amount = zStats.stringInfo.gcHeapTwoByte; handleReport
->Callback(EmptyCString(), nonNotablePath + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "gc-heap/two-byte"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "TwoByte strings. " "The characters may be inline or on the malloc heap."
)), data); gcTotal += amount; } while (0)
1590 zStats.stringInfo.gcHeapTwoByte,do { size_t amount = zStats.stringInfo.gcHeapTwoByte; handleReport
->Callback(EmptyCString(), nonNotablePath + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "gc-heap/two-byte"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "TwoByte strings. " "The characters may be inline or on the malloc heap."
)), data); gcTotal += amount; } while (0)
1591 "TwoByte strings. " MAYBE_INLINE)do { size_t amount = zStats.stringInfo.gcHeapTwoByte; handleReport
->Callback(EmptyCString(), nonNotablePath + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "gc-heap/two-byte"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "TwoByte strings. " "The characters may be inline or on the malloc heap."
)), data); gcTotal += amount; } while (0)
;
1592 }
1593
1594 if (zStats.stringInfo.mallocHeapLatin1 > 0) {
1595 REPORT_BYTES(nonNotablePath + NS_LITERAL_CSTRING("malloc-heap/latin1"),handleReport->Callback(EmptyCString(), nonNotablePath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/latin1"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, zStats.stringInfo.mallocHeapLatin1, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline Latin1 string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1596 KIND_HEAP, zStats.stringInfo.mallocHeapLatin1,handleReport->Callback(EmptyCString(), nonNotablePath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/latin1"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, zStats.stringInfo.mallocHeapLatin1, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline Latin1 string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1597 "Non-inline Latin1 string characters. " MAYBE_OVERALLOCATED)handleReport->Callback(EmptyCString(), nonNotablePath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/latin1"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, zStats.stringInfo.mallocHeapLatin1, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline Latin1 string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
;
1598 }
1599
1600 if (zStats.stringInfo.mallocHeapTwoByte > 0) {
1601 REPORT_BYTES(nonNotablePath + NS_LITERAL_CSTRING("malloc-heap/two-byte"),handleReport->Callback(EmptyCString(), nonNotablePath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/two-byte"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, zStats.stringInfo.mallocHeapTwoByte, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline TwoByte string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1602 KIND_HEAP, zStats.stringInfo.mallocHeapTwoByte,handleReport->Callback(EmptyCString(), nonNotablePath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/two-byte"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, zStats.stringInfo.mallocHeapTwoByte, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline TwoByte string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
1603 "Non-inline TwoByte string characters. " MAYBE_OVERALLOCATED)handleReport->Callback(EmptyCString(), nonNotablePath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "malloc-heap/two-byte"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, zStats.stringInfo.mallocHeapTwoByte, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline TwoByte string characters. "
"Sometimes over-allocated to simplify string concatenation."
)), data);;
;
1604 }
1605
1606 if (stringsNotableAboutMemoryGCHeap > 0) {
1607 MOZ_ASSERT(!zStats.isTotals)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!zStats.isTotals)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!zStats.isTotals))), 0))) { MOZ_ReportAssertionFailure
("!zStats.isTotals", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1607); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!zStats.isTotals"
")"); do { *((volatile int*)__null) = 1607; ::abort(); } while
(false); } } while (false)
;
1608 REPORT_GC_BYTES(do { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1609 pathPrefix +do { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1610 NS_LITERAL_CSTRING("strings/string(<about-memory>)/gc-heap"),do { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1611 stringsNotableAboutMemoryGCHeap,do { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1612 "Strings that contain the characters '" STRING_LENGTHdo { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1613 "', which "do { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1614 "are probably from about:memory itself." MAYBE_INLINEdo { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1615 " We filter them out rather than display them, because displaying "do { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1616 "them would create even more such strings every time about:memory "do { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
1617 "is refreshed.")do { size_t amount = stringsNotableAboutMemoryGCHeap; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/gc-heap"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Strings that contain the characters '" STRING_LENGTH "', which "
"are probably from about:memory itself." "The characters may be inline or on the malloc heap."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data); gcTotal += amount; } while (0)
;
1618 }
1619
1620 if (stringsNotableAboutMemoryMallocHeap > 0) {
1621 MOZ_ASSERT(!zStats.isTotals)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!zStats.isTotals)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!zStats.isTotals))), 0))) { MOZ_ReportAssertionFailure
("!zStats.isTotals", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1621); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!zStats.isTotals"
")"); do { *((volatile int*)__null) = 1621; ::abort(); } while
(false); } } while (false)
;
1622 REPORT_BYTES(handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1623 pathPrefix +handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1624 NS_LITERAL_CSTRING("strings/string(<about-memory>)/malloc-heap"),handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1625 KIND_HEAP, stringsNotableAboutMemoryMallocHeap,handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1626 "Non-inline string characters of strings that contain the "handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1627 "characters '" STRING_LENGTHhandleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1628 "', which are probably from "handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1629 "about:memory itself. " MAYBE_OVERALLOCATEDhandleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1630 " We filter them out rather than display them, because displaying "handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1631 "them would create even more such strings every time about:memory "handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
1632 "is refreshed.")handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "strings/string(<about-memory>)/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, stringsNotableAboutMemoryMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-inline string characters of strings that contain the "
"characters '" STRING_LENGTH "', which are probably from " "about:memory itself. "
"Sometimes over-allocated to simplify string concatenation."
" We filter them out rather than display them, because displaying "
"them would create even more such strings every time about:memory "
"is refreshed.")), data);;
;
1633 }
1634
1635 const JS::ShapeInfo& shapeInfo = zStats.shapeInfo;
1636 if (shapeInfo.shapesGCHeapTree > 0) {
1637 REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/tree"),do { size_t amount = shapeInfo.shapesGCHeapTree; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "shapes/gc-heap/tree"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Shapes in a property tree.")), data); gcTotal += amount;
} while (0)
1638 shapeInfo.shapesGCHeapTree, "Shapes in a property tree.")do { size_t amount = shapeInfo.shapesGCHeapTree; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "shapes/gc-heap/tree"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Shapes in a property tree.")), data); gcTotal += amount;
} while (0)
;
1639 }
1640
1641 if (shapeInfo.shapesGCHeapDict > 0) {
1642 REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/dict"),do { size_t amount = shapeInfo.shapesGCHeapDict; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "shapes/gc-heap/dict"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Shapes in dictionary mode.")), data); gcTotal += amount;
} while (0)
1643 shapeInfo.shapesGCHeapDict, "Shapes in dictionary mode.")do { size_t amount = shapeInfo.shapesGCHeapDict; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "shapes/gc-heap/dict"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Shapes in dictionary mode.")), data); gcTotal += amount;
} while (0)
;
1644 }
1645
1646 if (shapeInfo.shapesGCHeapBase > 0) {
1647 REPORT_GC_BYTES(pathPrefix + NS_LITERAL_CSTRING("shapes/gc-heap/base"),do { size_t amount = shapeInfo.shapesGCHeapBase; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "shapes/gc-heap/base"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Base shapes, which collate data common to many shapes.")
), data); gcTotal += amount; } while (0)
1648 shapeInfo.shapesGCHeapBase,do { size_t amount = shapeInfo.shapesGCHeapBase; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "shapes/gc-heap/base"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Base shapes, which collate data common to many shapes.")
), data); gcTotal += amount; } while (0)
1649 "Base shapes, which collate data common to many shapes.")do { size_t amount = shapeInfo.shapesGCHeapBase; handleReport
->Callback(EmptyCString(), pathPrefix + static_cast<const
nsLiteralCString&>(nsLiteralCString("" "shapes/gc-heap/base"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Base shapes, which collate data common to many shapes.")
), data); gcTotal += amount; } while (0)
;
1650 }
1651
1652 if (shapeInfo.shapesMallocHeapTreeTables > 0) {
1653 REPORT_BYTES(handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/tree-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapTreeTables, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Property tables of shapes in a property tree."
)), data);;
1654 pathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/tree-tables"),handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/tree-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapTreeTables, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Property tables of shapes in a property tree."
)), data);;
1655 KIND_HEAP, shapeInfo.shapesMallocHeapTreeTables,handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/tree-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapTreeTables, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Property tables of shapes in a property tree."
)), data);;
1656 "Property tables of shapes in a property tree.")handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/tree-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapTreeTables, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Property tables of shapes in a property tree."
)), data);;
;
1657 }
1658
1659 if (shapeInfo.shapesMallocHeapDictTables > 0) {
1660 REPORT_BYTES(handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/dict-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapDictTables, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Property tables of shapes in dictionary mode."
)), data);;
1661 pathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/dict-tables"),handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/dict-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapDictTables, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Property tables of shapes in dictionary mode."
)), data);;
1662 KIND_HEAP, shapeInfo.shapesMallocHeapDictTables,handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/dict-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapDictTables, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Property tables of shapes in dictionary mode."
)), data);;
1663 "Property tables of shapes in dictionary mode.")handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/dict-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapDictTables, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Property tables of shapes in dictionary mode."
)), data);;
;
1664 }
1665
1666 if (shapeInfo.shapesMallocHeapTreeKids > 0) {
1667 REPORT_BYTES(handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/tree-kids"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapTreeKids, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Kid hashes of shapes in a property tree."
)), data);;
1668 pathPrefix + NS_LITERAL_CSTRING("shapes/malloc-heap/tree-kids"),handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/tree-kids"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapTreeKids, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Kid hashes of shapes in a property tree."
)), data);;
1669 KIND_HEAP, shapeInfo.shapesMallocHeapTreeKids,handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/tree-kids"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapTreeKids, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Kid hashes of shapes in a property tree."
)), data);;
1670 "Kid hashes of shapes in a property tree.")handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "shapes/malloc-heap/tree-kids"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, shapeInfo.shapesMallocHeapTreeKids, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Kid hashes of shapes in a property tree."
)), data);;
;
1671 }
1672
1673 if (sundriesGCHeap > 0) {
1674 // We deliberately don't use ZRREPORT_GC_BYTES here.
1675 REPORT_GC_BYTES(do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
1676 pathPrefix + NS_LITERAL_CSTRING("sundries/gc-heap"), sundriesGCHeap,do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
1677 "The sum of all 'gc-heap' measurements that are too small to be "do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
1678 "worth showing individually.")do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), pathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
;
1679 }
1680
1681 if (sundriesMallocHeap > 0) {
1682 // We deliberately don't use ZRREPORT_BYTES here.
1683 REPORT_BYTES(handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "sundries/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sundriesMallocHeap, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
1684 pathPrefix + NS_LITERAL_CSTRING("sundries/malloc-heap"), KIND_HEAP,handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "sundries/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sundriesMallocHeap, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
1685 sundriesMallocHeap,handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "sundries/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sundriesMallocHeap, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
1686 "The sum of all 'malloc-heap' measurements that are too small to "handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "sundries/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sundriesMallocHeap, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
1687 "be worth showing individually.")handleReport->Callback(EmptyCString(), pathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "sundries/malloc-heap"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sundriesMallocHeap, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
;
1688 }
1689
1690 if (gcTotalOut) {
1691 *gcTotalOut += gcTotal;
1692 }
1693
1694#undef STRING_LENGTH
1695}
1696
1697static void ReportClassStats(const ClassInfo& classInfo, const nsACString& path,
1698 nsIHandleReportCallback* handleReport,
1699 nsISupports* data, size_t& gcTotal) {
1700 // We deliberately don't use ZRREPORT_BYTES, so that these per-class values
1701 // don't go into sundries.
1702
1703 if (classInfo.objectsGCHeap > 0) {
1704 REPORT_GC_BYTES(path + NS_LITERAL_CSTRING("objects/gc-heap"),do { size_t amount = classInfo.objectsGCHeap; handleReport->
Callback(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "objects/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Objects, including fixed slots."
)), data); gcTotal += amount; } while (0)
1705 classInfo.objectsGCHeap, "Objects, including fixed slots.")do { size_t amount = classInfo.objectsGCHeap; handleReport->
Callback(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "objects/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Objects, including fixed slots."
)), data); gcTotal += amount; } while (0)
;
1706 }
1707
1708 if (classInfo.objectsMallocHeapSlots > 0) {
1709 REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/malloc-heap/slots"),handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/slots"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapSlots, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-fixed object slots.")), data
);;
1710 KIND_HEAP, classInfo.objectsMallocHeapSlots,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/slots"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapSlots, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-fixed object slots.")), data
);;
1711 "Non-fixed object slots.")handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/slots"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapSlots, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Non-fixed object slots.")), data
);;
;
1712 }
1713
1714 if (classInfo.objectsMallocHeapElementsNormal > 0) {
1715 REPORT_BYTES(handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/elements/normal"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapElementsNormal, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Normal (non-wasm) indexed elements."
)), data);;
1716 path + NS_LITERAL_CSTRING("objects/malloc-heap/elements/normal"),handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/elements/normal"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapElementsNormal, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Normal (non-wasm) indexed elements."
)), data);;
1717 KIND_HEAP, classInfo.objectsMallocHeapElementsNormal,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/elements/normal"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapElementsNormal, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Normal (non-wasm) indexed elements."
)), data);;
1718 "Normal (non-wasm) indexed elements.")handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/elements/normal"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapElementsNormal, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Normal (non-wasm) indexed elements."
)), data);;
;
1719 }
1720
1721 if (classInfo.objectsMallocHeapElementsAsmJS > 0) {
1722 REPORT_BYTES(handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/elements/asm.js"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapElementsAsmJS, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "asm.js array buffer elements allocated in the malloc heap."
)), data);;
1723 path + NS_LITERAL_CSTRING("objects/malloc-heap/elements/asm.js"),handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/elements/asm.js"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapElementsAsmJS, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "asm.js array buffer elements allocated in the malloc heap."
)), data);;
1724 KIND_HEAP, classInfo.objectsMallocHeapElementsAsmJS,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/elements/asm.js"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapElementsAsmJS, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "asm.js array buffer elements allocated in the malloc heap."
)), data);;
1725 "asm.js array buffer elements allocated in the malloc heap.")handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/elements/asm.js"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapElementsAsmJS, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "asm.js array buffer elements allocated in the malloc heap."
)), data);;
;
1726 }
1727
1728 if (classInfo.objectsMallocHeapMisc > 0) {
1729 REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/malloc-heap/misc"),handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/misc"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapMisc, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Miscellaneous object data.")),
data);;
1730 KIND_HEAP, classInfo.objectsMallocHeapMisc,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/misc"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapMisc, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Miscellaneous object data.")),
data);;
1731 "Miscellaneous object data.")handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/malloc-heap/misc"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsMallocHeapMisc, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Miscellaneous object data.")),
data);;
;
1732 }
1733
1734 if (classInfo.objectsNonHeapElementsNormal > 0) {
1735 REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/non-heap/elements/normal"),handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/normal"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsNormal, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped non-shared array buffer elements."
)), data);;
1736 KIND_NONHEAP, classInfo.objectsNonHeapElementsNormal,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/normal"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsNormal, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped non-shared array buffer elements."
)), data);;
1737 "Memory-mapped non-shared array buffer elements.")handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/normal"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsNormal, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped non-shared array buffer elements."
)), data);;
;
1738 }
1739
1740 if (classInfo.objectsNonHeapElementsShared > 0) {
1741 REPORT_BYTES(handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/shared"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsShared, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped shared array buffer elements. These elements are "
"shared between one or more runtimes; the reported size is divided "
"by the buffer's refcount.")), data);;
1742 path + NS_LITERAL_CSTRING("objects/non-heap/elements/shared"),handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/shared"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsShared, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped shared array buffer elements. These elements are "
"shared between one or more runtimes; the reported size is divided "
"by the buffer's refcount.")), data);;
1743 KIND_NONHEAP, classInfo.objectsNonHeapElementsShared,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/shared"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsShared, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped shared array buffer elements. These elements are "
"shared between one or more runtimes; the reported size is divided "
"by the buffer's refcount.")), data);;
1744 "Memory-mapped shared array buffer elements. These elements are "handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/shared"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsShared, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped shared array buffer elements. These elements are "
"shared between one or more runtimes; the reported size is divided "
"by the buffer's refcount.")), data);;
1745 "shared between one or more runtimes; the reported size is divided "handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/shared"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsShared, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped shared array buffer elements. These elements are "
"shared between one or more runtimes; the reported size is divided "
"by the buffer's refcount.")), data);;
1746 "by the buffer's refcount.")handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/shared"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsShared, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Memory-mapped shared array buffer elements. These elements are "
"shared between one or more runtimes; the reported size is divided "
"by the buffer's refcount.")), data);;
;
1747 }
1748
1749 // WebAssembly memories are always non-heap-allocated (mmap). We never put
1750 // these under sundries, because (a) in practice they're almost always
1751 // larger than the sundries threshold, and (b) we'd need a third category of
1752 // sundries ("non-heap"), which would be a pain.
1753 if (classInfo.objectsNonHeapElementsWasm > 0) {
1754 REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/non-heap/elements/wasm"),handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/wasm"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsWasm, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "wasm/asm.js array buffer elements allocated outside both the "
"malloc heap and the GC heap.")), data);;
1755 KIND_NONHEAP, classInfo.objectsNonHeapElementsWasm,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/wasm"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsWasm, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "wasm/asm.js array buffer elements allocated outside both the "
"malloc heap and the GC heap.")), data);;
1756 "wasm/asm.js array buffer elements allocated outside both the "handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/wasm"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsWasm, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "wasm/asm.js array buffer elements allocated outside both the "
"malloc heap and the GC heap.")), data);;
1757 "malloc heap and the GC heap.")handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/elements/wasm"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapElementsWasm, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "wasm/asm.js array buffer elements allocated outside both the "
"malloc heap and the GC heap.")), data);;
;
1758 }
1759
1760 if (classInfo.objectsNonHeapCodeWasm > 0) {
1761 REPORT_BYTES(path + NS_LITERAL_CSTRING("objects/non-heap/code/wasm"),handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/code/wasm"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapCodeWasm, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "AOT-compiled wasm/asm.js code."
)), data);;
1762 KIND_NONHEAP, classInfo.objectsNonHeapCodeWasm,handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/code/wasm"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapCodeWasm, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "AOT-compiled wasm/asm.js code."
)), data);;
1763 "AOT-compiled wasm/asm.js code.")handleReport->Callback(EmptyCString(), path + static_cast<
const nsLiteralCString&>(nsLiteralCString("" "objects/non-heap/code/wasm"
)), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, classInfo.objectsNonHeapCodeWasm, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "AOT-compiled wasm/asm.js code."
)), data);;
;
1764 }
1765
1766 // Although wasm guard pages aren't committed in memory they can be very
1767 // large and contribute greatly to vsize and so are worth reporting.
1768 if (classInfo.wasmGuardPages > 0) {
1769 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-guard-pages"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, classInfo.wasmGuardPages, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Guard pages mapped after the end of wasm memories, reserved for "
"optimization tricks, but not committed and thus never contributing"
" to RSS, only vsize.")), data);;
1770 NS_LITERAL_CSTRING("wasm-guard-pages"), KIND_OTHER,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-guard-pages"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, classInfo.wasmGuardPages, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Guard pages mapped after the end of wasm memories, reserved for "
"optimization tricks, but not committed and thus never contributing"
" to RSS, only vsize.")), data);;
1771 classInfo.wasmGuardPages,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-guard-pages"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, classInfo.wasmGuardPages, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Guard pages mapped after the end of wasm memories, reserved for "
"optimization tricks, but not committed and thus never contributing"
" to RSS, only vsize.")), data);;
1772 "Guard pages mapped after the end of wasm memories, reserved for "handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-guard-pages"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, classInfo.wasmGuardPages, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Guard pages mapped after the end of wasm memories, reserved for "
"optimization tricks, but not committed and thus never contributing"
" to RSS, only vsize.")), data);;
1773 "optimization tricks, but not committed and thus never contributing"handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-guard-pages"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, classInfo.wasmGuardPages, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Guard pages mapped after the end of wasm memories, reserved for "
"optimization tricks, but not committed and thus never contributing"
" to RSS, only vsize.")), data);;
1774 " to RSS, only vsize.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-guard-pages"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, classInfo.wasmGuardPages, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Guard pages mapped after the end of wasm memories, reserved for "
"optimization tricks, but not committed and thus never contributing"
" to RSS, only vsize.")), data);;
;
1775 }
1776}
1777
1778static void ReportRealmStats(const JS::RealmStats& realmStats,
1779 const xpc::RealmStatsExtras& extras,
1780 nsIHandleReportCallback* handleReport,
1781 nsISupports* data, size_t* gcTotalOut = nullptr) {
1782 static const nsDependentCString addonPrefix("explicit/add-ons/");
1783
1784 size_t gcTotal = 0, sundriesGCHeap = 0, sundriesMallocHeap = 0;
1785 nsAutoCString realmJSPathPrefix(extras.jsPathPrefix);
1786 nsAutoCString realmDOMPathPrefix(extras.domPathPrefix);
1787
1788 MOZ_ASSERT(!gcTotalOut == realmStats.isTotals)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!gcTotalOut == realmStats.isTotals)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!gcTotalOut == realmStats.isTotals
))), 0))) { MOZ_ReportAssertionFailure("!gcTotalOut == realmStats.isTotals"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1788); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!gcTotalOut == realmStats.isTotals"
")"); do { *((volatile int*)__null) = 1788; ::abort(); } while
(false); } } while (false)
;
1789
1790 nsCString nonNotablePath = realmJSPathPrefix;
1791 nonNotablePath +=
1792 realmStats.isTotals
1793 ? NS_LITERAL_CSTRING("classes/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "classes/"))
1794 : NS_LITERAL_CSTRING("classes/class(<non-notable classes>)/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "classes/class(<non-notable classes>)/"))
;
1795
1796 ReportClassStats(realmStats.classInfo, nonNotablePath, handleReport, data,
1797 gcTotal);
1798
1799 for (size_t i = 0; i < realmStats.notableClasses.length(); i++) {
1800 MOZ_ASSERT(!realmStats.isTotals)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!realmStats.isTotals)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!realmStats.isTotals))), 0))
) { MOZ_ReportAssertionFailure("!realmStats.isTotals", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 1800); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!realmStats.isTotals"
")"); do { *((volatile int*)__null) = 1800; ::abort(); } while
(false); } } while (false)
;
1801 const JS::NotableClassInfo& classInfo = realmStats.notableClasses[i];
1802
1803 nsCString classPath =
1804 realmJSPathPrefix +
1805 nsPrintfCString("classes/class(%s)/", classInfo.className_.get());
1806
1807 ReportClassStats(classInfo, classPath, handleReport, data, gcTotal);
1808 }
1809
1810 // Note that we use realmDOMPathPrefix here. This is because we measure
1811 // orphan DOM nodes in the JS reporter, but we want to report them in a "dom"
1812 // sub-tree rather than a "js" sub-tree.
1813 ZRREPORT_BYTES(do { size_t amount = realmStats.objectsPrivate; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmDOMPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "orphan-nodes")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Orphan DOM nodes, i.e. those that are only reachable from JavaScript "
"objects.")), data); } else { sundriesMallocHeap += amount; }
} while (0)
1814 realmDOMPathPrefix + NS_LITERAL_CSTRING("orphan-nodes"),do { size_t amount = realmStats.objectsPrivate; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmDOMPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "orphan-nodes")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Orphan DOM nodes, i.e. those that are only reachable from JavaScript "
"objects.")), data); } else { sundriesMallocHeap += amount; }
} while (0)
1815 realmStats.objectsPrivate,do { size_t amount = realmStats.objectsPrivate; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmDOMPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "orphan-nodes")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Orphan DOM nodes, i.e. those that are only reachable from JavaScript "
"objects.")), data); } else { sundriesMallocHeap += amount; }
} while (0)
1816 "Orphan DOM nodes, i.e. those that are only reachable from JavaScript "do { size_t amount = realmStats.objectsPrivate; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmDOMPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "orphan-nodes")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Orphan DOM nodes, i.e. those that are only reachable from JavaScript "
"objects.")), data); } else { sundriesMallocHeap += amount; }
} while (0)
1817 "objects.")do { size_t amount = realmStats.objectsPrivate; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmDOMPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "orphan-nodes")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Orphan DOM nodes, i.e. those that are only reachable from JavaScript "
"objects.")), data); } else { sundriesMallocHeap += amount; }
} while (0)
;
1818
1819 ZRREPORT_GC_BYTES(do { size_t amount = realmStats.scriptsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scripts/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JSScript instances. There is one per user-defined function in a "
"script, and one for the top-level code in a script.")), data
); gcTotal += amount; } else { sundriesGCHeap += amount; } } while
(0)
1820 realmJSPathPrefix + NS_LITERAL_CSTRING("scripts/gc-heap"),do { size_t amount = realmStats.scriptsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scripts/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JSScript instances. There is one per user-defined function in a "
"script, and one for the top-level code in a script.")), data
); gcTotal += amount; } else { sundriesGCHeap += amount; } } while
(0)
1821 realmStats.scriptsGCHeap,do { size_t amount = realmStats.scriptsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scripts/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JSScript instances. There is one per user-defined function in a "
"script, and one for the top-level code in a script.")), data
); gcTotal += amount; } else { sundriesGCHeap += amount; } } while
(0)
1822 "JSScript instances. There is one per user-defined function in a "do { size_t amount = realmStats.scriptsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scripts/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JSScript instances. There is one per user-defined function in a "
"script, and one for the top-level code in a script.")), data
); gcTotal += amount; } else { sundriesGCHeap += amount; } } while
(0)
1823 "script, and one for the top-level code in a script.")do { size_t amount = realmStats.scriptsGCHeap; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "scripts/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JSScript instances. There is one per user-defined function in a "
"script, and one for the top-level code in a script.")), data
); gcTotal += amount; } else { sundriesGCHeap += amount; } } while
(0)
;
1824
1825 ZRREPORT_BYTES(do { size_t amount = realmStats.scriptsMallocHeapData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "scripts/malloc-heap/data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Various variable-length tables in JSScripts.")), data); }
else { sundriesMallocHeap += amount; } } while (0)
1826 realmJSPathPrefix + NS_LITERAL_CSTRING("scripts/malloc-heap/data"),do { size_t amount = realmStats.scriptsMallocHeapData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "scripts/malloc-heap/data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Various variable-length tables in JSScripts.")), data); }
else { sundriesMallocHeap += amount; } } while (0)
1827 realmStats.scriptsMallocHeapData,do { size_t amount = realmStats.scriptsMallocHeapData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "scripts/malloc-heap/data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Various variable-length tables in JSScripts.")), data); }
else { sundriesMallocHeap += amount; } } while (0)
1828 "Various variable-length tables in JSScripts.")do { size_t amount = realmStats.scriptsMallocHeapData; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "scripts/malloc-heap/data"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Various variable-length tables in JSScripts.")), data); }
else { sundriesMallocHeap += amount; } } while (0)
;
1829
1830 ZRREPORT_BYTES(realmJSPathPrefix + NS_LITERAL_CSTRING("baseline/data"),do { size_t amount = realmStats.baselineData; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "baseline/data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The Baseline JIT's compilation data (BaselineScripts)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1831 realmStats.baselineData,do { size_t amount = realmStats.baselineData; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "baseline/data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The Baseline JIT's compilation data (BaselineScripts)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1832 "The Baseline JIT's compilation data (BaselineScripts).")do { size_t amount = realmStats.baselineData; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "baseline/data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The Baseline JIT's compilation data (BaselineScripts)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1833
1834 ZRREPORT_BYTES(do { size_t amount = realmStats.baselineStubsFallback; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "baseline/fallback-stubs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The Baseline JIT's fallback IC stubs (excluding code).")
), data); } else { sundriesMallocHeap += amount; } } while (0
)
1835 realmJSPathPrefix + NS_LITERAL_CSTRING("baseline/fallback-stubs"),do { size_t amount = realmStats.baselineStubsFallback; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "baseline/fallback-stubs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The Baseline JIT's fallback IC stubs (excluding code).")
), data); } else { sundriesMallocHeap += amount; } } while (0
)
1836 realmStats.baselineStubsFallback,do { size_t amount = realmStats.baselineStubsFallback; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "baseline/fallback-stubs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The Baseline JIT's fallback IC stubs (excluding code).")
), data); } else { sundriesMallocHeap += amount; } } while (0
)
1837 "The Baseline JIT's fallback IC stubs (excluding code).")do { size_t amount = realmStats.baselineStubsFallback; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "baseline/fallback-stubs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The Baseline JIT's fallback IC stubs (excluding code).")
), data); } else { sundriesMallocHeap += amount; } } while (0
)
;
1838
1839 ZRREPORT_BYTES(realmJSPathPrefix + NS_LITERAL_CSTRING("ion-data"),do { size_t amount = realmStats.ionData; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "ion-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The IonMonkey JIT's compilation data (IonScripts)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1840 realmStats.ionData,do { size_t amount = realmStats.ionData; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "ion-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The IonMonkey JIT's compilation data (IonScripts)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1841 "The IonMonkey JIT's compilation data (IonScripts).")do { size_t amount = realmStats.ionData; if (amount >= js::
MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "ion-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The IonMonkey JIT's compilation data (IonScripts)."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1842
1843 ZRREPORT_BYTES(realmJSPathPrefix + NS_LITERAL_CSTRING("jit-scripts"),do { size_t amount = realmStats.jitScripts; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "jit-scripts")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JIT and Type Inference data associated with scripts."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1844 realmStats.jitScripts,do { size_t amount = realmStats.jitScripts; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "jit-scripts")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JIT and Type Inference data associated with scripts."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1845 "JIT and Type Inference data associated with scripts.")do { size_t amount = realmStats.jitScripts; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "jit-scripts")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JIT and Type Inference data associated with scripts."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1846
1847 ZRREPORT_BYTES(do { size_t amount = realmStats.typeInferenceAllocationSiteTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/allocation-site-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with allocation sites."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1848 realmJSPathPrefix +do { size_t amount = realmStats.typeInferenceAllocationSiteTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/allocation-site-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with allocation sites."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1849 NS_LITERAL_CSTRING("type-inference/allocation-site-tables"),do { size_t amount = realmStats.typeInferenceAllocationSiteTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/allocation-site-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with allocation sites."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1850 realmStats.typeInferenceAllocationSiteTables,do { size_t amount = realmStats.typeInferenceAllocationSiteTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/allocation-site-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with allocation sites."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1851 "Tables of type objects associated with allocation sites.")do { size_t amount = realmStats.typeInferenceAllocationSiteTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/allocation-site-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with allocation sites."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1852
1853 ZRREPORT_BYTES(realmJSPathPrefix +do { size_t amount = realmStats.typeInferenceArrayTypeTables;
if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/array-type-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with array literals.")
), data); } else { sundriesMallocHeap += amount; } } while (0
)
1854 NS_LITERAL_CSTRING("type-inference/array-type-tables"),do { size_t amount = realmStats.typeInferenceArrayTypeTables;
if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/array-type-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with array literals.")
), data); } else { sundriesMallocHeap += amount; } } while (0
)
1855 realmStats.typeInferenceArrayTypeTables,do { size_t amount = realmStats.typeInferenceArrayTypeTables;
if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/array-type-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with array literals.")
), data); } else { sundriesMallocHeap += amount; } } while (0
)
1856 "Tables of type objects associated with array literals.")do { size_t amount = realmStats.typeInferenceArrayTypeTables;
if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/array-type-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with array literals.")
), data); } else { sundriesMallocHeap += amount; } } while (0
)
;
1857
1858 ZRREPORT_BYTES(realmJSPathPrefix +do { size_t amount = realmStats.typeInferenceObjectTypeTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/object-type-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with object literals."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1859 NS_LITERAL_CSTRING("type-inference/object-type-tables"),do { size_t amount = realmStats.typeInferenceObjectTypeTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/object-type-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with object literals."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1860 realmStats.typeInferenceObjectTypeTables,do { size_t amount = realmStats.typeInferenceObjectTypeTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/object-type-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with object literals."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1861 "Tables of type objects associated with object literals.")do { size_t amount = realmStats.typeInferenceObjectTypeTables
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "type-inference/object-type-tables"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Tables of type objects associated with object literals."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1862
1863 ZRREPORT_BYTES(realmJSPathPrefix + NS_LITERAL_CSTRING("realm-object"),do { size_t amount = realmStats.realmObject; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "realm-object")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The JS::Realm object itself."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1864 realmStats.realmObject, "The JS::Realm object itself.")do { size_t amount = realmStats.realmObject; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "realm-object")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The JS::Realm object itself."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1865
1866 ZRREPORT_BYTES(do { size_t amount = realmStats.realmTables; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "realm-tables")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Realm-wide tables storing object group information and wasm instances."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1867 realmJSPathPrefix + NS_LITERAL_CSTRING("realm-tables"),do { size_t amount = realmStats.realmTables; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "realm-tables")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Realm-wide tables storing object group information and wasm instances."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1868 realmStats.realmTables,do { size_t amount = realmStats.realmTables; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "realm-tables")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Realm-wide tables storing object group information and wasm instances."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1869 "Realm-wide tables storing object group information and wasm instances.")do { size_t amount = realmStats.realmTables; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "realm-tables")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Realm-wide tables storing object group information and wasm instances."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1870
1871 ZRREPORT_BYTES(realmJSPathPrefix + NS_LITERAL_CSTRING("inner-views"),do { size_t amount = realmStats.innerViewsTable; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "inner-views")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The table for array buffer inner views."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1872 realmStats.innerViewsTable,do { size_t amount = realmStats.innerViewsTable; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "inner-views")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The table for array buffer inner views."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1873 "The table for array buffer inner views.")do { size_t amount = realmStats.innerViewsTable; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "inner-views")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The table for array buffer inner views."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1874
1875 ZRREPORT_BYTES(realmJSPathPrefix + NS_LITERAL_CSTRING("lazy-array-buffers"),do { size_t amount = realmStats.lazyArrayBuffersTable; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "lazy-array-buffers"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The table for typed object lazy array buffers.")), data)
; } else { sundriesMallocHeap += amount; } } while (0)
1876 realmStats.lazyArrayBuffersTable,do { size_t amount = realmStats.lazyArrayBuffersTable; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "lazy-array-buffers"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The table for typed object lazy array buffers.")), data)
; } else { sundriesMallocHeap += amount; } } while (0)
1877 "The table for typed object lazy array buffers.")do { size_t amount = realmStats.lazyArrayBuffersTable; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "lazy-array-buffers"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The table for typed object lazy array buffers.")), data)
; } else { sundriesMallocHeap += amount; } } while (0)
;
1878
1879 ZRREPORT_BYTES(do { size_t amount = realmStats.objectMetadataTable; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "object-metadata"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The table used by debugging tools for tracking object metadata"
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1880 realmJSPathPrefix + NS_LITERAL_CSTRING("object-metadata"),do { size_t amount = realmStats.objectMetadataTable; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "object-metadata"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The table used by debugging tools for tracking object metadata"
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1881 realmStats.objectMetadataTable,do { size_t amount = realmStats.objectMetadataTable; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "object-metadata"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The table used by debugging tools for tracking object metadata"
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1882 "The table used by debugging tools for tracking object metadata")do { size_t amount = realmStats.objectMetadataTable; if (amount
>= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "object-metadata"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The table used by debugging tools for tracking object metadata"
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1883
1884 ZRREPORT_BYTES(realmJSPathPrefix + NS_LITERAL_CSTRING("saved-stacks-set"),do { size_t amount = realmStats.savedStacksSet; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "saved-stacks-set")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The saved stacks set."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1885 realmStats.savedStacksSet, "The saved stacks set.")do { size_t amount = realmStats.savedStacksSet; if (amount >=
js::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "saved-stacks-set")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The saved stacks set."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1886
1887 ZRREPORT_BYTES(realmJSPathPrefix +do { size_t amount = realmStats.nonSyntacticLexicalScopesTable
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "non-syntactic-lexical-scopes-table"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The non-syntactic lexical scopes table.")), data); } else
{ sundriesMallocHeap += amount; } } while (0)
1888 NS_LITERAL_CSTRING("non-syntactic-lexical-scopes-table"),do { size_t amount = realmStats.nonSyntacticLexicalScopesTable
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "non-syntactic-lexical-scopes-table"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The non-syntactic lexical scopes table.")), data); } else
{ sundriesMallocHeap += amount; } } while (0)
1889 realmStats.nonSyntacticLexicalScopesTable,do { size_t amount = realmStats.nonSyntacticLexicalScopesTable
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "non-syntactic-lexical-scopes-table"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The non-syntactic lexical scopes table.")), data); } else
{ sundriesMallocHeap += amount; } } while (0)
1890 "The non-syntactic lexical scopes table.")do { size_t amount = realmStats.nonSyntacticLexicalScopesTable
; if (amount >= js::MemoryReportingSundriesThreshold()) { handleReport
->Callback(EmptyCString(), realmJSPathPrefix + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "non-syntactic-lexical-scopes-table"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The non-syntactic lexical scopes table.")), data); } else
{ sundriesMallocHeap += amount; } } while (0)
;
1891
1892 ZRREPORT_BYTES(realmJSPathPrefix + NS_LITERAL_CSTRING("jit-realm"),do { size_t amount = realmStats.jitRealm; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "jit-realm")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The JIT realm."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
1893 realmStats.jitRealm, "The JIT realm.")do { size_t amount = realmStats.jitRealm; if (amount >= js
::MemoryReportingSundriesThreshold()) { handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "jit-realm")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The JIT realm."
)), data); } else { sundriesMallocHeap += amount; } } while (
0)
;
1894
1895 if (sundriesGCHeap > 0) {
1896 // We deliberately don't use ZRREPORT_GC_BYTES here.
1897 REPORT_GC_BYTES(do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
1898 realmJSPathPrefix + NS_LITERAL_CSTRING("sundries/gc-heap"),do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
1899 sundriesGCHeap,do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
1900 "The sum of all 'gc-heap' measurements that are too small to be "do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
1901 "worth showing individually.")do { size_t amount = sundriesGCHeap; handleReport->Callback
(EmptyCString(), realmJSPathPrefix + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "sundries/gc-heap")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The sum of all 'gc-heap' measurements that are too small to be "
"worth showing individually.")), data); gcTotal += amount; }
while (0)
;
1902 }
1903
1904 if (sundriesMallocHeap > 0) {
1905 // We deliberately don't use ZRREPORT_BYTES here.
1906 REPORT_BYTES(handleReport->Callback(EmptyCString(), realmJSPathPrefix +
static_cast<const nsLiteralCString&>(nsLiteralCString
("" "sundries/malloc-heap")), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter
::UNITS_BYTES, sundriesMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
1907 realmJSPathPrefix + NS_LITERAL_CSTRING("sundries/malloc-heap"),handleReport->Callback(EmptyCString(), realmJSPathPrefix +
static_cast<const nsLiteralCString&>(nsLiteralCString
("" "sundries/malloc-heap")), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter
::UNITS_BYTES, sundriesMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
1908 KIND_HEAP, sundriesMallocHeap,handleReport->Callback(EmptyCString(), realmJSPathPrefix +
static_cast<const nsLiteralCString&>(nsLiteralCString
("" "sundries/malloc-heap")), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter
::UNITS_BYTES, sundriesMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
1909 "The sum of all 'malloc-heap' measurements that are too small to "handleReport->Callback(EmptyCString(), realmJSPathPrefix +
static_cast<const nsLiteralCString&>(nsLiteralCString
("" "sundries/malloc-heap")), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter
::UNITS_BYTES, sundriesMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
1910 "be worth showing individually.")handleReport->Callback(EmptyCString(), realmJSPathPrefix +
static_cast<const nsLiteralCString&>(nsLiteralCString
("" "sundries/malloc-heap")), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter
::UNITS_BYTES, sundriesMallocHeap, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The sum of all 'malloc-heap' measurements that are too small to "
"be worth showing individually.")), data);;
;
1911 }
1912
1913 if (gcTotalOut) {
1914 *gcTotalOut += gcTotal;
1915 }
1916}
1917
1918static void ReportScriptSourceStats(const ScriptSourceInfo& scriptSourceInfo,
1919 const nsACString& path,
1920 nsIHandleReportCallback* handleReport,
1921 nsISupports* data, size_t& rtTotal) {
1922 if (scriptSourceInfo.misc > 0) {
1923 RREPORT_BYTES(path + NS_LITERAL_CSTRING("misc"), KIND_HEAP,do { size_t amount = scriptSourceInfo.misc; handleReport->
Callback(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "misc")), nsIMemoryReporter::KIND_HEAP
, nsIMemoryReporter::UNITS_BYTES, amount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Miscellaneous data relating to JavaScript source code."
)), data); rtTotal += amount; } while (0)
1924 scriptSourceInfo.misc,do { size_t amount = scriptSourceInfo.misc; handleReport->
Callback(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "misc")), nsIMemoryReporter::KIND_HEAP
, nsIMemoryReporter::UNITS_BYTES, amount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Miscellaneous data relating to JavaScript source code."
)), data); rtTotal += amount; } while (0)
1925 "Miscellaneous data relating to JavaScript source code.")do { size_t amount = scriptSourceInfo.misc; handleReport->
Callback(EmptyCString(), path + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "misc")), nsIMemoryReporter::KIND_HEAP
, nsIMemoryReporter::UNITS_BYTES, amount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Miscellaneous data relating to JavaScript source code."
)), data); rtTotal += amount; } while (0)
;
1926 }
1927}
1928
1929void ReportJSRuntimeExplicitTreeStats(const JS::RuntimeStats& rtStats,
1930 const nsACString& rtPath,
1931 nsIHandleReportCallback* handleReport,
1932 nsISupports* data, bool anonymize,
1933 size_t* rtTotalOut) {
1934 size_t gcTotal = 0;
1935
1936 for (size_t i = 0; i < rtStats.zoneStatsVector.length(); i++) {
1937 const JS::ZoneStats& zStats = rtStats.zoneStatsVector[i];
1938 const xpc::ZoneStatsExtras* extras =
1939 static_cast<const xpc::ZoneStatsExtras*>(zStats.extra);
1940 ReportZoneStats(zStats, *extras, handleReport, data, anonymize, &gcTotal);
1941 }
1942
1943 for (size_t i = 0; i < rtStats.realmStatsVector.length(); i++) {
1944 const JS::RealmStats& realmStats = rtStats.realmStatsVector[i];
1945 const xpc::RealmStatsExtras* extras =
1946 static_cast<const xpc::RealmStatsExtras*>(realmStats.extra);
1947
1948 ReportRealmStats(realmStats, *extras, handleReport, data, &gcTotal);
1949 }
1950
1951 // Report the rtStats.runtime numbers under "runtime/", and compute their
1952 // total for later.
1953
1954 size_t rtTotal = 0;
1955
1956 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/runtime-object"),do { size_t amount = rtStats.runtime.object; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/runtime-object")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The JSRuntime object."
)), data); rtTotal += amount; } while (0)
1957 KIND_HEAP, rtStats.runtime.object, "The JSRuntime object.")do { size_t amount = rtStats.runtime.object; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/runtime-object")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The JSRuntime object."
)), data); rtTotal += amount; } while (0)
;
1958
1959 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/atoms-table"), KIND_HEAP,do { size_t amount = rtStats.runtime.atomsTable; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/atoms-table")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The atoms table."
)), data); rtTotal += amount; } while (0)
1960 rtStats.runtime.atomsTable, "The atoms table.")do { size_t amount = rtStats.runtime.atomsTable; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/atoms-table")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The atoms table."
)), data); rtTotal += amount; } while (0)
;
1961
1962 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/atoms-mark-bitmaps"),do { size_t amount = rtStats.runtime.atomsMarkBitmaps; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/atoms-mark-bitmaps")),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Mark bitmaps for atoms held by each zone.")), data); rtTotal
+= amount; } while (0)
1963 KIND_HEAP, rtStats.runtime.atomsMarkBitmaps,do { size_t amount = rtStats.runtime.atomsMarkBitmaps; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/atoms-mark-bitmaps")),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Mark bitmaps for atoms held by each zone.")), data); rtTotal
+= amount; } while (0)
1964 "Mark bitmaps for atoms held by each zone.")do { size_t amount = rtStats.runtime.atomsMarkBitmaps; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/atoms-mark-bitmaps")),
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Mark bitmaps for atoms held by each zone.")), data); rtTotal
+= amount; } while (0)
;
1965
1966 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/contexts"), KIND_HEAP,do { size_t amount = rtStats.runtime.contexts; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/contexts")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JSContext objects and structures that belong to them."
)), data); rtTotal += amount; } while (0)
1967 rtStats.runtime.contexts,do { size_t amount = rtStats.runtime.contexts; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/contexts")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JSContext objects and structures that belong to them."
)), data); rtTotal += amount; } while (0)
1968 "JSContext objects and structures that belong to them.")do { size_t amount = rtStats.runtime.contexts; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/contexts")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JSContext objects and structures that belong to them."
)), data); rtTotal += amount; } while (0)
;
1969
1970 RREPORT_BYTES(do { size_t amount = rtStats.runtime.temporary; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/temporary")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Transient data (mostly parse nodes) held by the JSRuntime during "
"compilation.")), data); rtTotal += amount; } while (0)
1971 rtPath + NS_LITERAL_CSTRING("runtime/temporary"), KIND_HEAP,do { size_t amount = rtStats.runtime.temporary; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/temporary")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Transient data (mostly parse nodes) held by the JSRuntime during "
"compilation.")), data); rtTotal += amount; } while (0)
1972 rtStats.runtime.temporary,do { size_t amount = rtStats.runtime.temporary; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/temporary")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Transient data (mostly parse nodes) held by the JSRuntime during "
"compilation.")), data); rtTotal += amount; } while (0)
1973 "Transient data (mostly parse nodes) held by the JSRuntime during "do { size_t amount = rtStats.runtime.temporary; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/temporary")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Transient data (mostly parse nodes) held by the JSRuntime during "
"compilation.")), data); rtTotal += amount; } while (0)
1974 "compilation.")do { size_t amount = rtStats.runtime.temporary; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/temporary")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Transient data (mostly parse nodes) held by the JSRuntime during "
"compilation.")), data); rtTotal += amount; } while (0)
;
1975
1976 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/interpreter-stack"),do { size_t amount = rtStats.runtime.interpreterStack; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/interpreter-stack")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JS interpreter frames."
)), data); rtTotal += amount; } while (0)
1977 KIND_HEAP, rtStats.runtime.interpreterStack,do { size_t amount = rtStats.runtime.interpreterStack; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/interpreter-stack")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JS interpreter frames."
)), data); rtTotal += amount; } while (0)
1978 "JS interpreter frames.")do { size_t amount = rtStats.runtime.interpreterStack; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/interpreter-stack")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "JS interpreter frames."
)), data); rtTotal += amount; } while (0)
;
1979
1980 RREPORT_BYTES(do { size_t amount = rtStats.runtime.sharedImmutableStringsCache
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/shared-immutable-strings-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Immutable strings (such as JS scripts' source text) shared across all "
"JSRuntimes.")), data); rtTotal += amount; } while (0)
1981 rtPath + NS_LITERAL_CSTRING("runtime/shared-immutable-strings-cache"),do { size_t amount = rtStats.runtime.sharedImmutableStringsCache
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/shared-immutable-strings-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Immutable strings (such as JS scripts' source text) shared across all "
"JSRuntimes.")), data); rtTotal += amount; } while (0)
1982 KIND_HEAP, rtStats.runtime.sharedImmutableStringsCache,do { size_t amount = rtStats.runtime.sharedImmutableStringsCache
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/shared-immutable-strings-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Immutable strings (such as JS scripts' source text) shared across all "
"JSRuntimes.")), data); rtTotal += amount; } while (0)
1983 "Immutable strings (such as JS scripts' source text) shared across all "do { size_t amount = rtStats.runtime.sharedImmutableStringsCache
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/shared-immutable-strings-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Immutable strings (such as JS scripts' source text) shared across all "
"JSRuntimes.")), data); rtTotal += amount; } while (0)
1984 "JSRuntimes.")do { size_t amount = rtStats.runtime.sharedImmutableStringsCache
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/shared-immutable-strings-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Immutable strings (such as JS scripts' source text) shared across all "
"JSRuntimes.")), data); rtTotal += amount; } while (0)
;
1985
1986 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/shared-intl-data"),do { size_t amount = rtStats.runtime.sharedIntlData; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/shared-intl-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Shared internationalization data."
)), data); rtTotal += amount; } while (0)
1987 KIND_HEAP, rtStats.runtime.sharedIntlData,do { size_t amount = rtStats.runtime.sharedIntlData; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/shared-intl-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Shared internationalization data."
)), data); rtTotal += amount; } while (0)
1988 "Shared internationalization data.")do { size_t amount = rtStats.runtime.sharedIntlData; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/shared-intl-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Shared internationalization data."
)), data); rtTotal += amount; } while (0)
;
1989
1990 RREPORT_BYTES(do { size_t amount = rtStats.runtime.uncompressedSourceCache;
handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/uncompressed-source-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The uncompressed source code cache.")), data); rtTotal +=
amount; } while (0)
1991 rtPath + NS_LITERAL_CSTRING("runtime/uncompressed-source-cache"),do { size_t amount = rtStats.runtime.uncompressedSourceCache;
handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/uncompressed-source-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The uncompressed source code cache.")), data); rtTotal +=
amount; } while (0)
1992 KIND_HEAP, rtStats.runtime.uncompressedSourceCache,do { size_t amount = rtStats.runtime.uncompressedSourceCache;
handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/uncompressed-source-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The uncompressed source code cache.")), data); rtTotal +=
amount; } while (0)
1993 "The uncompressed source code cache.")do { size_t amount = rtStats.runtime.uncompressedSourceCache;
handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/uncompressed-source-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The uncompressed source code cache.")), data); rtTotal +=
amount; } while (0)
;
1994
1995 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/script-data"), KIND_HEAP,do { size_t amount = rtStats.runtime.scriptData; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/script-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The table holding script data shared in the runtime."
)), data); rtTotal += amount; } while (0)
1996 rtStats.runtime.scriptData,do { size_t amount = rtStats.runtime.scriptData; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/script-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The table holding script data shared in the runtime."
)), data); rtTotal += amount; } while (0)
1997 "The table holding script data shared in the runtime.")do { size_t amount = rtStats.runtime.scriptData; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/script-data")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The table holding script data shared in the runtime."
)), data); rtTotal += amount; } while (0)
;
1998
1999 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/tracelogger"), KIND_HEAP,do { size_t amount = rtStats.runtime.tracelogger; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/tracelogger")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The memory used for the tracelogger (per-runtime)."
)), data); rtTotal += amount; } while (0)
2000 rtStats.runtime.tracelogger,do { size_t amount = rtStats.runtime.tracelogger; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/tracelogger")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The memory used for the tracelogger (per-runtime)."
)), data); rtTotal += amount; } while (0)
2001 "The memory used for the tracelogger (per-runtime).")do { size_t amount = rtStats.runtime.tracelogger; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/tracelogger")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The memory used for the tracelogger (per-runtime)."
)), data); rtTotal += amount; } while (0)
;
2002
2003 nsCString nonNotablePath =
2004 rtPath +
2005 nsPrintfCString(
2006 "runtime/script-sources/source(scripts=%d, <non-notable files>)/",
2007 rtStats.runtime.scriptSourceInfo.numScripts);
2008
2009 ReportScriptSourceStats(rtStats.runtime.scriptSourceInfo, nonNotablePath,
2010 handleReport, data, rtTotal);
2011
2012 for (size_t i = 0; i < rtStats.runtime.notableScriptSources.length(); i++) {
2013 const JS::NotableScriptSourceInfo& scriptSourceInfo =
2014 rtStats.runtime.notableScriptSources[i];
2015
2016 // Escape / to \ before we put the filename into the memory reporter
2017 // path, because we don't want any forward slashes in the string to
2018 // count as path separators. Consumers of memory reporters (e.g.
2019 // about:memory) will convert them back to / after doing path
2020 // splitting.
2021 nsCString escapedFilename;
2022 if (anonymize) {
2023 escapedFilename.AppendPrintf("<anonymized-source-%d>", int(i));
2024 } else {
2025 nsDependentCString filename(scriptSourceInfo.filename_.get());
2026 escapedFilename.Append(filename);
2027 escapedFilename.ReplaceSubstring("/", "\\");
2028 }
2029
2030 nsCString notablePath =
2031 rtPath +
2032 nsPrintfCString("runtime/script-sources/source(scripts=%d, %s)/",
2033 scriptSourceInfo.numScripts, escapedFilename.get());
2034
2035 ReportScriptSourceStats(scriptSourceInfo, notablePath, handleReport, data,
2036 rtTotal);
2037 }
2038
2039 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/ion"), KIND_NONHEAP,do { size_t amount = rtStats.runtime.code.ion; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/ion")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the IonMonkey JIT."
)), data); rtTotal += amount; } while (0)
2040 rtStats.runtime.code.ion,do { size_t amount = rtStats.runtime.code.ion; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/ion")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the IonMonkey JIT."
)), data); rtTotal += amount; } while (0)
2041 "Code generated by the IonMonkey JIT.")do { size_t amount = rtStats.runtime.code.ion; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/ion")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the IonMonkey JIT."
)), data); rtTotal += amount; } while (0)
;
2042
2043 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/baseline"),do { size_t amount = rtStats.runtime.code.baseline; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/baseline")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the Baseline JIT."
)), data); rtTotal += amount; } while (0)
2044 KIND_NONHEAP, rtStats.runtime.code.baseline,do { size_t amount = rtStats.runtime.code.baseline; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/baseline")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the Baseline JIT."
)), data); rtTotal += amount; } while (0)
2045 "Code generated by the Baseline JIT.")do { size_t amount = rtStats.runtime.code.baseline; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/baseline")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the Baseline JIT."
)), data); rtTotal += amount; } while (0)
;
2046
2047 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/regexp"),do { size_t amount = rtStats.runtime.code.regexp; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/regexp")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the regexp JIT."
)), data); rtTotal += amount; } while (0)
2048 KIND_NONHEAP, rtStats.runtime.code.regexp,do { size_t amount = rtStats.runtime.code.regexp; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/regexp")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the regexp JIT."
)), data); rtTotal += amount; } while (0)
2049 "Code generated by the regexp JIT.")do { size_t amount = rtStats.runtime.code.regexp; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/regexp")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the regexp JIT."
)), data); rtTotal += amount; } while (0)
;
2050
2051 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/code/other"), KIND_NONHEAP,do { size_t amount = rtStats.runtime.code.other; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/other")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the JITs for wrappers and trampolines."
)), data); rtTotal += amount; } while (0)
2052 rtStats.runtime.code.other,do { size_t amount = rtStats.runtime.code.other; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/other")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the JITs for wrappers and trampolines."
)), data); rtTotal += amount; } while (0)
2053 "Code generated by the JITs for wrappers and trampolines.")do { size_t amount = rtStats.runtime.code.other; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/other")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Code generated by the JITs for wrappers and trampolines."
)), data); rtTotal += amount; } while (0)
;
2054
2055 RREPORT_BYTES(do { size_t amount = rtStats.runtime.code.unused; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/unused")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Memory allocated by one of the JITs to hold code, but which is "
"currently unused.")), data); rtTotal += amount; } while (0)
2056 rtPath + NS_LITERAL_CSTRING("runtime/code/unused"), KIND_NONHEAP,do { size_t amount = rtStats.runtime.code.unused; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/unused")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Memory allocated by one of the JITs to hold code, but which is "
"currently unused.")), data); rtTotal += amount; } while (0)
2057 rtStats.runtime.code.unused,do { size_t amount = rtStats.runtime.code.unused; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/unused")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Memory allocated by one of the JITs to hold code, but which is "
"currently unused.")), data); rtTotal += amount; } while (0)
2058 "Memory allocated by one of the JITs to hold code, but which is "do { size_t amount = rtStats.runtime.code.unused; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/unused")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Memory allocated by one of the JITs to hold code, but which is "
"currently unused.")), data); rtTotal += amount; } while (0)
2059 "currently unused.")do { size_t amount = rtStats.runtime.code.unused; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/code/unused")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Memory allocated by one of the JITs to hold code, but which is "
"currently unused.")), data); rtTotal += amount; } while (0)
;
2060
2061 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/gc/marker"), KIND_HEAP,do { size_t amount = rtStats.runtime.gc.marker; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/marker")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The GC mark stack and gray roots."
)), data); rtTotal += amount; } while (0)
2062 rtStats.runtime.gc.marker, "The GC mark stack and gray roots.")do { size_t amount = rtStats.runtime.gc.marker; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/marker")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "The GC mark stack and gray roots."
)), data); rtTotal += amount; } while (0)
;
2063
2064 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/gc/nursery-committed"),do { size_t amount = rtStats.runtime.gc.nurseryCommitted; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/nursery-committed")
), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Memory being used by the GC's nursery.")), data); rtTotal
+= amount; } while (0)
2065 KIND_NONHEAP, rtStats.runtime.gc.nurseryCommitted,do { size_t amount = rtStats.runtime.gc.nurseryCommitted; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/nursery-committed")
), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Memory being used by the GC's nursery.")), data); rtTotal
+= amount; } while (0)
2066 "Memory being used by the GC's nursery.")do { size_t amount = rtStats.runtime.gc.nurseryCommitted; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/nursery-committed")
), nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Memory being used by the GC's nursery.")), data); rtTotal
+= amount; } while (0)
;
2067
2068 RREPORT_BYTES(do { size_t amount = rtStats.runtime.gc.nurseryMallocedBuffers
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/gc/nursery-malloced-buffers"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Out-of-line slots and elements belonging to objects in the nursery."
)), data); rtTotal += amount; } while (0)
2069 rtPath + NS_LITERAL_CSTRING("runtime/gc/nursery-malloced-buffers"),do { size_t amount = rtStats.runtime.gc.nurseryMallocedBuffers
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/gc/nursery-malloced-buffers"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Out-of-line slots and elements belonging to objects in the nursery."
)), data); rtTotal += amount; } while (0)
2070 KIND_HEAP, rtStats.runtime.gc.nurseryMallocedBuffers,do { size_t amount = rtStats.runtime.gc.nurseryMallocedBuffers
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/gc/nursery-malloced-buffers"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Out-of-line slots and elements belonging to objects in the nursery."
)), data); rtTotal += amount; } while (0)
2071 "Out-of-line slots and elements belonging to objects in the nursery.")do { size_t amount = rtStats.runtime.gc.nurseryMallocedBuffers
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/gc/nursery-malloced-buffers"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Out-of-line slots and elements belonging to objects in the nursery."
)), data); rtTotal += amount; } while (0)
;
2072
2073 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/gc/store-buffer/vals"),do { size_t amount = rtStats.runtime.gc.storeBufferVals; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/vals")
), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Values in the store buffer.")), data); rtTotal += amount
; } while (0)
2074 KIND_HEAP, rtStats.runtime.gc.storeBufferVals,do { size_t amount = rtStats.runtime.gc.storeBufferVals; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/vals")
), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Values in the store buffer.")), data); rtTotal += amount
; } while (0)
2075 "Values in the store buffer.")do { size_t amount = rtStats.runtime.gc.storeBufferVals; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/vals")
), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Values in the store buffer.")), data); rtTotal += amount
; } while (0)
;
2076
2077 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/gc/store-buffer/cells"),do { size_t amount = rtStats.runtime.gc.storeBufferCells; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/cells"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Cells in the store buffer.")), data); rtTotal += amount;
} while (0)
2078 KIND_HEAP, rtStats.runtime.gc.storeBufferCells,do { size_t amount = rtStats.runtime.gc.storeBufferCells; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/cells"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Cells in the store buffer.")), data); rtTotal += amount;
} while (0)
2079 "Cells in the store buffer.")do { size_t amount = rtStats.runtime.gc.storeBufferCells; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/cells"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Cells in the store buffer.")), data); rtTotal += amount;
} while (0)
;
2080
2081 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/gc/store-buffer/slots"),do { size_t amount = rtStats.runtime.gc.storeBufferSlots; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/slots"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Slots in the store buffer.")), data); rtTotal += amount;
} while (0)
2082 KIND_HEAP, rtStats.runtime.gc.storeBufferSlots,do { size_t amount = rtStats.runtime.gc.storeBufferSlots; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/slots"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Slots in the store buffer.")), data); rtTotal += amount;
} while (0)
2083 "Slots in the store buffer.")do { size_t amount = rtStats.runtime.gc.storeBufferSlots; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/slots"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Slots in the store buffer.")), data); rtTotal += amount;
} while (0)
;
2084
2085 RREPORT_BYTES(do { size_t amount = rtStats.runtime.gc.storeBufferWholeCells
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/gc/store-buffer/whole-cells"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Whole cells in the store buffer.")), data); rtTotal += amount
; } while (0)
2086 rtPath + NS_LITERAL_CSTRING("runtime/gc/store-buffer/whole-cells"),do { size_t amount = rtStats.runtime.gc.storeBufferWholeCells
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/gc/store-buffer/whole-cells"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Whole cells in the store buffer.")), data); rtTotal += amount
; } while (0)
2087 KIND_HEAP, rtStats.runtime.gc.storeBufferWholeCells,do { size_t amount = rtStats.runtime.gc.storeBufferWholeCells
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/gc/store-buffer/whole-cells"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Whole cells in the store buffer.")), data); rtTotal += amount
; } while (0)
2088 "Whole cells in the store buffer.")do { size_t amount = rtStats.runtime.gc.storeBufferWholeCells
; handleReport->Callback(EmptyCString(), rtPath + static_cast
<const nsLiteralCString&>(nsLiteralCString("" "runtime/gc/store-buffer/whole-cells"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Whole cells in the store buffer.")), data); rtTotal += amount
; } while (0)
;
2089
2090 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/gc/store-buffer/generics"),do { size_t amount = rtStats.runtime.gc.storeBufferGenerics; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/generics"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Generic things in the store buffer.")), data); rtTotal +=
amount; } while (0)
2091 KIND_HEAP, rtStats.runtime.gc.storeBufferGenerics,do { size_t amount = rtStats.runtime.gc.storeBufferGenerics; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/generics"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Generic things in the store buffer.")), data); rtTotal +=
amount; } while (0)
2092 "Generic things in the store buffer.")do { size_t amount = rtStats.runtime.gc.storeBufferGenerics; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/gc/store-buffer/generics"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Generic things in the store buffer.")), data); rtTotal +=
amount; } while (0)
;
2093
2094 RREPORT_BYTES(rtPath + NS_LITERAL_CSTRING("runtime/jit-lazylink"), KIND_HEAP,do { size_t amount = rtStats.runtime.jitLazyLink; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/jit-lazylink")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "IonMonkey compilations waiting for lazy linking."
)), data); rtTotal += amount; } while (0)
2095 rtStats.runtime.jitLazyLink,do { size_t amount = rtStats.runtime.jitLazyLink; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/jit-lazylink")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "IonMonkey compilations waiting for lazy linking."
)), data); rtTotal += amount; } while (0)
2096 "IonMonkey compilations waiting for lazy linking.")do { size_t amount = rtStats.runtime.jitLazyLink; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "runtime/jit-lazylink")), nsIMemoryReporter
::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "IonMonkey compilations waiting for lazy linking."
)), data); rtTotal += amount; } while (0)
;
2097
2098 if (rtTotalOut) {
2099 *rtTotalOut = rtTotal;
2100 }
2101
2102 // Report GC numbers that don't belong to a realm.
2103
2104 // We don't want to report decommitted memory in "explicit", so we just
2105 // change the leading "explicit/" to "decommitted/".
2106 nsCString rtPath2(rtPath);
2107 rtPath2.ReplaceLiteral(0, strlen("explicit"), "decommitted");
2108
2109 REPORT_GC_BYTES(do { size_t amount = rtStats.gcHeapDecommittedArenas; handleReport
->Callback(EmptyCString(), rtPath2 + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/decommitted-arenas")),
nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "GC arenas in non-empty chunks that is decommitted, i.e. it takes up "
"address space but no physical memory or swap space.")), data
); gcTotal += amount; } while (0)
2110 rtPath2 + NS_LITERAL_CSTRING("gc-heap/decommitted-arenas"),do { size_t amount = rtStats.gcHeapDecommittedArenas; handleReport
->Callback(EmptyCString(), rtPath2 + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/decommitted-arenas")),
nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "GC arenas in non-empty chunks that is decommitted, i.e. it takes up "
"address space but no physical memory or swap space.")), data
); gcTotal += amount; } while (0)
2111 rtStats.gcHeapDecommittedArenas,do { size_t amount = rtStats.gcHeapDecommittedArenas; handleReport
->Callback(EmptyCString(), rtPath2 + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/decommitted-arenas")),
nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "GC arenas in non-empty chunks that is decommitted, i.e. it takes up "
"address space but no physical memory or swap space.")), data
); gcTotal += amount; } while (0)
2112 "GC arenas in non-empty chunks that is decommitted, i.e. it takes up "do { size_t amount = rtStats.gcHeapDecommittedArenas; handleReport
->Callback(EmptyCString(), rtPath2 + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/decommitted-arenas")),
nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "GC arenas in non-empty chunks that is decommitted, i.e. it takes up "
"address space but no physical memory or swap space.")), data
); gcTotal += amount; } while (0)
2113 "address space but no physical memory or swap space.")do { size_t amount = rtStats.gcHeapDecommittedArenas; handleReport
->Callback(EmptyCString(), rtPath2 + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/decommitted-arenas")),
nsIMemoryReporter::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "GC arenas in non-empty chunks that is decommitted, i.e. it takes up "
"address space but no physical memory or swap space.")), data
); gcTotal += amount; } while (0)
;
2114
2115 REPORT_GC_BYTES(do { size_t amount = rtStats.gcHeapUnusedChunks; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/unused-chunks")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Empty GC chunks which will soon be released unless claimed for new "
"allocations.")), data); gcTotal += amount; } while (0)
2116 rtPath + NS_LITERAL_CSTRING("gc-heap/unused-chunks"),do { size_t amount = rtStats.gcHeapUnusedChunks; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/unused-chunks")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Empty GC chunks which will soon be released unless claimed for new "
"allocations.")), data); gcTotal += amount; } while (0)
2117 rtStats.gcHeapUnusedChunks,do { size_t amount = rtStats.gcHeapUnusedChunks; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/unused-chunks")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Empty GC chunks which will soon be released unless claimed for new "
"allocations.")), data); gcTotal += amount; } while (0)
2118 "Empty GC chunks which will soon be released unless claimed for new "do { size_t amount = rtStats.gcHeapUnusedChunks; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/unused-chunks")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Empty GC chunks which will soon be released unless claimed for new "
"allocations.")), data); gcTotal += amount; } while (0)
2119 "allocations.")do { size_t amount = rtStats.gcHeapUnusedChunks; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/unused-chunks")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Empty GC chunks which will soon be released unless claimed for new "
"allocations.")), data); gcTotal += amount; } while (0)
;
2120
2121 REPORT_GC_BYTES(rtPath + NS_LITERAL_CSTRING("gc-heap/unused-arenas"),do { size_t amount = rtStats.gcHeapUnusedArenas; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/unused-arenas")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Empty GC arenas within non-empty chunks."
)), data); gcTotal += amount; } while (0)
2122 rtStats.gcHeapUnusedArenas,do { size_t amount = rtStats.gcHeapUnusedArenas; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/unused-arenas")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Empty GC arenas within non-empty chunks."
)), data); gcTotal += amount; } while (0)
2123 "Empty GC arenas within non-empty chunks.")do { size_t amount = rtStats.gcHeapUnusedArenas; handleReport
->Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/unused-arenas")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Empty GC arenas within non-empty chunks."
)), data); gcTotal += amount; } while (0)
;
2124
2125 REPORT_GC_BYTES(rtPath + NS_LITERAL_CSTRING("gc-heap/chunk-admin"),do { size_t amount = rtStats.gcHeapChunkAdmin; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/chunk-admin")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Bookkeeping information within GC chunks."
)), data); gcTotal += amount; } while (0)
2126 rtStats.gcHeapChunkAdmin,do { size_t amount = rtStats.gcHeapChunkAdmin; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/chunk-admin")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Bookkeeping information within GC chunks."
)), data); gcTotal += amount; } while (0)
2127 "Bookkeeping information within GC chunks.")do { size_t amount = rtStats.gcHeapChunkAdmin; handleReport->
Callback(EmptyCString(), rtPath + static_cast<const nsLiteralCString
&>(nsLiteralCString("" "gc-heap/chunk-admin")), nsIMemoryReporter
::KIND_NONHEAP, nsIMemoryReporter::UNITS_BYTES, amount, static_cast
<const nsLiteralCString&>(nsLiteralCString("" "Bookkeeping information within GC chunks."
)), data); gcTotal += amount; } while (0)
;
2128
2129 // gcTotal is the sum of everything we've reported for the GC heap. It
2130 // should equal rtStats.gcHeapChunkTotal.
2131 MOZ_ASSERT(gcTotal == rtStats.gcHeapChunkTotal)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gcTotal == rtStats.gcHeapChunkTotal)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(gcTotal == rtStats.gcHeapChunkTotal
))), 0))) { MOZ_ReportAssertionFailure("gcTotal == rtStats.gcHeapChunkTotal"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gcTotal == rtStats.gcHeapChunkTotal"
")"); do { *((volatile int*)__null) = 2131; ::abort(); } while
(false); } } while (false)
;
2132}
2133
2134} // namespace xpc
2135
2136class JSMainRuntimeRealmsReporter final : public nsIMemoryReporter {
2137 ~JSMainRuntimeRealmsReporter() {}
2138
2139 public:
2140 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; typedef mozilla::FalseType HasThreadSafeRefCnt
; protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
2141
2142 struct Data {
2143 int anonymizeID;
2144 js::Vector<nsCString, 0, js::SystemAllocPolicy> paths;
2145 };
2146
2147 static void RealmCallback(JSContext* cx, void* vdata, Handle<Realm*> realm) {
2148 // silently ignore OOM errors
2149 Data* data = static_cast<Data*>(vdata);
2150 nsCString path;
2151 GetRealmName(realm, path, &data->anonymizeID, /* replaceSlashes = */ true);
2152 path.Insert(js::IsSystemRealm(realm)
2153 ? NS_LITERAL_CSTRING("js-main-runtime-realms/system/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "js-main-runtime-realms/system/"))
2154 : NS_LITERAL_CSTRING("js-main-runtime-realms/user/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "js-main-runtime-realms/user/"))
,
2155 0);
2156 mozilla::Unused << data->paths.append(path);
2157 }
2158
2159 NS_IMETHODvirtual nsresult CollectReports(nsIHandleReportCallback* handleReport,
2160 nsISupports* data, bool anonymize) override {
2161 // First we collect the realm paths. Then we report them. Doing
2162 // the two steps interleaved is a bad idea, because calling
2163 // |handleReport| from within RealmCallback() leads to all manner
2164 // of assertions.
2165
2166 Data d;
2167 d.anonymizeID = anonymize ? 1 : 0;
2168 JS::IterateRealms(XPCJSContext::Get()->Context(), &d, RealmCallback);
2169
2170 for (size_t i = 0; i < d.paths.length(); i++) {
2171 REPORT(nsCString(d.paths[i]), KIND_OTHER, UNITS_COUNT, 1,handleReport->Callback(EmptyCString(), nsCString(d.paths[i
]), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, 1, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "A live realm in the main JSRuntime.")), data);
2172 "A live realm in the main JSRuntime.")handleReport->Callback(EmptyCString(), nsCString(d.paths[i
]), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, 1, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "A live realm in the main JSRuntime.")), data);
;
2173 }
2174
2175 return NS_OK;
2176 }
2177};
2178
2179NS_IMPL_ISUPPORTS(JSMainRuntimeRealmsReporter, nsIMemoryReporter)MozExternalRefCountType JSMainRuntimeRealmsReporter::AddRef(void
) { static_assert(!mozilla::IsDestructible<JSMainRuntimeRealmsReporter
>::value, "Reference-counted class " "JSMainRuntimeRealmsReporter"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
2179; ::abort(); } while (false); } } while (false); do { static_assert
( mozilla::detail::AssertionConditionType<decltype("JSMainRuntimeRealmsReporter"
!= nullptr)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!("JSMainRuntimeRealmsReporter" != nullptr
))), 0))) { MOZ_ReportAssertionFailure("\"JSMainRuntimeRealmsReporter\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"JSMainRuntimeRealmsReporter\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2179; ::abort(); } while (false); } } while (false); if (
!mRefCnt.isThreadSafe) this->_mOwningThread.AssertOwnership
("JSMainRuntimeRealmsReporter" " not thread-safe"); nsrefcnt count
= ++mRefCnt; NS_LogAddRef((this), (count), ("JSMainRuntimeRealmsReporter"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
JSMainRuntimeRealmsReporter::Release(void) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(int32_t
(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0" " ("
"dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 2179
; ::abort(); } while (false); } } while (false); do { static_assert
( mozilla::detail::AssertionConditionType<decltype("JSMainRuntimeRealmsReporter"
!= nullptr)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!("JSMainRuntimeRealmsReporter" != nullptr
))), 0))) { MOZ_ReportAssertionFailure("\"JSMainRuntimeRealmsReporter\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"JSMainRuntimeRealmsReporter\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 2179; ::abort(); } while (false); } } while (false); if (
!mRefCnt.isThreadSafe) this->_mOwningThread.AssertOwnership
("JSMainRuntimeRealmsReporter" " not thread-safe"); const char
* const nametmp = "JSMainRuntimeRealmsReporter"; nsrefcnt count
= --mRefCnt; NS_LogRelease((this), (count), (nametmp)); if (
count == 0) { mRefCnt = 1; delete (this); return 0; } return count
; } nsresult JSMainRuntimeRealmsReporter::QueryInterface(const
nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2179); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&(nsIMemoryReporter
::COMTypeInfo<nsIMemoryReporter, void>::kIID), int32_t(
reinterpret_cast<char*>(static_cast<nsIMemoryReporter
*>((JSMainRuntimeRealmsReporter*)0x1000)) - reinterpret_cast
<char*>((JSMainRuntimeRealmsReporter*)0x1000))}, {&
(nsISupports::COMTypeInfo<nsISupports, void>::kIID), int32_t
(reinterpret_cast<char*>(static_cast<nsISupports*>
( static_cast<nsIMemoryReporter*>((JSMainRuntimeRealmsReporter
*)0x1000))) - reinterpret_cast<char*>((JSMainRuntimeRealmsReporter
*)0x1000))}, { nullptr, 0 } } ; static_assert((sizeof(table) /
sizeof(table[0])) > 1, "need at least 1 interface"); rv =
NS_TableDrivenQI(static_cast<void*>(this), aIID, aInstancePtr
, table); return rv; }
2180
2181MOZ_DEFINE_MALLOC_SIZE_OF(OrphanMallocSizeOf)static size_t OrphanMallocSizeOf(const void* aPtr) { mozilla::
dmd::Report(aPtr); return moz_malloc_size_of(aPtr); }
2182
2183namespace xpc {
2184
2185class OrphanReporter : public JS::ObjectPrivateVisitor {
2186 public:
2187 explicit OrphanReporter(GetISupportsFun aGetISupports)
2188 : JS::ObjectPrivateVisitor(aGetISupports), mState(OrphanMallocSizeOf) {}
2189
2190 virtual size_t sizeOfIncludingThis(nsISupports* aSupports) override {
2191 nsCOMPtr<nsINode> node = do_QueryInterface(aSupports);
2192 // https://bugzilla.mozilla.org/show_bug.cgi?id=773533#c11 explains that we
2193 // have to skip XBL elements because they violate certain assumptions. Yuk.
2194 if (!node || node->IsInComposedDoc() ||
2195 (node->IsElement() &&
2196 node->AsElement()->IsInNamespace(kNameSpaceID_XBL6))) {
2197 return 0;
2198 }
2199
2200 // This is an orphan node. If we haven't already handled the sub-tree that
2201 // this node belongs to, measure the sub-tree's size and then record its
2202 // root so we don't measure it again.
2203 nsCOMPtr<nsINode> orphanTree = node->SubtreeRoot();
2204 if (!orphanTree || mState.HaveSeenPtr(orphanTree.get())) {
2205 return 0;
2206 }
2207
2208 nsWindowSizes sizes(mState);
2209 mozilla::dom::Document::AddSizeOfNodeTree(*orphanTree, sizes);
2210
2211 // We combine the node size with nsStyleSizes here. It's not ideal, but it's
2212 // hard to get the style structs measurements out to nsWindowMemoryReporter.
2213 // Also, we drop mServoData in UnbindFromTree(), so in theory any
2214 // non-in-tree element won't have any style data to measure.
2215 //
2216 // FIXME(emilio): We should ideally not do this, since ShadowRoots keep
2217 // their StyleSheets alive even when detached from a document, and those
2218 // could be significant in theory.
2219 return sizes.getTotalSize();
2220 }
2221
2222 private:
2223 SizeOfState mState;
2224};
2225
2226#ifdef DEBUG1
2227static bool StartsWithExplicit(nsACString& s) {
2228 return StringBeginsWith(s, NS_LITERAL_CSTRING("explicit/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "explicit/"))
);
2229}
2230#endif
2231
2232class XPCJSRuntimeStats : public JS::RuntimeStats {
2233 WindowPaths* mWindowPaths;
2234 WindowPaths* mTopWindowPaths;
2235 int mAnonymizeID;
2236
2237 public:
2238 XPCJSRuntimeStats(WindowPaths* windowPaths, WindowPaths* topWindowPaths,
2239 bool anonymize)
2240 : JS::RuntimeStats(JSMallocSizeOf),
2241 mWindowPaths(windowPaths),
2242 mTopWindowPaths(topWindowPaths),
2243 mAnonymizeID(anonymize ? 1 : 0) {}
2244
2245 ~XPCJSRuntimeStats() {
2246 for (size_t i = 0; i != realmStatsVector.length(); ++i) {
2247 delete static_cast<xpc::RealmStatsExtras*>(realmStatsVector[i].extra);
2248 }
2249
2250 for (size_t i = 0; i != zoneStatsVector.length(); ++i) {
2251 delete static_cast<xpc::ZoneStatsExtras*>(zoneStatsVector[i].extra);
2252 }
2253 }
2254
2255 virtual void initExtraZoneStats(JS::Zone* zone,
2256 JS::ZoneStats* zStats) override {
2257 AutoSafeJSContext cx;
2258 xpc::ZoneStatsExtras* extras = new xpc::ZoneStatsExtras;
2259 extras->pathPrefix.AssignLiteral("explicit/js-non-window/zones/");
2260
2261 // Get some global in this zone.
2262 Rooted<Realm*> realm(cx, js::GetAnyRealmInZone(zone));
2263 if (realm) {
2264 RootedObject global(cx, JS::GetRealmGlobalOrNull(realm));
2265 if (global) {
2266 RefPtr<nsGlobalWindowInner> window;
2267 if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Window, global, window))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mozilla::dom::UnwrapNonWrapperObject
< mozilla::dom::prototypes::id::Window, mozilla::dom::Window_Binding
::NativeType>(global, window))), 1)))
) {
2268 // The global is a |window| object. Use the path prefix that
2269 // we should have already created for it.
2270 if (mTopWindowPaths->Get(window->WindowID(), &extras->pathPrefix))
2271 extras->pathPrefix.AppendLiteral("/js-");
2272 }
2273 }
2274 }
2275
2276 extras->pathPrefix += nsPrintfCString("zone(0x%p)/", (void*)zone);
2277
2278 MOZ_ASSERT(StartsWithExplicit(extras->pathPrefix))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StartsWithExplicit(extras->pathPrefix))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(StartsWithExplicit(extras->pathPrefix)))), 0))) { MOZ_ReportAssertionFailure
("StartsWithExplicit(extras->pathPrefix)", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2278); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StartsWithExplicit(extras->pathPrefix)"
")"); do { *((volatile int*)__null) = 2278; ::abort(); } while
(false); } } while (false)
;
2279
2280 zStats->extra = extras;
2281 }
2282
2283 virtual void initExtraRealmStats(Handle<Realm*> realm,
2284 JS::RealmStats* realmStats) override {
2285 xpc::RealmStatsExtras* extras = new xpc::RealmStatsExtras;
2286 nsCString rName;
2287 GetRealmName(realm, rName, &mAnonymizeID, /* replaceSlashes = */ true);
2288
2289 // Get the realm's global.
2290 AutoSafeJSContext cx;
2291 bool needZone = true;
2292 RootedObject global(cx, JS::GetRealmGlobalOrNull(realm));
2293 if (global) {
2294 RefPtr<nsGlobalWindowInner> window;
2295 if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Window, global, window))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mozilla::dom::UnwrapNonWrapperObject
< mozilla::dom::prototypes::id::Window, mozilla::dom::Window_Binding
::NativeType>(global, window))), 1)))
) {
2296 // The global is a |window| object. Use the path prefix that
2297 // we should have already created for it.
2298 if (mWindowPaths->Get(window->WindowID(), &extras->jsPathPrefix)) {
2299 extras->domPathPrefix.Assign(extras->jsPathPrefix);
2300 extras->domPathPrefix.AppendLiteral("/dom/");
2301 extras->jsPathPrefix.AppendLiteral("/js-");
2302 needZone = false;
2303 } else {
2304 extras->jsPathPrefix.AssignLiteral("explicit/js-non-window/zones/");
2305 extras->domPathPrefix.AssignLiteral(
2306 "explicit/dom/unknown-window-global?!/");
2307 }
2308 } else {
2309 extras->jsPathPrefix.AssignLiteral("explicit/js-non-window/zones/");
2310 extras->domPathPrefix.AssignLiteral(
2311 "explicit/dom/non-window-global?!/");
2312 }
2313 } else {
2314 extras->jsPathPrefix.AssignLiteral("explicit/js-non-window/zones/");
2315 extras->domPathPrefix.AssignLiteral("explicit/dom/no-global?!/");
2316 }
2317
2318 if (needZone) {
2319 extras->jsPathPrefix +=
2320 nsPrintfCString("zone(0x%p)/", (void*)js::GetRealmZone(realm));
2321 }
2322
2323 extras->jsPathPrefix +=
2324 NS_LITERAL_CSTRING("realm(")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "realm("))
+ rName + NS_LITERAL_CSTRING(")/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" ")/"))
;
2325
2326 // extras->jsPathPrefix is used for almost all the realm-specific
2327 // reports. At this point it has the form
2328 // "<something>realm(<rname>)/".
2329 //
2330 // extras->domPathPrefix is used for DOM orphan nodes, which are
2331 // counted by the JS reporter but reported as part of the DOM
2332 // measurements. At this point it has the form "<something>/dom/" if
2333 // this realm belongs to an nsGlobalWindow, and
2334 // "explicit/dom/<something>?!/" otherwise (in which case it shouldn't
2335 // be used, because non-nsGlobalWindow realms shouldn't have
2336 // orphan DOM nodes).
2337
2338 MOZ_ASSERT(StartsWithExplicit(extras->jsPathPrefix))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StartsWithExplicit(extras->jsPathPrefix))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(StartsWithExplicit(extras->jsPathPrefix)))), 0))) { MOZ_ReportAssertionFailure
("StartsWithExplicit(extras->jsPathPrefix)", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2338); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StartsWithExplicit(extras->jsPathPrefix)"
")"); do { *((volatile int*)__null) = 2338; ::abort(); } while
(false); } } while (false)
;
2339 MOZ_ASSERT(StartsWithExplicit(extras->domPathPrefix))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StartsWithExplicit(extras->domPathPrefix))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(StartsWithExplicit(extras->domPathPrefix)))), 0))) { MOZ_ReportAssertionFailure
("StartsWithExplicit(extras->domPathPrefix)", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2339); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StartsWithExplicit(extras->domPathPrefix)"
")"); do { *((volatile int*)__null) = 2339; ::abort(); } while
(false); } } while (false)
;
2340
2341 realmStats->extra = extras;
2342 }
2343};
2344
2345void JSReporter::CollectReports(WindowPaths* windowPaths,
2346 WindowPaths* topWindowPaths,
2347 nsIHandleReportCallback* handleReport,
2348 nsISupports* data, bool anonymize) {
2349 XPCJSRuntime* xpcrt = nsXPConnect::GetRuntimeInstance();
2350
2351 // In the first step we get all the stats and stash them in a local
2352 // data structure. In the second step we pass all the stashed stats to
2353 // the callback. Separating these steps is important because the
2354 // callback may be a JS function, and executing JS while getting these
2355 // stats seems like a bad idea.
2356
2357 XPCJSRuntimeStats rtStats(windowPaths, topWindowPaths, anonymize);
2358 OrphanReporter orphanReporter(XPCConvert::GetISupportsFromJSObject);
2359 JSContext* cx = XPCJSContext::Get()->Context();
2360 if (!JS::CollectRuntimeStats(cx, &rtStats, &orphanReporter, anonymize)) {
2361 return;
2362 }
2363
2364 // Collect JS stats not associated with a Runtime such as helper threads or
2365 // global tracelogger data. We do this here in JSReporter::CollectReports
2366 // as this is used for the main Runtime in process.
2367 JS::GlobalStats gStats(JSMallocSizeOf);
2368 if (!JS::CollectGlobalStats(&gStats)) {
2369 return;
2370 }
2371
2372 size_t xpcJSRuntimeSize = xpcrt->SizeOfIncludingThis(JSMallocSizeOf);
2373
2374 size_t wrappedJSSize =
2375 xpcrt->GetMultiCompartmentWrappedJSMap()->SizeOfWrappedJS(JSMallocSizeOf);
2376
2377 XPCWrappedNativeScope::ScopeSizeInfo sizeInfo(JSMallocSizeOf);
2378 XPCWrappedNativeScope::AddSizeOfAllScopesIncludingThis(cx, &sizeInfo);
2379
2380 mozJSComponentLoader* loader = mozJSComponentLoader::Get();
2381 size_t jsComponentLoaderSize =
2382 loader ? loader->SizeOfIncludingThis(JSMallocSizeOf) : 0;
2383
2384 // This is the second step (see above). First we report stuff in the
2385 // "explicit" tree, then we report other stuff.
2386
2387 size_t rtTotal = 0;
2388 xpc::ReportJSRuntimeExplicitTreeStats(
2389 rtStats, NS_LITERAL_CSTRING("explicit/js-non-window/")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "explicit/js-non-window/"))
, handleReport,
2390 data, anonymize, &rtTotal);
2391
2392 // Report the sums of the realm numbers.
2393 xpc::RealmStatsExtras realmExtrasTotal;
2394 realmExtrasTotal.jsPathPrefix.AssignLiteral("js-main-runtime/realms/");
2395 realmExtrasTotal.domPathPrefix.AssignLiteral("window-objects/dom/");
2396 ReportRealmStats(rtStats.realmTotals, realmExtrasTotal, handleReport, data);
2397
2398 xpc::ZoneStatsExtras zExtrasTotal;
2399 zExtrasTotal.pathPrefix.AssignLiteral("js-main-runtime/zones/");
2400 ReportZoneStats(rtStats.zTotals, zExtrasTotal, handleReport, data, anonymize);
2401
2402 // Report the sum of the runtime/ numbers.
2403 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/runtime"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtTotal, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The sum of all measurements under 'explicit/js-non-window/runtime/'."
)), data);;
2404 NS_LITERAL_CSTRING("js-main-runtime/runtime"), KIND_OTHER, rtTotal,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/runtime"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtTotal, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The sum of all measurements under 'explicit/js-non-window/runtime/'."
)), data);;
2405 "The sum of all measurements under 'explicit/js-non-window/runtime/'.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/runtime"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtTotal, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "The sum of all measurements under 'explicit/js-non-window/runtime/'."
)), data);;
;
2406
2407 // Report the number of HelperThread
2408
2409 REPORT(NS_LITERAL_CSTRING("js-helper-threads/idle"), KIND_OTHER, UNITS_COUNT,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-helper-threads/idle"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, gStats.helperThread.idleThreadCount, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The current number of idle JS HelperThreads."
)), data);
2410 gStats.helperThread.idleThreadCount,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-helper-threads/idle"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, gStats.helperThread.idleThreadCount, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The current number of idle JS HelperThreads."
)), data);
2411 "The current number of idle JS HelperThreads.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-helper-threads/idle"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, gStats.helperThread.idleThreadCount, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The current number of idle JS HelperThreads."
)), data);
;
2412
2413 REPORT(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-helper-threads/active"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, gStats.helperThread.activeThreadCount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "The current number of active JS HelperThreads. Memory held by these is"
" not reported.")), data);
2414 NS_LITERAL_CSTRING("js-helper-threads/active"), KIND_OTHER, UNITS_COUNT,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-helper-threads/active"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, gStats.helperThread.activeThreadCount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "The current number of active JS HelperThreads. Memory held by these is"
" not reported.")), data);
2415 gStats.helperThread.activeThreadCount,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-helper-threads/active"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, gStats.helperThread.activeThreadCount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "The current number of active JS HelperThreads. Memory held by these is"
" not reported.")), data);
2416 "The current number of active JS HelperThreads. Memory held by these is"handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-helper-threads/active"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, gStats.helperThread.activeThreadCount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "The current number of active JS HelperThreads. Memory held by these is"
" not reported.")), data);
2417 " not reported.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-helper-threads/active"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_COUNT
, gStats.helperThread.activeThreadCount, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "The current number of active JS HelperThreads. Memory held by these is"
" not reported.")), data);
;
2418
2419 // Report the numbers for memory used by wasm Runtime state.
2420 REPORT_BYTES(NS_LITERAL_CSTRING("wasm-runtime"), KIND_OTHER,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-runtime"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.runtime.wasmRuntime, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used for wasm runtime bookkeeping."
)), data);;
2421 rtStats.runtime.wasmRuntime,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-runtime"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.runtime.wasmRuntime, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used for wasm runtime bookkeeping."
)), data);;
2422 "The memory used for wasm runtime bookkeeping.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "wasm-runtime"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.runtime.wasmRuntime, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used for wasm runtime bookkeeping."
)), data);;
;
2423
2424 // Report the numbers for memory outside of realms.
2425
2426 REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/unused-chunks"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/unused-chunks"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedChunks, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."
)), data);;
2427 KIND_OTHER, rtStats.gcHeapUnusedChunks,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/unused-chunks"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedChunks, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."
)), data);;
2428 "The same as 'explicit/js-non-window/gc-heap/unused-chunks'.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/unused-chunks"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedChunks, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."
)), data);;
;
2429
2430 REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/unused-arenas"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/unused-arenas"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedArenas, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."
)), data);;
2431 KIND_OTHER, rtStats.gcHeapUnusedArenas,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/unused-arenas"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedArenas, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."
)), data);;
2432 "The same as 'explicit/js-non-window/gc-heap/unused-arenas'.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/unused-arenas"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedArenas, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."
)), data);;
;
2433
2434 REPORT_BYTES(NS_LITERAL_CSTRING("js-main-runtime/gc-heap/chunk-admin"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/chunk-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapChunkAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."
)), data);;
2435 KIND_OTHER, rtStats.gcHeapChunkAdmin,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/chunk-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapChunkAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."
)), data);;
2436 "The same as 'explicit/js-non-window/gc-heap/chunk-admin'.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime/gc-heap/chunk-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapChunkAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."
)), data);;
;
2437
2438 // Report a breakdown of the committed GC space.
2439
2440 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/chunks"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedChunks, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."
)), data);;
2441 NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/chunks"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/chunks"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedChunks, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."
)), data);;
2442 KIND_OTHER, rtStats.gcHeapUnusedChunks,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/chunks"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedChunks, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."
)), data);;
2443 "The same as 'explicit/js-non-window/gc-heap/unused-chunks'.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/chunks"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedChunks, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-chunks'."
)), data);;
;
2444
2445 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/arenas"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedArenas, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."
)), data);;
2446 NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/unused/arenas"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/arenas"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedArenas, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."
)), data);;
2447 KIND_OTHER, rtStats.gcHeapUnusedArenas,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/arenas"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedArenas, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."
)), data);;
2448 "The same as 'explicit/js-non-window/gc-heap/unused-arenas'.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/arenas"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapUnusedArenas, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/unused-arenas'."
)), data);;
;
2449
2450 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.object, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused object cells within non-empty arenas."
)), data);;
2451 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.object, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused object cells within non-empty arenas."
)), data);;
2452 "js-main-runtime-gc-heap-committed/unused/gc-things/objects"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.object, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused object cells within non-empty arenas."
)), data);;
2453 KIND_OTHER, rtStats.zTotals.unusedGCThings.object,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.object, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused object cells within non-empty arenas."
)), data);;
2454 "Unused object cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.object, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused object cells within non-empty arenas."
)), data);;
;
2455
2456 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.string, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused string cells within non-empty arenas."
)), data);;
2457 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.string, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused string cells within non-empty arenas."
)), data);;
2458 "js-main-runtime-gc-heap-committed/unused/gc-things/strings"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.string, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused string cells within non-empty arenas."
)), data);;
2459 KIND_OTHER, rtStats.zTotals.unusedGCThings.string,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.string, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused string cells within non-empty arenas."
)), data);;
2460 "Unused string cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.string, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused string cells within non-empty arenas."
)), data);;
;
2461
2462 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.symbol, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused symbol cells within non-empty arenas."
)), data);;
2463 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.symbol, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused symbol cells within non-empty arenas."
)), data);;
2464 "js-main-runtime-gc-heap-committed/unused/gc-things/symbols"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.symbol, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused symbol cells within non-empty arenas."
)), data);;
2465 KIND_OTHER, rtStats.zTotals.unusedGCThings.symbol,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.symbol, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused symbol cells within non-empty arenas."
)), data);;
2466 "Unused symbol cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.symbol, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused symbol cells within non-empty arenas."
)), data);;
;
2467
2468 REPORT_BYTES(NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.shape, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Unused shape cells within non-empty arenas."
)), data);;
2469 "js-main-runtime-gc-heap-committed/unused/gc-things/shapes"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.shape, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Unused shape cells within non-empty arenas."
)), data);;
2470 KIND_OTHER, rtStats.zTotals.unusedGCThings.shape,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.shape, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Unused shape cells within non-empty arenas."
)), data);;
2471 "Unused shape cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.shape, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Unused shape cells within non-empty arenas."
)), data);;
;
2472
2473 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.baseShape, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused base shape cells within non-empty arenas."
)), data);;
2474 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.baseShape, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused base shape cells within non-empty arenas."
)), data);;
2475 "js-main-runtime-gc-heap-committed/unused/gc-things/base-shapes"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.baseShape, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused base shape cells within non-empty arenas."
)), data);;
2476 KIND_OTHER, rtStats.zTotals.unusedGCThings.baseShape,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.baseShape, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused base shape cells within non-empty arenas."
)), data);;
2477 "Unused base shape cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.baseShape, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused base shape cells within non-empty arenas."
)), data);;
;
2478
2479 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.objectGroup, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused object group cells within non-empty arenas."
)), data);;
2480 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.objectGroup, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused object group cells within non-empty arenas."
)), data);;
2481 "js-main-runtime-gc-heap-committed/unused/gc-things/object-groups"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.objectGroup, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused object group cells within non-empty arenas."
)), data);;
2482 KIND_OTHER, rtStats.zTotals.unusedGCThings.objectGroup,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.objectGroup, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused object group cells within non-empty arenas."
)), data);;
2483 "Unused object group cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.objectGroup, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused object group cells within non-empty arenas."
)), data);;
;
2484
2485 REPORT_BYTES(NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scopes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.scope, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Unused scope cells within non-empty arenas."
)), data);;
2486 "js-main-runtime-gc-heap-committed/unused/gc-things/scopes"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scopes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.scope, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Unused scope cells within non-empty arenas."
)), data);;
2487 KIND_OTHER, rtStats.zTotals.unusedGCThings.scope,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scopes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.scope, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Unused scope cells within non-empty arenas."
)), data);;
2488 "Unused scope cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scopes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.scope, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Unused scope cells within non-empty arenas."
)), data);;
;
2489
2490 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.script, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused script cells within non-empty arenas."
)), data);;
2491 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.script, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused script cells within non-empty arenas."
)), data);;
2492 "js-main-runtime-gc-heap-committed/unused/gc-things/scripts"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.script, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused script cells within non-empty arenas."
)), data);;
2493 KIND_OTHER, rtStats.zTotals.unusedGCThings.script,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.script, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused script cells within non-empty arenas."
)), data);;
2494 "Unused script cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.script, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused script cells within non-empty arenas."
)), data);;
;
2495
2496 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.lazyScript, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused lazy script cells within non-empty arenas."
)), data);;
2497 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.lazyScript, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused lazy script cells within non-empty arenas."
)), data);;
2498 "js-main-runtime-gc-heap-committed/unused/gc-things/lazy-scripts"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.lazyScript, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused lazy script cells within non-empty arenas."
)), data);;
2499 KIND_OTHER, rtStats.zTotals.unusedGCThings.lazyScript,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.lazyScript, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused lazy script cells within non-empty arenas."
)), data);;
2500 "Unused lazy script cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.lazyScript, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused lazy script cells within non-empty arenas."
)), data);;
;
2501
2502 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.jitcode, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused jitcode cells within non-empty arenas."
)), data);;
2503 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.jitcode, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused jitcode cells within non-empty arenas."
)), data);;
2504 "js-main-runtime-gc-heap-committed/unused/gc-things/jitcode"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.jitcode, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused jitcode cells within non-empty arenas."
)), data);;
2505 KIND_OTHER, rtStats.zTotals.unusedGCThings.jitcode,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.jitcode, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused jitcode cells within non-empty arenas."
)), data);;
2506 "Unused jitcode cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.jitcode, static_cast<const
nsLiteralCString&>(nsLiteralCString("" "Unused jitcode cells within non-empty arenas."
)), data);;
;
2507
2508 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.regExpShared, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused regexpshared cells within non-empty arenas."
)), data);;
2509 NS_LITERAL_CSTRING(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.regExpShared, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused regexpshared cells within non-empty arenas."
)), data);;
2510 "js-main-runtime-gc-heap-committed/unused/gc-things/regexp-shareds"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.regExpShared, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused regexpshared cells within non-empty arenas."
)), data);;
2511 KIND_OTHER, rtStats.zTotals.unusedGCThings.regExpShared,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.regExpShared, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused regexpshared cells within non-empty arenas."
)), data);;
2512 "Unused regexpshared cells within non-empty arenas.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/unused/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.unusedGCThings.regExpShared, static_cast<
const nsLiteralCString&>(nsLiteralCString("" "Unused regexpshared cells within non-empty arenas."
)), data);;
;
2513
2514 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/chunk-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapChunkAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."
)), data);;
2515 NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/chunk-admin"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/chunk-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapChunkAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."
)), data);;
2516 KIND_OTHER, rtStats.gcHeapChunkAdmin,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/chunk-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapChunkAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."
)), data);;
2517 "The same as 'explicit/js-non-window/gc-heap/chunk-admin'.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/chunk-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.gcHeapChunkAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'explicit/js-non-window/gc-heap/chunk-admin'."
)), data);;
;
2518
2519 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/arena-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.gcHeapArenaAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'js-main-runtime/zones/gc-heap-arena-admin'."
)), data);;
2520 NS_LITERAL_CSTRING("js-main-runtime-gc-heap-committed/used/arena-admin"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/arena-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.gcHeapArenaAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'js-main-runtime/zones/gc-heap-arena-admin'."
)), data);;
2521 KIND_OTHER, rtStats.zTotals.gcHeapArenaAdmin,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/arena-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.gcHeapArenaAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'js-main-runtime/zones/gc-heap-arena-admin'."
)), data);;
2522 "The same as 'js-main-runtime/zones/gc-heap-arena-admin'.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/arena-admin"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, rtStats.zTotals.gcHeapArenaAdmin, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The same as 'js-main-runtime/zones/gc-heap-arena-admin'."
)), data);;
;
2523
2524 size_t gcThingTotal = 0;
2525
2526 MREPORT_BYTES(NS_LITERAL_CSTRING(do { size_t amount = rtStats.realmTotals.classInfo.objectsGCHeap
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object cells.")), data); gcThingTotal += amount; } while
(0)
2527 "js-main-runtime-gc-heap-committed/used/gc-things/objects"),do { size_t amount = rtStats.realmTotals.classInfo.objectsGCHeap
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object cells.")), data); gcThingTotal += amount; } while
(0)
2528 KIND_OTHER, rtStats.realmTotals.classInfo.objectsGCHeap,do { size_t amount = rtStats.realmTotals.classInfo.objectsGCHeap
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object cells.")), data); gcThingTotal += amount; } while
(0)
2529 "Used object cells.")do { size_t amount = rtStats.realmTotals.classInfo.objectsGCHeap
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/objects"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object cells.")), data); gcThingTotal += amount; } while
(0)
;
2530
2531 MREPORT_BYTES(NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.stringInfo.sizeOfLiveGCThings
(); handleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used string cells.")), data); gcThingTotal += amount; } while
(0)
2532 "js-main-runtime-gc-heap-committed/used/gc-things/strings"),do { size_t amount = rtStats.zTotals.stringInfo.sizeOfLiveGCThings
(); handleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used string cells.")), data); gcThingTotal += amount; } while
(0)
2533 KIND_OTHER, rtStats.zTotals.stringInfo.sizeOfLiveGCThings(),do { size_t amount = rtStats.zTotals.stringInfo.sizeOfLiveGCThings
(); handleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used string cells.")), data); gcThingTotal += amount; } while
(0)
2534 "Used string cells.")do { size_t amount = rtStats.zTotals.stringInfo.sizeOfLiveGCThings
(); handleReport->Callback(EmptyCString(), static_cast<
const nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/strings"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used string cells.")), data); gcThingTotal += amount; } while
(0)
;
2535
2536 MREPORT_BYTES(NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.symbolsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used symbol cells.")), data); gcThingTotal += amount; } while
(0)
2537 "js-main-runtime-gc-heap-committed/used/gc-things/symbols"),do { size_t amount = rtStats.zTotals.symbolsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used symbol cells.")), data); gcThingTotal += amount; } while
(0)
2538 KIND_OTHER, rtStats.zTotals.symbolsGCHeap,do { size_t amount = rtStats.zTotals.symbolsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used symbol cells.")), data); gcThingTotal += amount; } while
(0)
2539 "Used symbol cells.")do { size_t amount = rtStats.zTotals.symbolsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/symbols"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used symbol cells.")), data); gcThingTotal += amount; } while
(0)
;
2540
2541 MREPORT_BYTES(NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapTree
+ rtStats.zTotals.shapeInfo.shapesGCHeapDict; handleReport->
Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used shape cells.")), data); gcThingTotal += amount; } while
(0)
2542 "js-main-runtime-gc-heap-committed/used/gc-things/shapes"),do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapTree
+ rtStats.zTotals.shapeInfo.shapesGCHeapDict; handleReport->
Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used shape cells.")), data); gcThingTotal += amount; } while
(0)
2543 KIND_OTHER,do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapTree
+ rtStats.zTotals.shapeInfo.shapesGCHeapDict; handleReport->
Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used shape cells.")), data); gcThingTotal += amount; } while
(0)
2544 rtStats.zTotals.shapeInfo.shapesGCHeapTree +do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapTree
+ rtStats.zTotals.shapeInfo.shapesGCHeapDict; handleReport->
Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used shape cells.")), data); gcThingTotal += amount; } while
(0)
2545 rtStats.zTotals.shapeInfo.shapesGCHeapDict,do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapTree
+ rtStats.zTotals.shapeInfo.shapesGCHeapDict; handleReport->
Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used shape cells.")), data); gcThingTotal += amount; } while
(0)
2546 "Used shape cells.")do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapTree
+ rtStats.zTotals.shapeInfo.shapesGCHeapDict; handleReport->
Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used shape cells.")), data); gcThingTotal += amount; } while
(0)
;
2547
2548 MREPORT_BYTES(do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapBase
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used base shape cells.")), data); gcThingTotal += amount
; } while (0)
2549 NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapBase
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used base shape cells.")), data); gcThingTotal += amount
; } while (0)
2550 "js-main-runtime-gc-heap-committed/used/gc-things/base-shapes"),do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapBase
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used base shape cells.")), data); gcThingTotal += amount
; } while (0)
2551 KIND_OTHER, rtStats.zTotals.shapeInfo.shapesGCHeapBase,do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapBase
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used base shape cells.")), data); gcThingTotal += amount
; } while (0)
2552 "Used base shape cells.")do { size_t amount = rtStats.zTotals.shapeInfo.shapesGCHeapBase
; handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/base-shapes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used base shape cells.")), data); gcThingTotal += amount
; } while (0)
;
2553
2554 MREPORT_BYTES(do { size_t amount = rtStats.zTotals.objectGroupsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object group cells.")), data); gcThingTotal += amount
; } while (0)
2555 NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.objectGroupsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object group cells.")), data); gcThingTotal += amount
; } while (0)
2556 "js-main-runtime-gc-heap-committed/used/gc-things/object-groups"),do { size_t amount = rtStats.zTotals.objectGroupsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object group cells.")), data); gcThingTotal += amount
; } while (0)
2557 KIND_OTHER, rtStats.zTotals.objectGroupsGCHeap,do { size_t amount = rtStats.zTotals.objectGroupsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object group cells.")), data); gcThingTotal += amount
; } while (0)
2558 "Used object group cells.")do { size_t amount = rtStats.zTotals.objectGroupsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/object-groups"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used object group cells.")), data); gcThingTotal += amount
; } while (0)
;
2559
2560 MREPORT_BYTES(NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.scopesGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/scopes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used scope cells.")), data); gcThingTotal += amount; } while
(0)
2561 "js-main-runtime-gc-heap-committed/used/gc-things/scopes"),do { size_t amount = rtStats.zTotals.scopesGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/scopes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used scope cells.")), data); gcThingTotal += amount; } while
(0)
2562 KIND_OTHER, rtStats.zTotals.scopesGCHeap, "Used scope cells.")do { size_t amount = rtStats.zTotals.scopesGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/scopes"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used scope cells.")), data); gcThingTotal += amount; } while
(0)
;
2563
2564 MREPORT_BYTES(NS_LITERAL_CSTRING(do { size_t amount = rtStats.realmTotals.scriptsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used script cells.")), data); gcThingTotal += amount; } while
(0)
2565 "js-main-runtime-gc-heap-committed/used/gc-things/scripts"),do { size_t amount = rtStats.realmTotals.scriptsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used script cells.")), data); gcThingTotal += amount; } while
(0)
2566 KIND_OTHER, rtStats.realmTotals.scriptsGCHeap,do { size_t amount = rtStats.realmTotals.scriptsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used script cells.")), data); gcThingTotal += amount; } while
(0)
2567 "Used script cells.")do { size_t amount = rtStats.realmTotals.scriptsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used script cells.")), data); gcThingTotal += amount; } while
(0)
;
2568
2569 MREPORT_BYTES(do { size_t amount = rtStats.zTotals.lazyScriptsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used lazy script cells.")), data); gcThingTotal += amount
; } while (0)
2570 NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.lazyScriptsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used lazy script cells.")), data); gcThingTotal += amount
; } while (0)
2571 "js-main-runtime-gc-heap-committed/used/gc-things/lazy-scripts"),do { size_t amount = rtStats.zTotals.lazyScriptsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used lazy script cells.")), data); gcThingTotal += amount
; } while (0)
2572 KIND_OTHER, rtStats.zTotals.lazyScriptsGCHeap, "Used lazy script cells.")do { size_t amount = rtStats.zTotals.lazyScriptsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/lazy-scripts"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used lazy script cells.")), data); gcThingTotal += amount
; } while (0)
;
2573
2574 MREPORT_BYTES(NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.jitCodesGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used jitcode cells.")), data); gcThingTotal += amount; }
while (0)
2575 "js-main-runtime-gc-heap-committed/used/gc-things/jitcode"),do { size_t amount = rtStats.zTotals.jitCodesGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used jitcode cells.")), data); gcThingTotal += amount; }
while (0)
2576 KIND_OTHER, rtStats.zTotals.jitCodesGCHeap,do { size_t amount = rtStats.zTotals.jitCodesGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used jitcode cells.")), data); gcThingTotal += amount; }
while (0)
2577 "Used jitcode cells.")do { size_t amount = rtStats.zTotals.jitCodesGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/jitcode"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used jitcode cells.")), data); gcThingTotal += amount; }
while (0)
;
2578
2579 MREPORT_BYTES(do { size_t amount = rtStats.zTotals.regExpSharedsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used regexpshared cells.")), data); gcThingTotal += amount
; } while (0)
2580 NS_LITERAL_CSTRING(do { size_t amount = rtStats.zTotals.regExpSharedsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used regexpshared cells.")), data); gcThingTotal += amount
; } while (0)
2581 "js-main-runtime-gc-heap-committed/used/gc-things/regexp-shareds"),do { size_t amount = rtStats.zTotals.regExpSharedsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used regexpshared cells.")), data); gcThingTotal += amount
; } while (0)
2582 KIND_OTHER, rtStats.zTotals.regExpSharedsGCHeap,do { size_t amount = rtStats.zTotals.regExpSharedsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used regexpshared cells.")), data); gcThingTotal += amount
; } while (0)
2583 "Used regexpshared cells.")do { size_t amount = rtStats.zTotals.regExpSharedsGCHeap; handleReport
->Callback(EmptyCString(), static_cast<const nsLiteralCString
&>(nsLiteralCString("" "js-main-runtime-gc-heap-committed/used/gc-things/regexp-shareds"
)), nsIMemoryReporter::KIND_OTHER, nsIMemoryReporter::UNITS_BYTES
, amount, static_cast<const nsLiteralCString&>(nsLiteralCString
("" "Used regexpshared cells.")), data); gcThingTotal += amount
; } while (0)
;
2584
2585 MOZ_ASSERT(gcThingTotal == rtStats.gcHeapGCThings)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gcThingTotal == rtStats.gcHeapGCThings)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(gcThingTotal == rtStats.gcHeapGCThings))), 0))) { MOZ_ReportAssertionFailure
("gcThingTotal == rtStats.gcHeapGCThings", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2585); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gcThingTotal == rtStats.gcHeapGCThings"
")"); do { *((volatile int*)__null) = 2585; ::abort(); } while
(false); } } while (false)
;
2586
2587 // Report xpconnect.
2588
2589 REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect/runtime"), KIND_HEAP,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/runtime"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, xpcJSRuntimeSize, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The XPConnect runtime.")), data);;
2590 xpcJSRuntimeSize, "The XPConnect runtime.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/runtime"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, xpcJSRuntimeSize, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The XPConnect runtime.")), data);;
;
2591
2592 REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect/wrappedjs"), KIND_HEAP,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/wrappedjs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, wrappedJSSize, static_cast<const nsLiteralCString&>
(nsLiteralCString("" "Wrappers used to implement XPIDL interfaces with JS."
)), data);;
2593 wrappedJSSize,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/wrappedjs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, wrappedJSSize, static_cast<const nsLiteralCString&>
(nsLiteralCString("" "Wrappers used to implement XPIDL interfaces with JS."
)), data);;
2594 "Wrappers used to implement XPIDL interfaces with JS.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/wrappedjs"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, wrappedJSSize, static_cast<const nsLiteralCString&>
(nsLiteralCString("" "Wrappers used to implement XPIDL interfaces with JS."
)), data);;
;
2595
2596 REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect/scopes"), KIND_HEAP,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/scopes"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sizeInfo.mScopeAndMapSize, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "XPConnect scopes.")), data);;
2597 sizeInfo.mScopeAndMapSize, "XPConnect scopes.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/scopes"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sizeInfo.mScopeAndMapSize, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "XPConnect scopes.")), data);;
;
2598
2599 REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect/proto-iface-cache"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/proto-iface-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sizeInfo.mProtoAndIfaceCacheSize, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Prototype and interface binding caches."
)), data);;
2600 KIND_HEAP, sizeInfo.mProtoAndIfaceCacheSize,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/proto-iface-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sizeInfo.mProtoAndIfaceCacheSize, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Prototype and interface binding caches."
)), data);;
2601 "Prototype and interface binding caches.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/proto-iface-cache"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, sizeInfo.mProtoAndIfaceCacheSize, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Prototype and interface binding caches."
)), data);;
;
2602
2603 REPORT_BYTES(NS_LITERAL_CSTRING("explicit/xpconnect/js-component-loader"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/js-component-loader"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, jsComponentLoaderSize, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "XPConnect's JS component loader."
)), data);;
2604 KIND_HEAP, jsComponentLoaderSize,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/js-component-loader"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, jsComponentLoaderSize, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "XPConnect's JS component loader."
)), data);;
2605 "XPConnect's JS component loader.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/xpconnect/js-component-loader"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, jsComponentLoaderSize, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "XPConnect's JS component loader."
)), data);;
;
2606
2607 // Report tracelogger (global).
2608
2609 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/tracelogger"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.tracelogger, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The memory used for the tracelogger, including the graph and events."
)), data);;
2610 NS_LITERAL_CSTRING("explicit/js-non-window/tracelogger"), KIND_HEAP,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/tracelogger"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.tracelogger, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The memory used for the tracelogger, including the graph and events."
)), data);;
2611 gStats.tracelogger,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/tracelogger"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.tracelogger, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The memory used for the tracelogger, including the graph and events."
)), data);;
2612 "The memory used for the tracelogger, including the graph and events.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/tracelogger"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.tracelogger, static_cast<const nsLiteralCString&
>(nsLiteralCString("" "The memory used for the tracelogger, including the graph and events."
)), data);;
;
2613
2614 // Report HelperThreadState.
2615
2616 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/heap-other"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.stateData, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Memory used by HelperThreadState."
)), data);;
2617 NS_LITERAL_CSTRING("explicit/js-non-window/helper-thread/heap-other"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/heap-other"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.stateData, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Memory used by HelperThreadState."
)), data);;
2618 KIND_HEAP, gStats.helperThread.stateData,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/heap-other"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.stateData, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Memory used by HelperThreadState."
)), data);;
2619 "Memory used by HelperThreadState.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/heap-other"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.stateData, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "Memory used by HelperThreadState."
)), data);;
;
2620
2621 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/parse-task"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.parseTask, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by ParseTasks waiting in HelperThreadState."
)), data);;
2622 NS_LITERAL_CSTRING("explicit/js-non-window/helper-thread/parse-task"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/parse-task"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.parseTask, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by ParseTasks waiting in HelperThreadState."
)), data);;
2623 KIND_HEAP, gStats.helperThread.parseTask,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/parse-task"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.parseTask, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by ParseTasks waiting in HelperThreadState."
)), data);;
2624 "The memory used by ParseTasks waiting in HelperThreadState.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/parse-task"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.parseTask, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by ParseTasks waiting in HelperThreadState."
)), data);;
;
2625
2626 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/ion-builder"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.ionBuilder, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by IonBuilders waiting in HelperThreadState."
)), data);;
2627 NS_LITERAL_CSTRING("explicit/js-non-window/helper-thread/ion-builder"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/ion-builder"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.ionBuilder, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by IonBuilders waiting in HelperThreadState."
)), data);;
2628 KIND_HEAP, gStats.helperThread.ionBuilder,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/ion-builder"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.ionBuilder, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by IonBuilders waiting in HelperThreadState."
)), data);;
2629 "The memory used by IonBuilders waiting in HelperThreadState.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/ion-builder"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.ionBuilder, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by IonBuilders waiting in HelperThreadState."
)), data);;
;
2630
2631 REPORT_BYTES(handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/wasm-compile"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.parseTask, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by Wasm compilations waiting in HelperThreadState."
)), data);;
2632 NS_LITERAL_CSTRING("explicit/js-non-window/helper-thread/wasm-compile"),handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/wasm-compile"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.parseTask, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by Wasm compilations waiting in HelperThreadState."
)), data);;
2633 KIND_HEAP, gStats.helperThread.parseTask,handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/wasm-compile"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.parseTask, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by Wasm compilations waiting in HelperThreadState."
)), data);;
2634 "The memory used by Wasm compilations waiting in HelperThreadState.")handleReport->Callback(EmptyCString(), static_cast<const
nsLiteralCString&>(nsLiteralCString("" "explicit/js-non-window/helper-thread/wasm-compile"
)), nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES
, gStats.helperThread.parseTask, static_cast<const nsLiteralCString
&>(nsLiteralCString("" "The memory used by Wasm compilations waiting in HelperThreadState."
)), data);;
;
2635}
2636
2637static nsresult JSSizeOfTab(JSObject* objArg, size_t* jsObjectsSize,
2638 size_t* jsStringsSize, size_t* jsPrivateSize,
2639 size_t* jsOtherSize) {
2640 JSContext* cx = XPCJSContext::Get()->Context();
2641 JS::RootedObject obj(cx, objArg);
2642
2643 TabSizes sizes;
2644 OrphanReporter orphanReporter(XPCConvert::GetISupportsFromJSObject);
2645 NS_ENSURE_TRUE(do { if ((__builtin_expect(!!(!(JS::AddSizeOfTab(cx, obj, moz_malloc_size_of
, &orphanReporter, &sizes))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "JS::AddSizeOfTab(cx, obj, moz_malloc_size_of, &orphanReporter, &sizes)"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2647); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
2646 JS::AddSizeOfTab(cx, obj, moz_malloc_size_of, &orphanReporter, &sizes),do { if ((__builtin_expect(!!(!(JS::AddSizeOfTab(cx, obj, moz_malloc_size_of
, &orphanReporter, &sizes))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "JS::AddSizeOfTab(cx, obj, moz_malloc_size_of, &orphanReporter, &sizes)"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2647); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
2647 NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(JS::AddSizeOfTab(cx, obj, moz_malloc_size_of
, &orphanReporter, &sizes))), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "JS::AddSizeOfTab(cx, obj, moz_malloc_size_of, &orphanReporter, &sizes)"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2647); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
2648
2649 *jsObjectsSize = sizes.objects_;
2650 *jsStringsSize = sizes.strings_;
2651 *jsPrivateSize = sizes.private_;
2652 *jsOtherSize = sizes.other_;
2653 return NS_OK;
2654}
2655
2656} // namespace xpc
2657
2658static void AccumulateTelemetryCallback(int id, uint32_t sample,
2659 const char* key) {
2660 switch (id) {
2661 case JS_TELEMETRY_GC_REASON:
2662 Telemetry::Accumulate(Telemetry::GC_REASON_2, sample);
2663 break;
2664 case JS_TELEMETRY_GC_IS_ZONE_GC:
2665 Telemetry::Accumulate(Telemetry::GC_IS_COMPARTMENTAL, sample);
2666 break;
2667 case JS_TELEMETRY_GC_MS:
2668 Telemetry::Accumulate(Telemetry::GC_MS, sample);
2669 break;
2670 case JS_TELEMETRY_GC_BUDGET_MS:
2671 Telemetry::Accumulate(Telemetry::GC_BUDGET_MS, sample);
2672 break;
2673 case JS_TELEMETRY_GC_BUDGET_OVERRUN:
2674 Telemetry::Accumulate(Telemetry::GC_BUDGET_OVERRUN, sample);
2675 break;
2676 case JS_TELEMETRY_GC_ANIMATION_MS:
2677 Telemetry::Accumulate(Telemetry::GC_ANIMATION_MS, sample);
2678 break;
2679 case JS_TELEMETRY_GC_MAX_PAUSE_MS_2:
2680 Telemetry::Accumulate(Telemetry::GC_MAX_PAUSE_MS_2, sample);
2681 break;
2682 case JS_TELEMETRY_GC_MARK_MS:
2683 Telemetry::Accumulate(Telemetry::GC_MARK_MS, sample);
2684 break;
2685 case JS_TELEMETRY_GC_SWEEP_MS:
2686 Telemetry::Accumulate(Telemetry::GC_SWEEP_MS, sample);
2687 break;
2688 case JS_TELEMETRY_GC_COMPACT_MS:
2689 Telemetry::Accumulate(Telemetry::GC_COMPACT_MS, sample);
2690 break;
2691 case JS_TELEMETRY_GC_MARK_ROOTS_MS:
2692 Telemetry::Accumulate(Telemetry::GC_MARK_ROOTS_MS, sample);
2693 break;
2694 case JS_TELEMETRY_GC_MARK_GRAY_MS:
2695 Telemetry::Accumulate(Telemetry::GC_MARK_GRAY_MS, sample);
2696 break;
2697 case JS_TELEMETRY_GC_SLICE_MS:
2698 Telemetry::Accumulate(Telemetry::GC_SLICE_MS, sample);
2699 break;
2700 case JS_TELEMETRY_GC_SLOW_PHASE:
2701 Telemetry::Accumulate(Telemetry::GC_SLOW_PHASE, sample);
2702 break;
2703 case JS_TELEMETRY_GC_SLOW_TASK:
2704 Telemetry::Accumulate(Telemetry::GC_SLOW_TASK, sample);
2705 break;
2706 case JS_TELEMETRY_GC_MMU_50:
2707 Telemetry::Accumulate(Telemetry::GC_MMU_50, sample);
2708 break;
2709 case JS_TELEMETRY_GC_RESET:
2710 Telemetry::Accumulate(Telemetry::GC_RESET, sample);
2711 break;
2712 case JS_TELEMETRY_GC_RESET_REASON:
2713 Telemetry::Accumulate(Telemetry::GC_RESET_REASON, sample);
2714 break;
2715 case JS_TELEMETRY_GC_INCREMENTAL_DISABLED:
2716 Telemetry::Accumulate(Telemetry::GC_INCREMENTAL_DISABLED, sample);
2717 break;
2718 case JS_TELEMETRY_GC_NON_INCREMENTAL:
2719 Telemetry::Accumulate(Telemetry::GC_NON_INCREMENTAL, sample);
2720 break;
2721 case JS_TELEMETRY_GC_NON_INCREMENTAL_REASON:
2722 Telemetry::Accumulate(Telemetry::GC_NON_INCREMENTAL_REASON, sample);
2723 break;
2724 case JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS:
2725 Telemetry::Accumulate(Telemetry::GC_SCC_SWEEP_TOTAL_MS, sample);
2726 break;
2727 case JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS:
2728 Telemetry::Accumulate(Telemetry::GC_SCC_SWEEP_MAX_PAUSE_MS, sample);
2729 break;
2730 case JS_TELEMETRY_GC_MINOR_REASON:
2731 Telemetry::Accumulate(Telemetry::GC_MINOR_REASON, sample);
2732 break;
2733 case JS_TELEMETRY_GC_MINOR_REASON_LONG:
2734 Telemetry::Accumulate(Telemetry::GC_MINOR_REASON_LONG, sample);
2735 break;
2736 case JS_TELEMETRY_GC_MINOR_US:
2737 Telemetry::Accumulate(Telemetry::GC_MINOR_US, sample);
2738 break;
2739 case JS_TELEMETRY_GC_NURSERY_BYTES:
2740 Telemetry::Accumulate(Telemetry::GC_NURSERY_BYTES, sample);
2741 Telemetry::Accumulate(Telemetry::GC_NURSERY_BYTES_2, sample);
2742 break;
2743 case JS_TELEMETRY_GC_PRETENURE_COUNT:
2744 Telemetry::Accumulate(Telemetry::GC_PRETENURE_COUNT, sample);
2745 break;
2746 case JS_TELEMETRY_GC_NURSERY_PROMOTION_RATE:
2747 Telemetry::Accumulate(Telemetry::GC_NURSERY_PROMOTION_RATE, sample);
2748 break;
2749 case JS_TELEMETRY_GC_TENURED_SURVIVAL_RATE:
2750 Telemetry::Accumulate(Telemetry::GC_TENURED_SURVIVAL_RATE, sample);
2751 break;
2752 case JS_TELEMETRY_GC_MARK_RATE:
2753 Telemetry::Accumulate(Telemetry::GC_MARK_RATE, sample);
2754 break;
2755 case JS_TELEMETRY_GC_TIME_BETWEEN_S:
2756 Telemetry::Accumulate(Telemetry::GC_TIME_BETWEEN_S, sample);
2757 break;
2758 case JS_TELEMETRY_GC_TIME_BETWEEN_SLICES_MS:
2759 Telemetry::Accumulate(Telemetry::GC_TIME_BETWEEN_SLICES_MS, sample);
2760 break;
2761 case JS_TELEMETRY_GC_SLICE_COUNT:
2762 Telemetry::Accumulate(Telemetry::GC_SLICE_COUNT, sample);
2763 break;
2764 case JS_TELEMETRY_GC_EFFECTIVENESS:
2765 Telemetry::Accumulate(Telemetry::GC_EFFECTIVENESS, sample);
2766 break;
2767 case JS_TELEMETRY_PRIVILEGED_PARSER_COMPILE_LAZY_AFTER_MS:
2768 Telemetry::Accumulate(
2769 Telemetry::JS_PRIVILEGED_PARSER_COMPILE_LAZY_AFTER_MS, sample);
2770 break;
2771 case JS_TELEMETRY_WEB_PARSER_COMPILE_LAZY_AFTER_MS:
2772 Telemetry::Accumulate(Telemetry::JS_WEB_PARSER_COMPILE_LAZY_AFTER_MS,
2773 sample);
2774 break;
2775 default:
2776 MOZ_ASSERT_UNREACHABLE("Unexpected JS_TELEMETRY id")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { MOZ_ReportAssertionFailure
("false" " (" "MOZ_ASSERT_UNREACHABLE: " "Unexpected JS_TELEMETRY id"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2776); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected JS_TELEMETRY id" ")")
; do { *((volatile int*)__null) = 2776; ::abort(); } while (false
); } } while (false)
;
2777 }
2778}
2779
2780static void SetUseCounterCallback(JSObject* obj, JSUseCounter counter) {
2781 switch (counter) {
2782 case JSUseCounter::ASMJS:
2783 SetUseCounter(obj, eUseCounter_custom_JS_asmjs);
2784 break;
2785 case JSUseCounter::WASM:
2786 SetUseCounter(obj, eUseCounter_custom_JS_wasm);
2787 break;
2788 default:
2789 MOZ_ASSERT_UNREACHABLE("Unexpected JSUseCounter id")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { MOZ_ReportAssertionFailure
("false" " (" "MOZ_ASSERT_UNREACHABLE: " "Unexpected JSUseCounter id"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2789); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected JSUseCounter id" ")")
; do { *((volatile int*)__null) = 2789; ::abort(); } while (false
); } } while (false)
;
2790 }
2791}
2792
2793static void GetRealmNameCallback(JSContext* cx, Handle<Realm*> realm, char* buf,
2794 size_t bufsize) {
2795 nsCString name;
2796 // This is called via the JSAPI and isn't involved in memory reporting, so
2797 // we don't need to anonymize realm names.
2798 int anonymizeID = 0;
2799 GetRealmName(realm, name, &anonymizeID, /* replaceSlashes = */ false);
2800 if (name.Length() >= bufsize) {
2801 name.Truncate(bufsize - 1);
2802 }
2803 memcpy(buf, name.get(), name.Length() + 1);
2804}
2805
2806static void DestroyRealm(JSFreeOp* fop, JS::Realm* realm) {
2807 // Get the current compartment private into an AutoPtr (which will do the
2808 // cleanup for us), and null out the private field.
2809 mozilla::UniquePtr<RealmPrivate> priv(RealmPrivate::Get(realm));
2810 JS::SetRealmPrivate(realm, nullptr);
2811}
2812
2813static bool PreserveWrapper(JSContext* cx, JS::Handle<JSObject*> obj) {
2814 MOZ_ASSERT(cx)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cx)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(cx))), 0))) { MOZ_ReportAssertionFailure
("cx", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2814); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cx" ")"); do
{ *((volatile int*)__null) = 2814; ::abort(); } while (false
); } } while (false)
;
2815 MOZ_ASSERT(obj)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(obj))), 0))) { MOZ_ReportAssertionFailure
("obj", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2815); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj" ")"); do
{ *((volatile int*)__null) = 2815; ::abort(); } while (false
); } } while (false)
;
2816 MOZ_ASSERT(mozilla::dom::IsDOMObject(obj))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mozilla::dom::IsDOMObject(obj))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mozilla::dom::IsDOMObject(obj
)))), 0))) { MOZ_ReportAssertionFailure("mozilla::dom::IsDOMObject(obj)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2816); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mozilla::dom::IsDOMObject(obj)"
")"); do { *((volatile int*)__null) = 2816; ::abort(); } while
(false); } } while (false)
;
2817
2818 return mozilla::dom::TryPreserveWrapper(obj);
2819}
2820
2821static nsresult ReadSourceFromFilename(JSContext* cx, const char* filename,
2822 char16_t** twoByteSource,
2823 char** utf8Source, size_t* len) {
2824 MOZ_ASSERT(*len == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(*len == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*len == 0))), 0))) { MOZ_ReportAssertionFailure
("*len == 0", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2824); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*len == 0" ")"
); do { *((volatile int*)__null) = 2824; ::abort(); } while (
false); } } while (false)
;
2825 MOZ_ASSERT((twoByteSource != nullptr) != (utf8Source != nullptr),do { static_assert( mozilla::detail::AssertionConditionType<
decltype((twoByteSource != nullptr) != (utf8Source != nullptr
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!((twoByteSource != nullptr) != (utf8Source != nullptr
)))), 0))) { MOZ_ReportAssertionFailure("(twoByteSource != nullptr) != (utf8Source != nullptr)"
" (" "must be called requesting only one of UTF-8 or UTF-16 source"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2826); AnnotateMozCrashReason("MOZ_ASSERT" "(" "(twoByteSource != nullptr) != (utf8Source != nullptr)"
") (" "must be called requesting only one of UTF-8 or UTF-16 source"
")"); do { *((volatile int*)__null) = 2826; ::abort(); } while
(false); } } while (false)
2826 "must be called requesting only one of UTF-8 or UTF-16 source")do { static_assert( mozilla::detail::AssertionConditionType<
decltype((twoByteSource != nullptr) != (utf8Source != nullptr
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!((twoByteSource != nullptr) != (utf8Source != nullptr
)))), 0))) { MOZ_ReportAssertionFailure("(twoByteSource != nullptr) != (utf8Source != nullptr)"
" (" "must be called requesting only one of UTF-8 or UTF-16 source"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2826); AnnotateMozCrashReason("MOZ_ASSERT" "(" "(twoByteSource != nullptr) != (utf8Source != nullptr)"
") (" "must be called requesting only one of UTF-8 or UTF-16 source"
")"); do { *((volatile int*)__null) = 2826; ::abort(); } while
(false); } } while (false)
;
2827 MOZ_ASSERT_IF(twoByteSource, !*twoByteSource)do { if (twoByteSource) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(!*twoByteSource)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!*twoByteSource))), 0))) { MOZ_ReportAssertionFailure("!*twoByteSource"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2827); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!*twoByteSource"
")"); do { *((volatile int*)__null) = 2827; ::abort(); } while
(false); } } while (false); } } while (false)
;
2828 MOZ_ASSERT_IF(utf8Source, !*utf8Source)do { if (utf8Source) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(!*utf8Source)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!*utf8Source))), 0))) { MOZ_ReportAssertionFailure
("!*utf8Source", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2828); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!*utf8Source"
")"); do { *((volatile int*)__null) = 2828; ::abort(); } while
(false); } } while (false); } } while (false)
;
2829
2830 nsresult rv;
2831
2832 // mozJSSubScriptLoader prefixes the filenames of the scripts it loads with
2833 // the filename of its caller. Axe that if present.
2834 const char* arrow;
2835 while ((arrow = strstr(filename, " -> "))) {
2836 filename = arrow + strlen(" -> ");
2837 }
2838
2839 // Get the URI.
2840 nsCOMPtr<nsIURI> uri;
2841 rv = NS_NewURI(getter_AddRefs(uri), filename);
2842 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "rv", static_cast<uint32_t>(__rv)); NS_DebugBreak(NS_DEBUG_WARNING
, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2842); return rv; } } while (false)
;
2843
2844 nsCOMPtr<nsIChannel> scriptChannel;
2845 rv = NS_NewChannel(getter_AddRefs(scriptChannel), uri,
2846 nsContentUtils::GetSystemPrincipal(),
2847 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
2848 nsIContentPolicy::TYPE_OTHER);
2849 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "rv", static_cast<uint32_t>(__rv)); NS_DebugBreak(NS_DEBUG_WARNING
, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2849); return rv; } } while (false)
;
2850
2851 // Only allow local reading.
2852 nsCOMPtr<nsIURI> actualUri;
2853 rv = scriptChannel->GetURI(getter_AddRefs(actualUri));
2854 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "rv", static_cast<uint32_t>(__rv)); NS_DebugBreak(NS_DEBUG_WARNING
, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2854); return rv; } } while (false)
;
2855 nsCString scheme;
2856 rv = actualUri->GetScheme(scheme);
2857 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "rv", static_cast<uint32_t>(__rv)); NS_DebugBreak(NS_DEBUG_WARNING
, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2857); return rv; } } while (false)
;
2858 if (!scheme.EqualsLiteral("file") && !scheme.EqualsLiteral("jar")) {
2859 return NS_OK;
2860 }
2861
2862 // Explicitly set the content type so that we don't load the
2863 // exthandler to guess it.
2864 scriptChannel->SetContentType(NS_LITERAL_CSTRING("text/plain")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "text/plain"))
);
2865
2866 nsCOMPtr<nsIInputStream> scriptStream;
2867 rv = scriptChannel->Open(getter_AddRefs(scriptStream));
2868 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "rv", static_cast<uint32_t>(__rv)); NS_DebugBreak(NS_DEBUG_WARNING
, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2868); return rv; } } while (false)
;
2869
2870 uint64_t rawLen;
2871 rv = scriptStream->Available(&rawLen);
2872 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "rv", static_cast<uint32_t>(__rv)); NS_DebugBreak(NS_DEBUG_WARNING
, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2872); return rv; } } while (false)
;
2873 if (!rawLen) {
2874 return NS_ERROR_FAILURE;
2875 }
2876
2877 // Technically, this should be SIZE_MAX, but we don't run on machines
2878 // where that would be less than UINT32_MAX, and the latter is already
2879 // well beyond a reasonable limit.
2880 if (rawLen > UINT32_MAX(4294967295U)) {
2881 return NS_ERROR_FILE_TOO_BIG;
2882 }
2883
2884 // Allocate a buffer the size of the file to initially fill with the UTF-8
2885 // contents of the file. Use the JS allocator so that if UTF-8 source was
2886 // requested, we can return this memory directly.
2887 JS::UniqueChars buf(js_pod_malloc<char>(rawLen));
2888 if (!buf) {
2889 return NS_ERROR_OUT_OF_MEMORY;
2890 }
2891
2892 char* ptr = buf.get();
2893 char* end = ptr + rawLen;
2894 while (ptr < end) {
2895 uint32_t bytesRead;
2896 rv = scriptStream->Read(ptr, PointerRangeSize(ptr, end), &bytesRead);
2897 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2898 return rv;
2899 }
2900 MOZ_ASSERT(bytesRead > 0, "stream promised more bytes before EOF")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bytesRead > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(bytesRead > 0))), 0))) { MOZ_ReportAssertionFailure
("bytesRead > 0" " (" "stream promised more bytes before EOF"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bytesRead > 0"
") (" "stream promised more bytes before EOF" ")"); do { *((
volatile int*)__null) = 2900; ::abort(); } while (false); } }
while (false)
;
2901 ptr += bytesRead;
2902 }
2903
2904 size_t bytesAllocated;
2905 if (utf8Source) {
2906 // |buf| is already UTF-8, so we can directly return it.
2907 *len = bytesAllocated = rawLen;
Although the value stored to 'bytesAllocated' is used in the enclosing expression, the value is never actually read from 'bytesAllocated'
2908 *utf8Source = buf.release();
2909 } else {
2910 MOZ_ASSERT(twoByteSource != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(twoByteSource != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(twoByteSource != nullptr))),
0))) { MOZ_ReportAssertionFailure("twoByteSource != nullptr"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2910); AnnotateMozCrashReason("MOZ_ASSERT" "(" "twoByteSource != nullptr"
")"); do { *((volatile int*)__null) = 2910; ::abort(); } while
(false); } } while (false)
;
2911
2912 // |buf| can't be directly returned -- convert it to UTF-16.
2913
2914 // On success this overwrites |*twoByteSource| and |*len|.
2915 rv = ScriptLoader::ConvertToUTF16(
2916 scriptChannel, reinterpret_cast<const unsigned char*>(buf.get()),
2917 rawLen, NS_LITERAL_STRING("UTF-8")static_cast<const nsLiteralString&>(nsLiteralString
(u"" "UTF-8"))
, nullptr, *twoByteSource, *len);
2918 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "rv", static_cast<uint32_t>(__rv)); NS_DebugBreak(NS_DEBUG_WARNING
, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2918); return rv; } } while (false)
;
2919
2920 if (!*twoByteSource) {
2921 return NS_ERROR_FAILURE;
2922 }
2923
2924 bytesAllocated = *len * sizeof(char16_t);
2925 }
2926
2927 return NS_OK;
2928}
2929
2930// The JS engine calls this object's 'load' member function when it needs
2931// the source for a chrome JS function. See the comment in the XPCJSRuntime
2932// constructor.
2933class XPCJSSourceHook : public js::SourceHook {
2934 bool load(JSContext* cx, const char* filename, char16_t** twoByteSource,
2935 char** utf8Source, size_t* length) override {
2936 MOZ_ASSERT((twoByteSource != nullptr) != (utf8Source != nullptr),do { static_assert( mozilla::detail::AssertionConditionType<
decltype((twoByteSource != nullptr) != (utf8Source != nullptr
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!((twoByteSource != nullptr) != (utf8Source != nullptr
)))), 0))) { MOZ_ReportAssertionFailure("(twoByteSource != nullptr) != (utf8Source != nullptr)"
" (" "must be called requesting only one of UTF-8 or UTF-16 source"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2937); AnnotateMozCrashReason("MOZ_ASSERT" "(" "(twoByteSource != nullptr) != (utf8Source != nullptr)"
") (" "must be called requesting only one of UTF-8 or UTF-16 source"
")"); do { *((volatile int*)__null) = 2937; ::abort(); } while
(false); } } while (false)
2937 "must be called requesting only one of UTF-8 or UTF-16 source")do { static_assert( mozilla::detail::AssertionConditionType<
decltype((twoByteSource != nullptr) != (utf8Source != nullptr
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!((twoByteSource != nullptr) != (utf8Source != nullptr
)))), 0))) { MOZ_ReportAssertionFailure("(twoByteSource != nullptr) != (utf8Source != nullptr)"
" (" "must be called requesting only one of UTF-8 or UTF-16 source"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 2937); AnnotateMozCrashReason("MOZ_ASSERT" "(" "(twoByteSource != nullptr) != (utf8Source != nullptr)"
") (" "must be called requesting only one of UTF-8 or UTF-16 source"
")"); do { *((volatile int*)__null) = 2937; ::abort(); } while
(false); } } while (false)
;
2938
2939 *length = 0;
2940 if (twoByteSource) {
2941 *twoByteSource = nullptr;
2942 } else {
2943 *utf8Source = nullptr;
2944 }
2945
2946 if (!nsContentUtils::IsSystemCaller(cx)) {
2947 return true;
2948 }
2949
2950 if (!filename) {
2951 return true;
2952 }
2953
2954 nsresult rv =
2955 ReadSourceFromFilename(cx, filename, twoByteSource, utf8Source, length);
2956 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2957 xpc::Throw(cx, rv);
2958 return false;
2959 }
2960
2961 return true;
2962 }
2963};
2964
2965static const JSWrapObjectCallbacks WrapObjectCallbacks = {
2966 xpc::WrapperFactory::Rewrap, xpc::WrapperFactory::PrepareForWrapping};
2967
2968XPCJSRuntime::XPCJSRuntime(JSContext* aCx)
2969 : CycleCollectedJSRuntime(aCx),
2970 mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_LENGTH32)),
2971 mIID2NativeInterfaceMap(
2972 IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_LENGTH32)),
2973 mClassInfo2NativeSetMap(
2974 ClassInfo2NativeSetMap::newMap(XPC_NATIVE_SET_MAP_LENGTH32)),
2975 mNativeSetMap(NativeSetMap::newMap(XPC_NATIVE_SET_MAP_LENGTH32)),
2976 mWrappedNativeScopes(),
2977 mDyingWrappedNativeProtoMap(
2978 XPCWrappedNativeProtoMap::newMap(XPC_DYING_NATIVE_PROTO_MAP_LENGTH8)),
2979 mGCIsRunning(false),
2980 mNativesToReleaseArray(),
2981 mDoingFinalization(false),
2982 mVariantRoots(nullptr),
2983 mWrappedJSRoots(nullptr),
2984 mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite()) {
2985 MOZ_COUNT_CTOR_INHERITED(XPCJSRuntime, CycleCollectedJSRuntime)do { static_assert(mozilla::IsClass<XPCJSRuntime>::value
, "Token '" "XPCJSRuntime" "' is not a class type."); static_assert
(mozilla::IsClass<CycleCollectedJSRuntime>::value, "Token '"
"CycleCollectedJSRuntime" "' is not a class type."); static_assert
(!mozilla::IsBaseOf<nsISupports, XPCJSRuntime>::value, "nsISupports classes don't need to call MOZ_COUNT_CTOR or "
"MOZ_COUNT_DTOR");; NS_LogCtor((void*)this, "XPCJSRuntime", sizeof
(*this) - sizeof(CycleCollectedJSRuntime)); } while (0)
;
2986}
2987
2988/* static */
2989XPCJSRuntime* XPCJSRuntime::Get() { return nsXPConnect::GetRuntimeInstance(); }
2990
2991// Subclass of JS::ubi::Base for DOM reflector objects for the JS::ubi::Node
2992// memory analysis framework; see js/public/UbiNode.h. In
2993// XPCJSRuntime::Initialize, we register the ConstructUbiNode function as a hook
2994// with the SpiderMonkey runtime for it to use to construct ubi::Nodes of this
2995// class for JSObjects whose class has the JSCLASS_IS_DOMJSCLASS flag set.
2996// ReflectorNode specializes Concrete<JSObject> for DOM reflector nodes,
2997// reporting the edge from the JSObject to the nsINode it represents, in
2998// addition to the usual edges departing any normal JSObject.
2999namespace JS {
3000namespace ubi {
3001class ReflectorNode : public Concrete<JSObject> {
3002 protected:
3003 explicit ReflectorNode(JSObject* ptr) : Concrete<JSObject>(ptr) {}
3004
3005 public:
3006 static void construct(void* storage, JSObject* ptr) {
3007 new (storage) ReflectorNode(ptr);
3008 }
3009 js::UniquePtr<JS::ubi::EdgeRange> edges(JSContext* cx,
3010 bool wantNames) const override;
3011};
3012
3013js::UniquePtr<EdgeRange> ReflectorNode::edges(JSContext* cx,
3014 bool wantNames) const {
3015 js::UniquePtr<SimpleEdgeRange> range(static_cast<SimpleEdgeRange*>(
3016 Concrete<JSObject>::edges(cx, wantNames).release()));
3017 if (!range) {
3018 return nullptr;
3019 }
3020 // UNWRAP_NON_WRAPPER_OBJECT assumes the object is completely initialized,
3021 // but ours may not be. Luckily, UnwrapDOMObjectToISupports checks for the
3022 // uninitialized case (and returns null if uninitialized), so we can use that
3023 // to guard against uninitialized objects.
3024 nsISupports* supp = UnwrapDOMObjectToISupports(&get());
3025 if (supp) {
3026 JS::AutoSuppressGCAnalysis nogc; // bug 1582326
3027
3028 nsINode* node;
3029 // UnwrapDOMObjectToISupports can only return non-null if its argument is
3030 // an actual DOM object, not a cross-compartment wrapper.
3031 if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Node, &get(), node))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mozilla::dom::UnwrapNonWrapperObject
< mozilla::dom::prototypes::id::Node, mozilla::dom::Node_Binding
::NativeType>(&get(), node))), 1)))
) {
3032 char16_t* edgeName = nullptr;
3033 if (wantNames) {
3034 edgeName = NS_xstrdup(u"Reflected Node");
3035 }
3036 if (!range->addEdge(Edge(edgeName, node))) {
3037 return nullptr;
3038 }
3039 }
3040 }
3041 return js::UniquePtr<EdgeRange>(range.release());
3042}
3043
3044} // Namespace ubi
3045} // Namespace JS
3046
3047void ConstructUbiNode(void* storage, JSObject* ptr) {
3048 JS::ubi::ReflectorNode::construct(storage, ptr);
3049}
3050
3051void XPCJSRuntime::Initialize(JSContext* cx) {
3052 mUnprivilegedJunkScope.init(cx, nullptr);
3053 mLoaderGlobal.init(cx, nullptr);
3054
3055 // these jsids filled in later when we have a JSContext to work with.
3056 mStrIDs[0] = JSID_VOID;
3057
3058 // Unconstrain the runtime's threshold on nominal heap size, to avoid
3059 // triggering GC too often if operating continuously near an arbitrary
3060 // finite threshold (0xffffffff is infinity for uint32_t parameters).
3061 // This leaves the maximum-JS_malloc-bytes threshold still in effect
3062 // to cause period, and we hope hygienic, last-ditch GCs from within
3063 // the GC's allocator.
3064 JS_SetGCParameter(cx, JSGC_MAX_BYTES, 0xffffffff);
3065
3066 JS_SetDestroyCompartmentCallback(cx, CompartmentDestroyedCallback);
3067 JS_SetSizeOfIncludingThisCompartmentCallback(
3068 cx, CompartmentSizeOfIncludingThisCallback);
3069 JS::SetDestroyRealmCallback(cx, DestroyRealm);
3070 JS::SetRealmNameCallback(cx, GetRealmNameCallback);
3071 mPrevGCSliceCallback = JS::SetGCSliceCallback(cx, GCSliceCallback);
3072 mPrevDoCycleCollectionCallback =
3073 JS::SetDoCycleCollectionCallback(cx, DoCycleCollectionCallback);
3074 JS_AddFinalizeCallback(cx, FinalizeCallback, nullptr);
3075 JS_AddWeakPointerZonesCallback(cx, WeakPointerZonesCallback, this);
3076 JS_AddWeakPointerCompartmentCallback(cx, WeakPointerCompartmentCallback,
3077 this);
3078 JS_SetWrapObjectCallbacks(cx, &WrapObjectCallbacks);
3079 js::SetPreserveWrapperCallback(cx, PreserveWrapper);
3080 JS_InitReadPrincipalsCallback(cx, nsJSPrincipals::ReadPrincipals);
3081 JS_SetAccumulateTelemetryCallback(cx, AccumulateTelemetryCallback);
3082 JS_SetSetUseCounterCallback(cx, SetUseCounterCallback);
3083 js::SetWindowProxyClass(cx, &OuterWindowProxyClass);
3084 js::SetXrayJitInfo(&gXrayJitInfo);
3085 JS::SetProcessLargeAllocationFailureCallback(
3086 OnLargeAllocationFailureCallback);
3087 JS::SetProcessBuildIdOp(GetBuildId);
3088
3089 // Initialize a helper thread pool for JS offthread tasks. Set the
3090 // task callback to divert tasks to the helperthreads.
3091 InitializeHelperThreadPool();
3092 SetHelperThreadTaskCallback(&DispatchOffThreadTask);
3093
3094 // The JS engine needs to keep the source code around in order to implement
3095 // Function.prototype.toSource(). It'd be nice to not have to do this for
3096 // chrome code and simply stub out requests for source on it. Life is not so
3097 // easy, unfortunately. Nobody relies on chrome toSource() working in core
3098 // browser code, but chrome tests use it. The worst offenders are addons,
3099 // which like to monkeypatch chrome functions by calling toSource() on them
3100 // and using regular expressions to modify them. We avoid keeping most browser
3101 // JS source code in memory by setting LAZY_SOURCE on JS::CompileOptions when
3102 // compiling some chrome code. This causes the JS engine not save the source
3103 // code in memory. When the JS engine is asked to provide the source for a
3104 // function compiled with LAZY_SOURCE, it calls SourceHook to load it.
3105 ///
3106 // Note we do have to retain the source code in memory for scripts compiled in
3107 // isRunOnce mode and compiled function bodies (from
3108 // JS::CompileFunction). In practice, this means content scripts and event
3109 // handlers.
3110 mozilla::UniquePtr<XPCJSSourceHook> hook(new XPCJSSourceHook);
3111 js::SetSourceHook(cx, std::move(hook));
3112
3113 // Register memory reporters and distinguished amount functions.
3114 RegisterStrongMemoryReporter(new JSMainRuntimeRealmsReporter());
3115 RegisterStrongMemoryReporter(new JSMainRuntimeTemporaryPeakReporter());
3116 RegisterJSMainRuntimeGCHeapDistinguishedAmount(
3117 JSMainRuntimeGCHeapDistinguishedAmount);
3118 RegisterJSMainRuntimeTemporaryPeakDistinguishedAmount(
3119 JSMainRuntimeTemporaryPeakDistinguishedAmount);
3120 RegisterJSMainRuntimeCompartmentsSystemDistinguishedAmount(
3121 JSMainRuntimeCompartmentsSystemDistinguishedAmount);
3122 RegisterJSMainRuntimeCompartmentsUserDistinguishedAmount(
3123 JSMainRuntimeCompartmentsUserDistinguishedAmount);
3124 RegisterJSMainRuntimeRealmsSystemDistinguishedAmount(
3125 JSMainRuntimeRealmsSystemDistinguishedAmount);
3126 RegisterJSMainRuntimeRealmsUserDistinguishedAmount(
3127 JSMainRuntimeRealmsUserDistinguishedAmount);
3128 mozilla::RegisterJSSizeOfTab(JSSizeOfTab);
3129
3130 // Set the callback for reporting memory to ubi::Node.
3131 JS::ubi::SetConstructUbiNodeForDOMObjectCallback(cx, &ConstructUbiNode);
3132
3133 xpc_LocalizeRuntime(JS_GetRuntime(cx));
3134}
3135
3136bool XPCJSRuntime::InitializeStrings(JSContext* cx) {
3137 // if it is our first context then we need to generate our string ids
3138 if (JSID_IS_VOID(mStrIDs[0])) {
3139 RootedString str(cx);
3140 for (unsigned i = 0; i < XPCJSContext::IDX_TOTAL_COUNT; i++) {
3141 str = JS_AtomizeAndPinString(cx, mStrings[i]);
3142 if (!str) {
3143 mStrIDs[0] = JSID_VOID;
3144 return false;
3145 }
3146 mStrIDs[i] = INTERNED_STRING_TO_JSID(cx, str);
3147 mStrJSVals[i].setString(str);
3148 }
3149
3150 if (!mozilla::dom::DefineStaticJSVals(cx)) {
3151 return false;
3152 }
3153 }
3154
3155 return true;
3156}
3157
3158bool XPCJSRuntime::DescribeCustomObjects(JSObject* obj, const JSClass* clasp,
3159 char (&name)[72]) const {
3160 if (clasp != &XPC_WN_Proto_JSClass) {
3161 return false;
3162 }
3163
3164 XPCWrappedNativeProto* p =
3165 static_cast<XPCWrappedNativeProto*>(xpc_GetJSPrivate(obj));
3166 nsCOMPtr<nsIXPCScriptable> scr = p->GetScriptable();
3167 if (!scr) {
3168 return false;
3169 }
3170
3171 SprintfLiteral(name, "JS Object (%s - %s)", clasp->name,
3172 scr->GetJSClass()->name);
3173 return true;
3174}
3175
3176bool XPCJSRuntime::NoteCustomGCThingXPCOMChildren(
3177 const JSClass* clasp, JSObject* obj,
3178 nsCycleCollectionTraversalCallback& cb) const {
3179 if (clasp != &XPC_WN_Tearoff_JSClass) {
3180 return false;
3181 }
3182
3183 // A tearoff holds a strong reference to its native object
3184 // (see XPCWrappedNative::FlatJSObjectFinalized). Its XPCWrappedNative
3185 // will be held alive through tearoff's XPC_WN_TEAROFF_FLAT_OBJECT_SLOT,
3186 // which points to the XPCWrappedNative's mFlatJSObject.
3187 XPCWrappedNativeTearOff* to =
3188 static_cast<XPCWrappedNativeTearOff*>(xpc_GetJSPrivate(obj));
3189 NS_CYCLE_COLLECTION_NOTE_EDGE_NAMECycleCollectionNoteEdgeName(cb, "xpc_GetJSPrivate(obj)->mNative");
3190 cb.NoteXPCOMChild(to->GetNative());
3191 return true;
3192}
3193
3194/***************************************************************************/
3195
3196void XPCJSRuntime::DebugDump(int16_t depth) {
3197#ifdef DEBUG1
3198 depth--;
3199 XPC_LOG_ALWAYS(("XPCJSRuntime @ %p", this))do { if (XPC_Log_Check(1)) { XPC_Log_print ("XPCJSRuntime @ %p"
, this); } } while (0)
;
3200 XPC_LOG_INDENT()XPC_Log_Indent();
3201
3202 // iterate wrappers...
3203 XPC_LOG_ALWAYS(("mWrappedJSMap @ %p with %d wrappers(s)", mWrappedJSMap,do { if (XPC_Log_Check(1)) { XPC_Log_print ("mWrappedJSMap @ %p with %d wrappers(s)"
, mWrappedJSMap, mWrappedJSMap->Count()); } } while (0)
3204 mWrappedJSMap->Count()))do { if (XPC_Log_Check(1)) { XPC_Log_print ("mWrappedJSMap @ %p with %d wrappers(s)"
, mWrappedJSMap, mWrappedJSMap->Count()); } } while (0)
;
3205 if (depth && mWrappedJSMap->Count()) {
3206 XPC_LOG_INDENT()XPC_Log_Indent();
3207 mWrappedJSMap->Dump(depth);
3208 XPC_LOG_OUTDENT()XPC_Log_Outdent();
3209 }
3210
3211 XPC_LOG_ALWAYS(("mIID2NativeInterfaceMap @ %p with %d interface(s)",do { if (XPC_Log_Check(1)) { XPC_Log_print ("mIID2NativeInterfaceMap @ %p with %d interface(s)"
, mIID2NativeInterfaceMap, mIID2NativeInterfaceMap->Count(
)); } } while (0)
3212 mIID2NativeInterfaceMap, mIID2NativeInterfaceMap->Count()))do { if (XPC_Log_Check(1)) { XPC_Log_print ("mIID2NativeInterfaceMap @ %p with %d interface(s)"
, mIID2NativeInterfaceMap, mIID2NativeInterfaceMap->Count(
)); } } while (0)
;
3213
3214 XPC_LOG_ALWAYS(("mClassInfo2NativeSetMap @ %p with %d sets(s)",do { if (XPC_Log_Check(1)) { XPC_Log_print ("mClassInfo2NativeSetMap @ %p with %d sets(s)"
, mClassInfo2NativeSetMap, mClassInfo2NativeSetMap->Count(
)); } } while (0)
3215 mClassInfo2NativeSetMap, mClassInfo2NativeSetMap->Count()))do { if (XPC_Log_Check(1)) { XPC_Log_print ("mClassInfo2NativeSetMap @ %p with %d sets(s)"
, mClassInfo2NativeSetMap, mClassInfo2NativeSetMap->Count(
)); } } while (0)
;
3216
3217 XPC_LOG_ALWAYS(("mNativeSetMap @ %p with %d sets(s)", mNativeSetMap,do { if (XPC_Log_Check(1)) { XPC_Log_print ("mNativeSetMap @ %p with %d sets(s)"
, mNativeSetMap, mNativeSetMap->Count()); } } while (0)
3218 mNativeSetMap->Count()))do { if (XPC_Log_Check(1)) { XPC_Log_print ("mNativeSetMap @ %p with %d sets(s)"
, mNativeSetMap, mNativeSetMap->Count()); } } while (0)
;
3219
3220 // iterate sets...
3221 if (depth && mNativeSetMap->Count()) {
3222 XPC_LOG_INDENT()XPC_Log_Indent();
3223 for (auto i = mNativeSetMap->Iter(); !i.Done(); i.Next()) {
3224 auto entry = static_cast<NativeSetMap::Entry*>(i.Get());
3225 entry->key_value->DebugDump(depth);
3226 }
3227 XPC_LOG_OUTDENT()XPC_Log_Outdent();
3228 }
3229
3230 XPC_LOG_OUTDENT()XPC_Log_Outdent();
3231#endif
3232}
3233
3234/***************************************************************************/
3235
3236void XPCRootSetElem::AddToRootSet(XPCRootSetElem** listHead) {
3237 MOZ_ASSERT(!mSelfp, "Must be not linked")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSelfp)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mSelfp))), 0))) { MOZ_ReportAssertionFailure
("!mSelfp" " (" "Must be not linked" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3237); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSelfp" ") ("
"Must be not linked" ")"); do { *((volatile int*)__null) = 3237
; ::abort(); } while (false); } } while (false)
;
3238
3239 mSelfp = listHead;
3240 mNext = *listHead;
3241 if (mNext) {
3242 MOZ_ASSERT(mNext->mSelfp == listHead, "Must be list start")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mNext->mSelfp == listHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mNext->mSelfp == listHead
))), 0))) { MOZ_ReportAssertionFailure("mNext->mSelfp == listHead"
" (" "Must be list start" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3242); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mNext->mSelfp == listHead"
") (" "Must be list start" ")"); do { *((volatile int*)__null
) = 3242; ::abort(); } while (false); } } while (false)
;
3243 mNext->mSelfp = &mNext;
3244 }
3245 *listHead = this;
3246}
3247
3248void XPCRootSetElem::RemoveFromRootSet() {
3249 JS::NotifyGCRootsRemoved(XPCJSContext::Get()->Context());
3250
3251 MOZ_ASSERT(mSelfp, "Must be linked")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSelfp)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(mSelfp))), 0))) { MOZ_ReportAssertionFailure
("mSelfp" " (" "Must be linked" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3251); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSelfp" ") ("
"Must be linked" ")"); do { *((volatile int*)__null) = 3251;
::abort(); } while (false); } } while (false)
;
3252
3253 MOZ_ASSERT(*mSelfp == this, "Link invariant")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(*mSelfp == this)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*mSelfp == this))), 0))) { MOZ_ReportAssertionFailure
("*mSelfp == this" " (" "Link invariant" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3253); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*mSelfp == this"
") (" "Link invariant" ")"); do { *((volatile int*)__null) =
3253; ::abort(); } while (false); } } while (false)
;
3254 *mSelfp = mNext;
3255 if (mNext) {
3256 mNext->mSelfp = mSelfp;
3257 }
3258#ifdef DEBUG1
3259 mSelfp = nullptr;
3260 mNext = nullptr;
3261#endif
3262}
3263
3264void XPCJSRuntime::AddGCCallback(xpcGCCallback cb) {
3265 MOZ_ASSERT(cb, "null callback")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cb)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(cb))), 0))) { MOZ_ReportAssertionFailure
("cb" " (" "null callback" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3265); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cb" ") (" "null callback"
")"); do { *((volatile int*)__null) = 3265; ::abort(); } while
(false); } } while (false)
;
3266 extraGCCallbacks.AppendElement(cb);
3267}
3268
3269void XPCJSRuntime::RemoveGCCallback(xpcGCCallback cb) {
3270 MOZ_ASSERT(cb, "null callback")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cb)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(cb))), 0))) { MOZ_ReportAssertionFailure
("cb" " (" "null callback" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3270); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cb" ") (" "null callback"
")"); do { *((volatile int*)__null) = 3270; ::abort(); } while
(false); } } while (false)
;
3271 bool found = extraGCCallbacks.RemoveElement(cb);
3272 if (!found) {
3273 NS_ERROR("Removing a callback which was never added.")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "Removing a callback which was never added."
, "Error", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3273); MOZ_PretendNoReturn(); } while (0)
;
3274 }
3275}
3276
3277JSObject* XPCJSRuntime::GetUAWidgetScope(JSContext* cx,
3278 nsIPrincipal* principal) {
3279 MOZ_ASSERT(!nsContentUtils::IsSystemPrincipal(principal),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nsContentUtils::IsSystemPrincipal(principal))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!nsContentUtils::IsSystemPrincipal(principal)))), 0)
)) { MOZ_ReportAssertionFailure("!nsContentUtils::IsSystemPrincipal(principal)"
" (" "Running UA Widget in chrome" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3280); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nsContentUtils::IsSystemPrincipal(principal)"
") (" "Running UA Widget in chrome" ")"); do { *((volatile int
*)__null) = 3280; ::abort(); } while (false); } } while (false
)
3280 "Running UA Widget in chrome")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nsContentUtils::IsSystemPrincipal(principal))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!nsContentUtils::IsSystemPrincipal(principal)))), 0)
)) { MOZ_ReportAssertionFailure("!nsContentUtils::IsSystemPrincipal(principal)"
" (" "Running UA Widget in chrome" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3280); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nsContentUtils::IsSystemPrincipal(principal)"
") (" "Running UA Widget in chrome" ")"); do { *((volatile int
*)__null) = 3280; ::abort(); } while (false); } } while (false
)
;
3281
3282 RootedObject scope(cx);
3283 do {
3284 RefPtr<BasePrincipal> key = BasePrincipal::Cast(principal);
3285 if (Principal2JSObjectMap::Ptr p = mUAWidgetScopeMap.lookup(key)) {
3286 scope = p->value();
3287 break; // Need ~RefPtr to run, and potentially GC, before returning.
3288 }
3289
3290 SandboxOptions options;
3291 options.sandboxName.AssignLiteral("UA Widget Scope");
3292 options.wantXrays = false;
3293 options.wantComponents = false;
3294 options.isUAWidgetScope = true;
3295
3296 // Use an ExpandedPrincipal to create asymmetric security.
3297 MOZ_ASSERT(!nsContentUtils::IsExpandedPrincipal(principal))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nsContentUtils::IsExpandedPrincipal(principal))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!nsContentUtils::IsExpandedPrincipal(principal)))), 0
))) { MOZ_ReportAssertionFailure("!nsContentUtils::IsExpandedPrincipal(principal)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3297); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nsContentUtils::IsExpandedPrincipal(principal)"
")"); do { *((volatile int*)__null) = 3297; ::abort(); } while
(false); } } while (false)
;
3298 nsTArray<nsCOMPtr<nsIPrincipal>> principalAsArray(1);
3299 principalAsArray.AppendElement(principal);
3300 RefPtr<ExpandedPrincipal> ep = ExpandedPrincipal::Create(
3301 principalAsArray, principal->OriginAttributesRef());
3302
3303 // Create the sandbox.
3304 RootedValue v(cx);
3305 nsresult rv = CreateSandboxObject(
3306 cx, &v, static_cast<nsIExpandedPrincipal*>(ep), options);
3307 NS_ENSURE_SUCCESS(rv, nullptr)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { mozilla::SmprintfPointer msg = mozilla::Smprintf
( "NS_ENSURE_SUCCESS(%s, %s) failed with " "result 0x%" "X", "rv"
, "nullptr", static_cast<uint32_t>(__rv)); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3307); return nullptr; } } while (false)
;
3308 scope = &v.toObject();
3309
3310 MOZ_ASSERT(xpc::IsInUAWidgetScope(js::UncheckedUnwrap(scope)))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(xpc::IsInUAWidgetScope(js::UncheckedUnwrap(scope)))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(xpc::IsInUAWidgetScope(js::UncheckedUnwrap(scope))))
), 0))) { MOZ_ReportAssertionFailure("xpc::IsInUAWidgetScope(js::UncheckedUnwrap(scope))"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3310); AnnotateMozCrashReason("MOZ_ASSERT" "(" "xpc::IsInUAWidgetScope(js::UncheckedUnwrap(scope))"
")"); do { *((volatile int*)__null) = 3310; ::abort(); } while
(false); } } while (false)
;
3311
3312 MOZ_ALWAYS_TRUE(mUAWidgetScopeMap.putNew(key, scope))do { if ((mUAWidgetScopeMap.putNew(key, scope))) { } else { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { MOZ_ReportAssertionFailure
("false" " (" "mUAWidgetScopeMap.putNew(key, scope)" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3312); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"mUAWidgetScopeMap.putNew(key, scope)" ")"); do { *((volatile
int*)__null) = 3312; ::abort(); } while (false); } } while (
false); } } while (false)
;
3313 } while (false);
3314
3315 return scope;
3316}
3317
3318void XPCJSRuntime::InitSingletonScopes() {
3319 // This all happens very early, so we don't bother with cx pushing.
3320 JSContext* cx = XPCJSContext::Get()->Context();
3321 RootedValue v(cx);
3322 nsresult rv;
3323
3324 // Create the Unprivileged Junk Scope.
3325 SandboxOptions unprivilegedJunkScopeOptions;
3326 unprivilegedJunkScopeOptions.sandboxName.AssignLiteral(
3327 "XPConnect Junk Compartment");
3328 unprivilegedJunkScopeOptions.invisibleToDebugger = true;
3329 rv = CreateSandboxObject(cx, &v, nullptr, unprivilegedJunkScopeOptions);
3330 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { MOZ_ReportAssertionFailure("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3330); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3330; ::abort(); } while
(false); } } while (false)
;
3331 mUnprivilegedJunkScope = js::UncheckedUnwrap(&v.toObject());
3332}
3333
3334void XPCJSRuntime::DeleteSingletonScopes() {
3335 // We're pretty late in shutdown, so we call ReleaseWrapper on the scopes.
3336 // This way the GC can collect them immediately, and we don't rely on the CC
3337 // to clean up.
3338 RefPtr<SandboxPrivate> sandbox =
3339 SandboxPrivate::GetPrivate(mUnprivilegedJunkScope);
3340 sandbox->ReleaseWrapper(sandbox);
3341 mUnprivilegedJunkScope = nullptr;
3342 mLoaderGlobal = nullptr;
3343}
3344
3345JSObject* XPCJSRuntime::LoaderGlobal() {
3346 if (!mLoaderGlobal) {
3347 RefPtr<mozJSComponentLoader> loader = mozJSComponentLoader::Get();
3348
3349 dom::AutoJSAPI jsapi;
3350 jsapi.Init();
3351
3352 mLoaderGlobal = loader->GetSharedGlobal(jsapi.cx());
3353 MOZ_RELEASE_ASSERT(!JS_IsExceptionPending(jsapi.cx()))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!JS_IsExceptionPending(jsapi.cx()))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!JS_IsExceptionPending(jsapi
.cx())))), 0))) { MOZ_ReportAssertionFailure("!JS_IsExceptionPending(jsapi.cx())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/xpconnect/src/XPCJSRuntime.cpp"
, 3353); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!JS_IsExceptionPending(jsapi.cx())"
")"); do { *((volatile int*)__null) = 3353; ::abort(); } while
(false); } } while (false)
;
3354 }
3355 return mLoaderGlobal;
3356}
3357
3358uint32_t GetAndClampCPUCount() {
3359 // See HelperThreads.cpp for why we want between 2-8 threads
3360 int32_t proc = GetNumberOfProcessors();
3361 if (proc < 2) {
3362 return 2;
3363 }
3364 return std::min(proc, 8);
3365}
3366nsresult HelperThreadPool::Dispatch(
3367 already_AddRefed<HelperThreadTaskHandler> aRunnable) {
3368 mPool->Dispatch(std::move(aRunnable), NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL);
3369 return NS_OK;
3370}
3371
3372HelperThreadPool::HelperThreadPool() {
3373 mPool = new nsThreadPool();
3374 mPool->SetName(NS_LITERAL_CSTRING("JSHelperThreads")static_cast<const nsLiteralCString&>(nsLiteralCString
("" "JSHelperThreads"))
);
3375 mPool->SetThreadLimit(GetAndClampCPUCount());
3376 // Helper threads need a larger stack size than the default nsThreadPool stack
3377 // size. These values are described in detail in HelperThreads.cpp.
3378 const uint32_t kDefaultHelperStackSize = 2048 * 1024 - 2 * 4096;
3379
3380#if defined(MOZ_TSAN)
3381 const uint32_t HELPER_STACK_SIZE = 2 * kDefaultHelperStackSize;
3382#else
3383 const uint32_t HELPER_STACK_SIZE = kDefaultHelperStackSize;
3384#endif
3385
3386 mPool->SetThreadStackSize(HELPER_STACK_SIZE);
3387}
3388
3389void HelperThreadPool::Shutdown() { mPool->Shutdown(); }