mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
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:
parent
7fd2c94e79
commit
4ae1509807
@ -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; \
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user