prof.h revision 6e73dc194ee9682d3eacaf725a989f04629718f7
16109fe07a14b7a619365977d9523db9f8b333792Jason Evans/******************************************************************************/
26109fe07a14b7a619365977d9523db9f8b333792Jason Evans#ifdef JEMALLOC_H_TYPES
36109fe07a14b7a619365977d9523db9f8b333792Jason Evans
46109fe07a14b7a619365977d9523db9f8b333792Jason Evanstypedef struct prof_bt_s prof_bt_t;
56109fe07a14b7a619365977d9523db9f8b333792Jason Evanstypedef struct prof_cnt_s prof_cnt_t;
6602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evanstypedef struct prof_tctx_s prof_tctx_t;
7602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evanstypedef struct prof_gctx_s prof_gctx_t;
84d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evanstypedef struct prof_tdata_s prof_tdata_t;
96109fe07a14b7a619365977d9523db9f8b333792Jason Evans
10b9477e782b07afa38c4b1dc0688e053be8a84dd8Jason Evans/* Option defaults. */
115f60afa01eb2cf7d44024d162a1ecc6cceedcca1Jason Evans#ifdef JEMALLOC_PROF
125f60afa01eb2cf7d44024d162a1ecc6cceedcca1Jason Evans#  define PROF_PREFIX_DEFAULT		"jeprof"
135f60afa01eb2cf7d44024d162a1ecc6cceedcca1Jason Evans#else
145f60afa01eb2cf7d44024d162a1ecc6cceedcca1Jason Evans#  define PROF_PREFIX_DEFAULT		""
155f60afa01eb2cf7d44024d162a1ecc6cceedcca1Jason Evans#endif
160b25fe79aaf8840a5acda7e3160a053d42349872Jason Evans#define	LG_PROF_SAMPLE_DEFAULT		19
1737dab02e524c14cffa4bb938242e4cf2695a4a7dJason Evans#define	LG_PROF_INTERVAL_DEFAULT	-1
180b526ff94da7e59aa947a4d3529b2376794f8b01Jason Evans
196109fe07a14b7a619365977d9523db9f8b333792Jason Evans/*
205389146191b279ca3b90028357dd6ad66b283defJason Evans * Hard limit on stack backtrace depth.  The version of prof_backtrace() that
215389146191b279ca3b90028357dd6ad66b283defJason Evans * is based on __builtin_return_address() necessarily has a hard-coded number
225389146191b279ca3b90028357dd6ad66b283defJason Evans * of backtrace frame handlers, and should be kept in sync with this setting.
236109fe07a14b7a619365977d9523db9f8b333792Jason Evans */
245389146191b279ca3b90028357dd6ad66b283defJason Evans#define	PROF_BT_MAX			128
255389146191b279ca3b90028357dd6ad66b283defJason Evans
266109fe07a14b7a619365977d9523db9f8b333792Jason Evans/* Initial hash table size. */
27cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evans#define	PROF_CKH_MINITEMS		64
286109fe07a14b7a619365977d9523db9f8b333792Jason Evans
296109fe07a14b7a619365977d9523db9f8b333792Jason Evans/* Size of memory buffer to use when writing dump files. */
30cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evans#define	PROF_DUMP_BUFSIZE		65536
31cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evans
32cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evans/* Size of stack-allocated buffer used by prof_printf(). */
33cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evans#define	PROF_PRINTF_BUFSIZE		128
346109fe07a14b7a619365977d9523db9f8b333792Jason Evans
356da5418ded9170b087c35960e0010006430117c1Jason Evans/*
36602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans * Number of mutexes shared among all gctx's.  No space is allocated for these
376da5418ded9170b087c35960e0010006430117c1Jason Evans * unless profiling is enabled, so it's okay to over-provision.
386da5418ded9170b087c35960e0010006430117c1Jason Evans */
396da5418ded9170b087c35960e0010006430117c1Jason Evans#define	PROF_NCTX_LOCKS			1024
406da5418ded9170b087c35960e0010006430117c1Jason Evans
410050a0f7e6ea5a33c9aed769e2652afe20714194Jason Evans/*
42602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans * Number of mutexes shared among all tdata's.  No space is allocated for these
43602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans * unless profiling is enabled, so it's okay to over-provision.
44602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans */
45602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans#define	PROF_NTDATA_LOCKS		256
46602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
47602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans/*
480050a0f7e6ea5a33c9aed769e2652afe20714194Jason Evans * prof_tdata pointers close to NULL are used to encode state information that
490050a0f7e6ea5a33c9aed769e2652afe20714194Jason Evans * is used for cleaning up during thread shutdown.
500050a0f7e6ea5a33c9aed769e2652afe20714194Jason Evans */
510050a0f7e6ea5a33c9aed769e2652afe20714194Jason Evans#define	PROF_TDATA_STATE_REINCARNATED	((prof_tdata_t *)(uintptr_t)1)
520050a0f7e6ea5a33c9aed769e2652afe20714194Jason Evans#define	PROF_TDATA_STATE_PURGATORY	((prof_tdata_t *)(uintptr_t)2)
530050a0f7e6ea5a33c9aed769e2652afe20714194Jason Evans#define	PROF_TDATA_STATE_MAX		PROF_TDATA_STATE_PURGATORY
540050a0f7e6ea5a33c9aed769e2652afe20714194Jason Evans
556109fe07a14b7a619365977d9523db9f8b333792Jason Evans#endif /* JEMALLOC_H_TYPES */
566109fe07a14b7a619365977d9523db9f8b333792Jason Evans/******************************************************************************/
576109fe07a14b7a619365977d9523db9f8b333792Jason Evans#ifdef JEMALLOC_H_STRUCTS
586109fe07a14b7a619365977d9523db9f8b333792Jason Evans
596109fe07a14b7a619365977d9523db9f8b333792Jason Evansstruct prof_bt_s {
606109fe07a14b7a619365977d9523db9f8b333792Jason Evans	/* Backtrace, stored as len program counters. */
614d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	void		**vec;
624d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	unsigned	len;
636109fe07a14b7a619365977d9523db9f8b333792Jason Evans};
646109fe07a14b7a619365977d9523db9f8b333792Jason Evans
65b27805b36309681da1936eb33044584547552340Jason Evans#ifdef JEMALLOC_PROF_LIBGCC
66b27805b36309681da1936eb33044584547552340Jason Evans/* Data structure passed to libgcc _Unwind_Backtrace() callback functions. */
67b27805b36309681da1936eb33044584547552340Jason Evanstypedef struct {
68a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evans	prof_bt_t	*bt;
69a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evans	unsigned	max;
70b27805b36309681da1936eb33044584547552340Jason Evans} prof_unwind_data_t;
71b27805b36309681da1936eb33044584547552340Jason Evans#endif
72b27805b36309681da1936eb33044584547552340Jason Evans
736109fe07a14b7a619365977d9523db9f8b333792Jason Evansstruct prof_cnt_s {
74602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Profiling counters. */
75602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	uint64_t	curobjs;
76602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	uint64_t	curbytes;
776109fe07a14b7a619365977d9523db9f8b333792Jason Evans	uint64_t	accumobjs;
786109fe07a14b7a619365977d9523db9f8b333792Jason Evans	uint64_t	accumbytes;
796109fe07a14b7a619365977d9523db9f8b333792Jason Evans};
806109fe07a14b7a619365977d9523db9f8b333792Jason Evans
81602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evanstypedef enum {
82602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tctx_state_nominal,
83602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tctx_state_dumping,
84602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tctx_state_purgatory /* Dumper must finish destroying. */
85602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans} prof_tctx_state_t;
863a81cbd2d4f2d8c052f11f4b0b73ee5c84a33d4fJason Evans
87602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansstruct prof_tctx_s {
88602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Thread data for thread that performed the allocation. */
89602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tdata_t		*tdata;
90a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evans
91602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Profiling counters, protected by tdata->lock. */
92602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_cnt_t		cnts;
93602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
94602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Associated global context. */
95602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_gctx_t		*gctx;
96602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
97602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Linkage into gctx's tctxs. */
98602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	rb_node(prof_tctx_t)	tctx_link;
99602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
1006e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans	/*
1016e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans	 * True during prof_alloc_prep()..prof_malloc_sample_object(), prevents
1026e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans	 * sample vs destroy race.
1036e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans	 */
1046e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans	bool			prepared;
1056e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans
106602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Current dump-related state, protected by gctx->lock. */
107602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tctx_state_t	state;
1086109fe07a14b7a619365977d9523db9f8b333792Jason Evans
1096109fe07a14b7a619365977d9523db9f8b333792Jason Evans	/*
110602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * Copy of cnts snapshotted during early dump phase, protected by
111602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * dump_mtx.
1126109fe07a14b7a619365977d9523db9f8b333792Jason Evans	 */
113602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_cnt_t		dump_cnts;
1146109fe07a14b7a619365977d9523db9f8b333792Jason Evans};
115602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evanstypedef rb_tree(prof_tctx_t) prof_tctx_tree_t;
1166109fe07a14b7a619365977d9523db9f8b333792Jason Evans
117602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansstruct prof_gctx_s {
118602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Protects nlimbo, cnt_summed, and tctxs. */
1196da5418ded9170b087c35960e0010006430117c1Jason Evans	malloc_mutex_t		*lock;
1206109fe07a14b7a619365977d9523db9f8b333792Jason Evans
12152386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	/*
122602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * Number of threads that currently cause this gctx to be in a state of
12352386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	 * limbo due to one of:
124602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 *   - Initializing this gctx.
125602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 *   - Initializing per thread counters associated with this gctx.
126602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 *   - Preparing to destroy this gctx.
127602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 *   - Dumping a heap profile that includes this gctx.
12852386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	 * nlimbo must be 1 (single destroyer) in order to safely destroy the
129602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * gctx.
13052386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	 */
13152386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	unsigned		nlimbo;
13252386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans
1336109fe07a14b7a619365977d9523db9f8b333792Jason Evans	/*
1343a81cbd2d4f2d8c052f11f4b0b73ee5c84a33d4fJason Evans	 * Tree of profile counters, one for each thread that has allocated in
1356109fe07a14b7a619365977d9523db9f8b333792Jason Evans	 * this context.
1366109fe07a14b7a619365977d9523db9f8b333792Jason Evans	 */
137602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tctx_tree_t	tctxs;
1384f37ef693e3d5903ce07dc0b61c0da320b35e3d9Jason Evans
1393a81cbd2d4f2d8c052f11f4b0b73ee5c84a33d4fJason Evans	/* Linkage for tree of contexts to be dumped. */
140602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	rb_node(prof_gctx_t)	dump_link;
141602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
142602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Temporary storage for summation during dump. */
143602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_cnt_t		cnt_summed;
144ab532e97991d190e9368781cf308c60c2319b933Jason Evans
145ab532e97991d190e9368781cf308c60c2319b933Jason Evans	/* Associated backtrace. */
146ab532e97991d190e9368781cf308c60c2319b933Jason Evans	prof_bt_t		bt;
147ab532e97991d190e9368781cf308c60c2319b933Jason Evans
148ab532e97991d190e9368781cf308c60c2319b933Jason Evans	/* Backtrace vector, variable size, referred to by bt. */
149ab532e97991d190e9368781cf308c60c2319b933Jason Evans	void			*vec[1];
1506109fe07a14b7a619365977d9523db9f8b333792Jason Evans};
151602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evanstypedef rb_tree(prof_gctx_t) prof_gctx_tree_t;
152602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
153602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evanstypedef enum {
154602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tdata_state_attached, /* Active thread attached, data valid. */
155602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tdata_state_detached, /* Defunct thread, data remain valid. */
156602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tdata_state_expired   /* Predates reset, omit data from dump. */
157602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans} prof_tdata_state_t;
1586109fe07a14b7a619365977d9523db9f8b333792Jason Evans
1594d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evansstruct prof_tdata_s {
160602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	malloc_mutex_t		*lock;
161602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
162602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Monotonically increasing unique thread identifier. */
163602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	uint64_t		thr_uid;
164602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
165602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Included in heap profile dumps if non-NULL. */
166602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	char			*thread_name;
167602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
168602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tdata_state_t	state;
169602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
170602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	rb_node(prof_tdata_t)	tdata_link;
171602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
1724d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	/*
173602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * Hash of (prof_bt_t *)-->(prof_tctx_t *).  Each thread tracks
174b41ccdb125b312d4522da1a80091a0137773c964Jason Evans	 * backtraces for which it has non-zero allocation/deallocation counters
175602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * associated with thread-specific prof_tctx_t objects.  Other threads
176602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * may write to prof_tctx_t contents when freeing associated objects.
1774d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	 */
178602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	ckh_t			bt2tctx;
179a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evans
1804d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	/* Sampling state. */
18184f7cdb0c588322dfd50a26497fc1cb54b792018Jason Evans	uint64_t		prng_state;
1826c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer	uint64_t		bytes_until_sample;
18352386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans
18452386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	/* State used to avoid dumping while operating on prof internals. */
18552386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	bool			enq;
18652386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	bool			enq_idump;
18752386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	bool			enq_gdump;
188b41ccdb125b312d4522da1a80091a0137773c964Jason Evans
189602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/*
190602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * Set to true during an early dump phase for tdata's which are
191602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * currently being dumped.  New threads' tdata's have this initialized
192602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * to false so that they aren't accidentally included in later dump
193602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * phases.
194602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 */
195602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	bool			dumping;
196602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
197602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/*
198602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * True if profiling is active for this tdata's thread
199602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 * (thread.prof.active mallctl).
200602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	 */
201602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	bool			active;
202602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
203602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	/* Temporary storage for summation during dump. */
204602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_cnt_t		cnt_summed;
205602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
206b41ccdb125b312d4522da1a80091a0137773c964Jason Evans	/* Backtrace vector, used for calls to prof_backtrace(). */
207b41ccdb125b312d4522da1a80091a0137773c964Jason Evans	void			*vec[PROF_BT_MAX];
208a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evans};
209602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evanstypedef rb_tree(prof_tdata_t) prof_tdata_tree_t;
210a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evans
2116109fe07a14b7a619365977d9523db9f8b333792Jason Evans#endif /* JEMALLOC_H_STRUCTS */
2126109fe07a14b7a619365977d9523db9f8b333792Jason Evans/******************************************************************************/
2136109fe07a14b7a619365977d9523db9f8b333792Jason Evans#ifdef JEMALLOC_H_EXTERNS
2146109fe07a14b7a619365977d9523db9f8b333792Jason Evans
2156109fe07a14b7a619365977d9523db9f8b333792Jason Evansextern bool	opt_prof;
216f18c98200145de70779a1b3286e7829b0268231eJason Evans/*
217f18c98200145de70779a1b3286e7829b0268231eJason Evans * Even if opt_prof is true, sampling can be temporarily disabled by setting
218f18c98200145de70779a1b3286e7829b0268231eJason Evans * opt_prof_active to false.  No locking is used when updating opt_prof_active,
219f18c98200145de70779a1b3286e7829b0268231eJason Evans * so there are no guarantees regarding how long it will take for all threads
220f18c98200145de70779a1b3286e7829b0268231eJason Evans * to notice state changes.
221f18c98200145de70779a1b3286e7829b0268231eJason Evans */
222f18c98200145de70779a1b3286e7829b0268231eJason Evansextern bool	opt_prof_active;
223a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evansextern size_t	opt_lg_prof_sample;   /* Mean bytes between samples. */
224a02fc08ec9dd8479a6430155b6a433da09f6ff10Jason Evansextern ssize_t	opt_lg_prof_interval; /* lg(prof_interval). */
225e73397062ac3ab28a9d377591b63ed19fd154ccaJason Evansextern bool	opt_prof_gdump;       /* High-water memory dumping. */
2260b25fe79aaf8840a5acda7e3160a053d42349872Jason Evansextern bool	opt_prof_final;       /* Final profile dumping. */
227a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evansextern bool	opt_prof_leak;        /* Dump leak summary at exit. */
228a881cd2c61c1ced56f87fcb9d7ef6e92b81e6c58Jason Evansextern bool	opt_prof_accum;       /* Report cumulative bytes. */
229eefdd02e70ec1b9cf11920fcff585835dcbd766bJason Evansextern char	opt_prof_prefix[
230eefdd02e70ec1b9cf11920fcff585835dcbd766bJason Evans    /* Minimize memory bloat for non-prof builds. */
231eefdd02e70ec1b9cf11920fcff585835dcbd766bJason Evans#ifdef JEMALLOC_PROF
232eefdd02e70ec1b9cf11920fcff585835dcbd766bJason Evans    PATH_MAX +
233eefdd02e70ec1b9cf11920fcff585835dcbd766bJason Evans#endif
234eefdd02e70ec1b9cf11920fcff585835dcbd766bJason Evans    1];
2356109fe07a14b7a619365977d9523db9f8b333792Jason Evans
236d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evans/*
237d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evans * Profile dump interval, measured in bytes allocated.  Each arena triggers a
238d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evans * profile dump when it reaches this threshold.  The effect is that the
239d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evans * interval between profile dumps averages prof_interval, though the actual
240d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evans * interval between dumps will tend to be sporadic, and the interval will be a
241d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evans * maximum of approximately (prof_interval * narenas).
242d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evans */
243d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evansextern uint64_t	prof_interval;
244d34f9e7e9306698e298a703c28526cd6bfc073ecJason Evans
245602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans/*
246602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans * Initialized as opt_lg_prof_sample, and potentially modified during profiling
247602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans * resets.
248602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans */
249602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansextern size_t	lg_prof_sample;
250602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
2516e73dc194ee9682d3eacaf725a989f04629718f7Jason Evansvoid	prof_alloc_rollback(prof_tctx_t *tctx, bool updated);
252602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_malloc_sample_object(const void *ptr, size_t usize,
253602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans    prof_tctx_t *tctx);
254602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_free_sampled_object(size_t usize, prof_tctx_t *tctx);
2554d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evansvoid	bt_init(prof_bt_t *bt, void **vec);
2566f001059aa33d77a3cb7799002044faf8dd08fc0Jason Evansvoid	prof_backtrace(prof_bt_t *bt);
257602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansprof_tctx_t	*prof_lookup(prof_bt_t *bt);
258772163b4f3d8e9a12343e9215f6b070068507604Jason Evans#ifdef JEMALLOC_JET
259772163b4f3d8e9a12343e9215f6b070068507604Jason Evanssize_t	prof_bt_count(void);
260772163b4f3d8e9a12343e9215f6b070068507604Jason Evanstypedef int (prof_dump_open_t)(bool, const char *);
261772163b4f3d8e9a12343e9215f6b070068507604Jason Evansextern prof_dump_open_t *prof_dump_open;
262772163b4f3d8e9a12343e9215f6b070068507604Jason Evans#endif
2636109fe07a14b7a619365977d9523db9f8b333792Jason Evansvoid	prof_idump(void);
26422ca855e8fbf4c592f5e46aaec381b68de60c71aJason Evansbool	prof_mdump(const char *filename);
265e73397062ac3ab28a9d377591b63ed19fd154ccaJason Evansvoid	prof_gdump(void);
2664d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evansprof_tdata_t	*prof_tdata_init(void);
267602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansprof_tdata_t	*prof_tdata_reinit(prof_tdata_t *tdata);
268602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_reset(size_t lg_sample);
269cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evansvoid	prof_tdata_cleanup(void *arg);
270602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansconst char	*prof_thread_name_get(void);
271602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansbool	prof_thread_name_set(const char *thread_name);
272602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansbool	prof_thread_active_get(void);
273602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansbool	prof_thread_active_set(bool active);
2746109fe07a14b7a619365977d9523db9f8b333792Jason Evansvoid	prof_boot0(void);
275e73397062ac3ab28a9d377591b63ed19fd154ccaJason Evansvoid	prof_boot1(void);
276e73397062ac3ab28a9d377591b63ed19fd154ccaJason Evansbool	prof_boot2(void);
27720f1fc95adb35ea63dc61f47f2b0ffbd37d39f32Jason Evansvoid	prof_prefork(void);
27820f1fc95adb35ea63dc61f47f2b0ffbd37d39f32Jason Evansvoid	prof_postfork_parent(void);
27920f1fc95adb35ea63dc61f47f2b0ffbd37d39f32Jason Evansvoid	prof_postfork_child(void);
280602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_sample_threshold_update(prof_tdata_t *tdata);
2816109fe07a14b7a619365977d9523db9f8b333792Jason Evans
2826109fe07a14b7a619365977d9523db9f8b333792Jason Evans#endif /* JEMALLOC_H_EXTERNS */
2836109fe07a14b7a619365977d9523db9f8b333792Jason Evans/******************************************************************************/
2846109fe07a14b7a619365977d9523db9f8b333792Jason Evans#ifdef JEMALLOC_H_INLINES
2856109fe07a14b7a619365977d9523db9f8b333792Jason Evans
2864d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans#ifndef JEMALLOC_ENABLE_INLINE
287cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evansmalloc_tsd_protos(JEMALLOC_ATTR(unused), prof_tdata, prof_tdata_t *)
288cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evans
289bbe29d374d0fa5f4684621f16c099294e56c26efJason Evansprof_tdata_t	*prof_tdata_get(bool create);
290602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansbool	prof_sample_accum_update(size_t usize, bool commit,
291602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans    prof_tdata_t **tdata_out);
2926e73dc194ee9682d3eacaf725a989f04629718f7Jason Evansprof_tctx_t	*prof_alloc_prep(size_t usize, bool update);
293602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansprof_tctx_t	*prof_tctx_get(const void *ptr);
294602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_tctx_set(const void *ptr, prof_tctx_t *tctx);
295602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_malloc_sample_object(const void *ptr, size_t usize,
296602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans    prof_tctx_t *tctx);
297602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx);
298602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_realloc(const void *ptr, size_t usize, prof_tctx_t *tctx,
2996e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans    bool updated, size_t old_usize, prof_tctx_t *old_tctx);
300602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansvoid	prof_free(const void *ptr, size_t usize);
3014d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans#endif
3024d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3034d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_PROF_C_))
304602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans/* Thread-specific backtrace cache, used to reduce bt2gctx contention. */
305cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evansmalloc_tsd_externs(prof_tdata, prof_tdata_t *)
306cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evansmalloc_tsd_funcs(JEMALLOC_INLINE, prof_tdata, prof_tdata_t *, NULL,
307cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evans    prof_tdata_cleanup)
308cd9a1346e96f71bdecdc654ea50fc62d76371e74Jason Evans
30952386b2dc689db3bf71307424c4e1a2b7044c363Jason EvansJEMALLOC_INLINE prof_tdata_t *
310bbe29d374d0fa5f4684621f16c099294e56c26efJason Evansprof_tdata_get(bool create)
31152386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans{
312602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tdata_t *tdata;
31352386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans
31452386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans	cassert(config_prof);
31552386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans
316602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	tdata = *prof_tdata_tsd_get();
317602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if (create) {
3186fd53da030b5e9161a49d6010a8b38499ca2a124Jason Evans		if ((uintptr_t)tdata <= (uintptr_t)PROF_TDATA_STATE_MAX) {
3196fd53da030b5e9161a49d6010a8b38499ca2a124Jason Evans			if (tdata == NULL)
3206fd53da030b5e9161a49d6010a8b38499ca2a124Jason Evans				tdata = prof_tdata_init();
3216fd53da030b5e9161a49d6010a8b38499ca2a124Jason Evans		} else if (tdata->state == prof_tdata_state_expired)
322602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			tdata = prof_tdata_reinit(tdata);
3236fd53da030b5e9161a49d6010a8b38499ca2a124Jason Evans		assert((uintptr_t)tdata <= (uintptr_t)PROF_TDATA_STATE_MAX ||
3246fd53da030b5e9161a49d6010a8b38499ca2a124Jason Evans		    tdata->state == prof_tdata_state_attached);
325602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	}
32652386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans
327602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	return (tdata);
32852386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans}
32952386b2dc689db3bf71307424c4e1a2b7044c363Jason Evans
330602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason EvansJEMALLOC_INLINE prof_tctx_t *
331602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansprof_tctx_get(const void *ptr)
3324d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans{
333602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tctx_t *ret;
3344d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	arena_chunk_t *chunk;
3354d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3367372b15a31c63ac5cb9ed8aeabc2a0a3c005e8bfJason Evans	cassert(config_prof);
3374d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	assert(ptr != NULL);
3384d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3394d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3404d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	if (chunk != ptr) {
3414d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans		/* Region. */
342602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		ret = arena_prof_tctx_get(ptr);
3434d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	} else
344602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		ret = huge_prof_tctx_get(ptr);
3454d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3464d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	return (ret);
3474d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans}
3484d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3494d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason EvansJEMALLOC_INLINE void
350602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansprof_tctx_set(const void *ptr, prof_tctx_t *tctx)
3514d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans{
3524d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	arena_chunk_t *chunk;
3534d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3547372b15a31c63ac5cb9ed8aeabc2a0a3c005e8bfJason Evans	cassert(config_prof);
3554d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	assert(ptr != NULL);
3564d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3574d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3584d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	if (chunk != ptr) {
3594d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans		/* Region. */
360602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		arena_prof_tctx_set(ptr, tctx);
3614d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	} else
362602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		huge_prof_tctx_set(ptr, tctx);
3634d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans}
3644d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3654d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason EvansJEMALLOC_INLINE bool
3666e73dc194ee9682d3eacaf725a989f04629718f7Jason Evansprof_sample_accum_update(size_t usize, bool update, prof_tdata_t **tdata_out)
3674d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans{
368602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tdata_t *tdata;
3694d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
3707372b15a31c63ac5cb9ed8aeabc2a0a3c005e8bfJason Evans	cassert(config_prof);
3714d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
372602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	tdata = prof_tdata_get(true);
373602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if ((uintptr_t)tdata <= (uintptr_t)PROF_TDATA_STATE_MAX)
374602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		tdata = NULL;
3756c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer
376602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if (tdata_out != NULL)
377602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		*tdata_out = tdata;
3786c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer
379602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if (tdata == NULL)
380f27899402914065a6c1484ea8d81a2c8b70aa659Jason Evans		return (true);
3814d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
382602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if (tdata->bytes_until_sample >= usize) {
3836e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans		if (update)
384602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			tdata->bytes_until_sample -= usize;
3856c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer		return (true);
3866c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer	} else {
387ff7450727f64180367f430b1b747f9e682e26df4Jason Evans		/* Compute new sample threshold. */
3886e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans		if (update)
389602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			prof_sample_threshold_update(tdata);
390602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		return (tdata->active == false);
3914d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	}
3924d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans}
3934d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
394602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason EvansJEMALLOC_INLINE prof_tctx_t *
3956e73dc194ee9682d3eacaf725a989f04629718f7Jason Evansprof_alloc_prep(size_t usize, bool update)
396602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans{
397602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tctx_t *ret;
398602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tdata_t *tdata;
399602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_bt_t bt;
400602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
401602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	assert(usize == s2u(usize));
402602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
4036e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans	if (!opt_prof_active || prof_sample_accum_update(usize, update, &tdata))
404602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		ret = (prof_tctx_t *)(uintptr_t)1U;
405602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	else {
406602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		bt_init(&bt, tdata->vec);
407602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		prof_backtrace(&bt);
408602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		ret = prof_lookup(&bt);
4096c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer	}
410602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans
411602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	return (ret);
4126c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer}
4136c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer
4146c39f9e059d0825f4c29d8cec9f318b798912c3cBen MaurerJEMALLOC_INLINE void
415602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansprof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx)
4164d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans{
4174d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
4187372b15a31c63ac5cb9ed8aeabc2a0a3c005e8bfJason Evans	cassert(config_prof);
4194d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	assert(ptr != NULL);
420665769357cd77b74e00a146f196fff19243b33c4Jason Evans	assert(usize == isalloc(ptr, true));
4214d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
422602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if ((uintptr_t)tctx > (uintptr_t)1U)
423602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		prof_malloc_sample_object(ptr, usize, tctx);
4246c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer	else
425602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U);
4264d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans}
4274d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
4284d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason EvansJEMALLOC_INLINE void
4296e73dc194ee9682d3eacaf725a989f04629718f7Jason Evansprof_realloc(const void *ptr, size_t usize, prof_tctx_t *tctx, bool updated,
4306e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans    size_t old_usize, prof_tctx_t *old_tctx)
4314d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans{
4324d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
4337372b15a31c63ac5cb9ed8aeabc2a0a3c005e8bfJason Evans	cassert(config_prof);
434602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	assert(ptr != NULL || (uintptr_t)tctx <= (uintptr_t)1U);
4354d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
4366e73dc194ee9682d3eacaf725a989f04629718f7Jason Evans	if (!updated && ptr != NULL) {
437665769357cd77b74e00a146f196fff19243b33c4Jason Evans		assert(usize == isalloc(ptr, true));
4386c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer		if (prof_sample_accum_update(usize, true, NULL)) {
4396c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer			/*
440602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			 * Don't sample.  The usize passed to PROF_ALLOC_PREP()
441602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			 * was larger than what actually got allocated, so a
442602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			 * backtrace was captured for this allocation, even
443602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			 * though its actual usize was insufficient to cross the
444602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			 * sample threshold.
4456c39f9e059d0825f4c29d8cec9f318b798912c3cBen Maurer			 */
446602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans			tctx = (prof_tctx_t *)(uintptr_t)1U;
4474d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans		}
4484d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans	}
4494d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
450602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if ((uintptr_t)old_tctx > (uintptr_t)1U)
451602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		prof_free_sampled_object(old_usize, old_tctx);
452602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if ((uintptr_t)tctx > (uintptr_t)1U)
453602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		prof_malloc_sample_object(ptr, usize, tctx);
454602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	else
455602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U);
4564d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans}
4574d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
4584d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason EvansJEMALLOC_INLINE void
459602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evansprof_free(const void *ptr, size_t usize)
4604d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans{
461602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	prof_tctx_t *tctx = prof_tctx_get(ptr);
4624d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
4637372b15a31c63ac5cb9ed8aeabc2a0a3c005e8bfJason Evans	cassert(config_prof);
464602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	assert(usize == isalloc(ptr, true));
4657372b15a31c63ac5cb9ed8aeabc2a0a3c005e8bfJason Evans
466602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans	if ((uintptr_t)tctx > (uintptr_t)1U)
467602c8e0971160e4b85b08b16cf8a2375aa24bc04Jason Evans		prof_free_sampled_object(usize, tctx);
4684d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans}
4694d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans#endif
4704d6a134e13e1e9705faff6f5dc6ca90d416aa0a4Jason Evans
4716109fe07a14b7a619365977d9523db9f8b333792Jason Evans#endif /* JEMALLOC_H_INLINES */
4726109fe07a14b7a619365977d9523db9f8b333792Jason Evans/******************************************************************************/
473