mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1815069 - Make it possible to tweak mozjemalloc's max dirty page sizes dynamically, r=glandium,pbone
Differential Revision: https://phabricator.services.mozilla.com/D168900
This commit is contained in:
parent
94b151e6ac
commit
c1c5ec3417
@ -121,6 +121,12 @@ MALLOC_DECL(moz_create_arena_with_params, arena_id_t, arena_params_t*)
|
||||
// Passing an invalid id (inexistent or already disposed) to this function
|
||||
// will crash. The arena must be empty prior to calling this function.
|
||||
MALLOC_DECL(moz_dispose_arena, void, arena_id_t)
|
||||
|
||||
// Set the default modifier for mMaxDirty. The value is the number of shifts
|
||||
// applied to the value. Positive value is handled as <<, negative >>.
|
||||
// Arenas may override the default modifier.
|
||||
MALLOC_DECL(moz_set_max_dirty_page_modifier, void, int32_t)
|
||||
|
||||
# endif
|
||||
|
||||
# if MALLOC_FUNCS & MALLOC_FUNCS_ARENA_ALLOC
|
||||
|
@ -1138,6 +1138,9 @@ struct arena_t {
|
||||
// Maximum value allowed for mNumDirty.
|
||||
size_t mMaxDirty;
|
||||
|
||||
int32_t mMaxDirtyIncreaseOverride;
|
||||
int32_t mMaxDirtyDecreaseOverride;
|
||||
|
||||
private:
|
||||
// Size/address-ordered tree of this arena's available runs. This tree
|
||||
// is used for first-best-fit run allocation.
|
||||
@ -1290,6 +1293,11 @@ class ArenaCollection {
|
||||
delete aArena;
|
||||
}
|
||||
|
||||
void SetDefaultMaxDirtyPageModifier(int32_t aModifier) {
|
||||
mDefaultMaxDirtyPageModifier = aModifier;
|
||||
}
|
||||
int32_t DefaultMaxDirtyPageModifier() { return mDefaultMaxDirtyPageModifier; }
|
||||
|
||||
using Tree = RedBlackTree<arena_t, ArenaTreeTrait>;
|
||||
|
||||
struct Iterator : Tree::Iterator {
|
||||
@ -1328,6 +1336,7 @@ class ArenaCollection {
|
||||
arena_id_t mLastPublicArenaId;
|
||||
Tree mArenas;
|
||||
Tree mPrivateArenas;
|
||||
Atomic<int32_t> mDefaultMaxDirtyPageModifier;
|
||||
};
|
||||
|
||||
static ArenaCollection gArenas;
|
||||
@ -2760,8 +2769,20 @@ arena_run_t* arena_t::AllocRun(size_t aSize, bool aLarge, bool aZero) {
|
||||
void arena_t::Purge(bool aAll) {
|
||||
arena_chunk_t* chunk;
|
||||
size_t i, npages;
|
||||
|
||||
int32_t modifier = gArenas.DefaultMaxDirtyPageModifier();
|
||||
if (modifier) {
|
||||
int32_t arenaOverride =
|
||||
modifier > 0 ? mMaxDirtyIncreaseOverride : mMaxDirtyDecreaseOverride;
|
||||
if (arenaOverride) {
|
||||
modifier = arenaOverride;
|
||||
}
|
||||
}
|
||||
|
||||
// If all is set purge all dirty pages.
|
||||
size_t dirty_max = aAll ? 1 : mMaxDirty;
|
||||
size_t dirty_max = aAll ? 1
|
||||
: modifier >= 0 ? mMaxDirty << modifier
|
||||
: mMaxDirty >> -modifier;
|
||||
#ifdef MOZ_DEBUG
|
||||
size_t ndirty = 0;
|
||||
for (auto chunk : mChunksDirty.iter()) {
|
||||
@ -3884,7 +3905,14 @@ arena_t::arena_t(arena_params_t* aParams, bool aIsPrivate) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mMaxDirtyIncreaseOverride = aParams->mMaxDirtyIncreaseOverride;
|
||||
mMaxDirtyDecreaseOverride = aParams->mMaxDirtyDecreaseOverride;
|
||||
} else {
|
||||
mMaxDirtyIncreaseOverride = 0;
|
||||
mMaxDirtyDecreaseOverride = 0;
|
||||
}
|
||||
|
||||
mPRNG = nullptr;
|
||||
|
||||
mIsPrivate = aIsPrivate;
|
||||
@ -4837,6 +4865,11 @@ inline void MozJemalloc::moz_dispose_arena(arena_id_t aArenaId) {
|
||||
gArenas.DisposeArena(arena);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void MozJemalloc::moz_set_max_dirty_page_modifier(int32_t aModifier) {
|
||||
gArenas.SetDefaultMaxDirtyPageModifier(aModifier);
|
||||
}
|
||||
|
||||
#define MALLOC_DECL(name, return_type, ...) \
|
||||
template <> \
|
||||
inline return_type MozJemalloc::moz_arena_##name( \
|
||||
|
@ -65,6 +65,8 @@ struct DummyArenaAllocator {
|
||||
|
||||
static void moz_dispose_arena(arena_id_t) {}
|
||||
|
||||
static void moz_set_max_dirty_page_modifier(int32_t) {}
|
||||
|
||||
#define MALLOC_DECL(name, return_type, ...) \
|
||||
static return_type moz_arena_##name( \
|
||||
arena_id_t, ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) { \
|
||||
|
@ -65,10 +65,22 @@ typedef size_t arena_id_t;
|
||||
|
||||
typedef struct arena_params_s {
|
||||
size_t mMaxDirty;
|
||||
// Arena specific modifiers which override the value passed to
|
||||
// moz_set_max_dirty_page_modifier. If value > 0 is passed to that function,
|
||||
// and mMaxDirtyIncreaseOverride != 0, mMaxDirtyIncreaseOverride will be used
|
||||
// instead, and similarly if value < 0 is passed and mMaxDirtyDecreaseOverride
|
||||
// != 0, mMaxDirtyDecreaseOverride will be used as the modifier.
|
||||
int32_t mMaxDirtyIncreaseOverride;
|
||||
int32_t mMaxDirtyDecreaseOverride;
|
||||
|
||||
uint32_t mFlags;
|
||||
|
||||
#ifdef __cplusplus
|
||||
arena_params_s() : mMaxDirty(0), mFlags(0) {}
|
||||
arena_params_s()
|
||||
: mMaxDirty(0),
|
||||
mMaxDirtyIncreaseOverride(0),
|
||||
mMaxDirtyDecreaseOverride(0),
|
||||
mFlags(0) {}
|
||||
#endif
|
||||
} arena_params_t;
|
||||
|
||||
|
@ -1454,6 +1454,11 @@ void replace_moz_dispose_arena(arena_id_t aArenaId) {
|
||||
return sMallocTable.moz_dispose_arena(aArenaId);
|
||||
}
|
||||
|
||||
void replace_moz_set_max_dirty_page_modifier(int32_t aModifier) {
|
||||
// No need to do anything special here.
|
||||
return sMallocTable.moz_set_max_dirty_page_modifier(aModifier);
|
||||
}
|
||||
|
||||
void* replace_moz_arena_malloc(arena_id_t aArenaId, size_t aReqSize) {
|
||||
return PageMalloc(Some(aArenaId), aReqSize);
|
||||
}
|
||||
|
@ -550,6 +550,10 @@ static void replace_moz_dispose_arena(arena_id_t aArenaId) {
|
||||
return gMallocTable.moz_dispose_arena(aArenaId);
|
||||
}
|
||||
|
||||
static void replace_moz_set_max_dirty_page_modifier(int32_t aModifier) {
|
||||
return gMallocTable.moz_set_max_dirty_page_modifier(aModifier);
|
||||
}
|
||||
|
||||
// Must come after all the replace_* funcs
|
||||
void replace_init(malloc_table_t* aMallocTable, ReplaceMallocBridge** aBridge) {
|
||||
gMallocTable = *aMallocTable;
|
||||
|
Loading…
Reference in New Issue
Block a user