Bug 1052573 - Add an API for allocation in separate arenas. r=njn

The implementation is not doing anything just yet. This will be done in
a followup bug.

--HG--
extra : rebase_source : e301eac77c6bd8247c09d369074ecb8d7b5a1a2f
This commit is contained in:
Mike Hommey 2017-09-22 07:22:38 +09:00
Родитель c43db36061
Коммит 5cd3519571
9 изменённых файлов: 133 добавлений и 27 удалений

28
memory/build/fallback.cpp Normal file
Просмотреть файл

@ -0,0 +1,28 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "mozmemory.h"
#include "mozjemalloc.h"
struct SystemMalloc {
#define MALLOC_DECL(name, return_type, ...) \
static inline return_type \
name(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
{ \
return ::name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
}
#define MALLOC_FUNCS MALLOC_FUNCS_MALLOC_BASE
#include "malloc_decls.h"
};
#define MALLOC_DECL(name, return_type, ...) \
MOZ_JEMALLOC_API return_type \
name(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
{ \
return DummyArenaAllocator<SystemMalloc>::name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
}
#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
#include "malloc_decls.h"

Просмотреть файл

@ -22,13 +22,19 @@
# define MALLOC_FUNCS_JEMALLOC 4
# define MALLOC_FUNCS_INIT 8
# define MALLOC_FUNCS_BRIDGE 16
# define MALLOC_FUNCS_ARENA_BASE 32
# define MALLOC_FUNCS_ARENA_ALLOC 64
# define MALLOC_FUNCS_ARENA (MALLOC_FUNCS_ARENA_BASE | \
MALLOC_FUNCS_ARENA_ALLOC)
# define MALLOC_FUNCS_ALL (MALLOC_FUNCS_INIT | MALLOC_FUNCS_BRIDGE | \
MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC)
MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC | \
MALLOC_FUNCS_ARENA)
#endif /* malloc_decls_h */
#ifndef MALLOC_FUNCS
# define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC)
# define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC | \
MALLOC_FUNCS_ARENA)
#endif
#ifdef MALLOC_DECL
@ -101,6 +107,37 @@ MALLOC_DECL(jemalloc_thread_local_arena, void, bool)
MALLOC_DECL(jemalloc_ptr_info, void, const void*, jemalloc_ptr_info_t*)
# endif
# if MALLOC_FUNCS & MALLOC_FUNCS_ARENA_BASE
/*
* Creates a separate arena, and returns its id, valid to use with moz_arena_*
* functions.
*/
MALLOC_DECL(moz_create_arena, arena_id_t)
/*
* Dispose of the given arena. Subsequent uses of the arena will fail.
*/
MALLOC_DECL(moz_dispose_arena, void, arena_id_t)
# endif
# if MALLOC_FUNCS & MALLOC_FUNCS_ARENA_ALLOC
/*
* Same as the functions without the moz_arena_ prefix, but using arenas
* created with moz_create_arena.
* The contract, even if not enforced at runtime in some configurations,
* is that moz_arena_realloc and moz_arena_free will crash if the wrong
* arena id is given. All functions will crash if the arena id is invalid.
* Although discouraged, plain realloc and free can still be used on
* pointers allocated with these functions. Realloc will properly keep
* new pointers in the same arena as the original.
*/
MALLOC_DECL(moz_arena_malloc, void*, arena_id_t, size_t)
MALLOC_DECL(moz_arena_calloc, void*, arena_id_t, size_t, size_t)
MALLOC_DECL(moz_arena_realloc, void*, arena_id_t, void*, size_t)
MALLOC_DECL(moz_arena_free, void, arena_id_t, void*)
MALLOC_DECL(moz_arena_memalign, void*, arena_id_t, size_t, size_t)
# endif
#endif /* MALLOC_DECL */
#undef MALLOC_DECL

Просмотреть файл

@ -20,10 +20,15 @@ if CONFIG['MOZ_REPLACE_MALLOC']:
'replace_malloc_bridge.h',
]
if CONFIG['MOZ_MEMORY']:
UNIFIED_SOURCES += [
'mozjemalloc.cpp',
'mozmemory_wrap.cpp',
]
else:
UNIFIED_SOURCES += [
'fallback.cpp',
]
if CONFIG['OS_TARGET'] == 'Darwin' and (CONFIG['MOZ_REPLACE_MALLOC'] or
CONFIG['MOZ_MEMORY']):

Просмотреть файл

