зеркало из https://github.com/microsoft/snmalloc.git
Factor out libc code into a header. (#624)
* Factor out libc code into a header. This pulls the main definitions of the various libc malloc functions into a header for easier use and inclusion in other projects. * Clang-tidy fixes. * Clang-tidy fixes really. * More code quality changes * Minor fix * Clangformat
This commit is contained in:
Родитель
9d4466093a
Коммит
6cbc50fe2c
|
@ -68,7 +68,9 @@ namespace snmalloc
|
||||||
|
|
||||||
template<typename Rep>
|
template<typename Rep>
|
||||||
concept RBRep = //
|
concept RBRep = //
|
||||||
RBRepTypes<Rep> && RBRepMethods<Rep> &&
|
RBRepTypes<Rep> //
|
||||||
|
&& RBRepMethods<Rep> //
|
||||||
|
&&
|
||||||
ConceptSame<decltype(Rep::null), std::add_const_t<typename Rep::Contents>>;
|
ConceptSame<decltype(Rep::null), std::add_const_t<typename Rep::Contents>>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,13 @@ namespace snmalloc
|
||||||
}
|
}
|
||||||
|
|
||||||
return check_init([&](CoreAlloc* core_alloc) {
|
return check_init([&](CoreAlloc* core_alloc) {
|
||||||
|
if (size > bits::one_at_bit(bits::BITS - 1))
|
||||||
|
{
|
||||||
|
// Cannot allocate something that is more that half the size of the
|
||||||
|
// address space
|
||||||
|
errno = ENOMEM;
|
||||||
|
return capptr::Alloc<void>{nullptr};
|
||||||
|
}
|
||||||
// Grab slab of correct size
|
// Grab slab of correct size
|
||||||
// Set remote as large allocator remote.
|
// Set remote as large allocator remote.
|
||||||
auto [chunk, meta] = Config::Backend::alloc_chunk(
|
auto [chunk, meta] = Config::Backend::alloc_chunk(
|
||||||
|
@ -712,7 +719,7 @@ namespace snmalloc
|
||||||
auto pm_size = sizeclass_full_to_size(pm_sc);
|
auto pm_size = sizeclass_full_to_size(pm_sc);
|
||||||
snmalloc_check_client(
|
snmalloc_check_client(
|
||||||
mitigations(sanity_checks),
|
mitigations(sanity_checks),
|
||||||
sc == pm_sc,
|
(sc == pm_sc) || (p == nullptr),
|
||||||
"Dealloc rounded size mismatch: {} != {}",
|
"Dealloc rounded size mismatch: {} != {}",
|
||||||
rsize,
|
rsize,
|
||||||
pm_size);
|
pm_size);
|
||||||
|
|
|
@ -478,6 +478,12 @@ namespace snmalloc
|
||||||
{
|
{
|
||||||
if (size > sizeclass_to_size(NUM_SMALL_SIZECLASSES - 1))
|
if (size > sizeclass_to_size(NUM_SMALL_SIZECLASSES - 1))
|
||||||
{
|
{
|
||||||
|
if (size > bits::one_at_bit(bits::BITS - 1))
|
||||||
|
{
|
||||||
|
// This size is too large, no rounding should occur as will result in a
|
||||||
|
// failed allocation later.
|
||||||
|
return size;
|
||||||
|
}
|
||||||
return bits::next_pow2(size);
|
return bits::next_pow2(size);
|
||||||
}
|
}
|
||||||
// If realloc(ptr, 0) returns nullptr, some consumers treat this as a
|
// If realloc(ptr, 0) returns nullptr, some consumers treat this as a
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../global/global.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace snmalloc::libc
|
||||||
|
{
|
||||||
|
SNMALLOC_SLOW_PATH inline void* set_error(int err = ENOMEM)
|
||||||
|
{
|
||||||
|
errno = err;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SNMALLOC_SLOW_PATH inline int set_error_and_return(int err = ENOMEM)
|
||||||
|
{
|
||||||
|
errno = err;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* __malloc_end_pointer(void* ptr)
|
||||||
|
{
|
||||||
|
return ThreadAlloc::get().external_pointer<OnePastEnd>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
SNMALLOC_FAST_PATH_INLINE void* malloc(size_t size)
|
||||||
|
{
|
||||||
|
return ThreadAlloc::get().alloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
SNMALLOC_FAST_PATH_INLINE void free(void* ptr)
|
||||||
|
{
|
||||||
|
ThreadAlloc::get().dealloc(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
SNMALLOC_FAST_PATH_INLINE void free_sized(void* ptr, size_t size)
|
||||||
|
{
|
||||||
|
ThreadAlloc::get().dealloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
SNMALLOC_FAST_PATH_INLINE void* calloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
bool overflow = false;
|
||||||
|
size_t sz = bits::umul(size, nmemb, overflow);
|
||||||
|
if (SNMALLOC_UNLIKELY(overflow))
|
||||||
|
{
|
||||||
|
return set_error();
|
||||||
|
}
|
||||||
|
return ThreadAlloc::get().alloc<ZeroMem::YesZero>(sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
SNMALLOC_FAST_PATH_INLINE void* realloc(void* ptr, size_t size)
|
||||||
|
{
|
||||||
|
auto& a = ThreadAlloc::get();
|
||||||
|
size_t sz = a.alloc_size(ptr);
|
||||||
|
// Keep the current allocation if the given size is in the same sizeclass.
|
||||||
|
if (sz == round_size(size))
|
||||||
|
{
|
||||||
|
#ifdef SNMALLOC_PASS_THROUGH
|
||||||
|
// snmallocs alignment guarantees can be broken by realloc in pass-through
|
||||||
|
// this is not exercised, by existing clients, but is tested.
|
||||||
|
if (pointer_align_up(ptr, natural_alignment(size)) == ptr)
|
||||||
|
return ptr;
|
||||||
|
#else
|
||||||
|
return ptr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void* p = a.alloc(size);
|
||||||
|
if (SNMALLOC_LIKELY(p != nullptr))
|
||||||
|
{
|
||||||
|
sz = bits::min(size, sz);
|
||||||
|
// Guard memcpy as GCC is assuming not nullptr for ptr after the memcpy
|
||||||
|
// otherwise.
|
||||||
|
if (SNMALLOC_UNLIKELY(sz != 0))
|
||||||
|
::memcpy(p, ptr, sz);
|
||||||
|
a.dealloc(ptr);
|
||||||
|
}
|
||||||
|
else if (SNMALLOC_LIKELY(size == 0))
|
||||||
|
{
|
||||||
|
a.dealloc(ptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return set_error();
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t malloc_usable_size(const void* ptr)
|
||||||
|
{
|
||||||
|
return ThreadAlloc::get().alloc_size(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* reallocarray(void* ptr, size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
bool overflow = false;
|
||||||
|
size_t sz = bits::umul(size, nmemb, overflow);
|
||||||
|
if (SNMALLOC_UNLIKELY(overflow))
|
||||||
|
{
|
||||||
|
return set_error();
|
||||||
|
}
|
||||||
|
return realloc(ptr, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int reallocarr(void* ptr_, size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
int err = errno;
|
||||||
|
auto& a = ThreadAlloc::get();
|
||||||
|
bool overflow = false;
|
||||||
|
size_t sz = bits::umul(size, nmemb, overflow);
|
||||||
|
if (SNMALLOC_UNLIKELY(sz == 0))
|
||||||
|
{
|
||||||
|
errno = err;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (SNMALLOC_UNLIKELY(overflow))
|
||||||
|
{
|
||||||
|
return set_error_and_return(EOVERFLOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void** ptr = reinterpret_cast<void**>(ptr_);
|
||||||
|
void* p = a.alloc(sz);
|
||||||
|
if (SNMALLOC_UNLIKELY(p == nullptr))
|
||||||
|
{
|
||||||
|
return set_error_and_return(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
sz = bits::min(sz, a.alloc_size(*ptr));
|
||||||
|
|
||||||
|
SNMALLOC_ASSUME(*ptr != nullptr || sz == 0);
|
||||||
|
// Guard memcpy as GCC is assuming not nullptr for ptr after the memcpy
|
||||||
|
// otherwise.
|
||||||
|
if (SNMALLOC_UNLIKELY(sz != 0))
|
||||||
|
::memcpy(p, *ptr, sz);
|
||||||
|
errno = err;
|
||||||
|
a.dealloc(*ptr);
|
||||||
|
*ptr = p;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* memalign(size_t alignment, size_t size)
|
||||||
|
{
|
||||||
|
if (SNMALLOC_UNLIKELY(
|
||||||
|
alignment < sizeof(uintptr_t) || !bits::is_pow2(alignment)))
|
||||||
|
{
|
||||||
|
return set_error(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return malloc(aligned_size(alignment, size));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void* aligned_alloc(size_t alignment, size_t size)
|
||||||
|
{
|
||||||
|
SNMALLOC_ASSERT((size % alignment) == 0);
|
||||||
|
return memalign(alignment, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int posix_memalign(void** memptr, size_t alignment, size_t size)
|
||||||
|
{
|
||||||
|
if (SNMALLOC_UNLIKELY(
|
||||||
|
(alignment < sizeof(uintptr_t) || !bits::is_pow2(alignment))))
|
||||||
|
{
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* p = memalign(alignment, size);
|
||||||
|
if (SNMALLOC_UNLIKELY(p == nullptr))
|
||||||
|
{
|
||||||
|
if (size != 0)
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
*memptr = p;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace snmalloc::libc
|
|
@ -1,8 +1,6 @@
|
||||||
|
#include "libc.h"
|
||||||
#include "override.h"
|
#include "override.h"
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
using namespace snmalloc;
|
using namespace snmalloc;
|
||||||
|
|
||||||
#ifndef MALLOC_USABLE_SIZE_QUALIFIER
|
#ifndef MALLOC_USABLE_SIZE_QUALIFIER
|
||||||
|
@ -13,52 +11,34 @@ extern "C"
|
||||||
{
|
{
|
||||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(__malloc_end_pointer)(void* ptr)
|
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(__malloc_end_pointer)(void* ptr)
|
||||||
{
|
{
|
||||||
return ThreadAlloc::get().external_pointer<OnePastEnd>(ptr);
|
return snmalloc::libc::__malloc_end_pointer(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(malloc)(size_t size)
|
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(malloc)(size_t size)
|
||||||
{
|
{
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
SNMALLOC_EXPORT void SNMALLOC_NAME_MANGLE(free)(void* ptr)
|
SNMALLOC_EXPORT void SNMALLOC_NAME_MANGLE(free)(void* ptr)
|
||||||
{
|
{
|
||||||
ThreadAlloc::get().dealloc(ptr);
|
snmalloc::libc::free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SNMALLOC_EXPORT void SNMALLOC_NAME_MANGLE(cfree)(void* ptr)
|
SNMALLOC_EXPORT void SNMALLOC_NAME_MANGLE(cfree)(void* ptr)
|
||||||
{
|
{
|
||||||
ThreadAlloc::get().dealloc(ptr);
|
snmalloc::libc::free(ptr);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clang was helpfully inlining the constant return value, and
|
|
||||||
* thus converting from a tail call to an ordinary call.
|
|
||||||
*/
|
|
||||||
SNMALLOC_EXPORT inline void* snmalloc_not_allocated = nullptr;
|
|
||||||
|
|
||||||
static SNMALLOC_SLOW_PATH void* SNMALLOC_NAME_MANGLE(snmalloc_set_error)()
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return snmalloc_not_allocated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(calloc)(size_t nmemb, size_t size)
|
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(calloc)(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
bool overflow = false;
|
return snmalloc::libc::calloc(nmemb, size);
|
||||||
size_t sz = bits::umul(size, nmemb, overflow);
|
|
||||||
if (SNMALLOC_UNLIKELY(overflow))
|
|
||||||
{
|
|
||||||
return SNMALLOC_NAME_MANGLE(snmalloc_set_error)();
|
|
||||||
}
|
|
||||||
return ThreadAlloc::get().alloc<ZeroMem::YesZero>(sz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SNMALLOC_EXPORT
|
SNMALLOC_EXPORT
|
||||||
size_t SNMALLOC_NAME_MANGLE(malloc_usable_size)(
|
size_t SNMALLOC_NAME_MANGLE(malloc_usable_size)(
|
||||||
MALLOC_USABLE_SIZE_QUALIFIER void* ptr)
|
MALLOC_USABLE_SIZE_QUALIFIER void* ptr)
|
||||||
{
|
{
|
||||||
return ThreadAlloc::get().alloc_size(ptr);
|
return snmalloc::libc::malloc_usable_size(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
SNMALLOC_EXPORT
|
SNMALLOC_EXPORT
|
||||||
|
@ -69,162 +49,53 @@ extern "C"
|
||||||
|
|
||||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(realloc)(void* ptr, size_t size)
|
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(realloc)(void* ptr, size_t size)
|
||||||
{
|
{
|
||||||
auto& a = ThreadAlloc::get();
|
return snmalloc::libc::realloc(ptr, size);
|
||||||
size_t sz = a.alloc_size(ptr);
|
|
||||||
// Keep the current allocation if the given size is in the same sizeclass.
|
|
||||||
if (sz == round_size(size))
|
|
||||||
{
|
|
||||||
#ifdef SNMALLOC_PASS_THROUGH
|
|
||||||
// snmallocs alignment guarantees can be broken by realloc in pass-through
|
|
||||||
// this is not exercised, by existing clients, but is tested.
|
|
||||||
if (pointer_align_up(ptr, natural_alignment(size)) == ptr)
|
|
||||||
return ptr;
|
|
||||||
#else
|
|
||||||
return ptr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size == (size_t)-1)
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* p = a.alloc(size);
|
|
||||||
if (SNMALLOC_LIKELY(p != nullptr))
|
|
||||||
{
|
|
||||||
sz = bits::min(size, sz);
|
|
||||||
// Guard memcpy as GCC is assuming not nullptr for ptr after the memcpy
|
|
||||||
// otherwise.
|
|
||||||
if (sz != 0)
|
|
||||||
memcpy(p, ptr, sz);
|
|
||||||
a.dealloc(ptr);
|
|
||||||
}
|
|
||||||
else if (SNMALLOC_LIKELY(size == 0))
|
|
||||||
{
|
|
||||||
a.dealloc(ptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(SNMALLOC_NO_REALLOCARRAY)
|
#if !defined(SNMALLOC_NO_REALLOCARRAY)
|
||||||
SNMALLOC_EXPORT void*
|
SNMALLOC_EXPORT void*
|
||||||
SNMALLOC_NAME_MANGLE(reallocarray)(void* ptr, size_t nmemb, size_t size)
|
SNMALLOC_NAME_MANGLE(reallocarray)(void* ptr, size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
bool overflow = false;
|
return snmalloc::libc::reallocarray(ptr, nmemb, size);
|
||||||
size_t sz = bits::umul(size, nmemb, overflow);
|
|
||||||
if (overflow)
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return SNMALLOC_NAME_MANGLE(realloc)(ptr, sz);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(SNMALLOC_NO_REALLOCARR)
|
#if !defined(SNMALLOC_NO_REALLOCARR)
|
||||||
SNMALLOC_EXPORT int
|
SNMALLOC_EXPORT int
|
||||||
SNMALLOC_NAME_MANGLE(reallocarr)(void* ptr_, size_t nmemb, size_t size)
|
SNMALLOC_NAME_MANGLE(reallocarr)(void* ptr, size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
int err = errno;
|
return snmalloc::libc::reallocarr(ptr, nmemb, size);
|
||||||
auto& a = ThreadAlloc::get();
|
|
||||||
bool overflow = false;
|
|
||||||
size_t sz = bits::umul(size, nmemb, overflow);
|
|
||||||
if (sz == 0)
|
|
||||||
{
|
|
||||||
errno = err;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (overflow)
|
|
||||||
{
|
|
||||||
errno = err;
|
|
||||||
return EOVERFLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
void** ptr = reinterpret_cast<void**>(ptr_);
|
|
||||||
void* p = a.alloc(sz);
|
|
||||||
if (p == nullptr)
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
sz = bits::min(sz, a.alloc_size(*ptr));
|
|
||||||
|
|
||||||
SNMALLOC_ASSUME(*ptr != nullptr || sz == 0);
|
|
||||||
// Guard memcpy as GCC is assuming not nullptr for ptr after the memcpy
|
|
||||||
// otherwise.
|
|
||||||
if (sz != 0)
|
|
||||||
memcpy(p, *ptr, sz);
|
|
||||||
errno = err;
|
|
||||||
a.dealloc(*ptr);
|
|
||||||
*ptr = p;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SNMALLOC_EXPORT void*
|
SNMALLOC_EXPORT void*
|
||||||
SNMALLOC_NAME_MANGLE(memalign)(size_t alignment, size_t size)
|
SNMALLOC_NAME_MANGLE(memalign)(size_t alignment, size_t size)
|
||||||
{
|
{
|
||||||
if ((alignment == 0) || (alignment == size_t(-1)))
|
return snmalloc::libc::memalign(alignment, size);
|
||||||
{
|
|
||||||
errno = EINVAL;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size + alignment) < size)
|
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SNMALLOC_NAME_MANGLE(malloc)(aligned_size(alignment, size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SNMALLOC_EXPORT void*
|
SNMALLOC_EXPORT void*
|
||||||
SNMALLOC_NAME_MANGLE(aligned_alloc)(size_t alignment, size_t size)
|
SNMALLOC_NAME_MANGLE(aligned_alloc)(size_t alignment, size_t size)
|
||||||
{
|
{
|
||||||
SNMALLOC_ASSERT((size % alignment) == 0);
|
return snmalloc::libc::memalign(alignment, size);
|
||||||
return SNMALLOC_NAME_MANGLE(memalign)(alignment, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SNMALLOC_EXPORT int SNMALLOC_NAME_MANGLE(posix_memalign)(
|
SNMALLOC_EXPORT int SNMALLOC_NAME_MANGLE(posix_memalign)(
|
||||||
void** memptr, size_t alignment, size_t size)
|
void** memptr, size_t alignment, size_t size)
|
||||||
{
|
{
|
||||||
if ((alignment < sizeof(uintptr_t) || ((alignment & (alignment - 1)) != 0)))
|
return snmalloc::libc::posix_memalign(memptr, alignment, size);
|
||||||
{
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* p = SNMALLOC_NAME_MANGLE(memalign)(alignment, size);
|
|
||||||
if (SNMALLOC_UNLIKELY(p == nullptr))
|
|
||||||
{
|
|
||||||
if (size != 0)
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
*memptr = p;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
|
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
|
||||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(valloc)(size_t size)
|
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(valloc)(size_t size)
|
||||||
{
|
{
|
||||||
return SNMALLOC_NAME_MANGLE(memalign)(OS_PAGE_SIZE, size);
|
return snmalloc::libc::memalign(OS_PAGE_SIZE, size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(pvalloc)(size_t size)
|
SNMALLOC_EXPORT void* SNMALLOC_NAME_MANGLE(pvalloc)(size_t size)
|
||||||
{
|
{
|
||||||
if (size == size_t(-1))
|
return snmalloc::libc::memalign(
|
||||||
{
|
|
||||||
errno = ENOMEM;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return SNMALLOC_NAME_MANGLE(memalign)(
|
|
||||||
OS_PAGE_SIZE, (size + OS_PAGE_SIZE - 1) & ~(OS_PAGE_SIZE - 1));
|
OS_PAGE_SIZE, (size + OS_PAGE_SIZE - 1) & ~(OS_PAGE_SIZE - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,102 +20,96 @@ using namespace snmalloc;
|
||||||
|
|
||||||
void* operator new(size_t size)
|
void* operator new(size_t size)
|
||||||
{
|
{
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new[](size_t size)
|
void* operator new[](size_t size)
|
||||||
{
|
{
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new(size_t size, std::nothrow_t&)
|
void* operator new(size_t size, std::nothrow_t&)
|
||||||
{
|
{
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new[](size_t size, std::nothrow_t&)
|
void* operator new[](size_t size, std::nothrow_t&)
|
||||||
{
|
{
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void* p) EXCEPTSPEC
|
void operator delete(void* p) EXCEPTSPEC
|
||||||
{
|
{
|
||||||
ThreadAlloc::get().dealloc(p);
|
snmalloc::libc::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void* p, size_t size) EXCEPTSPEC
|
void operator delete(void* p, size_t size) EXCEPTSPEC
|
||||||
{
|
{
|
||||||
if (p == nullptr)
|
snmalloc::libc::free_sized(p, size);
|
||||||
return;
|
|
||||||
ThreadAlloc::get().dealloc(p, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void* p, std::nothrow_t&)
|
void operator delete(void* p, std::nothrow_t&)
|
||||||
{
|
{
|
||||||
ThreadAlloc::get().dealloc(p);
|
snmalloc::libc::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete[](void* p) EXCEPTSPEC
|
void operator delete[](void* p) EXCEPTSPEC
|
||||||
{
|
{
|
||||||
ThreadAlloc::get().dealloc(p);
|
snmalloc::libc::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete[](void* p, size_t size) EXCEPTSPEC
|
void operator delete[](void* p, size_t size) EXCEPTSPEC
|
||||||
{
|
{
|
||||||
if (p == nullptr)
|
snmalloc::libc::free_sized(p, size);
|
||||||
return;
|
|
||||||
ThreadAlloc::get().dealloc(p, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete[](void* p, std::nothrow_t&)
|
void operator delete[](void* p, std::nothrow_t&)
|
||||||
{
|
{
|
||||||
ThreadAlloc::get().dealloc(p);
|
snmalloc::libc::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new(size_t size, std::align_val_t val)
|
void* operator new(size_t size, std::align_val_t val)
|
||||||
{
|
{
|
||||||
size = aligned_size(size_t(val), size);
|
size = aligned_size(size_t(val), size);
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new[](size_t size, std::align_val_t val)
|
void* operator new[](size_t size, std::align_val_t val)
|
||||||
{
|
{
|
||||||
size = aligned_size(size_t(val), size);
|
size = aligned_size(size_t(val), size);
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new(size_t size, std::align_val_t val, std::nothrow_t&)
|
void* operator new(size_t size, std::align_val_t val, std::nothrow_t&)
|
||||||
{
|
{
|
||||||
size = aligned_size(size_t(val), size);
|
size = aligned_size(size_t(val), size);
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* operator new[](size_t size, std::align_val_t val, std::nothrow_t&)
|
void* operator new[](size_t size, std::align_val_t val, std::nothrow_t&)
|
||||||
{
|
{
|
||||||
size = aligned_size(size_t(val), size);
|
size = aligned_size(size_t(val), size);
|
||||||
return ThreadAlloc::get().alloc(size);
|
return snmalloc::libc::malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void* p, std::align_val_t) EXCEPTSPEC
|
void operator delete(void* p, std::align_val_t) EXCEPTSPEC
|
||||||
{
|
{
|
||||||
ThreadAlloc::get().dealloc(p);
|
snmalloc::libc::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete[](void* p, std::align_val_t) EXCEPTSPEC
|
void operator delete[](void* p, std::align_val_t) EXCEPTSPEC
|
||||||
{
|
{
|
||||||
ThreadAlloc::get().dealloc(p);
|
snmalloc::libc::free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void* p, size_t size, std::align_val_t val) EXCEPTSPEC
|
void operator delete(void* p, size_t size, std::align_val_t val) EXCEPTSPEC
|
||||||
{
|
{
|
||||||
size = aligned_size(size_t(val), size);
|
size = aligned_size(size_t(val), size);
|
||||||
ThreadAlloc::get().dealloc(p, size);
|
snmalloc::libc::free_sized(p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete[](void* p, size_t size, std::align_val_t val) EXCEPTSPEC
|
void operator delete[](void* p, size_t size, std::align_val_t val) EXCEPTSPEC
|
||||||
{
|
{
|
||||||
if (p == nullptr)
|
|
||||||
return;
|
|
||||||
size = aligned_size(size_t(val), size);
|
size = aligned_size(size_t(val), size);
|
||||||
ThreadAlloc::get().dealloc(p, size);
|
snmalloc::libc::free_sized(p, size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
#include "global/global.h"
|
#include "global/global.h"
|
||||||
|
#include "override/libc.h"
|
Загрузка…
Ссылка в новой задаче