xref: /freebsd/contrib/jemalloc/FREEBSD-diffs (revision c99b67a7947ea215f9c1d44ec022680e98920cd1)
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 &lt;<filename class="headerfile">jemalloc/jemalloc.h</filename>&gt;</funcsynopsisinfo>
23+      <funcsynopsisinfo>#include &lt;<filename class="headerfile">stdlib.h</filename>&gt;
24+#include &lt;<filename class="headerfile">malloc_np.h</filename>&gt;</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