diff --git a/configure.ac b/configure.ac index 846a049c..fbc6298b 100644 --- a/configure.ac +++ b/configure.ac @@ -546,6 +546,22 @@ typedef unsigned __int32 uint32_t; ;; esac AC_DEFINE_UNQUOTED([LG_VADDR], [$LG_VADDR], [ ]) +AC_CACHE_CHECK([asm volatile support], + [je_cv_asm_volatile], + AC_RUN_IFELSE([AC_LANG_PROGRAM( +[[ +]], +[[ + void* ptr; + asm volatile("" : "+r"(ptr)); + return 0; +]])], +[je_cv_asm_volatile=yes], +[je_cv_asm_volatile=no], +[je_cv_asm_volatile=no])) +if test "x${je_cv_asm_volatile}" = "xyes"; then + AC_DEFINE([JEMALLOC_HAVE_ASM_VOLATILE], [ ], [ ]) +fi LD_PRELOAD_VAR="LD_PRELOAD" so="so" diff --git a/include/jemalloc/internal/jemalloc_internal_defs.h.in b/include/jemalloc/internal/jemalloc_internal_defs.h.in index 55938433..41e40ccf 100644 --- a/include/jemalloc/internal/jemalloc_internal_defs.h.in +++ b/include/jemalloc/internal/jemalloc_internal_defs.h.in @@ -440,4 +440,7 @@ /* If defined, realloc(ptr, 0) defaults to "free" instead of "alloc". */ #undef JEMALLOC_ZERO_REALLOC_DEFAULT_FREE +/* If defined, use volatile asm during benchmarks. */ +#undef JEMALLOC_HAVE_ASM_VOLATILE + #endif /* JEMALLOC_INTERNAL_DEFS_H_ */ diff --git a/test/include/test/bench.h b/test/include/test/bench.h index 7421b4d2..29c6801f 100644 --- a/test/include/test/bench.h +++ b/test/include/test/bench.h @@ -58,3 +58,14 @@ compare_funcs(uint64_t nwarmup, uint64_t niter, const char *name_a, dallocx(p, 0); } + +static inline void * +no_opt_ptr(void *ptr) { +#ifdef JEMALLOC_HAVE_ASM_VOLATILE + asm volatile("" : "+r"(ptr)); +#else + void *volatile dup = ptr; + ptr = dup; +#endif + return ptr; +} diff --git a/test/stress/cpp/microbench.cpp b/test/stress/cpp/microbench.cpp index ab41b65d..203c3dc9 100644 --- a/test/stress/cpp/microbench.cpp +++ b/test/stress/cpp/microbench.cpp @@ -3,44 +3,50 @@ static void malloc_free(void) { - void* volatile p = malloc(1); + void* p = malloc(1); expect_ptr_not_null((void *)p, "Unexpected malloc failure"); + p = no_opt_ptr(p); free((void *)p); } static void new_delete(void) { - void* volatile p = ::operator new(1); + void* p = ::operator new(1); expect_ptr_not_null((void *)p, "Unexpected new failure"); + p = no_opt_ptr(p); ::operator delete((void *)p); } static void malloc_free_array(void) { - void* volatile p = malloc(sizeof(int)*8); + void* p = malloc(sizeof(int)*8); expect_ptr_not_null((void *)p, "Unexpected malloc failure"); + p = no_opt_ptr(p); free((void *)p); } static void new_delete_array(void) { - int* volatile p = new int[8]; - expect_ptr_not_null((int *)p, "Unexpected new[] failure"); + int* p = new int[8]; + expect_ptr_not_null((void *)p, "Unexpected new[] failure"); + p = (int *)no_opt_ptr((void *)p); delete[] (int *)p; } #if __cpp_sized_deallocation >= 201309 static void new_sized_delete(void) { - void* volatile p = ::operator new(1); + void* p = ::operator new(1); expect_ptr_not_null((void *)p, "Unexpected new failure"); + p = no_opt_ptr(p); ::operator delete((void *)p, 1); } static void malloc_sdallocx(void) { - void* volatile p = malloc(1); + void* p = malloc(1); expect_ptr_not_null((void *)p, "Unexpected malloc failure"); + p = no_opt_ptr(p); sdallocx((void *)p, 1, 0); } #endif diff --git a/test/stress/large_microbench.c b/test/stress/large_microbench.c index c66b33a1..44a60c53 100644 --- a/test/stress/large_microbench.c +++ b/test/stress/large_microbench.c @@ -9,6 +9,7 @@ large_mallocx_free(void) { */ void *p = mallocx(SC_LARGE_MINCLASS, MALLOCX_TCACHE_NONE); assert_ptr_not_null(p, "mallocx shouldn't fail"); + p = no_opt_ptr(p); free(p); } @@ -16,6 +17,7 @@ static void small_mallocx_free(void) { void *p = mallocx(16, 0); assert_ptr_not_null(p, "mallocx shouldn't fail"); + p = no_opt_ptr(p); free(p); } diff --git a/test/stress/microbench.c b/test/stress/microbench.c index 062e32fd..89479b7e 100644 --- a/test/stress/microbench.c +++ b/test/stress/microbench.c @@ -9,6 +9,7 @@ malloc_free(void) { test_fail("Unexpected malloc() failure"); return; } + p = no_opt_ptr(p); free(p); } @@ -19,6 +20,7 @@ mallocx_free(void) { test_fail("Unexpected mallocx() failure"); return; } + p = no_opt_ptr(p); free(p); } @@ -35,6 +37,7 @@ malloc_dallocx(void) { test_fail("Unexpected malloc() failure"); return; } + p = no_opt_ptr(p); dallocx(p, 0); } @@ -45,6 +48,7 @@ malloc_sdallocx(void) { test_fail("Unexpected malloc() failure"); return; } + p = no_opt_ptr(p); sdallocx(p, 1, 0); } @@ -82,6 +86,7 @@ malloc_sallocx_free(void) { test_fail("Unexpected malloc() failure"); return; } + p = no_opt_ptr(p); if (sallocx(p, 0) < 1) { test_fail("Unexpected sallocx() failure"); } @@ -103,6 +108,7 @@ malloc_nallocx_free(void) { test_fail("Unexpected malloc() failure"); return; } + p = no_opt_ptr(p); if (nallocx(1, 0) < 1) { test_fail("Unexpected nallocx() failure"); }