зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1814798 - pt 2. Add a PHCManager component to control PHC r=glandium,emilio
This change adds the PHCManager class which observes a pref to control PHC. The pref can be changed at runtime and will affect the parent and content processes. Differential Revision: https://phabricator.services.mozilla.com/D178754
This commit is contained in:
Родитель
accac535a0
Коммит
cda96811f8
|
@ -324,7 +324,7 @@ static const size_t kAllPagesSize = kNumAllPages * kPageSize;
|
|||
static const size_t kAllPagesJemallocSize = kAllPagesSize - kPageSize;
|
||||
|
||||
// The default state for PHC. Either Enabled or OnlyFree.
|
||||
#define DEFAULT_STATE mozilla::phc::Enabled
|
||||
#define DEFAULT_STATE mozilla::phc::OnlyFree
|
||||
|
||||
// The junk value used to fill new allocation in debug builds. It's same value
|
||||
// as the one used by mozjemalloc. PHC applies it unconditionally in debug
|
||||
|
@ -1399,8 +1399,6 @@ MOZ_ALWAYS_INLINE static void* PageRealloc(const Maybe<arena_id_t>& aArenaId,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aNewSize > kPageSize);
|
||||
|
||||
Delay reuseDelay = ReuseDelay(lock);
|
||||
|
||||
// Copy the usable size rather than the requested size, because the user
|
||||
|
|
|
@ -49,6 +49,8 @@ static const size_t kPageSize = 4096;
|
|||
|
||||
TEST(PHC, TestPHCAllocations)
|
||||
{
|
||||
ReplaceMalloc::SetPHCState(phc::PHCState::Enabled);
|
||||
|
||||
// First, check that allocations of various sizes all get put at the end of
|
||||
// their page as expected. Also, check their sizes are as expected.
|
||||
|
||||
|
@ -259,6 +261,8 @@ static void TestFreedAllocation(uint8_t* aPtr, size_t aSize) {
|
|||
|
||||
TEST(PHC, TestPHCInfo)
|
||||
{
|
||||
ReplaceMalloc::SetPHCState(phc::PHCState::Enabled);
|
||||
|
||||
int stackVar;
|
||||
phc::AddrInfo phcInfo;
|
||||
|
||||
|
@ -289,8 +293,10 @@ TEST(PHC, TestPHCInfo)
|
|||
// possible to reliably get ahold of such a page.
|
||||
}
|
||||
|
||||
TEST(PHC, TestPHCDisabling)
|
||||
TEST(PHC, TestPHCDisablingThread)
|
||||
{
|
||||
ReplaceMalloc::SetPHCState(phc::PHCState::Enabled);
|
||||
|
||||
uint8_t* p = GetPHCAllocation(32);
|
||||
uint8_t* q = GetPHCAllocation(32);
|
||||
if (!p || !q) {
|
||||
|
@ -329,6 +335,49 @@ TEST(PHC, TestPHCDisabling)
|
|||
free(s);
|
||||
}
|
||||
|
||||
TEST(PHC, TestPHCDisablingGlobal)
|
||||
{
|
||||
ReplaceMalloc::SetPHCState(phc::PHCState::Enabled);
|
||||
|
||||
uint8_t* p1 = GetPHCAllocation(32);
|
||||
uint8_t* p2 = GetPHCAllocation(32);
|
||||
uint8_t* q = GetPHCAllocation(32);
|
||||
if (!p1 || !p2 || !q) {
|
||||
MOZ_CRASH("failed to get a PHC allocation");
|
||||
}
|
||||
|
||||
ReplaceMalloc::SetPHCState(phc::PHCState::OnlyFree);
|
||||
|
||||
// Test realloc() on a PHC allocation while PHC is disabled on the thread.
|
||||
uint8_t* p3 = (uint8_t*)realloc(p1, 128);
|
||||
// The small realloc is evicted from PHC because in "OnlyFree" state PHC
|
||||
// tries to reduce its memory impact.
|
||||
ASSERT_TRUE(p3 != p1);
|
||||
ASSERT_FALSE(ReplaceMalloc::IsPHCAllocation(p3, nullptr));
|
||||
free(p3);
|
||||
uint8_t* p4 = (uint8_t*)realloc(p2, 8192);
|
||||
// The big realloc is not in-place, and the result is not a PHC
|
||||
// allocation, regardless of PHC's state.
|
||||
ASSERT_TRUE(p4 != p2);
|
||||
ASSERT_FALSE(ReplaceMalloc::IsPHCAllocation(p4, nullptr));
|
||||
free(p4);
|
||||
|
||||
// Test free() on a PHC allocation while PHC is disabled on the thread.
|
||||
free(q);
|
||||
|
||||
// These must not be PHC allocations.
|
||||
uint8_t* r = GetPHCAllocation(32); // This will fail.
|
||||
ASSERT_FALSE(!!r);
|
||||
|
||||
ReplaceMalloc::SetPHCState(phc::PHCState::Enabled);
|
||||
|
||||
// If it really was reenabled we should be able to get PHC allocations
|
||||
// again.
|
||||
uint8_t* s = GetPHCAllocation(32); // This should succeed.
|
||||
ASSERT_TRUE(!!s);
|
||||
free(s);
|
||||
}
|
||||
|
||||
// This test is disabled for now, see Bug 1845017 and Bug 1845655.
|
||||
// TEST(PHC, TestPHCExhaustion)
|
||||
// {
|
||||
|
|
|
@ -10959,6 +10959,19 @@
|
|||
mirror: always
|
||||
#endif
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Prefs starting with "memory."
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
- name: memory.phc.enabled
|
||||
type: bool
|
||||
#if defined(MOZ_PHC)
|
||||
value: true
|
||||
#else
|
||||
value: false
|
||||
#endif
|
||||
mirror: always
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Prefs starting with "midi."
|
||||
#---------------------------------------------------------------------------
|
||||
|
|
|
@ -62,6 +62,7 @@ pref_groups = [
|
|||
"layout",
|
||||
"mathml",
|
||||
"media",
|
||||
"memory",
|
||||
"midi",
|
||||
"mousewheel",
|
||||
"mozilla",
|
||||
|
@ -172,3 +173,6 @@ else:
|
|||
FINAL_TARGET_PP_FILES += [
|
||||
"greprefs.js",
|
||||
]
|
||||
|
||||
if CONFIG["MOZ_PHC"]:
|
||||
DEFINES["MOZ_PHC"] = True
|
||||
|
|
|
@ -7,6 +7,7 @@ export var CrashTestUtils = {
|
|||
dumpHasStream: null,
|
||||
dumpHasInstructionPointerMemory: null,
|
||||
dumpWin64CFITestSymbols: null,
|
||||
enablePHC: null,
|
||||
|
||||
// Constants for crash()
|
||||
// Keep these in sync with nsTestCrasher.cpp!
|
||||
|
@ -61,6 +62,11 @@ CrashTestUtils.saveAppMemory = lib.declare(
|
|||
ctypes.default_abi,
|
||||
ctypes.uint64_t
|
||||
);
|
||||
CrashTestUtils.enablePHC = lib.declare(
|
||||
"EnablePHC",
|
||||
ctypes.default_abi,
|
||||
ctypes.void_t
|
||||
);
|
||||
|
||||
try {
|
||||
CrashTestUtils.TryOverrideExceptionHandler = lib.declare(
|
||||
|
|
|
@ -323,6 +323,12 @@ extern "C" NS_EXPORT void Crash(int16_t how) {
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT void EnablePHC() {
|
||||
#ifdef MOZ_PHC
|
||||
ReplaceMalloc::SetPHCState(mozilla::phc::PHCState::Enabled);
|
||||
#endif
|
||||
};
|
||||
|
||||
char testData[32];
|
||||
|
||||
extern "C" NS_EXPORT uint64_t SaveAppMemory() {
|
||||
|
|
|
@ -27,3 +27,6 @@ const { CrashTestUtils } = ChromeUtils.importESModule(
|
|||
);
|
||||
var crashType = CrashTestUtils.CRASH_INVALID_POINTER_DEREF;
|
||||
var shouldDelay = false;
|
||||
|
||||
// Turn PHC on so that the PHC tests work.
|
||||
CrashTestUtils.enablePHC();
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PHCManager.h"
|
||||
|
||||
#include "replace_malloc_bridge.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/StaticPrefs_memory.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace phc;
|
||||
|
||||
static const char kPHCPref[] = "memory.phc.enabled";
|
||||
|
||||
static PHCState GetPHCStateFromPref() {
|
||||
return StaticPrefs::memory_phc_enabled() ? Enabled : OnlyFree;
|
||||
}
|
||||
|
||||
static void PrefChangeCallback(const char* aPrefName, void* aNull) {
|
||||
MOZ_ASSERT(0 == strcmp(aPrefName, kPHCPref));
|
||||
|
||||
ReplaceMalloc::SetPHCState(GetPHCStateFromPref());
|
||||
}
|
||||
|
||||
void InitPHCState() {
|
||||
ReplaceMalloc::SetPHCState(GetPHCStateFromPref());
|
||||
|
||||
Preferences::RegisterCallback(PrefChangeCallback, kPHCPref);
|
||||
}
|
||||
|
||||
}; // namespace mozilla
|
|
@ -0,0 +1,18 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_PHCManager_h
|
||||
#define mozilla_PHCManager_h
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Read the PHC pref and potentially initialise PHC. Also register a
|
||||
// callback for the pref to update PHC as the pref changes.
|
||||
void InitPHCState();
|
||||
|
||||
}; // namespace mozilla
|
||||
|
||||
#endif // mozilla_PHCManager_h
|
|
@ -257,3 +257,15 @@ LOCAL_INCLUDES += [
|
|||
|
||||
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
|
||||
CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]
|
||||
|
||||
if CONFIG["MOZ_PHC"]:
|
||||
EXPORTS.mozilla += [
|
||||
"PHCManager.h",
|
||||
]
|
||||
|
||||
DEFINES["MOZ_PHC"] = 1
|
||||
|
||||
UNIFIED_SOURCES += ["PHCManager.cpp"]
|
||||
|
||||
with Files("PHCManager.*"):
|
||||
BUG_COMPONENT = ("Core", "Memory Allocator")
|
||||
|
|
|
@ -89,6 +89,9 @@
|
|||
#include "mozilla/AvailableMemoryTracker.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/CountingAllocatorBase.h"
|
||||
#ifdef MOZ_PHC
|
||||
# include "mozilla/PHCManager.h"
|
||||
#endif
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/ServoStyleConsts.h"
|
||||
|
||||
|
@ -448,6 +451,12 @@ NS_InitXPCOM(nsIServiceManager** aResult, nsIFile* aBinDirectory,
|
|||
NS_ADDREF(*aResult = nsComponentManagerImpl::gComponentManager);
|
||||
}
|
||||
|
||||
#ifdef MOZ_PHC
|
||||
// This is the earliest possible moment we can start PHC while still being
|
||||
// able to read prefs.
|
||||
mozilla::InitPHCState();
|
||||
#endif
|
||||
|
||||
// After autoreg, but before we actually instantiate any components,
|
||||
// add any services listed in the "xpcom-directory-providers" category
|
||||
// to the directory service.
|
||||
|
|
|
@ -103,3 +103,6 @@ if CONFIG["MOZ_VPX"]:
|
|||
LOCAL_INCLUDES += [
|
||||
"/media/libvpx",
|
||||
]
|
||||
|
||||
if CONFIG["MOZ_PHC"]:
|
||||
DEFINES["MOZ_PHC"] = 1
|
||||
|
|
Загрузка…
Ссылка в новой задаче