1diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in 2index 21e401ac..f977c5f5 100644 3--- a/doc/jemalloc.xml.in 4+++ b/doc/jemalloc.xml.in 5@@ -53,11 +53,21 @@ 6 <para>This manual describes jemalloc @jemalloc_version@. More information 7 can be found at the <ulink 8 url="http://jemalloc.net/">jemalloc website</ulink>.</para> 9+ 10+ <para>The following configuration options are enabled in libc's built-in 11+ jemalloc: <option>--enable-fill</option>, 12+ <option>--enable-lazy-lock</option>, <option>--enable-stats</option>, 13+ <option>--enable-utrace</option>, and <option>--enable-xmalloc</option>. 14+ Additionally, <option>--enable-debug</option> is enabled in development 15+ versions of FreeBSD (controlled by the 16+ <constant>MALLOC_PRODUCTION</constant> make variable).</para> 17+ 18 </refsect1> 19 <refsynopsisdiv> 20 <title>SYNOPSIS</title> 21 <funcsynopsis> 22- <funcsynopsisinfo>#include <<filename class="headerfile">jemalloc/jemalloc.h</filename>></funcsynopsisinfo> 23+ <funcsynopsisinfo>#include <<filename class="headerfile">stdlib.h</filename>> 24+#include <<filename class="headerfile">malloc_np.h</filename>></funcsynopsisinfo> 25 <refsect2> 26 <title>Standard API</title> 27 <funcprototype> 28@@ -3252,4 +3262,18 @@ malloc_conf = "narenas:1";]]></programlisting></para> 29 <para>The <function>posix_memalign()</function> function conforms 30 to IEEE Std 1003.1-2001 (<quote>POSIX.1</quote>).</para> 31 </refsect1> 32+ <refsect1 id="history"> 33+ <title>HISTORY</title> 34+ <para>The <function>malloc_usable_size()</function> and 35+ <function>posix_memalign()</function> functions first appeared in FreeBSD 36+ 7.0.</para> 37+ 38+ <para>The <function>aligned_alloc()</function>, 39+ <function>malloc_stats_print()</function>, and 40+ <function>mallctl*()</function> functions first appeared in FreeBSD 41+ 10.0.</para> 42+ 43+ <para>The <function>*allocx()</function> functions first appeared in FreeBSD 44+ 11.0.</para> 45+ </refsect1> 46 </refentry> 47diff --git a/include/jemalloc/internal/hooks.h b/include/jemalloc/internal/hooks.h 48index cd49afcb..85e2a991 100644 49--- a/include/jemalloc/internal/hooks.h 50+++ b/include/jemalloc/internal/hooks.h 51@@ -6,13 +6,6 @@ extern JEMALLOC_EXPORT void (*hooks_libc_hook)(); 52 53 #define JEMALLOC_HOOK(fn, hook) ((void)(hook != NULL && (hook(), 0)), fn) 54 55-#define open JEMALLOC_HOOK(open, hooks_libc_hook) 56-#define read JEMALLOC_HOOK(read, hooks_libc_hook) 57-#define write JEMALLOC_HOOK(write, hooks_libc_hook) 58-#define readlink JEMALLOC_HOOK(readlink, hooks_libc_hook) 59-#define close JEMALLOC_HOOK(close, hooks_libc_hook) 60-#define creat JEMALLOC_HOOK(creat, hooks_libc_hook) 61-#define secure_getenv JEMALLOC_HOOK(secure_getenv, hooks_libc_hook) 62 /* Note that this is undef'd and re-define'd in src/prof.c. */ 63 #define _Unwind_Backtrace JEMALLOC_HOOK(_Unwind_Backtrace, hooks_libc_hook) 64 65diff --git a/include/jemalloc/internal/jemalloc_internal_decls.h b/include/jemalloc/internal/jemalloc_internal_decls.h 66index 1efdb56b..12a7e5a8 100644 67--- a/include/jemalloc/internal/jemalloc_internal_decls.h 68+++ b/include/jemalloc/internal/jemalloc_internal_decls.h 69@@ -1,6 +1,9 @@ 70 #ifndef JEMALLOC_INTERNAL_DECLS_H 71 #define JEMALLOC_INTERNAL_DECLS_H 72 73+#include "libc_private.h" 74+#include "namespace.h" 75+ 76 #include <math.h> 77 #ifdef _WIN32 78 # include <windows.h> 79diff --git a/include/jemalloc/internal/jemalloc_preamble.h.in b/include/jemalloc/internal/jemalloc_preamble.h.in 80index 18539a09..c8af8683 100644 81--- a/include/jemalloc/internal/jemalloc_preamble.h.in 82+++ b/include/jemalloc/internal/jemalloc_preamble.h.in 83@@ -8,6 +8,9 @@ 84 #include <sys/ktrace.h> 85 #endif 86 87+#include "un-namespace.h" 88+#include "libc_private.h" 89+ 90 #define JEMALLOC_NO_DEMANGLE 91 #ifdef JEMALLOC_JET 92 # undef JEMALLOC_IS_MALLOC 93@@ -68,13 +71,7 @@ static const bool config_fill = 94 false 95 #endif 96 ; 97-static const bool config_lazy_lock = 98-#ifdef JEMALLOC_LAZY_LOCK 99- true 100-#else 101- false 102-#endif 103- ; 104+static const bool config_lazy_lock = true; 105 static const char * const config_malloc_conf = JEMALLOC_CONFIG_MALLOC_CONF; 106 static const bool config_prof = 107 #ifdef JEMALLOC_PROF 108diff --git a/include/jemalloc/internal/mutex.h b/include/jemalloc/internal/mutex.h 109index 6520c251..0013cbe9 100644 110--- a/include/jemalloc/internal/mutex.h 111+++ b/include/jemalloc/internal/mutex.h 112@@ -121,9 +121,6 @@ struct malloc_mutex_s { 113 114 #ifdef JEMALLOC_LAZY_LOCK 115 extern bool isthreaded; 116-#else 117-# undef isthreaded /* Undo private_namespace.h definition. */ 118-# define isthreaded true 119 #endif 120 121 bool malloc_mutex_init(malloc_mutex_t *mutex, const char *name, 122@@ -131,6 +128,7 @@ bool malloc_mutex_init(malloc_mutex_t *mutex, const char *name, 123 void malloc_mutex_prefork(tsdn_t *tsdn, malloc_mutex_t *mutex); 124 void malloc_mutex_postfork_parent(tsdn_t *tsdn, malloc_mutex_t *mutex); 125 void malloc_mutex_postfork_child(tsdn_t *tsdn, malloc_mutex_t *mutex); 126+bool malloc_mutex_first_thread(void); 127 bool malloc_mutex_boot(void); 128 void malloc_mutex_prof_data_reset(tsdn_t *tsdn, malloc_mutex_t *mutex); 129 130diff --git a/include/jemalloc/jemalloc_FreeBSD.h b/include/jemalloc/jemalloc_FreeBSD.h 131new file mode 100644 132index 00000000..355b565c 133--- /dev/null 134+++ b/include/jemalloc/jemalloc_FreeBSD.h 135@@ -0,0 +1,185 @@ 136+/* 137+ * Override settings that were generated in jemalloc_defs.h as necessary. 138+ */ 139+ 140+#undef JEMALLOC_OVERRIDE_VALLOC 141+ 142+#ifndef MALLOC_PRODUCTION 143+#define JEMALLOC_DEBUG 144+#endif 145+ 146+#undef JEMALLOC_DSS 147+ 148+#undef JEMALLOC_BACKGROUND_THREAD 149+ 150+/* 151+ * The following are architecture-dependent, so conditionally define them for 152+ * each supported architecture. 153+ */ 154+#undef JEMALLOC_TLS_MODEL 155+#undef STATIC_PAGE_SHIFT 156+#undef LG_VADDR 157+#undef LG_SIZEOF_PTR 158+#undef LG_SIZEOF_INT 159+#undef LG_SIZEOF_LONG 160+#undef LG_SIZEOF_INTMAX_T 161+ 162+#ifdef __i386__ 163+# define LG_VADDR 32 164+# define LG_SIZEOF_PTR 2 165+# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) 166+#endif 167+#ifdef __ia64__ 168+# define LG_VADDR 64 169+# define LG_SIZEOF_PTR 3 170+#endif 171+#ifdef __sparc64__ 172+# define LG_VADDR 64 173+# define LG_SIZEOF_PTR 3 174+# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) 175+#endif 176+#ifdef __amd64__ 177+# define LG_VADDR 48 178+# define LG_SIZEOF_PTR 3 179+# define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) 180+#endif 181+#ifdef __arm__ 182+# define LG_VADDR 32 183+# define LG_SIZEOF_PTR 2 184+#endif 185+#ifdef __aarch64__ 186+# define LG_VADDR 48 187+# define LG_SIZEOF_PTR 3 188+#endif 189+#ifdef __mips__ 190+#ifdef __mips_n64 191+# define LG_VADDR 64 192+# define LG_SIZEOF_PTR 3 193+#else 194+# define LG_VADDR 32 195+# define LG_SIZEOF_PTR 2 196+#endif 197+#endif 198+#ifdef __powerpc64__ 199+# define LG_VADDR 64 200+# define LG_SIZEOF_PTR 3 201+#elif defined(__powerpc__) 202+# define LG_VADDR 32 203+# define LG_SIZEOF_PTR 2 204+#endif 205+#ifdef __riscv__ 206+# define LG_VADDR 64 207+# define LG_SIZEOF_PTR 3 208+#endif 209+ 210+#ifndef JEMALLOC_TLS_MODEL 211+# define JEMALLOC_TLS_MODEL /* Default. */ 212+#endif 213+ 214+#define STATIC_PAGE_SHIFT PAGE_SHIFT 215+#define LG_SIZEOF_INT 2 216+#define LG_SIZEOF_LONG LG_SIZEOF_PTR 217+#define LG_SIZEOF_INTMAX_T 3 218+ 219+#undef CPU_SPINWAIT 220+#include <machine/cpu.h> 221+#include <machine/cpufunc.h> 222+#define CPU_SPINWAIT cpu_spinwait() 223+ 224+/* Disable lazy-lock machinery, mangle isthreaded, and adjust its type. */ 225+#undef JEMALLOC_LAZY_LOCK 226+extern int __isthreaded; 227+#define isthreaded ((bool)__isthreaded) 228+ 229+/* Mangle. */ 230+#undef je_malloc 231+#undef je_calloc 232+#undef je_posix_memalign 233+#undef je_aligned_alloc 234+#undef je_realloc 235+#undef je_free 236+#undef je_malloc_usable_size 237+#undef je_mallocx 238+#undef je_rallocx 239+#undef je_xallocx 240+#undef je_sallocx 241+#undef je_dallocx 242+#undef je_sdallocx 243+#undef je_nallocx 244+#undef je_mallctl 245+#undef je_mallctlnametomib 246+#undef je_mallctlbymib 247+#undef je_malloc_stats_print 248+#undef je_allocm 249+#undef je_rallocm 250+#undef je_sallocm 251+#undef je_dallocm 252+#undef je_nallocm 253+#define je_malloc __malloc 254+#define je_calloc __calloc 255+#define je_posix_memalign __posix_memalign 256+#define je_aligned_alloc __aligned_alloc 257+#define je_realloc __realloc 258+#define je_free __free 259+#define je_malloc_usable_size __malloc_usable_size 260+#define je_mallocx __mallocx 261+#define je_rallocx __rallocx 262+#define je_xallocx __xallocx 263+#define je_sallocx __sallocx 264+#define je_dallocx __dallocx 265+#define je_sdallocx __sdallocx 266+#define je_nallocx __nallocx 267+#define je_mallctl __mallctl 268+#define je_mallctlnametomib __mallctlnametomib 269+#define je_mallctlbymib __mallctlbymib 270+#define je_malloc_stats_print __malloc_stats_print 271+#define je_allocm __allocm 272+#define je_rallocm __rallocm 273+#define je_sallocm __sallocm 274+#define je_dallocm __dallocm 275+#define je_nallocm __nallocm 276+#define open _open 277+#define read _read 278+#define write _write 279+#define close _close 280+#define pthread_join _pthread_join 281+#define pthread_once _pthread_once 282+#define pthread_self _pthread_self 283+#define pthread_equal _pthread_equal 284+#define pthread_mutex_lock _pthread_mutex_lock 285+#define pthread_mutex_trylock _pthread_mutex_trylock 286+#define pthread_mutex_unlock _pthread_mutex_unlock 287+#define pthread_cond_init _pthread_cond_init 288+#define pthread_cond_wait _pthread_cond_wait 289+#define pthread_cond_timedwait _pthread_cond_timedwait 290+#define pthread_cond_signal _pthread_cond_signal 291+ 292+#ifdef JEMALLOC_C_ 293+/* 294+ * Define 'weak' symbols so that an application can have its own versions 295+ * of malloc, calloc, realloc, free, et al. 296+ */ 297+__weak_reference(__malloc, malloc); 298+__weak_reference(__calloc, calloc); 299+__weak_reference(__posix_memalign, posix_memalign); 300+__weak_reference(__aligned_alloc, aligned_alloc); 301+__weak_reference(__realloc, realloc); 302+__weak_reference(__free, free); 303+__weak_reference(__malloc_usable_size, malloc_usable_size); 304+__weak_reference(__mallocx, mallocx); 305+__weak_reference(__rallocx, rallocx); 306+__weak_reference(__xallocx, xallocx); 307+__weak_reference(__sallocx, sallocx); 308+__weak_reference(__dallocx, dallocx); 309+__weak_reference(__sdallocx, sdallocx); 310+__weak_reference(__nallocx, nallocx); 311+__weak_reference(__mallctl, mallctl); 312+__weak_reference(__mallctlnametomib, mallctlnametomib); 313+__weak_reference(__mallctlbymib, mallctlbymib); 314+__weak_reference(__malloc_stats_print, malloc_stats_print); 315+__weak_reference(__allocm, allocm); 316+__weak_reference(__rallocm, rallocm); 317+__weak_reference(__sallocm, sallocm); 318+__weak_reference(__dallocm, dallocm); 319+__weak_reference(__nallocm, nallocm); 320+#endif 321diff --git a/include/jemalloc/jemalloc_rename.sh b/include/jemalloc/jemalloc_rename.sh 322index f9438912..47d032c1 100755 323--- a/include/jemalloc/jemalloc_rename.sh 324+++ b/include/jemalloc/jemalloc_rename.sh 325@@ -19,4 +19,6 @@ done 326 327 cat <<EOF 328 #endif 329+ 330+#include "jemalloc_FreeBSD.h" 331 EOF 332diff --git a/src/jemalloc.c b/src/jemalloc.c 333index 52c86aa6..868c9e86 100644 334--- a/src/jemalloc.c 335+++ b/src/jemalloc.c 336@@ -20,6 +20,10 @@ 337 /******************************************************************************/ 338 /* Data. */ 339 340+/* Work around <http://llvm.org/bugs/show_bug.cgi?id=12623>: */ 341+const char *__malloc_options_1_0 = NULL; 342+__sym_compat(_malloc_options, __malloc_options_1_0, FBSD_1.0); 343+ 344 /* Runtime configuration options. */ 345 const char *je_malloc_conf 346 #ifndef _WIN32 347@@ -2981,6 +2985,103 @@ je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr) { 348 */ 349 /******************************************************************************/ 350 /* 351+ * Begin compatibility functions. 352+ */ 353+ 354+#define ALLOCM_LG_ALIGN(la) (la) 355+#define ALLOCM_ALIGN(a) (ffsl(a)-1) 356+#define ALLOCM_ZERO ((int)0x40) 357+#define ALLOCM_NO_MOVE ((int)0x80) 358+ 359+#define ALLOCM_SUCCESS 0 360+#define ALLOCM_ERR_OOM 1 361+#define ALLOCM_ERR_NOT_MOVED 2 362+ 363+int 364+je_allocm(void **ptr, size_t *rsize, size_t size, int flags) { 365+ assert(ptr != NULL); 366+ 367+ void *p = je_mallocx(size, flags); 368+ if (p == NULL) { 369+ return (ALLOCM_ERR_OOM); 370+ } 371+ if (rsize != NULL) { 372+ *rsize = isalloc(tsdn_fetch(), p); 373+ } 374+ *ptr = p; 375+ return ALLOCM_SUCCESS; 376+} 377+ 378+int 379+je_rallocm(void **ptr, size_t *rsize, size_t size, size_t extra, int flags) { 380+ assert(ptr != NULL); 381+ assert(*ptr != NULL); 382+ assert(size != 0); 383+ assert(SIZE_T_MAX - size >= extra); 384+ 385+ int ret; 386+ bool no_move = flags & ALLOCM_NO_MOVE; 387+ 388+ if (no_move) { 389+ size_t usize = je_xallocx(*ptr, size, extra, flags); 390+ ret = (usize >= size) ? ALLOCM_SUCCESS : ALLOCM_ERR_NOT_MOVED; 391+ if (rsize != NULL) { 392+ *rsize = usize; 393+ } 394+ } else { 395+ void *p = je_rallocx(*ptr, size+extra, flags); 396+ if (p != NULL) { 397+ *ptr = p; 398+ ret = ALLOCM_SUCCESS; 399+ } else { 400+ ret = ALLOCM_ERR_OOM; 401+ } 402+ if (rsize != NULL) { 403+ *rsize = isalloc(tsdn_fetch(), *ptr); 404+ } 405+ } 406+ return ret; 407+} 408+ 409+int 410+je_sallocm(const void *ptr, size_t *rsize, int flags) { 411+ assert(rsize != NULL); 412+ *rsize = je_sallocx(ptr, flags); 413+ return ALLOCM_SUCCESS; 414+} 415+ 416+int 417+je_dallocm(void *ptr, int flags) { 418+ je_dallocx(ptr, flags); 419+ return ALLOCM_SUCCESS; 420+} 421+ 422+int 423+je_nallocm(size_t *rsize, size_t size, int flags) { 424+ size_t usize = je_nallocx(size, flags); 425+ if (usize == 0) { 426+ return ALLOCM_ERR_OOM; 427+ } 428+ if (rsize != NULL) { 429+ *rsize = usize; 430+ } 431+ return ALLOCM_SUCCESS; 432+} 433+ 434+#undef ALLOCM_LG_ALIGN 435+#undef ALLOCM_ALIGN 436+#undef ALLOCM_ZERO 437+#undef ALLOCM_NO_MOVE 438+ 439+#undef ALLOCM_SUCCESS 440+#undef ALLOCM_ERR_OOM 441+#undef ALLOCM_ERR_NOT_MOVED 442+ 443+/* 444+ * End compatibility functions. 445+ */ 446+/******************************************************************************/ 447+/* 448 * The following functions are used by threading libraries for protection of 449 * malloc during fork(). 450 */ 451@@ -3141,4 +3242,11 @@ jemalloc_postfork_child(void) { 452 ctl_postfork_child(tsd_tsdn(tsd)); 453 } 454 455+void 456+_malloc_first_thread(void) 457+{ 458+ 459+ (void)malloc_mutex_first_thread(); 460+} 461+ 462 /******************************************************************************/ 463diff --git a/src/malloc_io.c b/src/malloc_io.c 464index 6b99afcd..4363cb83 100644 465--- a/src/malloc_io.c 466+++ b/src/malloc_io.c 467@@ -88,6 +88,20 @@ wrtmessage(void *cbopaque, const char *s) { 468 469 JEMALLOC_EXPORT void (*je_malloc_message)(void *, const char *s); 470 471+JEMALLOC_ATTR(visibility("hidden")) 472+void 473+wrtmessage_1_0(const char *s1, const char *s2, const char *s3, const char *s4) { 474+ 475+ wrtmessage(NULL, s1); 476+ wrtmessage(NULL, s2); 477+ wrtmessage(NULL, s3); 478+ wrtmessage(NULL, s4); 479+} 480+ 481+void (*__malloc_message_1_0)(const char *s1, const char *s2, const char *s3, 482+ const char *s4) = wrtmessage_1_0; 483+__sym_compat(_malloc_message, __malloc_message_1_0, FBSD_1.0); 484+ 485 /* 486 * Wrapper around malloc_message() that avoids the need for 487 * je_malloc_message(...) throughout the code. 488diff --git a/src/mutex.c b/src/mutex.c 489index a528ef0c..820af613 100644 490--- a/src/mutex.c 491+++ b/src/mutex.c 492@@ -40,6 +40,17 @@ pthread_create(pthread_t *__restrict thread, 493 #ifdef JEMALLOC_MUTEX_INIT_CB 494 JEMALLOC_EXPORT int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, 495 void *(calloc_cb)(size_t, size_t)); 496+ 497+#pragma weak _pthread_mutex_init_calloc_cb 498+int 499+_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, 500+ void *(calloc_cb)(size_t, size_t)) 501+{ 502+ 503+ return (((int (*)(pthread_mutex_t *, void *(*)(size_t, size_t))) 504+ __libc_interposing[INTERPOS__pthread_mutex_init_calloc_cb])(mutex, 505+ calloc_cb)); 506+} 507 #endif 508 509 void 510@@ -130,6 +141,16 @@ mutex_addr_comp(const witness_t *witness1, void *mutex1, 511 } 512 513 bool 514+malloc_mutex_first_thread(void) { 515+ 516+#ifndef JEMALLOC_MUTEX_INIT_CB 517+ return (malloc_mutex_first_thread()); 518+#else 519+ return (false); 520+#endif 521+} 522+ 523+bool 524 malloc_mutex_init(malloc_mutex_t *mutex, const char *name, 525 witness_rank_t rank, malloc_mutex_lock_order_t lock_order) { 526 mutex_prof_data_init(&mutex->prof_data); 527