summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lapenkou <lapenkov@fb.com>2022-04-19 19:51:27 -0700
committerAlexander Lapenkov <lapenkov.a@yandex.ru>2022-05-18 17:01:09 -0700
commit5b1f2cc5d79672e0d8852da1b705d68a74d22cd4 (patch)
tree87131b7944f6631065340fc5b27164e97499ef99
parentcd5aaf308a46ce8ad0232ee9efb697b4ed33a7e4 (diff)
downloadjemalloc-5b1f2cc5d79672e0d8852da1b705d68a74d22cd4.tar.gz
Implement pvalloc replacement
Despite being an obsolete function, pvalloc is still present in GLIBC and should work correctly when jemalloc replaces libc allocator.
-rw-r--r--configure.ac6
-rw-r--r--include/jemalloc/internal/hook.h1
-rw-r--r--include/jemalloc/internal/jemalloc_internal_defs.h.in1
-rw-r--r--include/jemalloc/jemalloc_defs.h.in1
-rw-r--r--include/jemalloc/jemalloc_protos.h.in6
-rw-r--r--src/jemalloc.c46
-rw-r--r--test/unit/hook.c14
7 files changed, 75 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index f6d25f33..8248f52d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1064,6 +1064,9 @@ AC_CHECK_FUNC([memalign],
AC_CHECK_FUNC([valloc],
[AC_DEFINE([JEMALLOC_OVERRIDE_VALLOC], [ ], [ ])
public_syms="${public_syms} valloc"])
+AC_CHECK_FUNC([pvalloc],
+ [AC_DEFINE([JEMALLOC_OVERRIDE_PVALLOC], [ ], [ ])
+ public_syms="${public_syms} pvalloc"])
AC_CHECK_FUNC([malloc_size],
[AC_DEFINE([JEMALLOC_HAVE_MALLOC_SIZE], [ ], [ ])
public_syms="${public_syms} malloc_size"])
@@ -1089,6 +1092,9 @@ if test "x${JEMALLOC_PREFIX}" = "x" ; then
AC_CHECK_FUNC([__libc_valloc],
[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_VALLOC], [ ], [ ])
wrap_syms="${wrap_syms} __libc_valloc"])
+ AC_CHECK_FUNC([__libc_pvalloc],
+ [AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_PVALLOC], [ ], [ ])
+ wrap_syms="${wrap_syms} __libc_pvalloc"])
AC_CHECK_FUNC([__posix_memalign],
[AC_DEFINE([JEMALLOC_OVERRIDE___POSIX_MEMALIGN], [ ], [ ])
wrap_syms="${wrap_syms} __posix_memalign"])
diff --git a/include/jemalloc/internal/hook.h b/include/jemalloc/internal/hook.h
index ee246b1e..af03d2f5 100644
--- a/include/jemalloc/internal/hook.h
+++ b/include/jemalloc/internal/hook.h
@@ -55,6 +55,7 @@ enum hook_alloc_e {
hook_alloc_calloc,
hook_alloc_memalign,
hook_alloc_valloc,
+ hook_alloc_pvalloc,
hook_alloc_mallocx,
/* The reallocating functions have both alloc and dalloc variants */
diff --git a/include/jemalloc/internal/jemalloc_internal_defs.h.in b/include/jemalloc/internal/jemalloc_internal_defs.h.in
index 3588072f..888ef470 100644
--- a/include/jemalloc/internal/jemalloc_internal_defs.h.in
+++ b/include/jemalloc/internal/jemalloc_internal_defs.h.in
@@ -18,6 +18,7 @@
#undef JEMALLOC_OVERRIDE___LIBC_MEMALIGN
#undef JEMALLOC_OVERRIDE___LIBC_REALLOC
#undef JEMALLOC_OVERRIDE___LIBC_VALLOC
+#undef JEMALLOC_OVERRIDE___LIBC_PVALLOC
#undef JEMALLOC_OVERRIDE___POSIX_MEMALIGN
/*
diff --git a/include/jemalloc/jemalloc_defs.h.in b/include/jemalloc/jemalloc_defs.h.in
index cbe2fca6..77d9d3b5 100644
--- a/include/jemalloc/jemalloc_defs.h.in
+++ b/include/jemalloc/jemalloc_defs.h.in
@@ -25,6 +25,7 @@
*/
#undef JEMALLOC_OVERRIDE_MEMALIGN
#undef JEMALLOC_OVERRIDE_VALLOC
+#undef JEMALLOC_OVERRIDE_PVALLOC
/*
* At least Linux omits the "const" in:
diff --git a/include/jemalloc/jemalloc_protos.h.in b/include/jemalloc/jemalloc_protos.h.in
index 356221cc..3f9fc848 100644
--- a/include/jemalloc/jemalloc_protos.h.in
+++ b/include/jemalloc/jemalloc_protos.h.in
@@ -69,3 +69,9 @@ JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
void JEMALLOC_SYS_NOTHROW *@je_@valloc(size_t size) JEMALLOC_CXX_THROW
JEMALLOC_ATTR(malloc);
#endif
+
+#ifdef JEMALLOC_OVERRIDE_PVALLOC
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+ void JEMALLOC_SYS_NOTHROW *@je_@pvalloc(size_t size) JEMALLOC_CXX_THROW
+ JEMALLOC_ATTR(malloc);
+#endif
diff --git a/src/jemalloc.c b/src/jemalloc.c
index 7655de4e..68db1f36 100644
--- a/src/jemalloc.c
+++ b/src/jemalloc.c
@@ -3250,6 +3250,49 @@ je_valloc(size_t size) {
}
#endif
+#ifdef JEMALLOC_OVERRIDE_PVALLOC
+JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
+void JEMALLOC_NOTHROW *
+JEMALLOC_ATTR(malloc)
+je_pvalloc(size_t size) {
+ void *ret;
+
+ static_opts_t sopts;
+ dynamic_opts_t dopts;
+
+ LOG("core.pvalloc.entry", "size: %zu\n", size);
+
+ static_opts_init(&sopts);
+ dynamic_opts_init(&dopts);
+
+ sopts.null_out_result_on_error = true;
+ sopts.min_alignment = PAGE;
+ sopts.oom_string =
+ "<jemalloc>: Error allocating aligned memory: out of memory\n";
+ sopts.invalid_alignment_string =
+ "<jemalloc>: Error allocating aligned memory: invalid alignment\n";
+
+ dopts.result = &ret;
+ dopts.num_items = 1;
+ /*
+ * This is the only difference from je_valloc - size is rounded up to
+ * a PAGE multiple.
+ */
+ dopts.item_size = PAGE_CEILING(size);
+ dopts.alignment = PAGE;
+
+ imalloc(&sopts, &dopts);
+ if (sopts.slow) {
+ uintptr_t args[3] = {size};
+ hook_invoke_alloc(hook_alloc_pvalloc, ret, (uintptr_t)ret,
+ args);
+ }
+
+ LOG("core.pvalloc.exit", "result: %p\n", ret);
+ return ret;
+}
+#endif
+
#if defined(JEMALLOC_IS_MALLOC) && defined(JEMALLOC_GLIBC_MALLOC_HOOK)
/*
* glibc provides the RTLD_DEEPBIND flag for dlopen which can make it possible
@@ -3297,6 +3340,9 @@ void *__libc_realloc(void* ptr, size_t size) PREALIAS(je_realloc);
# ifdef JEMALLOC_OVERRIDE___LIBC_VALLOC
void *__libc_valloc(size_t size) PREALIAS(je_valloc);
# endif
+# ifdef JEMALLOC_OVERRIDE___LIBC_PVALLOC
+void *__libc_pvalloc(size_t size) PREALIAS(je_pvalloc);
+# endif
# ifdef JEMALLOC_OVERRIDE___POSIX_MEMALIGN
int __posix_memalign(void** r, size_t a, size_t s) PREALIAS(je_posix_memalign);
# endif
diff --git a/test/unit/hook.c b/test/unit/hook.c
index 16a6f1b0..36dbd269 100644
--- a/test/unit/hook.c
+++ b/test/unit/hook.c
@@ -313,6 +313,20 @@ TEST_BEGIN(test_hooks_alloc_simple) {
free(ptr);
#endif /* JEMALLOC_OVERRIDE_VALLOC */
+ /* pvalloc */
+#ifdef JEMALLOC_OVERRIDE_PVALLOC
+ reset();
+ ptr = pvalloc(1);
+ expect_d_eq(call_count, 1, "Hook not called");
+ expect_ptr_eq(arg_extra, (void *)123, "Wrong extra");
+ expect_d_eq(arg_type, (int)hook_alloc_pvalloc, "Wrong hook type");
+ expect_ptr_eq(ptr, arg_result, "Wrong result");
+ expect_u64_eq((uintptr_t)ptr, (uintptr_t)arg_result_raw,
+ "Wrong raw result");
+ expect_u64_eq((uintptr_t)1, arg_args_raw[0], "Wrong argument");
+ free(ptr);
+#endif /* JEMALLOC_OVERRIDE_PVALLOC */
+
/* mallocx */
reset();
ptr = mallocx(1, MALLOCX_LG_ALIGN(10));