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