2014-05-28 11:39:13 +08:00
|
|
|
#ifndef JEMALLOC_INTERNAL_DECLS_H
|
2017-01-20 13:41:41 +08:00
|
|
|
#define JEMALLOC_INTERNAL_DECLS_H
|
2014-05-28 11:39:13 +08:00
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#ifdef _WIN32
|
|
|
|
# include <windows.h>
|
2015-07-24 04:56:25 +08:00
|
|
|
# include "msvc_compat/windows_extra.h"
|
Support C++17 over-aligned allocation
Summary:
Add support for C++17 over-aligned allocation:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0035r4.html
Supporting all 10 operators means we avoid thunking thru libstdc++-v3/libsupc++ and just call jemalloc directly.
It's also worth noting that there is now an aligned *and sized* operator delete:
```
void operator delete(void* ptr, std::size_t size, std::align_val_t al) noexcept;
```
If JeMalloc did not provide this, the default implementation would ignore the size parameter entirely:
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/del_opsa.cc#L30-L33
(I must also update ax_cxx_compile_stdcxx.m4 to a newer version with C++17 support.)
Test Plan:
Wrote a simple test that allocates and then deletes an over-aligned type:
```
struct alignas(32) Foo {};
Foo *f;
int main()
{
f = new Foo;
delete f;
}
```
Before this change, both new and delete go thru PLT, and we end up calling regular old free:
```
(gdb) disassemble
Dump of assembler code for function main():
...
0x00000000004029b7 <+55>: call 0x4022d0 <_ZnwmSt11align_val_t@plt>
...
0x00000000004029d5 <+85>: call 0x4022e0 <_ZdlPvmSt11align_val_t@plt>
...
(gdb) s
free (ptr=0x7ffff6408020) at /home/engshare/third-party2/jemalloc/master/src/jemalloc.git-trunk/src/jemalloc.c:2842
2842 if (!free_fastpath(ptr, 0, false)) {
```
After this change, we directly call new/delete and ultimately call sdallocx:
```
(gdb) disassemble
Dump of assembler code for function main():
...
0x0000000000402b77 <+55>: call 0x496ca0 <operator new(unsigned long, std::align_val_t)>
...
0x0000000000402b95 <+85>: call 0x496e60 <operator delete(void*, unsigned long, std::align_val_t)>
...
(gdb) s
116 je_sdallocx_noflags(ptr, size);
```
2019-10-27 14:28:42 +08:00
|
|
|
# include "msvc_compat/strings.h"
|
2018-01-19 23:28:33 +08:00
|
|
|
# ifdef _WIN64
|
|
|
|
# if LG_VADDR <= 32
|
|
|
|
# error Generate the headers using x64 vcargs
|
|
|
|
# endif
|
|
|
|
# else
|
|
|
|
# if LG_VADDR > 32
|
|
|
|
# undef LG_VADDR
|
|
|
|
# define LG_VADDR 32
|
|
|
|
# endif
|
|
|
|
# endif
|
2014-05-28 11:39:13 +08:00
|
|
|
#else
|
|
|
|
# include <sys/param.h>
|
|
|
|
# include <sys/mman.h>
|
2014-05-29 10:37:02 +08:00
|
|
|
# if !defined(__pnacl__) && !defined(__native_client__)
|
|
|
|
# include <sys/syscall.h>
|
|
|
|
# if !defined(SYS_write) && defined(__NR_write)
|
|
|
|
# define SYS_write __NR_write
|
|
|
|
# endif
|
2017-04-20 03:22:10 +08:00
|
|
|
# if defined(SYS_open) && defined(__aarch64__)
|
|
|
|
/* Android headers may define SYS_open to __NR_open even though
|
|
|
|
* __NR_open may not exist on AArch64 (superseded by __NR_openat). */
|
|
|
|
# undef SYS_open
|
|
|
|
# endif
|
2014-05-29 10:37:02 +08:00
|
|
|
# include <sys/uio.h>
|
2014-05-28 11:39:13 +08:00
|
|
|
# endif
|
|
|
|
# include <pthread.h>
|
2022-06-08 04:43:08 +08:00
|
|
|
# if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
|
2018-10-06 23:43:07 +08:00
|
|
|
# include <pthread_np.h>
|
2021-12-03 00:40:05 +08:00
|
|
|
# include <sched.h>
|
|
|
|
# if defined(__FreeBSD__)
|
|
|
|
# define cpu_set_t cpuset_t
|
|
|
|
# endif
|
2018-10-06 23:43:07 +08:00
|
|
|
# endif
|
2017-06-20 11:35:33 +08:00
|
|
|
# include <signal.h>
|
2016-11-03 09:09:45 +08:00
|
|
|
# ifdef JEMALLOC_OS_UNFAIR_LOCK
|
|
|
|
# include <os/lock.h>
|
|
|
|
# endif
|
Support static linking of jemalloc with glibc
glibc defines its malloc implementation with several weak and strong
symbols:
strong_alias (__libc_calloc, __calloc) weak_alias (__libc_calloc, calloc)
strong_alias (__libc_free, __cfree) weak_alias (__libc_free, cfree)
strong_alias (__libc_free, __free) strong_alias (__libc_free, free)
strong_alias (__libc_malloc, __malloc) strong_alias (__libc_malloc, malloc)
The issue is not with the weak symbols, but that other parts of glibc
depend on __libc_malloc explicitly. Defining them in terms of jemalloc
API's allows the linker to drop glibc's malloc.o completely from the link,
and static linking no longer results in symbol collisions.
Another wrinkle: jemalloc during initialization calls sysconf to
get the number of CPU's. GLIBC allocates for the first time before
setting up isspace (and other related) tables, which are used by
sysconf. Instead, use the pthread API to get the number of
CPUs with GLIBC, which seems to work.
This resolves #442.
2016-10-29 04:51:52 +08:00
|
|
|
# ifdef JEMALLOC_GLIBC_MALLOC_HOOK
|
|
|
|
# include <sched.h>
|
|
|
|
# endif
|
2014-05-28 11:39:13 +08:00
|
|
|
# include <errno.h>
|
2016-02-24 03:39:02 +08:00
|
|
|
# include <sys/time.h>
|
2016-10-07 23:47:16 +08:00
|
|
|
# include <time.h>
|
|
|
|
# ifdef JEMALLOC_HAVE_MACH_ABSOLUTE_TIME
|
|
|
|
# include <mach/mach_time.h>
|
|
|
|
# endif
|
2014-05-28 11:39:13 +08:00
|
|
|
#endif
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#include <limits.h>
|
|
|
|
#ifndef SIZE_T_MAX
|
|
|
|
# define SIZE_T_MAX SIZE_MAX
|
|
|
|
#endif
|
2017-05-18 01:47:00 +08:00
|
|
|
#ifndef SSIZE_MAX
|
|
|
|
# define SSIZE_MAX ((ssize_t)(SIZE_T_MAX >> 1))
|
|
|
|
#endif
|
2014-05-28 11:39:13 +08:00
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#ifndef offsetof
|
|
|
|
# define offsetof(type, member) ((size_t)&(((type *)NULL)->member))
|
|
|
|
#endif
|
|
|
|
#include <string.h>
|
|
|
|
#include <strings.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
# include <io.h>
|
|
|
|
typedef intptr_t ssize_t;
|
|
|
|
# define PATH_MAX 1024
|
|
|
|
# define STDERR_FILENO 2
|
|
|
|
# define __func__ __FUNCTION__
|
2015-07-28 04:48:27 +08:00
|
|
|
# ifdef JEMALLOC_HAS_RESTRICT
|
|
|
|
# define restrict __restrict
|
|
|
|
# endif
|
2014-12-09 06:40:14 +08:00
|
|
|
/* Disable warnings about deprecated system functions. */
|
2014-05-28 11:39:13 +08:00
|
|
|
# pragma warning(disable: 4996)
|
2014-12-18 14:01:21 +08:00
|
|
|
#if _MSC_VER < 1800
|
|
|
|
static int
|
2017-01-16 08:56:30 +08:00
|
|
|
isblank(int c) {
|
2014-12-18 14:01:21 +08:00
|
|
|
return (c == '\t' || c == ' ');
|
|
|
|
}
|
|
|
|
#endif
|
2014-05-28 11:39:13 +08:00
|
|
|
#else
|
|
|
|
# include <unistd.h>
|
|
|
|
#endif
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
2020-02-24 12:33:04 +08:00
|
|
|
/*
|
|
|
|
* The Win32 midl compiler has #define small char; we don't use midl, but
|
|
|
|
* "small" is a nice identifier to have available when talking about size
|
|
|
|
* classes.
|
|
|
|
*/
|
|
|
|
#ifdef small
|
|
|
|
# undef small
|
|
|
|
#endif
|
|
|
|
|
2023-07-25 01:33:36 +08:00
|
|
|
/*
|
|
|
|
* Oftentimes we'd like to perform some kind of arithmetic to obtain
|
|
|
|
* a pointer from another pointer but with some offset or mask applied.
|
|
|
|
* Naively you would accomplish this by casting the source pointer to
|
|
|
|
* `uintptr_t`, performing all of the relevant arithmetic, and then casting
|
|
|
|
* the result to the desired pointer type. However, this has the unfortunate
|
|
|
|
* side-effect of concealing pointer provenance, hiding useful information for
|
|
|
|
* optimization from the compiler (see here for details:
|
|
|
|
* https://clang.llvm.org/extra/clang-tidy/checks/performance/no-int-to-ptr.html
|
|
|
|
* )
|
|
|
|
* Instead what one should do is cast the source pointer to `char *` and perform
|
|
|
|
* the equivalent arithmetic (since `char` of course represents one byte). But
|
|
|
|
* because `char *` has the semantic meaning of "string", we define this typedef
|
|
|
|
* simply to make it clearer where we are performing such pointer arithmetic.
|
|
|
|
*/
|
|
|
|
typedef char byte_t;
|
|
|
|
|
2014-05-28 11:39:13 +08:00
|
|
|
#endif /* JEMALLOC_INTERNAL_H */
|