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