Bug 964976 - Prevent crash of unsupported pixel format gralloc allocation. r=nical
[gecko.git] / xpcom / base / nsIMemoryReporter.idl
blob15265503507e4f459c639b20cd498069e95dd87b
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/. */
7 #include "nsISupports.idl"
9 interface nsICancelableRunnable;
10 interface nsIDOMWindow;
11 interface nsIRunnable;
12 interface nsISimpleEnumerator;
15 * Memory reporters measure Firefox's memory usage. They are primarily used to
16 * generate the about:memory page. You should read
17 * https://wiki.mozilla.org/Memory_Reporting before writing a memory
18 * reporter.
21 [scriptable, function, uuid(3a61be3b-b93b-461a-a4f8-388214f558b1)]
22 interface nsIMemoryReporterCallback : nsISupports
25 * The arguments to the callback are as follows.
28 * |process| The name of the process containing this reporter. Each
29 * reporter initially has "" in this field, indicating that it applies to the
30 * current process. (This is true even for reporters in a child process.)
31 * When a reporter from a child process is copied into the main process, the
32 * copy has its 'process' field set appropriately.
35 * |path| The path that this memory usage should be reported under. Paths
36 * are '/'-delimited, eg. "a/b/c".
38 * Each reporter can be viewed as representing a leaf node in a tree.
39 * Internal nodes of the tree don't have reporters. So, for example, the
40 * reporters "explicit/a/b", "explicit/a/c", "explicit/d/e", and
41 * "explicit/d/f" define this tree:
43 * explicit
44 * |--a
45 * | |--b [*]
46 * | \--c [*]
47 * \--d
48 * |--e [*]
49 * \--f [*]
51 * Nodes marked with a [*] have a reporter. Notice that the internal
52 * nodes are implicitly defined by the paths.
54 * Nodes within a tree should not overlap measurements, otherwise the
55 * parent node measurements will be double-counted. So in the example
56 * above, |b| should not count any allocations counted by |c|, and vice
57 * versa.
59 * All nodes within each tree must have the same units.
61 * If you want to include a '/' not as a path separator, e.g. because the
62 * path contains a URL, you need to convert each '/' in the URL to a '\'.
63 * Consumers of the path will undo this change. Any other '\' character
64 * in a path will also be changed. This is clumsy but hasn't caused any
65 * problems so far.
67 * The paths of all reporters form a set of trees. Trees can be
68 * "degenerate", i.e. contain a single entry with no '/'.
71 * |kind| There are three kinds of memory reporters.
73 * - HEAP: reporters measuring memory allocated by the heap allocator,
74 * e.g. by calling malloc, calloc, realloc, memalign, operator new, or
75 * operator new[]. Reporters in this category must have units
76 * UNITS_BYTES.
78 * - NONHEAP: reporters measuring memory which the program explicitly
79 * allocated, but does not live on the heap. Such memory is commonly
80 * allocated by calling one of the OS's memory-mapping functions (e.g.
81 * mmap, VirtualAlloc, or vm_allocate). Reporters in this category
82 * must have units UNITS_BYTES.
84 * - OTHER: reporters which don't fit into either of these categories.
85 * They can have any units.
87 * The kind only matters for reporters in the "explicit" tree;
88 * aboutMemory.js uses it to calculate "heap-unclassified".
91 * |units| The units on the reporter's amount. One of the following.
93 * - BYTES: The amount contains a number of bytes.
95 * - COUNT: The amount is an instantaneous count of things currently in
96 * existence. For instance, the number of tabs currently open would have
97 * units COUNT.
99 * - COUNT_CUMULATIVE: The amount contains the number of times some event
100 * has occurred since the application started up. For instance, the
101 * number of times the user has opened a new tab would have units
102 * COUNT_CUMULATIVE.
104 * The amount returned by a reporter with units COUNT_CUMULATIVE must
105 * never decrease over the lifetime of the application.
107 * - PERCENTAGE: The amount contains a fraction that should be expressed as
108 * a percentage. NOTE! The |amount| field should be given a value 100x
109 * the actual percentage; this number will be divided by 100 when shown.
110 * This allows a fractional percentage to be shown even though |amount| is
111 * an integer. E.g. if the actual percentage is 12.34%, |amount| should
112 * be 1234.
114 * Values greater than 100% are allowed.
117 * |amount| The numeric value reported by this memory reporter. Accesses
118 * can fail if something goes wrong when getting the amount.
121 * |description| A human-readable description of this memory usage report.
123 void callback(in ACString process, in AUTF8String path, in int32_t kind,
124 in int32_t units, in int64_t amount,
125 in AUTF8String description, in nsISupports data);
129 * An nsIMemoryReporter reports one or more memory measurements via a
130 * callback function which is called once for each measurement.
132 * An nsIMemoryReporter that reports a single measurement is sometimes called a
133 * "uni-reporter". One that reports multiple measurements is sometimes called
134 * a "multi-reporter".
136 * aboutMemory.js is the most important consumer of memory reports. It
137 * places the following constraints on reports.
139 * - All reports within a single sub-tree must have the same units.
141 * - There may be an "explicit" tree. If present, it represents
142 * non-overlapping regions of memory that have been explicitly allocated with
143 * an OS-level allocation (e.g. mmap/VirtualAlloc/vm_allocate) or a
144 * heap-level allocation (e.g. malloc/calloc/operator new). Reporters in
145 * this tree must have kind HEAP or NONHEAP, units BYTES.
147 * It is preferred, but not required, that report descriptions use complete
148 * sentences (i.e. start with a capital letter and end with a period, or
149 * similar).
151 [scriptable, uuid(0884cd0f-5829-4381-979b-0f53904030ed)]
152 interface nsIMemoryReporter : nsISupports
155 * Run the reporter.
157 void collectReports(in nsIMemoryReporterCallback callback,
158 in nsISupports data);
161 * Kinds. See the |kind| comment in nsIMemoryReporterCallback.
163 const int32_t KIND_NONHEAP = 0;
164 const int32_t KIND_HEAP = 1;
165 const int32_t KIND_OTHER = 2;
168 * Units. See the |units| comment in nsIMemoryReporterCallback.
170 const int32_t UNITS_BYTES = 0;
171 const int32_t UNITS_COUNT = 1;
172 const int32_t UNITS_COUNT_CUMULATIVE = 2;
173 const int32_t UNITS_PERCENTAGE = 3;
176 [scriptable, function, uuid(548b3909-c04d-4ca6-8466-b8bee3837457)]
177 interface nsIFinishReportingCallback : nsISupports
179 void callback(in nsISupports data);
182 [scriptable, builtinclass, uuid(e4e4ca56-13e0-46f1-b3c5-62d2c09fc98e)]
183 interface nsIMemoryReporterManager : nsISupports
186 * Initialize.
188 void init();
191 * Register the given nsIMemoryReporter. The Manager service will hold a
192 * strong reference to the given reporter, and will be responsible for freeing
193 * the reporter at shutdown. You may manually unregister the reporter with
194 * unregisterStrongReporter() at any point.
196 void registerStrongReporter(in nsIMemoryReporter reporter);
199 * Like registerReporter, but the Manager service will hold a weak reference
200 * via a raw pointer to the given reporter. The reporter should be
201 * unregistered before shutdown.
202 * You cannot register JavaScript components with this function! Always
203 * register your JavaScript components with registerStrongReporter().
205 void registerWeakReporter(in nsIMemoryReporter reporter);
208 * Unregister the given memory reporter, which must have been registered with
209 * registerStrongReporter(). You normally don't need to unregister your
210 * strong reporters, as nsIMemoryReporterManager will take care of that at
211 * shutdown.
213 void unregisterStrongReporter(in nsIMemoryReporter reporter);
216 * Unregister the given memory reporter, which must have been registered with
217 * registerWeakReporter().
219 void unregisterWeakReporter(in nsIMemoryReporter reporter);
222 * These functions should only be used for testing purposes.
224 void blockRegistrationAndHideExistingReporters();
225 void unblockRegistrationAndRestoreOriginalReporters();
226 void registerStrongReporterEvenIfBlocked(in nsIMemoryReporter aReporter);
229 * Get memory reports for the current process and all child processes.
230 * |handleReport| is called for each report, and |finishReporting| is called
231 * once all reports have been handled.
233 * |finishReporting| is called even if, for example, some child processes
234 * fail to report back. However, calls to this method will silently and
235 * immediately abort -- and |finishReporting| will not be called -- if a
236 * previous getReports() call is still in flight, i.e. if it has not yet
237 * finished invoking |finishReporting|. The silent abort is because the
238 * in-flight request will finish soon, and the caller would very likely just
239 * catch and ignore any error anyway.
241 void getReports(in nsIMemoryReporterCallback handleReport,
242 in nsISupports handleReportData,
243 in nsIFinishReportingCallback finishReporting,
244 in nsISupports finishReportingData);
247 * Get memory reports in the current process only. |handleReport| is called
248 * for each report.
250 void getReportsForThisProcess(in nsIMemoryReporterCallback handleReport,
251 in nsISupports handleReportData);
254 * The memory reporter manager, for the most part, treats reporters
255 * registered with it as a black box. However, there are some
256 * "distinguished" amounts (as could be reported by a memory reporter) that
257 * the manager provides as attributes, because they are sufficiently
258 * interesting that we want external code (e.g. telemetry) to be able to rely
259 * on them.
261 * Note that these are not reporters and so getReports() and
262 * getReportsForThisProcess() do not look at them. However, distinguished
263 * amounts can be embedded in a reporter.
265 * Access to these attributes can fail. In particular, some of them are not
266 * available on all platforms.
268 * If you add a new distinguished amount, please update
269 * toolkit/components/aboutmemory/tests/test_memoryReporters.xul.
271 * |explicit| (UNITS_BYTES) The total size of explicit memory allocations,
272 * both at the OS-level (eg. via mmap, VirtualAlloc) and at the heap level
273 * (eg. via malloc, calloc, operator new). It covers all heap allocations,
274 * but will miss any OS-level ones not covered by memory reporters.
276 * |vsize| (UNITS_BYTES) The virtual size, i.e. the amount of address space
277 * taken up.
279 * |vsizeMaxContiguous| (UNITS_BYTES) The size of the largest contiguous
280 * block of virtual memory.
282 * |resident| (UNITS_BYTES) The resident size (a.k.a. RSS or physical memory
283 * used).
285 * |residentFast| (UNITS_BYTES) This is like |resident|, but on Mac OS
286 * |resident| can purge pages, which is slow. It also affects the result of
287 * |residentFast|, and so |resident| and |residentFast| should not be used
288 * together.
290 * |heapAllocated| (UNITS_BYTES) Memory mapped by the heap allocator.
292 * |heapOverheadRatio| (UNITS_PERCENTAGE) In the heap allocator, this is the
293 * ratio of committed, unused bytes to allocated bytes. Like all
294 * UNITS_PERCENTAGE measurements, its amount is multiplied by 100x so it can
295 * be represented by an int64_t.
297 * |JSMainRuntimeGCHeap| (UNITS_BYTES) Size of the main JS runtime's GC
298 * heap.
300 * |JSMainRuntimeTemporaryPeak| (UNITS_BYTES) Peak size of the transient
301 * storage in the main JSRuntime.
303 * |JSMainRuntimeCompartments{System,User}| (UNITS_COUNT) The number of
304 * {system,user} compartments in the main JS runtime.
306 * |imagesContentUsedUncompressed| (UNITS_BYTES) Memory used for decoded
307 * images in content.
309 * |storageSQLite| (UNITS_BYTES) Memory used by SQLite.
311 * |lowMemoryEvents{Virtual,Physical}| (UNITS_COUNT_CUMULATIVE) The number
312 * of low-{virtual,physical}-memory events that have occurred since the
313 * process started.
315 * |ghostWindows| (UNITS_COUNT) The number of ghost windows.
317 * |pageFaultsHard| (UNITS_COUNT_CUMULATIVE) The number of hard (a.k.a.
318 * major) page faults that have occurred since the process started.
320 readonly attribute int64_t explicit;
321 readonly attribute int64_t vsize;
322 readonly attribute int64_t vsizeMaxContiguous;
323 readonly attribute int64_t resident;
324 readonly attribute int64_t residentFast;
326 readonly attribute int64_t heapAllocated;
327 readonly attribute int64_t heapOverheadRatio;
329 readonly attribute int64_t JSMainRuntimeGCHeap;
330 readonly attribute int64_t JSMainRuntimeTemporaryPeak;
331 readonly attribute int64_t JSMainRuntimeCompartmentsSystem;
332 readonly attribute int64_t JSMainRuntimeCompartmentsUser;
334 readonly attribute int64_t imagesContentUsedUncompressed;
336 readonly attribute int64_t storageSQLite;
338 readonly attribute int64_t lowMemoryEventsVirtual;
339 readonly attribute int64_t lowMemoryEventsPhysical;
341 readonly attribute int64_t ghostWindows;
343 readonly attribute int64_t pageFaultsHard;
346 * This attribute indicates if moz_malloc_usable_size() works.
348 [infallible] readonly attribute boolean hasMozMallocUsableSize;
351 * Run a series of GC/CC's in an attempt to minimize the application's memory
352 * usage. When we're finished, we invoke the given runnable if it's not
353 * null. Returns a reference to the runnable used for carrying out the task.
355 nsICancelableRunnable minimizeMemoryUsage(in nsIRunnable callback);
358 * Measure the memory that is known to be owned by this tab, split up into
359 * several broad categories. Note that this will be an underestimate of the
360 * true number, due to imperfect memory reporter coverage (corresponding to
361 * about:memory's "heap-unclassified"), and due to some memory shared between
362 * tabs not being counted.
364 * The time taken for the measurement (split into JS and non-JS parts) is
365 * also returned.
367 void sizeOfTab(in nsIDOMWindow window,
368 out int64_t jsObjectsSize, out int64_t jsStringsSize,
369 out int64_t jsOtherSize, out int64_t domSize,
370 out int64_t styleSize, out int64_t otherSize,
371 out int64_t totalSize,
372 out double jsMilliseconds, out double nonJSMilliseconds);
375 %{C++
377 #include "js/TypeDecls.h"
378 #include "nsStringGlue.h"
379 #include "nsTArray.h"
381 class nsPIDOMWindow;
383 // nsIHandleReportCallback is a better name, but keep nsIMemoryReporterCallback
384 // around for backwards compatibility.
385 typedef nsIMemoryReporterCallback nsIHandleReportCallback;
387 namespace mozilla {
389 // Register a memory reporter. The manager service will hold a strong
390 // reference to this reporter.
391 XPCOM_API(nsresult) RegisterStrongMemoryReporter(nsIMemoryReporter* aReporter);
393 // Register a memory reporter. The manager service will hold a weak reference
394 // to this reporter.
395 XPCOM_API(nsresult) RegisterWeakMemoryReporter(nsIMemoryReporter* aReporter);
397 // Unregister a weak memory reporter.
398 XPCOM_API(nsresult) UnregisterWeakMemoryReporter(nsIMemoryReporter* aReporter);
400 // The memory reporter manager provides access to several distinguished
401 // amounts via attributes. Some of these amounts are provided by Gecko
402 // components that cannot be accessed directly from XPCOM code. So we provide
403 // the following functions for those components to be registered with the
404 // manager.
406 typedef int64_t (*InfallibleAmountFn)();
407 typedef nsresult (*FallibleAmountFn)(int64_t* aAmount);
409 #define DECL_REGISTER_DISTINGUISHED_AMOUNT(kind, name) \
410 nsresult Register##name##DistinguishedAmount(kind##AmountFn aAmountFn);
411 #define DECL_UNREGISTER_DISTINGUISHED_AMOUNT(name) \
412 nsresult Unregister##name##DistinguishedAmount();
414 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, JSMainRuntimeGCHeap)
415 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, JSMainRuntimeTemporaryPeak)
416 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, JSMainRuntimeCompartmentsSystem)
417 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, JSMainRuntimeCompartmentsUser)
419 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, ImagesContentUsedUncompressed)
421 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, StorageSQLite)
422 DECL_UNREGISTER_DISTINGUISHED_AMOUNT(StorageSQLite)
424 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, LowMemoryEventsVirtual)
425 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, LowMemoryEventsPhysical)
427 DECL_REGISTER_DISTINGUISHED_AMOUNT(Infallible, GhostWindows)
429 #undef DECL_REGISTER_DISTINGUISHED_AMOUNT
430 #undef DECL_UNREGISTER_DISTINGUISHED_AMOUNT
432 // Likewise for per-tab measurement.
434 typedef nsresult (*JSSizeOfTabFn)(JSObject* aObj,
435 size_t* aJsObjectsSize,
436 size_t* aJsStringSize,
437 size_t* aJsPrivateSize,
438 size_t* aJsOtherSize);
439 typedef nsresult (*NonJSSizeOfTabFn)(nsPIDOMWindow* aWindow,
440 size_t* aDomSize,
441 size_t* aStyleSize,
442 size_t* aOtherSize);
444 nsresult RegisterJSSizeOfTab(JSSizeOfTabFn aSizeOfTabFn);
445 nsresult RegisterNonJSSizeOfTab(NonJSSizeOfTabFn aSizeOfTabFn);
449 #if defined(MOZ_DMD)
450 namespace mozilla {
451 namespace dmd {
452 // This runs all the memory reporters in the current process but does nothing
453 // with the results; i.e. it does the minimal amount of work possible for DMD
454 // to do its thing. It does nothing with child processes.
455 void RunReportersForThisProcess();
459 #if !defined(MOZ_MEMORY)
460 #error "MOZ_DMD requires MOZ_MEMORY"
461 #endif
463 #include "DMD.h"
465 #define MOZ_REPORT(ptr) mozilla::dmd::Report(ptr)
466 #define MOZ_REPORT_ON_ALLOC(ptr) mozilla::dmd::ReportOnAlloc(ptr)
468 #else
470 #define MOZ_REPORT(ptr)
471 #define MOZ_REPORT_ON_ALLOC(ptr)
473 #endif // defined(MOZ_DMD)
475 // Functions generated via this macro should be used by all traversal-based
476 // memory reporters. Such functions return |moz_malloc_size_of(ptr)|; this
477 // will always be zero on some obscure platforms.
479 // You might be wondering why we have a macro that creates multiple functions
480 // that differ only in their name, instead of a single MallocSizeOf function.
481 // It's mostly to help with DMD integration, though it sometimes also helps
482 // with debugging and temporary ad hoc profiling. The function name chosen
483 // doesn't matter greatly, but it's best to make it similar to the path used by
484 // the relevant memory reporter(s).
485 #define MOZ_DEFINE_MALLOC_SIZE_OF(fn) \
486 static size_t fn(const void* aPtr) \
488 MOZ_REPORT(aPtr); \
489 return moz_malloc_size_of(aPtr); \
492 // Functions generated by the next two macros should be used by wrapping
493 // allocators that report heap blocks as soon as they are allocated and
494 // unreport them as soon as they are freed. Such allocators are used in cases
495 // where we have third-party code that we cannot modify. The two functions
496 // must always be used in tandem.
497 #define MOZ_DEFINE_MALLOC_SIZE_OF_ON_ALLOC(fn) \
498 static size_t fn(const void* aPtr) \
500 MOZ_REPORT_ON_ALLOC(aPtr); \
501 return moz_malloc_size_of(aPtr); \
503 #define MOZ_DEFINE_MALLOC_SIZE_OF_ON_FREE(fn) \
504 static size_t fn(const void* aPtr) \
506 return moz_malloc_size_of(aPtr); \
509 // This macro assumes the presence of appropriate |aHandleReport| and |aData|
510 // variables.
511 #define MOZ_COLLECT_REPORT(path, kind, units, amount, description) \
512 aHandleReport->Callback(EmptyCString(), NS_LITERAL_CSTRING(path), \
513 kind, units, amount, \
514 NS_LITERAL_CSTRING(description), aData)