@ -5131,6 +5131,15 @@ MozJemalloc::jemalloc_free_dirty_pages(void)
malloc_spin_unlock(&arenas_lock);
}
#define MALLOC_DECL(name, return_type, ...) \
template<> inline return_type \
MozJemalloc::name(ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
{ \
return DummyArenaAllocator<MozJemalloc>::name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
}
#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
#include "malloc_decls.h"
/*
* End non-standard functions.
*/
@ -5327,7 +5336,6 @@ init()
} \
return replace_malloc_table.name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
}
#define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC)
#include "malloc_decls.h"
MOZ_JEMALLOC_API struct ReplaceMallocBridge*
@ -5374,6 +5382,13 @@ replace_malloc_init_funcs()
if (!replace_malloc_table.valloc && replace_malloc_table.memalign) {
replace_malloc_table.valloc = AlignedAllocator<ReplaceMalloc::memalign>::valloc;
}
if (!replace_malloc_table.moz_create_arena && replace_malloc_table.malloc) {
#define MALLOC_DECL(name, ...) \
replace_malloc_table.name = DummyArenaAllocator<ReplaceMalloc>::name;
#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
#include "malloc_decls.h"
}
#define MALLOC_DECL(name, ...) \
if (!replace_malloc_table.name) { \
replace_malloc_table.name = MozJemalloc::name; \
@ -5403,7 +5418,7 @@ replace_malloc_init_funcs()
GENERIC_MALLOC_DECL2(name, name, return_type, ##__VA_ARGS__)
#define MALLOC_DECL(...) MOZ_JEMALLOC_API MACRO_CALL(GENERIC_MALLOC_DECL, (__VA_ARGS__))
#define MALLOC_FUNCS MALLOC_FUNCS_JEMALLOC
#define MALLOC_FUNCS (MALLOC_FUNCS_JEMALLOC | MALLOC_FUNCS_ARENA)
#include "malloc_decls.h"
/******************************************************************************/

Просмотреть файл

@ -26,13 +26,14 @@
#define ARGS2(t1, t2) ARGS1(t1), arg2
#define ARGS3(t1, t2, t3) ARGS2(t1, t2), arg3
#ifdef MOZ_MEMORY
/* Generic interface exposing the whole public allocator API
* This facilitates the implementation of things like replace-malloc.
* Note: compilers are expected to be able to optimize out `this`.
*/
template <typename T>
struct Allocator: public T {
#define MALLOC_FUNCS (MALLOC_FUNCS_MALLOC | MALLOC_FUNCS_JEMALLOC)
#define MALLOC_DECL(name, return_type, ...) \
static return_type name(__VA_ARGS__);
#include "malloc_decls.h"
@ -51,3 +52,23 @@ typedef ReplaceMalloc DefaultMalloc;
#else
typedef MozJemalloc DefaultMalloc;
#endif
#endif /* MOZ_MEMORY */
/* Dummy implementation of the moz_arena_* API, falling back to a given
* implementation of the base allocator. */
template <typename T>
struct DummyArenaAllocator {
static arena_id_t moz_create_arena(void) { return 0; }
static void moz_dispose_arena(arena_id_t) { }
#define MALLOC_DECL(name, return_type, ...) \
static return_type \
moz_arena_ ## name(arena_id_t, ARGS_HELPER(TYPED_ARGS, ##__VA_ARGS__)) \
{ \
return T::name(ARGS_HELPER(ARGS, ##__VA_ARGS__)); \
}
#define MALLOC_FUNCS MALLOC_FUNCS_MALLOC_BASE
#include "malloc_decls.h"
};

Просмотреть файл

@ -50,6 +50,8 @@ extern "C" {
typedef MALLOC_USABLE_SIZE_CONST_PTR void* usable_ptr_t;
typedef size_t arena_id_t;
/*
* jemalloc_stats() is not a stable interface. When using jemalloc_stats_t, be
* sure that the compiled results of jemalloc.c are in sync with this header

Просмотреть файл

@ -16,22 +16,20 @@
* - jemalloc_ptr_info
*/
#ifndef MOZ_MEMORY
# error Should not include mozmemory.h when MOZ_MEMORY is not set
#ifdef MALLOC_H
#include MALLOC_H
#endif
#include "mozmemory_wrap.h"
#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
#include "mozjemalloc_types.h"
#ifdef MOZ_MEMORY
/*
* On OSX, malloc/malloc.h contains the declaration for malloc_good_size,
* which will call back in jemalloc, through the zone allocator so just use it.
*/
#ifdef XP_DARWIN
# include <malloc/malloc.h>
#else
#ifndef XP_DARWIN
MOZ_MEMORY_API size_t malloc_good_size_impl(size_t size);
/* Note: the MOZ_GLUE_IN_PROGRAM ifdef below is there to avoid -Werror turning
@ -54,4 +52,11 @@ static inline size_t _malloc_good_size(size_t size) {
#define MALLOC_FUNCS MALLOC_FUNCS_JEMALLOC
#include "malloc_decls.h"
#endif
#define MALLOC_DECL(name, return_type, ...) \
MOZ_JEMALLOC_API return_type name(__VA_ARGS__);
#define MALLOC_FUNCS MALLOC_FUNCS_ARENA
#include "malloc_decls.h"
#endif /* mozmemory_h */

Просмотреть файл

@ -88,10 +88,6 @@
* That implementation would call malloc by using "malloc_impl".
*/
#ifndef MOZ_MEMORY
# error Should only include mozmemory_wrap.h when MOZ_MEMORY is set.
#endif
#if defined(MOZ_MEMORY_IMPL) && !defined(IMPL_MFBT)
# ifdef MFBT_API /* mozilla/Types.h was already included */
# error mozmemory_wrap.h has to be included before mozilla/Types.h when MOZ_MEMORY_IMPL is set and IMPL_MFBT is not.

Просмотреть файл

@ -8,6 +8,7 @@ with Files("**"):
BUG_COMPONENT = ("Core", "Memory Allocator")
DIRS += [
'build',
'mozalloc',
'fallible',
]
@ -15,12 +16,8 @@ DIRS += [
if not CONFIG['JS_STANDALONE']:
DIRS += ['volatile']
if CONFIG['MOZ_MEMORY']:
# NB: gtest dir is included in toolkit/toolkit.build due to its dependency
# on libxul.
DIRS += [
'build',
]
if CONFIG['MOZ_REPLACE_MALLOC']:
DIRS += ['replace']