summaryrefslogtreecommitdiffstats
path: root/xpcom/base
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/base')
-rw-r--r--xpcom/base/CycleCollectedJSContext.h1
-rw-r--r--xpcom/base/CycleCollectedJSRuntime.cpp18
-rw-r--r--xpcom/base/CycleCollectedJSRuntime.h5
-rw-r--r--xpcom/base/DarwinObjectPtr.h144
-rw-r--r--xpcom/base/moz.build1
-rw-r--r--xpcom/base/nsCycleCollector.cpp92
-rw-r--r--xpcom/base/nsCycleCollector.h3
-rw-r--r--xpcom/base/nsICycleCollectorListener.idl3
-rw-r--r--xpcom/base/nsIDebug2.idl2
-rw-r--r--xpcom/base/nsIMacPreferencesReader.idl2
-rw-r--r--xpcom/base/nsIMemoryInfoDumper.idl8
-rw-r--r--xpcom/base/nsINIParser.cpp1
-rw-r--r--xpcom/base/nsMemoryInfoDumper.cpp2
-rw-r--r--xpcom/base/nsMemoryReporterManager.cpp63
-rw-r--r--xpcom/base/nsrootidl.idl28
15 files changed, 284 insertions, 89 deletions
diff --git a/xpcom/base/CycleCollectedJSContext.h b/xpcom/base/CycleCollectedJSContext.h
index bbe47a57a5..631afc1504 100644
--- a/xpcom/base/CycleCollectedJSContext.h
+++ b/xpcom/base/CycleCollectedJSContext.h
@@ -296,6 +296,7 @@ class CycleCollectedJSContext : dom::PerThreadAtomCache, private JS::JobQueue {
MOZ_CAN_RUN_SCRIPT_BOUNDARY
void runJobs(JSContext* cx) override;
bool empty() const override;
+ bool isDrainingStopped() const override { return false; }
class SavedMicroTaskQueue;
js::UniquePtr<SavedJobQueue> saveJobQueue(JSContext*) override;
diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp
index c3f9d56857..6833dee791 100644
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -1563,17 +1563,27 @@ void CycleCollectedJSRuntime::GarbageCollect(JS::GCOptions aOptions,
void CycleCollectedJSRuntime::JSObjectsTenured() {
JSContext* cx = CycleCollectedJSContext::Get()->Context();
- for (auto iter = mNurseryObjects.Iter(); !iter.Done(); iter.Next()) {
+
+ NurseryObjectsVector objects;
+ std::swap(objects, mNurseryObjects);
+
+ for (auto iter = objects.Iter(); !iter.Done(); iter.Next()) {
nsWrapperCache* cache = iter.Get();
JSObject* wrapper = cache->GetWrapperMaybeDead();
MOZ_DIAGNOSTIC_ASSERT(wrapper);
- if (!JS::ObjectIsTenured(wrapper)) {
+
+ if (!js::gc::IsInsideNursery(wrapper)) {
+ continue;
+ }
+
+ if (js::gc::IsDeadNurseryObject(wrapper)) {
MOZ_ASSERT(!cache->PreservingWrapper());
js::gc::FinalizeDeadNurseryObject(cx, wrapper);
+ continue;
}
- }
- mNurseryObjects.Clear();
+ mNurseryObjects.InfallibleAppend(cache);
+ }
}
void CycleCollectedJSRuntime::NurseryWrapperAdded(nsWrapperCache* aCache) {
diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h
index 6f03d3ee99..af837e1ae7 100644
--- a/xpcom/base/CycleCollectedJSRuntime.h
+++ b/xpcom/base/CycleCollectedJSRuntime.h
@@ -473,8 +473,9 @@ class CycleCollectedJSRuntime {
OOMState mLargeAllocationFailureState;
static const size_t kSegmentSize = 512;
- SegmentedVector<nsWrapperCache*, kSegmentSize, InfallibleAllocPolicy>
- mNurseryObjects;
+ using NurseryObjectsVector =
+ SegmentedVector<nsWrapperCache*, kSegmentSize, InfallibleAllocPolicy>;
+ NurseryObjectsVector mNurseryObjects;
nsTHashSet<JS::Zone*> mZonesWaitingForGC;
diff --git a/xpcom/base/DarwinObjectPtr.h b/xpcom/base/DarwinObjectPtr.h
new file mode 100644
index 0000000000..3d5842553b
--- /dev/null
+++ b/xpcom/base/DarwinObjectPtr.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2014-2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Adapted from
+// https://github.com/WebKit/WebKit/blob/ad340677c00a4b4b6a299c93a6e18cd073b3f4e9/Source/WTF/wtf/OSObjectPtr.h
+
+#ifndef mozilla_DarwinObjectPtr_h
+#define mozilla_DarwinObjectPtr_h
+
+#include <os/object.h>
+#include <utility>
+#include "mozilla/Attributes.h"
+
+// Because ARC enablement is a compile-time choice, and we compile this header
+// both ways, we need a separate copy of our code when ARC is enabled.
+#if __has_feature(objc_arc)
+# define AdoptDarwinObject AdoptDarwinObjectArc
+# define RetainDarwinObject RetainDarwinObjectArc
+# define ReleaseDarwinObject ReleaseDarwinObjectArc
+#endif
+
+namespace mozilla {
+
+template <typename>
+class DarwinObjectPtr;
+template <typename T>
+[[nodiscard]] DarwinObjectPtr<T> AdoptDarwinObject(T);
+
+template <typename T>
+static inline void RetainDarwinObject(T aPtr) {
+#if !__has_feature(objc_arc)
+ os_retain(aPtr);
+#endif
+}
+
+template <typename T>
+static inline void ReleaseDarwinObject(T aPtr) {
+#if !__has_feature(objc_arc)
+ os_release(aPtr);
+#endif
+}
+
+template <typename T>
+class DarwinObjectPtr {
+ public:
+ DarwinObjectPtr() : mPtr(nullptr) {}
+
+ ~DarwinObjectPtr() {
+ if (mPtr) {
+ ReleaseDarwinObject(mPtr);
+ }
+ }
+
+ T get() const { return mPtr; }
+
+ explicit operator bool() const { return mPtr; }
+ bool operator!() const { return !mPtr; }
+
+ DarwinObjectPtr(const DarwinObjectPtr& aOther) : mPtr(aOther.mPtr) {
+ if (mPtr) {
+ RetainDarwinObject(mPtr);
+ }
+ }
+
+ DarwinObjectPtr(DarwinObjectPtr&& aOther) : mPtr(std::move(aOther.mPtr)) {
+ aOther.mPtr = nullptr;
+ }
+
+ MOZ_IMPLICIT DarwinObjectPtr(T aPtr) : mPtr(std::move(aPtr)) {
+ if (mPtr) {
+ RetainDarwinObject(mPtr);
+ }
+ }
+
+ DarwinObjectPtr& operator=(const DarwinObjectPtr& aOther) {
+ DarwinObjectPtr ptr = aOther;
+ swap(ptr);
+ return *this;
+ }
+
+ DarwinObjectPtr& operator=(DarwinObjectPtr&& aOther) {
+ DarwinObjectPtr ptr = std::move(aOther);
+ swap(ptr);
+ return *this;
+ }
+
+ DarwinObjectPtr& operator=(std::nullptr_t) {
+ if (mPtr) {
+ ReleaseDarwinObject(mPtr);
+ }
+ mPtr = nullptr;
+ return *this;
+ }
+
+ DarwinObjectPtr& operator=(T aOther) {
+ DarwinObjectPtr ptr = std::move(aOther);
+ swap(ptr);
+ return *this;
+ }
+
+ void swap(DarwinObjectPtr& aOther) { std::swap(mPtr, aOther.mPtr); }
+
+ [[nodiscard]] T forget() { return std::exchange(mPtr, nullptr); }
+
+ friend DarwinObjectPtr AdoptDarwinObject<T>(T);
+
+ private:
+ struct AdoptDarwinObjectTag {};
+ DarwinObjectPtr(AdoptDarwinObjectTag, T aPtr) : mPtr(std::move(aPtr)) {}
+
+ T mPtr;
+};
+
+template <typename T>
+inline DarwinObjectPtr<T> AdoptDarwinObject(T aPtr) {
+ return DarwinObjectPtr<T>{typename DarwinObjectPtr<T>::AdoptDarwinObjectTag{},
+ std::move(aPtr)};
+}
+
+} // namespace mozilla
+
+#endif
diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build
index 16870a9dbc..b7779a67db 100644
--- a/xpcom/base/moz.build
+++ b/xpcom/base/moz.build
@@ -41,6 +41,7 @@ if CONFIG["OS_ARCH"] == "Darwin":
"nsObjCExceptions.h",
]
EXPORTS.mozilla += [
+ "DarwinObjectPtr.h",
"MacStringHelpers.h",
]
UNIFIED_SOURCES += [
diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp
index 9c39dee475..7908fe8037 100644
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -159,6 +159,7 @@
#include "mozilla/HashFunctions.h"
#include "mozilla/HashTable.h"
#include "mozilla/HoldDropJSObjects.h"
+#include "mozilla/Maybe.h"
/* This must occur *after* base/process_util.h to avoid typedefs conflicts. */
#include <stdint.h>
#include <stdio.h>
@@ -269,6 +270,11 @@ static void SuspectUsingNurseryPurpleBuffer(
// MOZ_CC_LOG_DIRECTORY: The directory in which logs are placed (such as
// logs from MOZ_CC_LOG_ALL and MOZ_CC_LOG_SHUTDOWN, or other uses
// of nsICycleCollectorListener)
+//
+// MOZ_CC_DISABLE_GC_LOG: If defined, don't make a GC log whenever we make a
+// cycle collector log. This can be useful for leaks that go away when shutdown
+// gets slower, when the JS heap is not involved in the leak. The default is to
+// make the GC log.
// Various parameters of this collector can be tuned using environment
// variables.
@@ -279,13 +285,15 @@ struct nsCycleCollectorParams {
bool mAllTracesAll;
bool mAllTracesShutdown;
bool mLogThisThread;
+ bool mLogGC;
int32_t mLogShutdownSkip = 0;
nsCycleCollectorParams()
: mLogAll(PR_GetEnv("MOZ_CC_LOG_ALL") != nullptr),
mLogShutdown(PR_GetEnv("MOZ_CC_LOG_SHUTDOWN") != nullptr),
mAllTracesAll(false),
- mAllTracesShutdown(false) {
+ mAllTracesShutdown(false),
+ mLogGC(!PR_GetEnv("MOZ_CC_DISABLE_GC_LOG")) {
if (const char* lssEnv = PR_GetEnv("MOZ_CC_LOG_SHUTDOWN_SKIP")) {
mLogShutdown = true;
nsDependentCString lssString(lssEnv);
@@ -352,6 +360,8 @@ struct nsCycleCollectorParams {
bool AllTracesThisCC(bool aIsShutdown) {
return mAllTracesAll || (aIsShutdown && mAllTracesShutdown);
}
+
+ bool LogThisGC() const { return mLogGC; }
};
#ifdef COLLECT_TIME_DEBUG
@@ -1376,10 +1386,12 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink {
public:
NS_DECL_ISUPPORTS
- nsCycleCollectorLogSinkToFile()
- : mProcessIdentifier(base::GetCurrentProcId()),
- mGCLog("gc-edges"),
- mCCLog("cc-edges") {}
+ explicit nsCycleCollectorLogSinkToFile(bool aLogGC)
+ : mProcessIdentifier(base::GetCurrentProcId()), mCCLog("cc-edges") {
+ if (aLogGC) {
+ mGCLog.emplace("gc-edges");
+ }
+ }
NS_IMETHOD GetFilenameIdentifier(nsAString& aIdentifier) override {
aIdentifier = mFilenameIdentifier;
@@ -1402,7 +1414,10 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink {
}
NS_IMETHOD GetGcLog(nsIFile** aPath) override {
- NS_IF_ADDREF(*aPath = mGCLog.mFile);
+ if (mGCLog.isNothing()) {
+ return NS_ERROR_UNEXPECTED;
+ }
+ NS_IF_ADDREF(*aPath = mGCLog.ref().mFile);
return NS_OK;
}
@@ -1414,13 +1429,21 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink {
NS_IMETHOD Open(FILE** aGCLog, FILE** aCCLog) override {
nsresult rv;
- if (mGCLog.mStream || mCCLog.mStream) {
+ if (mCCLog.mStream) {
return NS_ERROR_UNEXPECTED;
}
- rv = OpenLog(&mGCLog);
- NS_ENSURE_SUCCESS(rv, rv);
- *aGCLog = mGCLog.mStream;
+ if (mGCLog.isSome()) {
+ if (mGCLog.ref().mStream) {
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rv = OpenLog(&mGCLog.ref());
+ NS_ENSURE_SUCCESS(rv, rv);
+ *aGCLog = mGCLog.ref().mStream;
+ } else {
+ *aGCLog = nullptr;
+ }
rv = OpenLog(&mCCLog);
NS_ENSURE_SUCCESS(rv, rv);
@@ -1430,10 +1453,13 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink {
}
NS_IMETHOD CloseGCLog() override {
- if (!mGCLog.mStream) {
+ if (mGCLog.isNothing()) {
+ return NS_OK;
+ }
+ if (!mGCLog.ref().mStream) {
return NS_ERROR_UNEXPECTED;
}
- CloseLog(&mGCLog, u"Garbage"_ns);
+ CloseLog(&mGCLog.ref(), u"Garbage"_ns);
return NS_OK;
}
@@ -1447,9 +1473,9 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink {
private:
~nsCycleCollectorLogSinkToFile() {
- if (mGCLog.mStream) {
- MozillaUnRegisterDebugFILE(mGCLog.mStream);
- fclose(mGCLog.mStream);
+ if (mGCLog.isSome() && mGCLog.ref().mStream) {
+ MozillaUnRegisterDebugFILE(mGCLog.ref().mStream);
+ fclose(mGCLog.ref().mStream);
}
if (mCCLog.mStream) {
MozillaUnRegisterDebugFILE(mCCLog.mStream);
@@ -1566,7 +1592,7 @@ class nsCycleCollectorLogSinkToFile final : public nsICycleCollectorLogSink {
int32_t mProcessIdentifier;
nsString mFilenameIdentifier;
- FileInfo mGCLog;
+ Maybe<FileInfo> mGCLog;
FileInfo mCCLog;
};
@@ -1576,8 +1602,8 @@ class nsCycleCollectorLogger final : public nsICycleCollectorListener {
~nsCycleCollectorLogger() { ClearDescribers(); }
public:
- nsCycleCollectorLogger()
- : mLogSink(nsCycleCollector_createLogSink()),
+ explicit nsCycleCollectorLogger(bool aLogGC)
+ : mLogSink(nsCycleCollector_createLogSink(aLogGC)),
mWantAllTraces(false),
mDisableLog(false),
mWantAfterProcessing(false),
@@ -1646,13 +1672,14 @@ class nsCycleCollectorLogger final : public nsICycleCollectorListener {
rv = mLogSink->Open(&gcLog, &mCCLog);
NS_ENSURE_SUCCESS(rv, rv);
// Dump the JS heap.
- CollectorData* data = sCollectorData.get();
- if (data && data->mContext) {
- data->mContext->Runtime()->DumpJSHeap(gcLog);
+ if (gcLog) {
+ CollectorData* data = sCollectorData.get();
+ if (data && data->mContext) {
+ data->mContext->Runtime()->DumpJSHeap(gcLog);
+ }
+ rv = mLogSink->CloseGCLog();
+ NS_ENSURE_SUCCESS(rv, rv);
}
- rv = mLogSink->CloseGCLog();
- NS_ENSURE_SUCCESS(rv, rv);
-
fprintf(mCCLog, "# WantAllTraces=%s\n", mWantAllTraces ? "true" : "false");
return NS_OK;
}
@@ -1822,7 +1849,8 @@ class nsCycleCollectorLogger final : public nsICycleCollectorListener {
NS_IMPL_ISUPPORTS(nsCycleCollectorLogger, nsICycleCollectorListener)
already_AddRefed<nsICycleCollectorListener> nsCycleCollector_createLogger() {
- nsCOMPtr<nsICycleCollectorListener> logger = new nsCycleCollectorLogger();
+ nsCOMPtr<nsICycleCollectorListener> logger =
+ new nsCycleCollectorLogger(/* aLogGC = */ true);
return logger.forget();
}
@@ -3283,7 +3311,11 @@ void nsCycleCollector::SuspectNurseryEntries() {
while (gNurseryPurpleBufferEntryCount) {
NurseryPurpleBufferEntry& entry =
gNurseryPurpleBufferEntry[--gNurseryPurpleBufferEntryCount];
- mPurpleBuf.Put(entry.mPtr, entry.mParticipant, entry.mRefCnt);
+ if (!entry.mRefCnt->IsPurple() && IsIdle()) {
+ entry.mRefCnt->RemoveFromPurpleBuffer();
+ } else {
+ mPurpleBuf.Put(entry.mPtr, entry.mParticipant, entry.mRefCnt);
+ }
}
}
@@ -3628,7 +3660,7 @@ void nsCycleCollector::BeginCollection(
aManualListener = nullptr;
if (!mLogger && mParams.LogThisCC(mShutdownCount)) {
- mLogger = new nsCycleCollectorLogger();
+ mLogger = new nsCycleCollectorLogger(mParams.LogThisGC());
if (mParams.AllTracesThisCC(isShutdown)) {
mLogger->SetAllTraces();
}
@@ -3963,8 +3995,10 @@ bool nsCycleCollector_doDeferredDeletionWithBudget(js::SliceBudget& aBudget) {
return data->mCollector->FreeSnowWhiteWithBudget(aBudget);
}
-already_AddRefed<nsICycleCollectorLogSink> nsCycleCollector_createLogSink() {
- nsCOMPtr<nsICycleCollectorLogSink> sink = new nsCycleCollectorLogSinkToFile();
+already_AddRefed<nsICycleCollectorLogSink> nsCycleCollector_createLogSink(
+ bool aLogGC) {
+ nsCOMPtr<nsICycleCollectorLogSink> sink =
+ new nsCycleCollectorLogSinkToFile(aLogGC);
return sink.forget();
}
diff --git a/xpcom/base/nsCycleCollector.h b/xpcom/base/nsCycleCollector.h
index 1c583e04cf..e25647175e 100644
--- a/xpcom/base/nsCycleCollector.h
+++ b/xpcom/base/nsCycleCollector.h
@@ -49,7 +49,8 @@ void nsCycleCollector_dispatchDeferredDeletion(bool aContinuation = false,
bool nsCycleCollector_doDeferredDeletion();
bool nsCycleCollector_doDeferredDeletionWithBudget(js::SliceBudget& aBudget);
-already_AddRefed<nsICycleCollectorLogSink> nsCycleCollector_createLogSink();
+already_AddRefed<nsICycleCollectorLogSink> nsCycleCollector_createLogSink(
+ bool aLogGC);
already_AddRefed<nsICycleCollectorListener> nsCycleCollector_createLogger();
// Run a cycle collection and return whether anything was collected.
diff --git a/xpcom/base/nsICycleCollectorListener.idl b/xpcom/base/nsICycleCollectorListener.idl
index 5e0b059a13..c93f3c9174 100644
--- a/xpcom/base/nsICycleCollectorListener.idl
+++ b/xpcom/base/nsICycleCollectorListener.idl
@@ -72,8 +72,11 @@ interface nsICycleCollectorHandler : nsISupports
[scriptable, builtinclass, uuid(3ad9875f-d0e4-4ac2-87e3-f127f6c02ce1)]
interface nsICycleCollectorLogSink : nsISupports
{
+ // aGCLog can be null, if the sink was not configured to create a GC log.
[noscript] void open(out FILE aGCLog, out FILE aCCLog);
+
void closeGCLog();
+
void closeCCLog();
// This string will appear somewhere in the log's filename.
diff --git a/xpcom/base/nsIDebug2.idl b/xpcom/base/nsIDebug2.idl
index 4672fea7ea..f60a8eafa5 100644
--- a/xpcom/base/nsIDebug2.idl
+++ b/xpcom/base/nsIDebug2.idl
@@ -33,7 +33,7 @@ interface nsIDebug2 : nsISupports
* Whether a debugger is currently attached.
* Supports Windows + Mac
*/
- readonly attribute bool isDebuggerAttached;
+ readonly attribute boolean isDebuggerAttached;
/**
* Show an assertion and trigger nsIDebug2.break().
diff --git a/xpcom/base/nsIMacPreferencesReader.idl b/xpcom/base/nsIMacPreferencesReader.idl
index 470fd92ec9..29461f862a 100644
--- a/xpcom/base/nsIMacPreferencesReader.idl
+++ b/xpcom/base/nsIMacPreferencesReader.idl
@@ -22,7 +22,7 @@ interface nsIMacPreferencesReader : nsISupports
*
* @return true if macOS policies are enabled, false otherwise.
*/
- bool policiesEnabled();
+ boolean policiesEnabled();
/**
* This method reads and returns the macOS preferences.
diff --git a/xpcom/base/nsIMemoryInfoDumper.idl b/xpcom/base/nsIMemoryInfoDumper.idl
index 79b03a709d..83290b57ab 100644
--- a/xpcom/base/nsIMemoryInfoDumper.idl
+++ b/xpcom/base/nsIMemoryInfoDumper.idl
@@ -36,7 +36,7 @@ interface nsIDumpGCAndCCLogsCallback : nsISupports
*/
void onDump(in nsIFile aGCLog,
in nsIFile aCCLog,
- in bool aIsParent);
+ in boolean aIsParent);
/**
* Called when GC/CC logging has finished, after all calls to |onDump|.
@@ -153,8 +153,8 @@ interface nsIMemoryInfoDumper : nsISupports
*
*/
void dumpGCAndCCLogsToFile(in AString aIdentifier,
- in bool aDumpAllTraces,
- in bool aDumpChildProcesses,
+ in boolean aDumpAllTraces,
+ in boolean aDumpChildProcesses,
in nsIDumpGCAndCCLogsCallback aCallback);
/**
@@ -162,6 +162,6 @@ interface nsIMemoryInfoDumper : nsISupports
* sink object instead of accessing the filesystem directly, and
* dumps the current process only.
*/
- void dumpGCAndCCLogsToSink(in bool aDumpAllTraces,
+ void dumpGCAndCCLogsToSink(in boolean aDumpAllTraces,
in nsICycleCollectorLogSink aSink);
};
diff --git a/xpcom/base/nsINIParser.cpp b/xpcom/base/nsINIParser.cpp
index 1447aa6fbf..df3f1fcc0d 100644
--- a/xpcom/base/nsINIParser.cpp
+++ b/xpcom/base/nsINIParser.cpp
@@ -243,7 +243,6 @@ nsresult nsINIParser::DeleteString(const char* aSection, const char* aKey) {
mSections.Remove(aSection);
} else {
mSections.InsertOrUpdate(aSection, std::move(val->next));
- delete val;
}
return NS_OK;
}
diff --git a/xpcom/base/nsMemoryInfoDumper.cpp b/xpcom/base/nsMemoryInfoDumper.cpp
index 28af408178..433919146a 100644
--- a/xpcom/base/nsMemoryInfoDumper.cpp
+++ b/xpcom/base/nsMemoryInfoDumper.cpp
@@ -323,7 +323,7 @@ nsMemoryInfoDumper::DumpGCAndCCLogsToFile(
for (uint32_t i = 0; i < children.Length(); i++) {
ContentParent* cp = children[i];
nsCOMPtr<nsICycleCollectorLogSink> logSink =
- nsCycleCollector_createLogSink();
+ nsCycleCollector_createLogSink(/* aLogGC = */ true);
logSink->SetFilenameIdentifier(identifier);
logSink->SetProcessIdentifier(cp->Pid());
diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp
index aaf1baeea2..a3a2a247f6 100644
--- a/xpcom/base/nsMemoryReporterManager.cpp
+++ b/xpcom/base/nsMemoryReporterManager.cpp
@@ -1247,7 +1247,7 @@ NS_IMPL_ISUPPORTS(PageFaultsHardReporter, nsIMemoryReporter)
#ifdef HAVE_JEMALLOC_STATS
static size_t HeapOverhead(const jemalloc_stats_t& aStats) {
- return aStats.waste + aStats.bookkeeping + aStats.page_cache +
+ return aStats.waste + aStats.bookkeeping + aStats.pages_dirty +
aStats.bin_unused;
}
@@ -1278,7 +1278,7 @@ class JemallocHeapReporter final : public nsIMemoryReporter {
// clang-format off
MOZ_COLLECT_REPORT(
- "heap-committed/allocated", KIND_OTHER, UNITS_BYTES, stats.allocated,
+ "heap/committed/allocated", KIND_OTHER, UNITS_BYTES, stats.allocated,
"Memory mapped by the heap allocator that is currently allocated to the "
"application. This may exceed the amount of memory requested by the "
"application because the allocator regularly rounds up request sizes. (The "
@@ -1286,14 +1286,14 @@ class JemallocHeapReporter final : public nsIMemoryReporter {
MOZ_COLLECT_REPORT(
"heap-allocated", KIND_OTHER, UNITS_BYTES, stats.allocated,
-"The same as 'heap-committed/allocated'.");
+"The same as 'heap/committed/allocated'.");
- // We mark this and the other heap-overhead reporters as KIND_NONHEAP
+ // We mark this and the other heap/committed/overhead reporters as KIND_NONHEAP
// because KIND_HEAP memory means "counted in heap-allocated", which
// this is not.
for (auto& bin : bin_stats) {
MOZ_ASSERT(bin.size);
- nsPrintfCString path("explicit/heap-overhead/bin-unused/bin-%zu",
+ nsPrintfCString path("heap/committed/bin-unused/bin-%zu",
bin.size);
aHandleReport->Callback(EmptyCString(), path, KIND_NONHEAP, UNITS_BYTES,
bin.bytes_unused,
@@ -1304,36 +1304,63 @@ class JemallocHeapReporter final : public nsIMemoryReporter {
if (stats.waste > 0) {
MOZ_COLLECT_REPORT(
- "explicit/heap-overhead/waste", KIND_NONHEAP, UNITS_BYTES,
+ "heap/committed/waste", KIND_NONHEAP, UNITS_BYTES,
stats.waste,
"Committed bytes which do not correspond to an active allocation and which the "
"allocator is not intentionally keeping alive (i.e., not "
-"'explicit/heap-overhead/{bookkeeping,page-cache,bin-unused}').");
+"'heap/{bookkeeping,unused-pages,bin-unused}').");
}
MOZ_COLLECT_REPORT(
- "explicit/heap-overhead/bookkeeping", KIND_NONHEAP, UNITS_BYTES,
+ "heap/committed/bookkeeping", KIND_NONHEAP, UNITS_BYTES,
stats.bookkeeping,
"Committed bytes which the heap allocator uses for internal data structures.");
MOZ_COLLECT_REPORT(
- "explicit/heap-overhead/page-cache", KIND_NONHEAP, UNITS_BYTES,
- stats.page_cache,
+ "heap/committed/unused-pages/dirty", KIND_NONHEAP, UNITS_BYTES,
+ stats.pages_dirty,
"Memory which the allocator could return to the operating system, but hasn't. "
"The allocator keeps this memory around as an optimization, so it doesn't "
"have to ask the OS the next time it needs to fulfill a request. This value "
"is typically not larger than a few megabytes.");
MOZ_COLLECT_REPORT(
- "heap-committed/overhead", KIND_OTHER, UNITS_BYTES,
- HeapOverhead(stats),
-"The sum of 'explicit/heap-overhead/*'.");
+ "heap/decommitted/unused-pages/fresh", KIND_OTHER, UNITS_BYTES, stats.pages_fresh,
+"Amount of memory currently mapped but has never been used.");
+ // A duplicate entry in the decommitted part of the tree.
+ MOZ_COLLECT_REPORT(
+ "decommitted/heap/unused-pages/fresh", KIND_OTHER, UNITS_BYTES, stats.pages_fresh,
+"Amount of memory currently mapped but has never been used.");
+// On MacOS madvised memory is still counted in the resident set until the OS
+// actually decommits it.
+#ifdef XP_MACOSX
+#define MADVISED_GROUP "committed"
+#else
+#define MADVISED_GROUP "decommitted"
+#endif
+ MOZ_COLLECT_REPORT(
+ "heap/" MADVISED_GROUP "/unused-pages/madvised", KIND_OTHER, UNITS_BYTES,
+ stats.pages_madvised,
+"Amount of memory currently mapped, not used and that the OS should remove "
+"from the application's resident set.");
+ // A duplicate entry in the decommitted part of the tree.
MOZ_COLLECT_REPORT(
- "heap-mapped", KIND_OTHER, UNITS_BYTES, stats.mapped,
-"Amount of memory currently mapped. Includes memory that is uncommitted, i.e. "
-"neither in physical memory nor paged to disk.");
+ "decommitted/heap/unused-pages/madvised", KIND_OTHER, UNITS_BYTES, stats.pages_madvised,
+"Amount of memory currently mapped, not used and that the OS should remove "
+"from the application's resident set.");
+ {
+ size_t decommitted = stats.mapped - stats.allocated - stats.waste - stats.pages_dirty - stats.pages_fresh - stats.bookkeeping - stats.bin_unused;
+ MOZ_COLLECT_REPORT(
+ "heap/decommitted/unmapped", KIND_OTHER, UNITS_BYTES, decommitted,
+ "Amount of memory currently mapped but not committed, "
+ "neither in physical memory nor paged to disk.");
+ MOZ_COLLECT_REPORT(
+ "decommitted/heap/decommitted", KIND_OTHER, UNITS_BYTES, decommitted,
+ "Amount of memory currently mapped but not committed, "
+ "neither in physical memory nor paged to disk.");
+ }
MOZ_COLLECT_REPORT(
"heap-chunksize", KIND_OTHER, UNITS_BYTES, stats.chunksize,
"Size of chunks.");
@@ -1343,11 +1370,11 @@ class JemallocHeapReporter final : public nsIMemoryReporter {
mozilla::phc::PHCMemoryUsage(usage);
MOZ_COLLECT_REPORT(
- "explicit/heap-overhead/phc/metadata", KIND_NONHEAP, UNITS_BYTES,
+ "explicit/phc/metadata", KIND_NONHEAP, UNITS_BYTES,
usage.mMetadataBytes,
"Memory used by PHC to store stacks and other metadata for each allocation");
MOZ_COLLECT_REPORT(
- "explicit/heap-overhead/phc/fragmentation", KIND_NONHEAP, UNITS_BYTES,
+ "explicit/phc/fragmentation", KIND_NONHEAP, UNITS_BYTES,
usage.mFragmentationBytes,
"The amount of memory lost due to rounding up allocations to the next page "
"size. "
diff --git a/xpcom/base/nsrootidl.idl b/xpcom/base/nsrootidl.idl
index 292ea54890..364d0b75eb 100644
--- a/xpcom/base/nsrootidl.idl
+++ b/xpcom/base/nsrootidl.idl
@@ -11,7 +11,6 @@
#include "nscore.h"
#include "nsID.h"
-typedef int64_t PRTime;
/*
* Forward declarations for new string types
@@ -29,27 +28,9 @@ class Promise;
} // namespace dom
} // namespace mozilla
-/*
- * Start commenting out the C++ versions of the below in the output header
- */
-#if 0
%}
-// [substitute] typedefs emit the underlying builtin type directly, and
-// avoid polluting bindings for other languages with C++ stdint types.
-
-[substitute] typedef boolean bool ;
-[substitute] typedef octet uint8_t ;
-[substitute] typedef unsigned short uint16_t ;
-[substitute] typedef unsigned long uint32_t ;
-[substitute] typedef unsigned long long uint64_t ;
-[substitute] typedef short int16_t ;
-[substitute] typedef long int32_t ;
-[substitute] typedef long long int64_t ;
-
- typedef unsigned short char16_t ;
- typedef unsigned long nsresult ;
- typedef long long PRTime ;
+typedef long long PRTime;
// If we ever want to use `size_t` in scriptable interfaces, this will need to
// be built into the xpidl compiler, as the size varies based on platform.
@@ -99,10 +80,3 @@ class Promise;
native jsid(jsid);
[ptr, promise] native Promise(ignored);
-
-%{C++
-/*
- * End commenting out the C++ versions of the above in the output header
- */
-#endif
-%}