2022-03-11 10:04:35 +00:00
|
|
|
#include <cassert>
|
2020-01-16 12:37:29 +00:00
|
|
|
#include <new>
|
2022-09-28 08:45:15 +00:00
|
|
|
#include "config.h"
|
2022-03-11 10:04:35 +00:00
|
|
|
#include <Common/memory.h>
|
2020-01-16 12:37:29 +00:00
|
|
|
|
2021-12-03 18:46:56 +00:00
|
|
|
#if defined(OS_DARWIN) && (USE_JEMALLOC)
|
|
|
|
/// In case of OSX jemalloc register itself as a default zone allocator.
|
|
|
|
///
|
|
|
|
/// Sure jemalloc will register itself, since zone_register() declared with
|
|
|
|
/// constructor attribute (since zone_register is also forbidden from
|
|
|
|
/// optimizing out), however those constructors will be called before
|
|
|
|
/// constructors for global variable initializers (__cxx_global_var_init()).
|
|
|
|
///
|
|
|
|
/// So to make jemalloc under OSX more stable, we will call it explicitly from
|
|
|
|
/// global variable initializers so that each allocation will use it.
|
|
|
|
/// (NOTE: It is ok to call it twice, since zone_register() is a no-op if the
|
|
|
|
/// default zone is already replaced with something.)
|
|
|
|
///
|
|
|
|
/// Refs: https://github.com/jemalloc/jemalloc/issues/708
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
extern void zone_register();
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct InitializeJemallocZoneAllocatorForOSX
|
|
|
|
{
|
|
|
|
InitializeJemallocZoneAllocatorForOSX()
|
|
|
|
{
|
|
|
|
zone_register();
|
|
|
|
/// jemalloc() initializes itself only on malloc()
|
|
|
|
/// and so if some global initializer will have free(nullptr)
|
|
|
|
/// jemalloc may trigger some internal assertion.
|
|
|
|
///
|
|
|
|
/// To prevent this, we explicitly call malloc(free()) here.
|
|
|
|
if (void * ptr = malloc(0))
|
|
|
|
{
|
|
|
|
free(ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} initializeJemallocZoneAllocatorForOSX;
|
|
|
|
#endif
|
|
|
|
|
2020-06-24 18:05:30 +00:00
|
|
|
|
2019-07-10 18:12:50 +00:00
|
|
|
/// Replace default new/delete with memory tracking versions.
|
|
|
|
/// @sa https://en.cppreference.com/w/cpp/memory/new/operator_new
|
|
|
|
/// https://en.cppreference.com/w/cpp/memory/new/operator_delete
|
|
|
|
|
2019-07-11 15:40:55 +00:00
|
|
|
/// new
|
|
|
|
|
|
|
|
void * operator new(std::size_t size)
|
2019-07-10 18:12:50 +00:00
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::trackMemory(size);
|
|
|
|
return Memory::newImpl(size);
|
2019-07-11 15:40:55 +00:00
|
|
|
}
|
2019-07-10 18:12:50 +00:00
|
|
|
|
2022-03-11 10:04:35 +00:00
|
|
|
void * operator new(std::size_t size, std::align_val_t align)
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::trackMemory(size, align);
|
|
|
|
return Memory::newImpl(size, align);
|
2022-03-11 10:04:35 +00:00
|
|
|
}
|
|
|
|
|
2019-07-11 15:40:55 +00:00
|
|
|
void * operator new[](std::size_t size)
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::trackMemory(size);
|
|
|
|
return Memory::newImpl(size);
|
2019-07-11 15:40:55 +00:00
|
|
|
}
|
2019-07-10 18:12:50 +00:00
|
|
|
|
2022-03-11 10:04:35 +00:00
|
|
|
void * operator new[](std::size_t size, std::align_val_t align)
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::trackMemory(size, align);
|
|
|
|
return Memory::newImpl(size, align);
|
2022-03-11 10:04:35 +00:00
|
|
|
}
|
|
|
|
|
2019-07-11 15:40:55 +00:00
|
|
|
void * operator new(std::size_t size, const std::nothrow_t &) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::trackMemory(size);
|
|
|
|
return Memory::newNoExept(size);
|
2019-07-11 15:40:55 +00:00
|
|
|
}
|
2019-07-10 18:12:50 +00:00
|
|
|
|
2019-07-11 15:40:55 +00:00
|
|
|
void * operator new[](std::size_t size, const std::nothrow_t &) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::trackMemory(size);
|
|
|
|
return Memory::newNoExept(size);
|
2019-07-11 15:40:55 +00:00
|
|
|
}
|
|
|
|
|
2022-03-11 10:04:35 +00:00
|
|
|
void * operator new(std::size_t size, std::align_val_t align, const std::nothrow_t &) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::trackMemory(size, align);
|
|
|
|
return Memory::newNoExept(size, align);
|
2022-03-11 10:04:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void * operator new[](std::size_t size, std::align_val_t align, const std::nothrow_t &) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::trackMemory(size, align);
|
|
|
|
return Memory::newNoExept(size, align);
|
2022-03-11 10:04:35 +00:00
|
|
|
}
|
|
|
|
|
2019-07-11 15:40:55 +00:00
|
|
|
/// delete
|
|
|
|
|
2019-07-12 14:41:59 +00:00
|
|
|
/// C++17 std 21.6.2.1 (11)
|
|
|
|
/// If a function without a size parameter is defined, the program should also define the corresponding function with a size parameter.
|
|
|
|
/// If a function with a size parameter is defined, the program shall also define the corresponding version without the size parameter.
|
2019-07-11 15:40:55 +00:00
|
|
|
|
2019-07-12 14:41:59 +00:00
|
|
|
/// cppreference:
|
|
|
|
/// It's unspecified whether size-aware or size-unaware version is called when deleting objects of
|
|
|
|
/// incomplete type and arrays of non-class and trivially-destructible class types.
|
2019-07-11 15:40:55 +00:00
|
|
|
|
2022-03-11 10:04:35 +00:00
|
|
|
|
2019-07-12 14:41:59 +00:00
|
|
|
void operator delete(void * ptr) noexcept
|
2019-07-11 15:40:55 +00:00
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::untrackMemory(ptr);
|
2019-07-11 15:40:55 +00:00
|
|
|
Memory::deleteImpl(ptr);
|
|
|
|
}
|
|
|
|
|
2022-03-11 10:04:35 +00:00
|
|
|
void operator delete(void * ptr, std::align_val_t align) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::untrackMemory(ptr, 0, align);
|
2022-03-11 10:04:35 +00:00
|
|
|
Memory::deleteImpl(ptr);
|
|
|
|
}
|
|
|
|
|
2019-07-12 14:41:59 +00:00
|
|
|
void operator delete[](void * ptr) noexcept
|
2019-07-11 15:40:55 +00:00
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::untrackMemory(ptr);
|
2019-07-11 15:40:55 +00:00
|
|
|
Memory::deleteImpl(ptr);
|
|
|
|
}
|
|
|
|
|
2022-03-11 10:04:35 +00:00
|
|
|
void operator delete[](void * ptr, std::align_val_t align) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::untrackMemory(ptr, 0, align);
|
2022-03-11 10:04:35 +00:00
|
|
|
Memory::deleteImpl(ptr);
|
|
|
|
}
|
|
|
|
|
2019-07-11 15:40:55 +00:00
|
|
|
void operator delete(void * ptr, std::size_t size) noexcept
|
2019-07-10 18:12:50 +00:00
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::untrackMemory(ptr, size);
|
2019-07-11 15:40:55 +00:00
|
|
|
Memory::deleteSized(ptr, size);
|
|
|
|
}
|
2019-07-10 18:12:50 +00:00
|
|
|
|
2022-03-11 10:04:35 +00:00
|
|
|
void operator delete(void * ptr, std::size_t size, std::align_val_t align) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::untrackMemory(ptr, size, align);
|
2022-03-11 10:04:35 +00:00
|
|
|
Memory::deleteSized(ptr, size, align);
|
|
|
|
}
|
|
|
|
|
2019-07-11 15:40:55 +00:00
|
|
|
void operator delete[](void * ptr, std::size_t size) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::untrackMemory(ptr, size);
|
2019-07-11 15:40:55 +00:00
|
|
|
Memory::deleteSized(ptr, size);
|
2019-07-10 18:12:50 +00:00
|
|
|
}
|
2022-03-11 10:04:35 +00:00
|
|
|
|
|
|
|
void operator delete[](void * ptr, std::size_t size, std::align_val_t align) noexcept
|
|
|
|
{
|
2022-12-27 13:28:13 +00:00
|
|
|
Memory::untrackMemory(ptr, size, align);
|
2022-03-11 10:04:35 +00:00
|
|
|
Memory::deleteSized(ptr, size, align);
|
|
|
|
}
|