Bug 1368932 - Handle missing replace_posix_memalign at the replace-malloc level. r=njn

Replace-malloc libraries, such as DMD, don't really need to care about
the details of implementing all the variants of aligned memory
allocation functions. Currently, by defining MOZ_REPLACE_ONLY_MEMALIGN
before including replace_malloc.h, they get predefined functions.

Instead of making that an opt-in at build time, we make the
replace-malloc initialization just fill the replace-malloc
malloc_table_t with implementations that rely on the replace_memalign
the library provides.

--HG--
extra : rebase_source : 0842a67d9bc27a9a86c33d14d98b9c25f39982fb
This commit is contained in:
Mike Hommey 2017-05-31 13:47:17 +09:00
parent 7fd2c94e79
commit 4ae1509807
3 changed files with 57 additions and 63 deletions

View File

@ -19,6 +19,10 @@
#include "mozilla/Likely.h"
#include "mozilla/MacroArgs.h"
#include <errno.h>
#ifndef XP_WIN
#include <unistd.h>
#endif
/*
* Windows doesn't come with weak imports as they are possible with
@ -210,6 +214,50 @@ MOZ_MEMORY_API __memalign_hook_type __memalign_hook = memalign_impl;
#endif
/*
* posix_memalign, aligned_alloc, memalign and valloc all implement some kind
* of aligned memory allocation. For convenience, a replace-malloc library can
* skip defining replace_posix_memalign, replace_aligned_alloc and
* replace_valloc, and default implementations will be automatically derived
* from replace_memalign.
*/
static int
default_posix_memalign(void** ptr, size_t alignment, size_t size)
{
if (size == 0) {
*ptr = NULL;
return 0;
}
/* alignment must be a power of two and a multiple of sizeof(void *) */
if (((alignment - 1) & alignment) != 0 || (alignment % sizeof(void *)))
return EINVAL;
*ptr = replace_malloc_table.memalign(alignment, size);
return *ptr ? 0 : ENOMEM;
}
static void*
default_aligned_alloc(size_t alignment, size_t size)
{
/* size should be a multiple of alignment */
if (size % alignment)
return NULL;
return replace_malloc_table.memalign(alignment, size);
}
// Nb: sysconf() is expensive, but valloc is obsolete and rarely used.
static void*
default_valloc(size_t size)
{
#ifdef XP_WIN
SYSTEM_INFO si;
GetSystemInfo(&si);
size_t page_size = si.dwPageSize;
#else
size_t page_size = sysconf(_SC_PAGE_SIZE);
#endif
return replace_malloc_table.memalign(page_size, size);
}
static void
replace_malloc_init_funcs()
{
@ -228,6 +276,15 @@ replace_malloc_init_funcs()
#include "malloc_decls.h"
}
if (!replace_malloc_table.posix_memalign && replace_malloc_table.memalign)
replace_malloc_table.posix_memalign = default_posix_memalign;
if (!replace_malloc_table.aligned_alloc && replace_malloc_table.memalign)
replace_malloc_table.aligned_alloc = default_aligned_alloc;
if (!replace_malloc_table.valloc && replace_malloc_table.memalign)
replace_malloc_table.valloc = default_valloc;
#define MALLOC_DECL(name, ...) \
if (!replace_malloc_table.name) { \
replace_malloc_table.name = je_ ## name; \

View File

@ -91,43 +91,6 @@ MOZ_BEGIN_EXTERN_C
#endif /* MOZ_NO_REPLACE_FUNC_DECL */
/*
* posix_memalign, aligned_alloc, memalign and valloc all implement some
* kind of aligned memory allocation. For convenience, replace_posix_memalign,
* replace_aligned_alloc and replace_valloc can be automatically derived from
* memalign when MOZ_REPLACE_ONLY_MEMALIGN is defined before including this
* header. PAGE_SIZE also needs to be defined to the appropriate expression.
*/
#ifdef MOZ_REPLACE_ONLY_MEMALIGN
#include <errno.h>
int replace_posix_memalign(void **ptr, size_t alignment, size_t size)
{
if (size == 0) {
*ptr = NULL;
return 0;
}
/* alignment must be a power of two and a multiple of sizeof(void *) */
if (((alignment - 1) & alignment) != 0 || (alignment % sizeof(void *)))
return EINVAL;
*ptr = replace_memalign(alignment, size);
return *ptr ? 0 : ENOMEM;
}
void *replace_aligned_alloc(size_t alignment, size_t size)
{
/* size should be a multiple of alignment */
if (size % alignment)
return NULL;
return replace_memalign(alignment, size);
}
void *replace_valloc(size_t size)
{
return replace_memalign(PAGE_SIZE, size);
}
#endif
MOZ_END_EXTERN_C
#endif /* replace_malloc_h */

View File

@ -49,33 +49,7 @@
// replace_malloc.h needs to be included before replace_malloc_bridge.h,
// which DMD.h includes, so DMD.h needs to be included after replace_malloc.h.
// MOZ_REPLACE_ONLY_MEMALIGN saves us from having to define
// replace_{posix_memalign,aligned_alloc,valloc}. It requires defining
// PAGE_SIZE. Nb: sysconf() is expensive, but it's only used for (the obsolete
// and rarely used) valloc.
#define MOZ_REPLACE_ONLY_MEMALIGN 1
#ifndef PAGE_SIZE
#define DMD_DEFINED_PAGE_SIZE
#ifdef XP_WIN
#define PAGE_SIZE GetPageSize()
static long GetPageSize()
{
SYSTEM_INFO si;
GetSystemInfo(&si);
return si.dwPageSize;
}
#else // XP_WIN
#define PAGE_SIZE sysconf(_SC_PAGESIZE)
#endif // XP_WIN
#endif // PAGE_SIZE
#include "replace_malloc.h"
#undef MOZ_REPLACE_ONLY_MEMALIGN
#ifdef DMD_DEFINED_PAGE_SIZE
#undef DMD_DEFINED_PAGE_SIZE
#undef PAGE_SIZE
#endif // DMD_DEFINED_PAGE_SIZE
#include "DMD.h"
namespace mozilla {