Update jemalloc to 4.0.2.
This commit is contained in:
parent
6acf853d7a
commit
536b3538e0
@ -4,6 +4,76 @@ brevity. Much more detail can be found in the git revision history:
|
|||||||
|
|
||||||
https://github.com/jemalloc/jemalloc
|
https://github.com/jemalloc/jemalloc
|
||||||
|
|
||||||
|
* 4.0.2 (September 21, 2015)
|
||||||
|
|
||||||
|
This bugfix release addresses a few bugs specific to heap profiling.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Fix ixallocx_prof_sample() to never modify nor create sampled small
|
||||||
|
allocations. xallocx() is in general incapable of moving small allocations,
|
||||||
|
so this fix removes buggy code without loss of generality.
|
||||||
|
- Fix irallocx_prof_sample() to always allocate large regions, even when
|
||||||
|
alignment is non-zero.
|
||||||
|
- Fix prof_alloc_rollback() to read tdata from thread-specific data rather
|
||||||
|
than dereferencing a potentially invalid tctx.
|
||||||
|
|
||||||
|
* 4.0.1 (September 15, 2015)
|
||||||
|
|
||||||
|
This is a bugfix release that is somewhat high risk due to the amount of
|
||||||
|
refactoring required to address deep xallocx() problems. As a side effect of
|
||||||
|
these fixes, xallocx() now tries harder to partially fulfill requests for
|
||||||
|
optional extra space. Note that a couple of minor heap profiling
|
||||||
|
optimizations are included, but these are better thought of as performance
|
||||||
|
fixes that were integral to disovering most of the other bugs.
|
||||||
|
|
||||||
|
Optimizations:
|
||||||
|
- Avoid a chunk metadata read in arena_prof_tctx_set(), since it is in the
|
||||||
|
fast path when heap profiling is enabled. Additionally, split a special
|
||||||
|
case out into arena_prof_tctx_reset(), which also avoids chunk metadata
|
||||||
|
reads.
|
||||||
|
- Optimize irallocx_prof() to optimistically update the sampler state. The
|
||||||
|
prior implementation appears to have been a holdover from when
|
||||||
|
rallocx()/xallocx() functionality was combined as rallocm().
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Fix TLS configuration such that it is enabled by default for platforms on
|
||||||
|
which it works correctly.
|
||||||
|
- Fix arenas_cache_cleanup() and arena_get_hard() to handle
|
||||||
|
allocation/deallocation within the application's thread-specific data
|
||||||
|
cleanup functions even after arenas_cache is torn down.
|
||||||
|
- Fix xallocx() bugs related to size+extra exceeding HUGE_MAXCLASS.
|
||||||
|
- Fix chunk purge hook calls for in-place huge shrinking reallocation to
|
||||||
|
specify the old chunk size rather than the new chunk size. This bug caused
|
||||||
|
no correctness issues for the default chunk purge function, but was
|
||||||
|
visible to custom functions set via the "arena.<i>.chunk_hooks" mallctl.
|
||||||
|
- Fix heap profiling bugs:
|
||||||
|
+ Fix heap profiling to distinguish among otherwise identical sample sites
|
||||||
|
with interposed resets (triggered via the "prof.reset" mallctl). This bug
|
||||||
|
could cause data structure corruption that would most likely result in a
|
||||||
|
segfault.
|
||||||
|
+ Fix irealloc_prof() to prof_alloc_rollback() on OOM.
|
||||||
|
+ Make one call to prof_active_get_unlocked() per allocation event, and use
|
||||||
|
the result throughout the relevant functions that handle an allocation
|
||||||
|
event. Also add a missing check in prof_realloc(). These fixes protect
|
||||||
|
allocation events against concurrent prof_active changes.
|
||||||
|
+ Fix ixallocx_prof() to pass usize_max and zero to ixallocx_prof_sample()
|
||||||
|
in the correct order.
|
||||||
|
+ Fix prof_realloc() to call prof_free_sampled_object() after calling
|
||||||
|
prof_malloc_sample_object(). Prior to this fix, if tctx and old_tctx were
|
||||||
|
the same, the tctx could have been prematurely destroyed.
|
||||||
|
- Fix portability bugs:
|
||||||
|
+ Don't bitshift by negative amounts when encoding/decoding run sizes in
|
||||||
|
chunk header maps. This affected systems with page sizes greater than 8
|
||||||
|
KiB.
|
||||||
|
+ Rename index_t to szind_t to avoid an existing type on Solaris.
|
||||||
|
+ Add JEMALLOC_CXX_THROW to the memalign() function prototype, in order to
|
||||||
|
match glibc and avoid compilation errors when including both
|
||||||
|
jemalloc/jemalloc.h and malloc.h in C++ code.
|
||||||
|
+ Don't assume that /bin/sh is appropriate when running size_classes.sh
|
||||||
|
during configuration.
|
||||||
|
+ Consider __sparcv9 a synonym for __sparc64__ when defining LG_QUANTUM.
|
||||||
|
+ Link tests to librt if it contains clock_gettime(2).
|
||||||
|
|
||||||
* 4.0.0 (August 17, 2015)
|
* 4.0.0 (August 17, 2015)
|
||||||
|
|
||||||
This version contains many speed and space optimizations, both minor and
|
This version contains many speed and space optimizations, both minor and
|
||||||
|
@ -47,7 +47,7 @@ index 8fc774b..fdbef95 100644
|
|||||||
+ </refsect1>
|
+ </refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in
|
diff --git a/include/jemalloc/internal/jemalloc_internal.h.in b/include/jemalloc/internal/jemalloc_internal.h.in
|
||||||
index 7a137b6..b0001e9 100644
|
index 8536a3e..0c2a81f 100644
|
||||||
--- a/include/jemalloc/internal/jemalloc_internal.h.in
|
--- a/include/jemalloc/internal/jemalloc_internal.h.in
|
||||||
+++ b/include/jemalloc/internal/jemalloc_internal.h.in
|
+++ b/include/jemalloc/internal/jemalloc_internal.h.in
|
||||||
@@ -8,6 +8,9 @@
|
@@ -8,6 +8,9 @@
|
||||||
@ -111,10 +111,10 @@ index f051f29..561378f 100644
|
|||||||
|
|
||||||
#endif /* JEMALLOC_H_EXTERNS */
|
#endif /* JEMALLOC_H_EXTERNS */
|
||||||
diff --git a/include/jemalloc/internal/private_symbols.txt b/include/jemalloc/internal/private_symbols.txt
|
diff --git a/include/jemalloc/internal/private_symbols.txt b/include/jemalloc/internal/private_symbols.txt
|
||||||
index dbf6aa7..f87dba8 100644
|
index a90021a..34904bf 100644
|
||||||
--- a/include/jemalloc/internal/private_symbols.txt
|
--- a/include/jemalloc/internal/private_symbols.txt
|
||||||
+++ b/include/jemalloc/internal/private_symbols.txt
|
+++ b/include/jemalloc/internal/private_symbols.txt
|
||||||
@@ -277,7 +277,6 @@ iralloct_realign
|
@@ -280,7 +280,6 @@ iralloct_realign
|
||||||
isalloc
|
isalloc
|
||||||
isdalloct
|
isdalloct
|
||||||
isqalloc
|
isqalloc
|
||||||
@ -282,7 +282,7 @@ index f943891..47d032c 100755
|
|||||||
+#include "jemalloc_FreeBSD.h"
|
+#include "jemalloc_FreeBSD.h"
|
||||||
EOF
|
EOF
|
||||||
diff --git a/src/jemalloc.c b/src/jemalloc.c
|
diff --git a/src/jemalloc.c b/src/jemalloc.c
|
||||||
index ed7863b..d078a1f 100644
|
index 5a2d324..b6cbb79 100644
|
||||||
--- a/src/jemalloc.c
|
--- a/src/jemalloc.c
|
||||||
+++ b/src/jemalloc.c
|
+++ b/src/jemalloc.c
|
||||||
@@ -4,6 +4,10 @@
|
@@ -4,6 +4,10 @@
|
||||||
@ -296,7 +296,7 @@ index ed7863b..d078a1f 100644
|
|||||||
/* Runtime configuration options. */
|
/* Runtime configuration options. */
|
||||||
const char *je_malloc_conf JEMALLOC_ATTR(weak);
|
const char *je_malloc_conf JEMALLOC_ATTR(weak);
|
||||||
bool opt_abort =
|
bool opt_abort =
|
||||||
@@ -2475,6 +2479,107 @@ je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)
|
@@ -2490,6 +2494,107 @@ je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr)
|
||||||
*/
|
*/
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/*
|
/*
|
||||||
@ -404,7 +404,7 @@ index ed7863b..d078a1f 100644
|
|||||||
* The following functions are used by threading libraries for protection of
|
* The following functions are used by threading libraries for protection of
|
||||||
* malloc during fork().
|
* malloc during fork().
|
||||||
*/
|
*/
|
||||||
@@ -2575,4 +2680,11 @@ jemalloc_postfork_child(void)
|
@@ -2590,4 +2695,11 @@ jemalloc_postfork_child(void)
|
||||||
ctl_postfork_child();
|
ctl_postfork_child();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
4.0.0-0-g6e98caf8f064482b9ab292ef3638dea67420bbc2
|
4.0.2-0-g486d249fb4715fd3de679b6c2a04f7e657883111
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
.\" Title: JEMALLOC
|
.\" Title: JEMALLOC
|
||||||
.\" Author: Jason Evans
|
.\" Author: Jason Evans
|
||||||
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
|
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
|
||||||
.\" Date: 08/18/2015
|
.\" Date: 09/21/2015
|
||||||
.\" Manual: User Manual
|
.\" Manual: User Manual
|
||||||
.\" Source: jemalloc 4.0.0-0-g6e98caf8f064482b9ab292ef3638dea67420bbc2
|
.\" Source: jemalloc 4.0.2-0-g486d249fb4715fd3de679b6c2a04f7e657883111
|
||||||
.\" Language: English
|
.\" Language: English
|
||||||
.\"
|
.\"
|
||||||
.TH "JEMALLOC" "3" "08/18/2015" "jemalloc 4.0.0-0-g6e98caf8f064" "User Manual"
|
.TH "JEMALLOC" "3" "09/21/2015" "jemalloc 4.0.2-0-g486d249fb471" "User Manual"
|
||||||
.\" -----------------------------------------------------------------
|
.\" -----------------------------------------------------------------
|
||||||
.\" * Define some portability stuff
|
.\" * Define some portability stuff
|
||||||
.\" -----------------------------------------------------------------
|
.\" -----------------------------------------------------------------
|
||||||
@ -31,7 +31,7 @@
|
|||||||
jemalloc \- general purpose memory allocation functions
|
jemalloc \- general purpose memory allocation functions
|
||||||
.SH "LIBRARY"
|
.SH "LIBRARY"
|
||||||
.PP
|
.PP
|
||||||
This manual describes jemalloc 4\&.0\&.0\-0\-g6e98caf8f064482b9ab292ef3638dea67420bbc2\&. More information can be found at the
|
This manual describes jemalloc 4\&.0\&.2\-0\-g486d249fb4715fd3de679b6c2a04f7e657883111\&. More information can be found at the
|
||||||
\m[blue]\fBjemalloc website\fR\m[]\&\s-2\u[1]\d\s+2\&.
|
\m[blue]\fBjemalloc website\fR\m[]\&\s-2\u[1]\d\s+2\&.
|
||||||
.PP
|
.PP
|
||||||
The following configuration options are enabled in libc\*(Aqs built\-in jemalloc:
|
The following configuration options are enabled in libc\*(Aqs built\-in jemalloc:
|
||||||
|
@ -39,7 +39,7 @@ typedef struct arena_s arena_t;
|
|||||||
#ifdef JEMALLOC_ARENA_STRUCTS_A
|
#ifdef JEMALLOC_ARENA_STRUCTS_A
|
||||||
struct arena_run_s {
|
struct arena_run_s {
|
||||||
/* Index of bin this run is associated with. */
|
/* Index of bin this run is associated with. */
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
|
|
||||||
/* Number of free regions in run. */
|
/* Number of free regions in run. */
|
||||||
unsigned nfree;
|
unsigned nfree;
|
||||||
@ -424,7 +424,7 @@ extern arena_bin_info_t arena_bin_info[NBINS];
|
|||||||
extern size_t map_bias; /* Number of arena chunk header pages. */
|
extern size_t map_bias; /* Number of arena chunk header pages. */
|
||||||
extern size_t map_misc_offset;
|
extern size_t map_misc_offset;
|
||||||
extern size_t arena_maxrun; /* Max run size for arenas. */
|
extern size_t arena_maxrun; /* Max run size for arenas. */
|
||||||
extern size_t arena_maxclass; /* Max size class for arenas. */
|
extern size_t large_maxclass; /* Max large size class. */
|
||||||
extern unsigned nlclasses; /* Number of large size classes. */
|
extern unsigned nlclasses; /* Number of large size classes. */
|
||||||
extern unsigned nhclasses; /* Number of huge size classes. */
|
extern unsigned nhclasses; /* Number of huge size classes. */
|
||||||
|
|
||||||
@ -448,7 +448,7 @@ bool arena_lg_dirty_mult_set(arena_t *arena, ssize_t lg_dirty_mult);
|
|||||||
void arena_maybe_purge(arena_t *arena);
|
void arena_maybe_purge(arena_t *arena);
|
||||||
void arena_purge_all(arena_t *arena);
|
void arena_purge_all(arena_t *arena);
|
||||||
void arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin,
|
void arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin,
|
||||||
index_t binind, uint64_t prof_accumbytes);
|
szind_t binind, uint64_t prof_accumbytes);
|
||||||
void arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info,
|
void arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info,
|
||||||
bool zero);
|
bool zero);
|
||||||
#ifdef JEMALLOC_JET
|
#ifdef JEMALLOC_JET
|
||||||
@ -488,7 +488,7 @@ extern arena_ralloc_junk_large_t *arena_ralloc_junk_large;
|
|||||||
bool arena_ralloc_no_move(void *ptr, size_t oldsize, size_t size,
|
bool arena_ralloc_no_move(void *ptr, size_t oldsize, size_t size,
|
||||||
size_t extra, bool zero);
|
size_t extra, bool zero);
|
||||||
void *arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize,
|
void *arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize,
|
||||||
size_t size, size_t extra, size_t alignment, bool zero, tcache_t *tcache);
|
size_t size, size_t alignment, bool zero, tcache_t *tcache);
|
||||||
dss_prec_t arena_dss_prec_get(arena_t *arena);
|
dss_prec_t arena_dss_prec_get(arena_t *arena);
|
||||||
bool arena_dss_prec_set(arena_t *arena, dss_prec_t dss_prec);
|
bool arena_dss_prec_set(arena_t *arena, dss_prec_t dss_prec);
|
||||||
ssize_t arena_lg_dirty_mult_default_get(void);
|
ssize_t arena_lg_dirty_mult_default_get(void);
|
||||||
@ -519,17 +519,19 @@ arena_chunk_map_misc_t *arena_run_to_miscelm(arena_run_t *run);
|
|||||||
size_t *arena_mapbitsp_get(arena_chunk_t *chunk, size_t pageind);
|
size_t *arena_mapbitsp_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
size_t arena_mapbitsp_read(size_t *mapbitsp);
|
size_t arena_mapbitsp_read(size_t *mapbitsp);
|
||||||
size_t arena_mapbits_get(arena_chunk_t *chunk, size_t pageind);
|
size_t arena_mapbits_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
|
size_t arena_mapbits_size_decode(size_t mapbits);
|
||||||
size_t arena_mapbits_unallocated_size_get(arena_chunk_t *chunk,
|
size_t arena_mapbits_unallocated_size_get(arena_chunk_t *chunk,
|
||||||
size_t pageind);
|
size_t pageind);
|
||||||
size_t arena_mapbits_large_size_get(arena_chunk_t *chunk, size_t pageind);
|
size_t arena_mapbits_large_size_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
size_t arena_mapbits_small_runind_get(arena_chunk_t *chunk, size_t pageind);
|
size_t arena_mapbits_small_runind_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
index_t arena_mapbits_binind_get(arena_chunk_t *chunk, size_t pageind);
|
szind_t arena_mapbits_binind_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
size_t arena_mapbits_dirty_get(arena_chunk_t *chunk, size_t pageind);
|
size_t arena_mapbits_dirty_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
size_t arena_mapbits_unzeroed_get(arena_chunk_t *chunk, size_t pageind);
|
size_t arena_mapbits_unzeroed_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
size_t arena_mapbits_decommitted_get(arena_chunk_t *chunk, size_t pageind);
|
size_t arena_mapbits_decommitted_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
size_t arena_mapbits_large_get(arena_chunk_t *chunk, size_t pageind);
|
size_t arena_mapbits_large_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
size_t arena_mapbits_allocated_get(arena_chunk_t *chunk, size_t pageind);
|
size_t arena_mapbits_allocated_get(arena_chunk_t *chunk, size_t pageind);
|
||||||
void arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits);
|
void arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits);
|
||||||
|
size_t arena_mapbits_size_encode(size_t size);
|
||||||
void arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind,
|
void arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind,
|
||||||
size_t size, size_t flags);
|
size_t size, size_t flags);
|
||||||
void arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind,
|
void arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind,
|
||||||
@ -539,21 +541,23 @@ void arena_mapbits_internal_set(arena_chunk_t *chunk, size_t pageind,
|
|||||||
void arena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind,
|
void arena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind,
|
||||||
size_t size, size_t flags);
|
size_t size, size_t flags);
|
||||||
void arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind,
|
void arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind,
|
||||||
index_t binind);
|
szind_t binind);
|
||||||
void arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind,
|
void arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind,
|
||||||
size_t runind, index_t binind, size_t flags);
|
size_t runind, szind_t binind, size_t flags);
|
||||||
void arena_metadata_allocated_add(arena_t *arena, size_t size);
|
void arena_metadata_allocated_add(arena_t *arena, size_t size);
|
||||||
void arena_metadata_allocated_sub(arena_t *arena, size_t size);
|
void arena_metadata_allocated_sub(arena_t *arena, size_t size);
|
||||||
size_t arena_metadata_allocated_get(arena_t *arena);
|
size_t arena_metadata_allocated_get(arena_t *arena);
|
||||||
bool arena_prof_accum_impl(arena_t *arena, uint64_t accumbytes);
|
bool arena_prof_accum_impl(arena_t *arena, uint64_t accumbytes);
|
||||||
bool arena_prof_accum_locked(arena_t *arena, uint64_t accumbytes);
|
bool arena_prof_accum_locked(arena_t *arena, uint64_t accumbytes);
|
||||||
bool arena_prof_accum(arena_t *arena, uint64_t accumbytes);
|
bool arena_prof_accum(arena_t *arena, uint64_t accumbytes);
|
||||||
index_t arena_ptr_small_binind_get(const void *ptr, size_t mapbits);
|
szind_t arena_ptr_small_binind_get(const void *ptr, size_t mapbits);
|
||||||
index_t arena_bin_index(arena_t *arena, arena_bin_t *bin);
|
szind_t arena_bin_index(arena_t *arena, arena_bin_t *bin);
|
||||||
unsigned arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info,
|
unsigned arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info,
|
||||||
const void *ptr);
|
const void *ptr);
|
||||||
prof_tctx_t *arena_prof_tctx_get(const void *ptr);
|
prof_tctx_t *arena_prof_tctx_get(const void *ptr);
|
||||||
void arena_prof_tctx_set(const void *ptr, prof_tctx_t *tctx);
|
void arena_prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx);
|
||||||
|
void arena_prof_tctx_reset(const void *ptr, size_t usize,
|
||||||
|
const void *old_ptr, prof_tctx_t *old_tctx);
|
||||||
void *arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero,
|
void *arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero,
|
||||||
tcache_t *tcache);
|
tcache_t *tcache);
|
||||||
arena_t *arena_aalloc(const void *ptr);
|
arena_t *arena_aalloc(const void *ptr);
|
||||||
@ -652,6 +656,22 @@ arena_mapbits_get(arena_chunk_t *chunk, size_t pageind)
|
|||||||
return (arena_mapbitsp_read(arena_mapbitsp_get(chunk, pageind)));
|
return (arena_mapbitsp_read(arena_mapbitsp_get(chunk, pageind)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE size_t
|
||||||
|
arena_mapbits_size_decode(size_t mapbits)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
#if CHUNK_MAP_SIZE_SHIFT > 0
|
||||||
|
size = (mapbits & CHUNK_MAP_SIZE_MASK) >> CHUNK_MAP_SIZE_SHIFT;
|
||||||
|
#elif CHUNK_MAP_SIZE_SHIFT == 0
|
||||||
|
size = mapbits & CHUNK_MAP_SIZE_MASK;
|
||||||
|
#else
|
||||||
|
size = (mapbits & CHUNK_MAP_SIZE_MASK) << -CHUNK_MAP_SIZE_SHIFT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (size);
|
||||||
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE size_t
|
JEMALLOC_ALWAYS_INLINE size_t
|
||||||
arena_mapbits_unallocated_size_get(arena_chunk_t *chunk, size_t pageind)
|
arena_mapbits_unallocated_size_get(arena_chunk_t *chunk, size_t pageind)
|
||||||
{
|
{
|
||||||
@ -659,7 +679,7 @@ arena_mapbits_unallocated_size_get(arena_chunk_t *chunk, size_t pageind)
|
|||||||
|
|
||||||
mapbits = arena_mapbits_get(chunk, pageind);
|
mapbits = arena_mapbits_get(chunk, pageind);
|
||||||
assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0);
|
assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0);
|
||||||
return ((mapbits & CHUNK_MAP_SIZE_MASK) >> CHUNK_MAP_SIZE_SHIFT);
|
return (arena_mapbits_size_decode(mapbits));
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE size_t
|
JEMALLOC_ALWAYS_INLINE size_t
|
||||||
@ -670,7 +690,7 @@ arena_mapbits_large_size_get(arena_chunk_t *chunk, size_t pageind)
|
|||||||
mapbits = arena_mapbits_get(chunk, pageind);
|
mapbits = arena_mapbits_get(chunk, pageind);
|
||||||
assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) ==
|
assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) ==
|
||||||
(CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED));
|
(CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED));
|
||||||
return ((mapbits & CHUNK_MAP_SIZE_MASK) >> CHUNK_MAP_SIZE_SHIFT);
|
return (arena_mapbits_size_decode(mapbits));
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE size_t
|
JEMALLOC_ALWAYS_INLINE size_t
|
||||||
@ -684,11 +704,11 @@ arena_mapbits_small_runind_get(arena_chunk_t *chunk, size_t pageind)
|
|||||||
return (mapbits >> CHUNK_MAP_RUNIND_SHIFT);
|
return (mapbits >> CHUNK_MAP_RUNIND_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE index_t
|
JEMALLOC_ALWAYS_INLINE szind_t
|
||||||
arena_mapbits_binind_get(arena_chunk_t *chunk, size_t pageind)
|
arena_mapbits_binind_get(arena_chunk_t *chunk, size_t pageind)
|
||||||
{
|
{
|
||||||
size_t mapbits;
|
size_t mapbits;
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
|
|
||||||
mapbits = arena_mapbits_get(chunk, pageind);
|
mapbits = arena_mapbits_get(chunk, pageind);
|
||||||
binind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT;
|
binind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT;
|
||||||
@ -754,6 +774,23 @@ arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits)
|
|||||||
*mapbitsp = mapbits;
|
*mapbitsp = mapbits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE size_t
|
||||||
|
arena_mapbits_size_encode(size_t size)
|
||||||
|
{
|
||||||
|
size_t mapbits;
|
||||||
|
|
||||||
|
#if CHUNK_MAP_SIZE_SHIFT > 0
|
||||||
|
mapbits = size << CHUNK_MAP_SIZE_SHIFT;
|
||||||
|
#elif CHUNK_MAP_SIZE_SHIFT == 0
|
||||||
|
mapbits = size;
|
||||||
|
#else
|
||||||
|
mapbits = size >> -CHUNK_MAP_SIZE_SHIFT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert((mapbits & ~CHUNK_MAP_SIZE_MASK) == 0);
|
||||||
|
return (mapbits);
|
||||||
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, size_t size,
|
arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, size_t size,
|
||||||
size_t flags)
|
size_t flags)
|
||||||
@ -761,11 +798,10 @@ arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, size_t size,
|
|||||||
size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);
|
size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);
|
||||||
|
|
||||||
assert((size & PAGE_MASK) == 0);
|
assert((size & PAGE_MASK) == 0);
|
||||||
assert(((size << CHUNK_MAP_SIZE_SHIFT) & ~CHUNK_MAP_SIZE_MASK) == 0);
|
|
||||||
assert((flags & CHUNK_MAP_FLAGS_MASK) == flags);
|
assert((flags & CHUNK_MAP_FLAGS_MASK) == flags);
|
||||||
assert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags &
|
assert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags &
|
||||||
(CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);
|
(CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);
|
||||||
arena_mapbitsp_write(mapbitsp, (size << CHUNK_MAP_SIZE_SHIFT) |
|
arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) |
|
||||||
CHUNK_MAP_BININD_INVALID | flags);
|
CHUNK_MAP_BININD_INVALID | flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,10 +813,9 @@ arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind,
|
|||||||
size_t mapbits = arena_mapbitsp_read(mapbitsp);
|
size_t mapbits = arena_mapbitsp_read(mapbitsp);
|
||||||
|
|
||||||
assert((size & PAGE_MASK) == 0);
|
assert((size & PAGE_MASK) == 0);
|
||||||
assert(((size << CHUNK_MAP_SIZE_SHIFT) & ~CHUNK_MAP_SIZE_MASK) == 0);
|
|
||||||
assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0);
|
assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0);
|
||||||
arena_mapbitsp_write(mapbitsp, (size << CHUNK_MAP_SIZE_SHIFT) | (mapbits
|
arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) |
|
||||||
& ~CHUNK_MAP_SIZE_MASK));
|
(mapbits & ~CHUNK_MAP_SIZE_MASK));
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
@ -799,18 +834,17 @@ arena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind, size_t size,
|
|||||||
size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);
|
size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);
|
||||||
|
|
||||||
assert((size & PAGE_MASK) == 0);
|
assert((size & PAGE_MASK) == 0);
|
||||||
assert(((size << CHUNK_MAP_SIZE_SHIFT) & ~CHUNK_MAP_SIZE_MASK) == 0);
|
|
||||||
assert((flags & CHUNK_MAP_FLAGS_MASK) == flags);
|
assert((flags & CHUNK_MAP_FLAGS_MASK) == flags);
|
||||||
assert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags &
|
assert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags &
|
||||||
(CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);
|
(CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0);
|
||||||
arena_mapbitsp_write(mapbitsp, (size << CHUNK_MAP_SIZE_SHIFT) |
|
arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) |
|
||||||
CHUNK_MAP_BININD_INVALID | flags | CHUNK_MAP_LARGE |
|
CHUNK_MAP_BININD_INVALID | flags | CHUNK_MAP_LARGE |
|
||||||
CHUNK_MAP_ALLOCATED);
|
CHUNK_MAP_ALLOCATED);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind,
|
arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind,
|
||||||
index_t binind)
|
szind_t binind)
|
||||||
{
|
{
|
||||||
size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);
|
size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);
|
||||||
size_t mapbits = arena_mapbitsp_read(mapbitsp);
|
size_t mapbits = arena_mapbitsp_read(mapbitsp);
|
||||||
@ -824,7 +858,7 @@ arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind,
|
|||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind, size_t runind,
|
arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind, size_t runind,
|
||||||
index_t binind, size_t flags)
|
szind_t binind, size_t flags)
|
||||||
{
|
{
|
||||||
size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);
|
size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind);
|
||||||
|
|
||||||
@ -901,10 +935,10 @@ arena_prof_accum(arena_t *arena, uint64_t accumbytes)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE index_t
|
JEMALLOC_ALWAYS_INLINE szind_t
|
||||||
arena_ptr_small_binind_get(const void *ptr, size_t mapbits)
|
arena_ptr_small_binind_get(const void *ptr, size_t mapbits)
|
||||||
{
|
{
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
|
|
||||||
binind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT;
|
binind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT;
|
||||||
|
|
||||||
@ -916,7 +950,7 @@ arena_ptr_small_binind_get(const void *ptr, size_t mapbits)
|
|||||||
size_t rpages_ind;
|
size_t rpages_ind;
|
||||||
arena_run_t *run;
|
arena_run_t *run;
|
||||||
arena_bin_t *bin;
|
arena_bin_t *bin;
|
||||||
index_t run_binind, actual_binind;
|
szind_t run_binind, actual_binind;
|
||||||
arena_bin_info_t *bin_info;
|
arena_bin_info_t *bin_info;
|
||||||
arena_chunk_map_misc_t *miscelm;
|
arena_chunk_map_misc_t *miscelm;
|
||||||
void *rpages;
|
void *rpages;
|
||||||
@ -950,10 +984,10 @@ arena_ptr_small_binind_get(const void *ptr, size_t mapbits)
|
|||||||
# endif /* JEMALLOC_ARENA_INLINE_A */
|
# endif /* JEMALLOC_ARENA_INLINE_A */
|
||||||
|
|
||||||
# ifdef JEMALLOC_ARENA_INLINE_B
|
# ifdef JEMALLOC_ARENA_INLINE_B
|
||||||
JEMALLOC_INLINE index_t
|
JEMALLOC_INLINE szind_t
|
||||||
arena_bin_index(arena_t *arena, arena_bin_t *bin)
|
arena_bin_index(arena_t *arena, arena_bin_t *bin)
|
||||||
{
|
{
|
||||||
index_t binind = bin - arena->bins;
|
szind_t binind = bin - arena->bins;
|
||||||
assert(binind < NBINS);
|
assert(binind < NBINS);
|
||||||
return (binind);
|
return (binind);
|
||||||
}
|
}
|
||||||
@ -1060,7 +1094,7 @@ arena_prof_tctx_get(const void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE void
|
JEMALLOC_INLINE void
|
||||||
arena_prof_tctx_set(const void *ptr, prof_tctx_t *tctx)
|
arena_prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
|
|
||||||
@ -1070,17 +1104,59 @@ arena_prof_tctx_set(const void *ptr, prof_tctx_t *tctx)
|
|||||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
||||||
if (likely(chunk != ptr)) {
|
if (likely(chunk != ptr)) {
|
||||||
size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
||||||
|
|
||||||
assert(arena_mapbits_allocated_get(chunk, pageind) != 0);
|
assert(arena_mapbits_allocated_get(chunk, pageind) != 0);
|
||||||
|
|
||||||
if (unlikely(arena_mapbits_large_get(chunk, pageind) != 0)) {
|
if (unlikely(usize > SMALL_MAXCLASS || (uintptr_t)tctx >
|
||||||
arena_chunk_map_misc_t *elm = arena_miscelm_get(chunk,
|
(uintptr_t)1U)) {
|
||||||
pageind);
|
arena_chunk_map_misc_t *elm;
|
||||||
|
|
||||||
|
assert(arena_mapbits_large_get(chunk, pageind) != 0);
|
||||||
|
|
||||||
|
elm = arena_miscelm_get(chunk, pageind);
|
||||||
atomic_write_p(&elm->prof_tctx_pun, tctx);
|
atomic_write_p(&elm->prof_tctx_pun, tctx);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* tctx must always be initialized for large runs.
|
||||||
|
* Assert that the surrounding conditional logic is
|
||||||
|
* equivalent to checking whether ptr refers to a large
|
||||||
|
* run.
|
||||||
|
*/
|
||||||
|
assert(arena_mapbits_large_get(chunk, pageind) == 0);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
huge_prof_tctx_set(ptr, tctx);
|
huge_prof_tctx_set(ptr, tctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JEMALLOC_INLINE void
|
||||||
|
arena_prof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr,
|
||||||
|
prof_tctx_t *old_tctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
cassert(config_prof);
|
||||||
|
assert(ptr != NULL);
|
||||||
|
|
||||||
|
if (unlikely(usize > SMALL_MAXCLASS || (ptr == old_ptr &&
|
||||||
|
(uintptr_t)old_tctx > (uintptr_t)1U))) {
|
||||||
|
arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
||||||
|
if (likely(chunk != ptr)) {
|
||||||
|
size_t pageind;
|
||||||
|
arena_chunk_map_misc_t *elm;
|
||||||
|
|
||||||
|
pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >>
|
||||||
|
LG_PAGE;
|
||||||
|
assert(arena_mapbits_allocated_get(chunk, pageind) !=
|
||||||
|
0);
|
||||||
|
assert(arena_mapbits_large_get(chunk, pageind) != 0);
|
||||||
|
|
||||||
|
elm = arena_miscelm_get(chunk, pageind);
|
||||||
|
atomic_write_p(&elm->prof_tctx_pun,
|
||||||
|
(prof_tctx_t *)(uintptr_t)1U);
|
||||||
|
} else
|
||||||
|
huge_prof_tctx_reset(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void *
|
JEMALLOC_ALWAYS_INLINE void *
|
||||||
arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero,
|
arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero,
|
||||||
tcache_t *tcache)
|
tcache_t *tcache)
|
||||||
@ -1098,7 +1174,7 @@ arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero,
|
|||||||
zero));
|
zero));
|
||||||
} else
|
} else
|
||||||
return (arena_malloc_small(arena, size, zero));
|
return (arena_malloc_small(arena, size, zero));
|
||||||
} else if (likely(size <= arena_maxclass)) {
|
} else if (likely(size <= large_maxclass)) {
|
||||||
/*
|
/*
|
||||||
* Initialize tcache after checking size in order to avoid
|
* Initialize tcache after checking size in order to avoid
|
||||||
* infinite recursion during tcache initialization.
|
* infinite recursion during tcache initialization.
|
||||||
@ -1131,7 +1207,7 @@ arena_salloc(const void *ptr, bool demote)
|
|||||||
size_t ret;
|
size_t ret;
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
size_t pageind;
|
size_t pageind;
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
|
|
||||||
assert(ptr != NULL);
|
assert(ptr != NULL);
|
||||||
|
|
||||||
@ -1190,7 +1266,7 @@ arena_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache)
|
|||||||
if (likely((mapbits & CHUNK_MAP_LARGE) == 0)) {
|
if (likely((mapbits & CHUNK_MAP_LARGE) == 0)) {
|
||||||
/* Small allocation. */
|
/* Small allocation. */
|
||||||
if (likely(tcache != NULL)) {
|
if (likely(tcache != NULL)) {
|
||||||
index_t binind = arena_ptr_small_binind_get(ptr,
|
szind_t binind = arena_ptr_small_binind_get(ptr,
|
||||||
mapbits);
|
mapbits);
|
||||||
tcache_dalloc_small(tsd, tcache, ptr, binind);
|
tcache_dalloc_small(tsd, tcache, ptr, binind);
|
||||||
} else {
|
} else {
|
||||||
@ -1242,7 +1318,7 @@ arena_sdalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache)
|
|||||||
if (likely(size <= SMALL_MAXCLASS)) {
|
if (likely(size <= SMALL_MAXCLASS)) {
|
||||||
/* Small allocation. */
|
/* Small allocation. */
|
||||||
if (likely(tcache != NULL)) {
|
if (likely(tcache != NULL)) {
|
||||||
index_t binind = size2index(size);
|
szind_t binind = size2index(size);
|
||||||
tcache_dalloc_small(tsd, tcache, ptr, binind);
|
tcache_dalloc_small(tsd, tcache, ptr, binind);
|
||||||
} else {
|
} else {
|
||||||
size_t pageind = ((uintptr_t)ptr -
|
size_t pageind = ((uintptr_t)ptr -
|
||||||
|
@ -13,11 +13,10 @@ void *huge_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero,
|
|||||||
tcache_t *tcache);
|
tcache_t *tcache);
|
||||||
void *huge_palloc(tsd_t *tsd, arena_t *arena, size_t size, size_t alignment,
|
void *huge_palloc(tsd_t *tsd, arena_t *arena, size_t size, size_t alignment,
|
||||||
bool zero, tcache_t *tcache);
|
bool zero, tcache_t *tcache);
|
||||||
bool huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size,
|
bool huge_ralloc_no_move(void *ptr, size_t oldsize, size_t usize_min,
|
||||||
size_t extra, bool zero);
|
size_t usize_max, bool zero);
|
||||||
void *huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize,
|
void *huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize,
|
||||||
size_t size, size_t extra, size_t alignment, bool zero,
|
size_t usize, size_t alignment, bool zero, tcache_t *tcache);
|
||||||
tcache_t *tcache);
|
|
||||||
#ifdef JEMALLOC_JET
|
#ifdef JEMALLOC_JET
|
||||||
typedef void (huge_dalloc_junk_t)(void *, size_t);
|
typedef void (huge_dalloc_junk_t)(void *, size_t);
|
||||||
extern huge_dalloc_junk_t *huge_dalloc_junk;
|
extern huge_dalloc_junk_t *huge_dalloc_junk;
|
||||||
@ -27,6 +26,7 @@ arena_t *huge_aalloc(const void *ptr);
|
|||||||
size_t huge_salloc(const void *ptr);
|
size_t huge_salloc(const void *ptr);
|
||||||
prof_tctx_t *huge_prof_tctx_get(const void *ptr);
|
prof_tctx_t *huge_prof_tctx_get(const void *ptr);
|
||||||
void huge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx);
|
void huge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx);
|
||||||
|
void huge_prof_tctx_reset(const void *ptr);
|
||||||
|
|
||||||
#endif /* JEMALLOC_H_EXTERNS */
|
#endif /* JEMALLOC_H_EXTERNS */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -181,7 +181,7 @@ static const bool config_cache_oblivious =
|
|||||||
#include "jemalloc/internal/jemalloc_internal_macros.h"
|
#include "jemalloc/internal/jemalloc_internal_macros.h"
|
||||||
|
|
||||||
/* Size class index type. */
|
/* Size class index type. */
|
||||||
typedef unsigned index_t;
|
typedef unsigned szind_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags bits:
|
* Flags bits:
|
||||||
@ -229,7 +229,7 @@ typedef unsigned index_t;
|
|||||||
# ifdef __alpha__
|
# ifdef __alpha__
|
||||||
# define LG_QUANTUM 4
|
# define LG_QUANTUM 4
|
||||||
# endif
|
# endif
|
||||||
# ifdef __sparc64__
|
# if (defined(__sparc64__) || defined(__sparcv9))
|
||||||
# define LG_QUANTUM 4
|
# define LG_QUANTUM 4
|
||||||
# endif
|
# endif
|
||||||
# if (defined(__amd64__) || defined(__x86_64__) || defined(_M_X64))
|
# if (defined(__amd64__) || defined(__x86_64__) || defined(_M_X64))
|
||||||
@ -508,12 +508,12 @@ void jemalloc_postfork_child(void);
|
|||||||
#include "jemalloc/internal/huge.h"
|
#include "jemalloc/internal/huge.h"
|
||||||
|
|
||||||
#ifndef JEMALLOC_ENABLE_INLINE
|
#ifndef JEMALLOC_ENABLE_INLINE
|
||||||
index_t size2index_compute(size_t size);
|
szind_t size2index_compute(size_t size);
|
||||||
index_t size2index_lookup(size_t size);
|
szind_t size2index_lookup(size_t size);
|
||||||
index_t size2index(size_t size);
|
szind_t size2index(size_t size);
|
||||||
size_t index2size_compute(index_t index);
|
size_t index2size_compute(szind_t index);
|
||||||
size_t index2size_lookup(index_t index);
|
size_t index2size_lookup(szind_t index);
|
||||||
size_t index2size(index_t index);
|
size_t index2size(szind_t index);
|
||||||
size_t s2u_compute(size_t size);
|
size_t s2u_compute(size_t size);
|
||||||
size_t s2u_lookup(size_t size);
|
size_t s2u_lookup(size_t size);
|
||||||
size_t s2u(size_t size);
|
size_t s2u(size_t size);
|
||||||
@ -524,7 +524,7 @@ arena_t *arena_get(tsd_t *tsd, unsigned ind, bool init_if_missing,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_))
|
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_))
|
||||||
JEMALLOC_INLINE index_t
|
JEMALLOC_INLINE szind_t
|
||||||
size2index_compute(size_t size)
|
size2index_compute(size_t size)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -555,7 +555,7 @@ size2index_compute(size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE index_t
|
JEMALLOC_ALWAYS_INLINE szind_t
|
||||||
size2index_lookup(size_t size)
|
size2index_lookup(size_t size)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -568,7 +568,7 @@ size2index_lookup(size_t size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE index_t
|
JEMALLOC_ALWAYS_INLINE szind_t
|
||||||
size2index(size_t size)
|
size2index(size_t size)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -579,7 +579,7 @@ size2index(size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE size_t
|
JEMALLOC_INLINE size_t
|
||||||
index2size_compute(index_t index)
|
index2size_compute(szind_t index)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if (NTBINS > 0)
|
#if (NTBINS > 0)
|
||||||
@ -606,7 +606,7 @@ index2size_compute(index_t index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE size_t
|
JEMALLOC_ALWAYS_INLINE size_t
|
||||||
index2size_lookup(index_t index)
|
index2size_lookup(szind_t index)
|
||||||
{
|
{
|
||||||
size_t ret = (size_t)index2size_tab[index];
|
size_t ret = (size_t)index2size_tab[index];
|
||||||
assert(ret == index2size_compute(index));
|
assert(ret == index2size_compute(index));
|
||||||
@ -614,7 +614,7 @@ index2size_lookup(index_t index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE size_t
|
JEMALLOC_ALWAYS_INLINE size_t
|
||||||
index2size(index_t index)
|
index2size(szind_t index)
|
||||||
{
|
{
|
||||||
|
|
||||||
assert(index < NSIZES);
|
assert(index < NSIZES);
|
||||||
@ -702,7 +702,7 @@ sa2u(size_t size, size_t alignment)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Try for a large size class. */
|
/* Try for a large size class. */
|
||||||
if (likely(size <= arena_maxclass) && likely(alignment < chunksize)) {
|
if (likely(size <= large_maxclass) && likely(alignment < chunksize)) {
|
||||||
/*
|
/*
|
||||||
* We can't achieve subpage alignment, so round up alignment
|
* We can't achieve subpage alignment, so round up alignment
|
||||||
* to the minimum that can actually be supported.
|
* to the minimum that can actually be supported.
|
||||||
@ -973,7 +973,7 @@ u2rz(size_t usize)
|
|||||||
size_t ret;
|
size_t ret;
|
||||||
|
|
||||||
if (usize <= SMALL_MAXCLASS) {
|
if (usize <= SMALL_MAXCLASS) {
|
||||||
index_t binind = size2index(usize);
|
szind_t binind = size2index(usize);
|
||||||
ret = arena_bin_info[binind].redzone_size;
|
ret = arena_bin_info[binind].redzone_size;
|
||||||
} else
|
} else
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@ -1093,7 +1093,7 @@ iralloct(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, size_t alignment,
|
|||||||
zero, tcache, arena));
|
zero, tcache, arena));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (arena_ralloc(tsd, arena, ptr, oldsize, size, 0, alignment, zero,
|
return (arena_ralloc(tsd, arena, ptr, oldsize, size, alignment, zero,
|
||||||
tcache));
|
tcache));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,13 +50,14 @@
|
|||||||
#define arena_mapbitsp_get JEMALLOC_N(arena_mapbitsp_get)
|
#define arena_mapbitsp_get JEMALLOC_N(arena_mapbitsp_get)
|
||||||
#define arena_mapbitsp_read JEMALLOC_N(arena_mapbitsp_read)
|
#define arena_mapbitsp_read JEMALLOC_N(arena_mapbitsp_read)
|
||||||
#define arena_mapbitsp_write JEMALLOC_N(arena_mapbitsp_write)
|
#define arena_mapbitsp_write JEMALLOC_N(arena_mapbitsp_write)
|
||||||
|
#define arena_mapbits_size_decode JEMALLOC_N(arena_mapbits_size_decode)
|
||||||
|
#define arena_mapbits_size_encode JEMALLOC_N(arena_mapbits_size_encode)
|
||||||
#define arena_mapbits_small_runind_get JEMALLOC_N(arena_mapbits_small_runind_get)
|
#define arena_mapbits_small_runind_get JEMALLOC_N(arena_mapbits_small_runind_get)
|
||||||
#define arena_mapbits_small_set JEMALLOC_N(arena_mapbits_small_set)
|
#define arena_mapbits_small_set JEMALLOC_N(arena_mapbits_small_set)
|
||||||
#define arena_mapbits_unallocated_set JEMALLOC_N(arena_mapbits_unallocated_set)
|
#define arena_mapbits_unallocated_set JEMALLOC_N(arena_mapbits_unallocated_set)
|
||||||
#define arena_mapbits_unallocated_size_get JEMALLOC_N(arena_mapbits_unallocated_size_get)
|
#define arena_mapbits_unallocated_size_get JEMALLOC_N(arena_mapbits_unallocated_size_get)
|
||||||
#define arena_mapbits_unallocated_size_set JEMALLOC_N(arena_mapbits_unallocated_size_set)
|
#define arena_mapbits_unallocated_size_set JEMALLOC_N(arena_mapbits_unallocated_size_set)
|
||||||
#define arena_mapbits_unzeroed_get JEMALLOC_N(arena_mapbits_unzeroed_get)
|
#define arena_mapbits_unzeroed_get JEMALLOC_N(arena_mapbits_unzeroed_get)
|
||||||
#define arena_maxclass JEMALLOC_N(arena_maxclass)
|
|
||||||
#define arena_maxrun JEMALLOC_N(arena_maxrun)
|
#define arena_maxrun JEMALLOC_N(arena_maxrun)
|
||||||
#define arena_maybe_purge JEMALLOC_N(arena_maybe_purge)
|
#define arena_maybe_purge JEMALLOC_N(arena_maybe_purge)
|
||||||
#define arena_metadata_allocated_add JEMALLOC_N(arena_metadata_allocated_add)
|
#define arena_metadata_allocated_add JEMALLOC_N(arena_metadata_allocated_add)
|
||||||
@ -79,6 +80,7 @@
|
|||||||
#define arena_prof_accum_locked JEMALLOC_N(arena_prof_accum_locked)
|
#define arena_prof_accum_locked JEMALLOC_N(arena_prof_accum_locked)
|
||||||
#define arena_prof_promoted JEMALLOC_N(arena_prof_promoted)
|
#define arena_prof_promoted JEMALLOC_N(arena_prof_promoted)
|
||||||
#define arena_prof_tctx_get JEMALLOC_N(arena_prof_tctx_get)
|
#define arena_prof_tctx_get JEMALLOC_N(arena_prof_tctx_get)
|
||||||
|
#define arena_prof_tctx_reset JEMALLOC_N(arena_prof_tctx_reset)
|
||||||
#define arena_prof_tctx_set JEMALLOC_N(arena_prof_tctx_set)
|
#define arena_prof_tctx_set JEMALLOC_N(arena_prof_tctx_set)
|
||||||
#define arena_ptr_small_binind_get JEMALLOC_N(arena_ptr_small_binind_get)
|
#define arena_ptr_small_binind_get JEMALLOC_N(arena_ptr_small_binind_get)
|
||||||
#define arena_purge_all JEMALLOC_N(arena_purge_all)
|
#define arena_purge_all JEMALLOC_N(arena_purge_all)
|
||||||
@ -249,6 +251,7 @@
|
|||||||
#define huge_malloc JEMALLOC_N(huge_malloc)
|
#define huge_malloc JEMALLOC_N(huge_malloc)
|
||||||
#define huge_palloc JEMALLOC_N(huge_palloc)
|
#define huge_palloc JEMALLOC_N(huge_palloc)
|
||||||
#define huge_prof_tctx_get JEMALLOC_N(huge_prof_tctx_get)
|
#define huge_prof_tctx_get JEMALLOC_N(huge_prof_tctx_get)
|
||||||
|
#define huge_prof_tctx_reset JEMALLOC_N(huge_prof_tctx_reset)
|
||||||
#define huge_prof_tctx_set JEMALLOC_N(huge_prof_tctx_set)
|
#define huge_prof_tctx_set JEMALLOC_N(huge_prof_tctx_set)
|
||||||
#define huge_ralloc JEMALLOC_N(huge_ralloc)
|
#define huge_ralloc JEMALLOC_N(huge_ralloc)
|
||||||
#define huge_ralloc_no_move JEMALLOC_N(huge_ralloc_no_move)
|
#define huge_ralloc_no_move JEMALLOC_N(huge_ralloc_no_move)
|
||||||
@ -282,6 +285,7 @@
|
|||||||
#define jemalloc_postfork_child JEMALLOC_N(jemalloc_postfork_child)
|
#define jemalloc_postfork_child JEMALLOC_N(jemalloc_postfork_child)
|
||||||
#define jemalloc_postfork_parent JEMALLOC_N(jemalloc_postfork_parent)
|
#define jemalloc_postfork_parent JEMALLOC_N(jemalloc_postfork_parent)
|
||||||
#define jemalloc_prefork JEMALLOC_N(jemalloc_prefork)
|
#define jemalloc_prefork JEMALLOC_N(jemalloc_prefork)
|
||||||
|
#define large_maxclass JEMALLOC_N(large_maxclass)
|
||||||
#define lg_floor JEMALLOC_N(lg_floor)
|
#define lg_floor JEMALLOC_N(lg_floor)
|
||||||
#define malloc_cprintf JEMALLOC_N(malloc_cprintf)
|
#define malloc_cprintf JEMALLOC_N(malloc_cprintf)
|
||||||
#define malloc_mutex_init JEMALLOC_N(malloc_mutex_init)
|
#define malloc_mutex_init JEMALLOC_N(malloc_mutex_init)
|
||||||
@ -376,6 +380,7 @@
|
|||||||
#define prof_sample_accum_update JEMALLOC_N(prof_sample_accum_update)
|
#define prof_sample_accum_update JEMALLOC_N(prof_sample_accum_update)
|
||||||
#define prof_sample_threshold_update JEMALLOC_N(prof_sample_threshold_update)
|
#define prof_sample_threshold_update JEMALLOC_N(prof_sample_threshold_update)
|
||||||
#define prof_tctx_get JEMALLOC_N(prof_tctx_get)
|
#define prof_tctx_get JEMALLOC_N(prof_tctx_get)
|
||||||
|
#define prof_tctx_reset JEMALLOC_N(prof_tctx_reset)
|
||||||
#define prof_tctx_set JEMALLOC_N(prof_tctx_set)
|
#define prof_tctx_set JEMALLOC_N(prof_tctx_set)
|
||||||
#define prof_tdata_cleanup JEMALLOC_N(prof_tdata_cleanup)
|
#define prof_tdata_cleanup JEMALLOC_N(prof_tdata_cleanup)
|
||||||
#define prof_tdata_get JEMALLOC_N(prof_tdata_get)
|
#define prof_tdata_get JEMALLOC_N(prof_tdata_get)
|
||||||
|
@ -90,10 +90,11 @@ struct prof_tctx_s {
|
|||||||
prof_tdata_t *tdata;
|
prof_tdata_t *tdata;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy of tdata->thr_uid, necessary because tdata may be defunct during
|
* Copy of tdata->thr_{uid,discrim}, necessary because tdata may be
|
||||||
* teardown.
|
* defunct during teardown.
|
||||||
*/
|
*/
|
||||||
uint64_t thr_uid;
|
uint64_t thr_uid;
|
||||||
|
uint64_t thr_discrim;
|
||||||
|
|
||||||
/* Profiling counters, protected by tdata->lock. */
|
/* Profiling counters, protected by tdata->lock. */
|
||||||
prof_cnt_t cnts;
|
prof_cnt_t cnts;
|
||||||
@ -330,14 +331,18 @@ bool prof_gdump_get_unlocked(void);
|
|||||||
prof_tdata_t *prof_tdata_get(tsd_t *tsd, bool create);
|
prof_tdata_t *prof_tdata_get(tsd_t *tsd, bool create);
|
||||||
bool prof_sample_accum_update(tsd_t *tsd, size_t usize, bool commit,
|
bool prof_sample_accum_update(tsd_t *tsd, size_t usize, bool commit,
|
||||||
prof_tdata_t **tdata_out);
|
prof_tdata_t **tdata_out);
|
||||||
prof_tctx_t *prof_alloc_prep(tsd_t *tsd, size_t usize, bool update);
|
prof_tctx_t *prof_alloc_prep(tsd_t *tsd, size_t usize, bool prof_active,
|
||||||
|
bool update);
|
||||||
prof_tctx_t *prof_tctx_get(const void *ptr);
|
prof_tctx_t *prof_tctx_get(const void *ptr);
|
||||||
void prof_tctx_set(const void *ptr, prof_tctx_t *tctx);
|
void prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx);
|
||||||
|
void prof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr,
|
||||||
|
prof_tctx_t *tctx);
|
||||||
void prof_malloc_sample_object(const void *ptr, size_t usize,
|
void prof_malloc_sample_object(const void *ptr, size_t usize,
|
||||||
prof_tctx_t *tctx);
|
prof_tctx_t *tctx);
|
||||||
void prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx);
|
void prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx);
|
||||||
void prof_realloc(tsd_t *tsd, const void *ptr, size_t usize,
|
void prof_realloc(tsd_t *tsd, const void *ptr, size_t usize,
|
||||||
prof_tctx_t *tctx, bool updated, size_t old_usize, prof_tctx_t *old_tctx);
|
prof_tctx_t *tctx, bool prof_active, bool updated, const void *old_ptr,
|
||||||
|
size_t old_usize, prof_tctx_t *old_tctx);
|
||||||
void prof_free(tsd_t *tsd, const void *ptr, size_t usize);
|
void prof_free(tsd_t *tsd, const void *ptr, size_t usize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -402,13 +407,24 @@ prof_tctx_get(const void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
prof_tctx_set(const void *ptr, prof_tctx_t *tctx)
|
prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
assert(ptr != NULL);
|
assert(ptr != NULL);
|
||||||
|
|
||||||
arena_prof_tctx_set(ptr, tctx);
|
arena_prof_tctx_set(ptr, usize, tctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
|
prof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr,
|
||||||
|
prof_tctx_t *old_tctx)
|
||||||
|
{
|
||||||
|
|
||||||
|
cassert(config_prof);
|
||||||
|
assert(ptr != NULL);
|
||||||
|
|
||||||
|
arena_prof_tctx_reset(ptr, usize, old_ptr, old_tctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE bool
|
JEMALLOC_ALWAYS_INLINE bool
|
||||||
@ -442,7 +458,7 @@ prof_sample_accum_update(tsd_t *tsd, size_t usize, bool update,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE prof_tctx_t *
|
JEMALLOC_ALWAYS_INLINE prof_tctx_t *
|
||||||
prof_alloc_prep(tsd_t *tsd, size_t usize, bool update)
|
prof_alloc_prep(tsd_t *tsd, size_t usize, bool prof_active, bool update)
|
||||||
{
|
{
|
||||||
prof_tctx_t *ret;
|
prof_tctx_t *ret;
|
||||||
prof_tdata_t *tdata;
|
prof_tdata_t *tdata;
|
||||||
@ -450,8 +466,8 @@ prof_alloc_prep(tsd_t *tsd, size_t usize, bool update)
|
|||||||
|
|
||||||
assert(usize == s2u(usize));
|
assert(usize == s2u(usize));
|
||||||
|
|
||||||
if (!prof_active_get_unlocked() || likely(prof_sample_accum_update(tsd,
|
if (!prof_active || likely(prof_sample_accum_update(tsd, usize, update,
|
||||||
usize, update, &tdata)))
|
&tdata)))
|
||||||
ret = (prof_tctx_t *)(uintptr_t)1U;
|
ret = (prof_tctx_t *)(uintptr_t)1U;
|
||||||
else {
|
else {
|
||||||
bt_init(&bt, tdata->vec);
|
bt_init(&bt, tdata->vec);
|
||||||
@ -473,22 +489,24 @@ prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
|||||||
if (unlikely((uintptr_t)tctx > (uintptr_t)1U))
|
if (unlikely((uintptr_t)tctx > (uintptr_t)1U))
|
||||||
prof_malloc_sample_object(ptr, usize, tctx);
|
prof_malloc_sample_object(ptr, usize, tctx);
|
||||||
else
|
else
|
||||||
prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U);
|
prof_tctx_set(ptr, usize, (prof_tctx_t *)(uintptr_t)1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx,
|
prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx,
|
||||||
bool updated, size_t old_usize, prof_tctx_t *old_tctx)
|
bool prof_active, bool updated, const void *old_ptr, size_t old_usize,
|
||||||
|
prof_tctx_t *old_tctx)
|
||||||
{
|
{
|
||||||
|
bool sampled, old_sampled;
|
||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
assert(ptr != NULL || (uintptr_t)tctx <= (uintptr_t)1U);
|
assert(ptr != NULL || (uintptr_t)tctx <= (uintptr_t)1U);
|
||||||
|
|
||||||
if (!updated && ptr != NULL) {
|
if (prof_active && !updated && ptr != NULL) {
|
||||||
assert(usize == isalloc(ptr, true));
|
assert(usize == isalloc(ptr, true));
|
||||||
if (prof_sample_accum_update(tsd, usize, true, NULL)) {
|
if (prof_sample_accum_update(tsd, usize, true, NULL)) {
|
||||||
/*
|
/*
|
||||||
* Don't sample. The usize passed to PROF_ALLOC_PREP()
|
* Don't sample. The usize passed to prof_alloc_prep()
|
||||||
* was larger than what actually got allocated, so a
|
* was larger than what actually got allocated, so a
|
||||||
* backtrace was captured for this allocation, even
|
* backtrace was captured for this allocation, even
|
||||||
* though its actual usize was insufficient to cross the
|
* though its actual usize was insufficient to cross the
|
||||||
@ -498,12 +516,16 @@ prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely((uintptr_t)old_tctx > (uintptr_t)1U))
|
sampled = ((uintptr_t)tctx > (uintptr_t)1U);
|
||||||
prof_free_sampled_object(tsd, old_usize, old_tctx);
|
old_sampled = ((uintptr_t)old_tctx > (uintptr_t)1U);
|
||||||
if (unlikely((uintptr_t)tctx > (uintptr_t)1U))
|
|
||||||
|
if (unlikely(sampled))
|
||||||
prof_malloc_sample_object(ptr, usize, tctx);
|
prof_malloc_sample_object(ptr, usize, tctx);
|
||||||
else
|
else
|
||||||
prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U);
|
prof_tctx_reset(ptr, usize, old_ptr, old_tctx);
|
||||||
|
|
||||||
|
if (unlikely(old_sampled))
|
||||||
|
prof_free_sampled_object(tsd, old_usize, old_tctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
* LOOKUP_MAXCLASS: Maximum size class included in lookup table.
|
* LOOKUP_MAXCLASS: Maximum size class included in lookup table.
|
||||||
* SMALL_MAXCLASS: Maximum small size class.
|
* SMALL_MAXCLASS: Maximum small size class.
|
||||||
* LG_LARGE_MINCLASS: Lg of minimum large size class.
|
* LG_LARGE_MINCLASS: Lg of minimum large size class.
|
||||||
|
* HUGE_MAXCLASS: Maximum (huge) size class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LG_SIZE_CLASS_GROUP 2
|
#define LG_SIZE_CLASS_GROUP 2
|
||||||
@ -180,6 +181,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
||||||
#define LG_LARGE_MINCLASS 14
|
#define LG_LARGE_MINCLASS 14
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 13)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 13)
|
||||||
@ -333,6 +335,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
||||||
#define LG_LARGE_MINCLASS 15
|
#define LG_LARGE_MINCLASS 15
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 14)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 14)
|
||||||
@ -486,6 +489,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
||||||
#define LG_LARGE_MINCLASS 16
|
#define LG_LARGE_MINCLASS 16
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 16)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 16)
|
||||||
@ -639,6 +643,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
||||||
#define LG_LARGE_MINCLASS 18
|
#define LG_LARGE_MINCLASS 18
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 12)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 12)
|
||||||
@ -789,6 +794,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
||||||
#define LG_LARGE_MINCLASS 14
|
#define LG_LARGE_MINCLASS 14
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 13)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 13)
|
||||||
@ -939,6 +945,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
||||||
#define LG_LARGE_MINCLASS 15
|
#define LG_LARGE_MINCLASS 15
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 14)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 14)
|
||||||
@ -1089,6 +1096,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
||||||
#define LG_LARGE_MINCLASS 16
|
#define LG_LARGE_MINCLASS 16
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 16)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 16)
|
||||||
@ -1239,6 +1247,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
||||||
#define LG_LARGE_MINCLASS 18
|
#define LG_LARGE_MINCLASS 18
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 12)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 12)
|
||||||
@ -1387,6 +1396,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
||||||
#define LG_LARGE_MINCLASS 14
|
#define LG_LARGE_MINCLASS 14
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 13)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 13)
|
||||||
@ -1535,6 +1545,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
||||||
#define LG_LARGE_MINCLASS 15
|
#define LG_LARGE_MINCLASS 15
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 14)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 14)
|
||||||
@ -1683,6 +1694,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
||||||
#define LG_LARGE_MINCLASS 16
|
#define LG_LARGE_MINCLASS 16
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 16)
|
#if (LG_SIZEOF_PTR == 2 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 16)
|
||||||
@ -1831,6 +1843,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
||||||
#define LG_LARGE_MINCLASS 18
|
#define LG_LARGE_MINCLASS 18
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 31) + (((size_t)3) << 29))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 12)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 12)
|
||||||
@ -2144,6 +2157,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
||||||
#define LG_LARGE_MINCLASS 14
|
#define LG_LARGE_MINCLASS 14
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 13)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 13)
|
||||||
@ -2457,6 +2471,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
||||||
#define LG_LARGE_MINCLASS 15
|
#define LG_LARGE_MINCLASS 15
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 14)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 14)
|
||||||
@ -2770,6 +2785,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
||||||
#define LG_LARGE_MINCLASS 16
|
#define LG_LARGE_MINCLASS 16
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 16)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 3 && LG_PAGE == 16)
|
||||||
@ -3083,6 +3099,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
||||||
#define LG_LARGE_MINCLASS 18
|
#define LG_LARGE_MINCLASS 18
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 12)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 12)
|
||||||
@ -3393,6 +3410,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
||||||
#define LG_LARGE_MINCLASS 14
|
#define LG_LARGE_MINCLASS 14
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 13)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 13)
|
||||||
@ -3703,6 +3721,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
||||||
#define LG_LARGE_MINCLASS 15
|
#define LG_LARGE_MINCLASS 15
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 14)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 14)
|
||||||
@ -4013,6 +4032,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
||||||
#define LG_LARGE_MINCLASS 16
|
#define LG_LARGE_MINCLASS 16
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 16)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 3 && LG_QUANTUM == 4 && LG_PAGE == 16)
|
||||||
@ -4323,6 +4343,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
||||||
#define LG_LARGE_MINCLASS 18
|
#define LG_LARGE_MINCLASS 18
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 12)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 12)
|
||||||
@ -4631,6 +4652,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
#define SMALL_MAXCLASS ((((size_t)1) << 13) + (((size_t)3) << 11))
|
||||||
#define LG_LARGE_MINCLASS 14
|
#define LG_LARGE_MINCLASS 14
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 13)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 13)
|
||||||
@ -4939,6 +4961,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
#define SMALL_MAXCLASS ((((size_t)1) << 14) + (((size_t)3) << 12))
|
||||||
#define LG_LARGE_MINCLASS 15
|
#define LG_LARGE_MINCLASS 15
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 14)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 14)
|
||||||
@ -5247,6 +5270,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
#define SMALL_MAXCLASS ((((size_t)1) << 15) + (((size_t)3) << 13))
|
||||||
#define LG_LARGE_MINCLASS 16
|
#define LG_LARGE_MINCLASS 16
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 16)
|
#if (LG_SIZEOF_PTR == 3 && LG_TINY_MIN == 4 && LG_QUANTUM == 4 && LG_PAGE == 16)
|
||||||
@ -5555,6 +5579,7 @@
|
|||||||
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
#define LOOKUP_MAXCLASS ((((size_t)1) << 11) + (((size_t)4) << 9))
|
||||||
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
#define SMALL_MAXCLASS ((((size_t)1) << 17) + (((size_t)3) << 15))
|
||||||
#define LG_LARGE_MINCLASS 18
|
#define LG_LARGE_MINCLASS 18
|
||||||
|
#define HUGE_MAXCLASS ((((size_t)1) << 63) + (((size_t)3) << 61))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SIZE_CLASSES_DEFINED
|
#ifndef SIZE_CLASSES_DEFINED
|
||||||
|
@ -77,7 +77,7 @@ struct tcache_s {
|
|||||||
ql_elm(tcache_t) link; /* Used for aggregating stats. */
|
ql_elm(tcache_t) link; /* Used for aggregating stats. */
|
||||||
uint64_t prof_accumbytes;/* Cleared after arena_prof_accum(). */
|
uint64_t prof_accumbytes;/* Cleared after arena_prof_accum(). */
|
||||||
unsigned ev_cnt; /* Event count since incremental GC. */
|
unsigned ev_cnt; /* Event count since incremental GC. */
|
||||||
index_t next_gc_bin; /* Next bin to GC. */
|
szind_t next_gc_bin; /* Next bin to GC. */
|
||||||
tcache_bin_t tbins[1]; /* Dynamically sized. */
|
tcache_bin_t tbins[1]; /* Dynamically sized. */
|
||||||
/*
|
/*
|
||||||
* The pointer stacks associated with tbins follow as a contiguous
|
* The pointer stacks associated with tbins follow as a contiguous
|
||||||
@ -126,10 +126,10 @@ extern tcaches_t *tcaches;
|
|||||||
size_t tcache_salloc(const void *ptr);
|
size_t tcache_salloc(const void *ptr);
|
||||||
void tcache_event_hard(tsd_t *tsd, tcache_t *tcache);
|
void tcache_event_hard(tsd_t *tsd, tcache_t *tcache);
|
||||||
void *tcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
|
void *tcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
|
||||||
tcache_bin_t *tbin, index_t binind);
|
tcache_bin_t *tbin, szind_t binind);
|
||||||
void tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin,
|
void tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin,
|
||||||
index_t binind, unsigned rem);
|
szind_t binind, unsigned rem);
|
||||||
void tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, index_t binind,
|
void tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind,
|
||||||
unsigned rem, tcache_t *tcache);
|
unsigned rem, tcache_t *tcache);
|
||||||
void tcache_arena_associate(tcache_t *tcache, arena_t *arena);
|
void tcache_arena_associate(tcache_t *tcache, arena_t *arena);
|
||||||
void tcache_arena_reassociate(tcache_t *tcache, arena_t *oldarena,
|
void tcache_arena_reassociate(tcache_t *tcache, arena_t *oldarena,
|
||||||
@ -161,7 +161,7 @@ void *tcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
|
|||||||
void *tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
|
void *tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
|
||||||
size_t size, bool zero);
|
size_t size, bool zero);
|
||||||
void tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr,
|
void tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr,
|
||||||
index_t binind);
|
szind_t binind);
|
||||||
void tcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr,
|
void tcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr,
|
||||||
size_t size);
|
size_t size);
|
||||||
tcache_t *tcaches_get(tsd_t *tsd, unsigned ind);
|
tcache_t *tcaches_get(tsd_t *tsd, unsigned ind);
|
||||||
@ -267,7 +267,7 @@ tcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size,
|
|||||||
bool zero)
|
bool zero)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
size_t usize;
|
size_t usize;
|
||||||
tcache_bin_t *tbin;
|
tcache_bin_t *tbin;
|
||||||
|
|
||||||
@ -312,7 +312,7 @@ tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size,
|
|||||||
bool zero)
|
bool zero)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
size_t usize;
|
size_t usize;
|
||||||
tcache_bin_t *tbin;
|
tcache_bin_t *tbin;
|
||||||
|
|
||||||
@ -360,7 +360,7 @@ tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr, index_t binind)
|
tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr, szind_t binind)
|
||||||
{
|
{
|
||||||
tcache_bin_t *tbin;
|
tcache_bin_t *tbin;
|
||||||
tcache_bin_info_t *tbin_info;
|
tcache_bin_info_t *tbin_info;
|
||||||
@ -386,7 +386,7 @@ tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr, index_t binind)
|
|||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
tcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr, size_t size)
|
tcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
tcache_bin_t *tbin;
|
tcache_bin_t *tbin;
|
||||||
tcache_bin_info_t *tbin_info;
|
tcache_bin_info_t *tbin_info;
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ a_name##tsd_boot0(void) \
|
|||||||
return (false); \
|
return (false); \
|
||||||
} \
|
} \
|
||||||
a_attr void \
|
a_attr void \
|
||||||
a_name##tsd_boot1() \
|
a_name##tsd_boot1(void) \
|
||||||
{ \
|
{ \
|
||||||
\
|
\
|
||||||
/* Do nothing. */ \
|
/* Do nothing. */ \
|
||||||
@ -235,7 +235,7 @@ a_name##tsd_boot0(void) \
|
|||||||
return (false); \
|
return (false); \
|
||||||
} \
|
} \
|
||||||
a_attr void \
|
a_attr void \
|
||||||
a_name##tsd_boot1() \
|
a_name##tsd_boot1(void) \
|
||||||
{ \
|
{ \
|
||||||
\
|
\
|
||||||
/* Do nothing. */ \
|
/* Do nothing. */ \
|
||||||
@ -345,7 +345,7 @@ a_name##tsd_boot0(void) \
|
|||||||
return (false); \
|
return (false); \
|
||||||
} \
|
} \
|
||||||
a_attr void \
|
a_attr void \
|
||||||
a_name##tsd_boot1() \
|
a_name##tsd_boot1(void) \
|
||||||
{ \
|
{ \
|
||||||
a_name##tsd_wrapper_t *wrapper; \
|
a_name##tsd_wrapper_t *wrapper; \
|
||||||
wrapper = (a_name##tsd_wrapper_t *) \
|
wrapper = (a_name##tsd_wrapper_t *) \
|
||||||
@ -467,7 +467,7 @@ a_name##tsd_boot0(void) \
|
|||||||
return (false); \
|
return (false); \
|
||||||
} \
|
} \
|
||||||
a_attr void \
|
a_attr void \
|
||||||
a_name##tsd_boot1() \
|
a_name##tsd_boot1(void) \
|
||||||
{ \
|
{ \
|
||||||
a_name##tsd_wrapper_t *wrapper; \
|
a_name##tsd_wrapper_t *wrapper; \
|
||||||
wrapper = (a_name##tsd_wrapper_t *) \
|
wrapper = (a_name##tsd_wrapper_t *) \
|
||||||
|
@ -79,12 +79,12 @@ extern "C" {
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#define JEMALLOC_VERSION "4.0.0-0-g6e98caf8f064482b9ab292ef3638dea67420bbc2"
|
#define JEMALLOC_VERSION "4.0.2-0-g486d249fb4715fd3de679b6c2a04f7e657883111"
|
||||||
#define JEMALLOC_VERSION_MAJOR 4
|
#define JEMALLOC_VERSION_MAJOR 4
|
||||||
#define JEMALLOC_VERSION_MINOR 0
|
#define JEMALLOC_VERSION_MINOR 0
|
||||||
#define JEMALLOC_VERSION_BUGFIX 0
|
#define JEMALLOC_VERSION_BUGFIX 2
|
||||||
#define JEMALLOC_VERSION_NREV 0
|
#define JEMALLOC_VERSION_NREV 0
|
||||||
#define JEMALLOC_VERSION_GID "6e98caf8f064482b9ab292ef3638dea67420bbc2"
|
#define JEMALLOC_VERSION_GID "486d249fb4715fd3de679b6c2a04f7e657883111"
|
||||||
|
|
||||||
# define MALLOCX_LG_ALIGN(la) (la)
|
# define MALLOCX_LG_ALIGN(la) (la)
|
||||||
# if LG_SIZEOF_PTR == 2
|
# if LG_SIZEOF_PTR == 2
|
||||||
@ -234,7 +234,7 @@ JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_malloc_usable_size(
|
|||||||
#ifdef JEMALLOC_OVERRIDE_MEMALIGN
|
#ifdef JEMALLOC_OVERRIDE_MEMALIGN
|
||||||
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
|
JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN
|
||||||
void JEMALLOC_NOTHROW *je_memalign(size_t alignment, size_t size)
|
void JEMALLOC_NOTHROW *je_memalign(size_t alignment, size_t size)
|
||||||
JEMALLOC_ATTR(malloc);
|
JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef JEMALLOC_OVERRIDE_VALLOC
|
#ifdef JEMALLOC_OVERRIDE_VALLOC
|
||||||
|
@ -11,7 +11,7 @@ arena_bin_info_t arena_bin_info[NBINS];
|
|||||||
size_t map_bias;
|
size_t map_bias;
|
||||||
size_t map_misc_offset;
|
size_t map_misc_offset;
|
||||||
size_t arena_maxrun; /* Max run size for arenas. */
|
size_t arena_maxrun; /* Max run size for arenas. */
|
||||||
size_t arena_maxclass; /* Max size class for arenas. */
|
size_t large_maxclass; /* Max large size class. */
|
||||||
static size_t small_maxrun; /* Max run size used for small size classes. */
|
static size_t small_maxrun; /* Max run size used for small size classes. */
|
||||||
static bool *small_run_tab; /* Valid small run page multiples. */
|
static bool *small_run_tab; /* Valid small run page multiples. */
|
||||||
unsigned nlclasses; /* Number of large size classes. */
|
unsigned nlclasses; /* Number of large size classes. */
|
||||||
@ -39,7 +39,7 @@ JEMALLOC_INLINE_C arena_chunk_map_misc_t *
|
|||||||
arena_miscelm_key_create(size_t size)
|
arena_miscelm_key_create(size_t size)
|
||||||
{
|
{
|
||||||
|
|
||||||
return ((arena_chunk_map_misc_t *)((size << CHUNK_MAP_SIZE_SHIFT) |
|
return ((arena_chunk_map_misc_t *)(arena_mapbits_size_encode(size) |
|
||||||
CHUNK_MAP_KEY));
|
CHUNK_MAP_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,8 +58,7 @@ arena_miscelm_key_size_get(const arena_chunk_map_misc_t *miscelm)
|
|||||||
|
|
||||||
assert(arena_miscelm_is_key(miscelm));
|
assert(arena_miscelm_is_key(miscelm));
|
||||||
|
|
||||||
return (((uintptr_t)miscelm & CHUNK_MAP_SIZE_MASK) >>
|
return (arena_mapbits_size_decode((uintptr_t)miscelm));
|
||||||
CHUNK_MAP_SIZE_SHIFT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE_C size_t
|
JEMALLOC_INLINE_C size_t
|
||||||
@ -73,7 +72,7 @@ arena_miscelm_size_get(arena_chunk_map_misc_t *miscelm)
|
|||||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm);
|
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm);
|
||||||
pageind = arena_miscelm_to_pageind(miscelm);
|
pageind = arena_miscelm_to_pageind(miscelm);
|
||||||
mapbits = arena_mapbits_get(chunk, pageind);
|
mapbits = arena_mapbits_get(chunk, pageind);
|
||||||
return ((mapbits & CHUNK_MAP_SIZE_MASK) >> CHUNK_MAP_SIZE_SHIFT);
|
return (arena_mapbits_size_decode(mapbits));
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE_C int
|
JEMALLOC_INLINE_C int
|
||||||
@ -315,7 +314,7 @@ arena_run_reg_dalloc(arena_run_t *run, void *ptr)
|
|||||||
arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
|
arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
|
||||||
size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
||||||
size_t mapbits = arena_mapbits_get(chunk, pageind);
|
size_t mapbits = arena_mapbits_get(chunk, pageind);
|
||||||
index_t binind = arena_ptr_small_binind_get(ptr, mapbits);
|
szind_t binind = arena_ptr_small_binind_get(ptr, mapbits);
|
||||||
arena_bin_info_t *bin_info = &arena_bin_info[binind];
|
arena_bin_info_t *bin_info = &arena_bin_info[binind];
|
||||||
unsigned regind = arena_run_regind(run, bin_info, ptr);
|
unsigned regind = arena_run_regind(run, bin_info, ptr);
|
||||||
|
|
||||||
@ -426,7 +425,7 @@ arena_run_split_large_helper(arena_t *arena, arena_run_t *run, size_t size,
|
|||||||
{
|
{
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
arena_chunk_map_misc_t *miscelm;
|
arena_chunk_map_misc_t *miscelm;
|
||||||
size_t flag_dirty, flag_decommitted, run_ind, need_pages, i;
|
size_t flag_dirty, flag_decommitted, run_ind, need_pages;
|
||||||
size_t flag_unzeroed_mask;
|
size_t flag_unzeroed_mask;
|
||||||
|
|
||||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
|
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
|
||||||
@ -460,6 +459,7 @@ arena_run_split_large_helper(arena_t *arena, arena_run_t *run, size_t size,
|
|||||||
* The run is clean, so some pages may be zeroed (i.e.
|
* The run is clean, so some pages may be zeroed (i.e.
|
||||||
* never before touched).
|
* never before touched).
|
||||||
*/
|
*/
|
||||||
|
size_t i;
|
||||||
for (i = 0; i < need_pages; i++) {
|
for (i = 0; i < need_pages; i++) {
|
||||||
if (arena_mapbits_unzeroed_get(chunk, run_ind+i)
|
if (arena_mapbits_unzeroed_get(chunk, run_ind+i)
|
||||||
!= 0)
|
!= 0)
|
||||||
@ -508,7 +508,7 @@ arena_run_init_large(arena_t *arena, arena_run_t *run, size_t size, bool zero)
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
arena_run_split_small(arena_t *arena, arena_run_t *run, size_t size,
|
arena_run_split_small(arena_t *arena, arena_run_t *run, size_t size,
|
||||||
index_t binind)
|
szind_t binind)
|
||||||
{
|
{
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
arena_chunk_map_misc_t *miscelm;
|
arena_chunk_map_misc_t *miscelm;
|
||||||
@ -780,7 +780,7 @@ arena_chunk_dalloc(arena_t *arena, arena_chunk_t *chunk)
|
|||||||
static void
|
static void
|
||||||
arena_huge_malloc_stats_update(arena_t *arena, size_t usize)
|
arena_huge_malloc_stats_update(arena_t *arena, size_t usize)
|
||||||
{
|
{
|
||||||
index_t index = size2index(usize) - nlclasses - NBINS;
|
szind_t index = size2index(usize) - nlclasses - NBINS;
|
||||||
|
|
||||||
cassert(config_stats);
|
cassert(config_stats);
|
||||||
|
|
||||||
@ -793,7 +793,7 @@ arena_huge_malloc_stats_update(arena_t *arena, size_t usize)
|
|||||||
static void
|
static void
|
||||||
arena_huge_malloc_stats_update_undo(arena_t *arena, size_t usize)
|
arena_huge_malloc_stats_update_undo(arena_t *arena, size_t usize)
|
||||||
{
|
{
|
||||||
index_t index = size2index(usize) - nlclasses - NBINS;
|
szind_t index = size2index(usize) - nlclasses - NBINS;
|
||||||
|
|
||||||
cassert(config_stats);
|
cassert(config_stats);
|
||||||
|
|
||||||
@ -806,7 +806,7 @@ arena_huge_malloc_stats_update_undo(arena_t *arena, size_t usize)
|
|||||||
static void
|
static void
|
||||||
arena_huge_dalloc_stats_update(arena_t *arena, size_t usize)
|
arena_huge_dalloc_stats_update(arena_t *arena, size_t usize)
|
||||||
{
|
{
|
||||||
index_t index = size2index(usize) - nlclasses - NBINS;
|
szind_t index = size2index(usize) - nlclasses - NBINS;
|
||||||
|
|
||||||
cassert(config_stats);
|
cassert(config_stats);
|
||||||
|
|
||||||
@ -819,7 +819,7 @@ arena_huge_dalloc_stats_update(arena_t *arena, size_t usize)
|
|||||||
static void
|
static void
|
||||||
arena_huge_dalloc_stats_update_undo(arena_t *arena, size_t usize)
|
arena_huge_dalloc_stats_update_undo(arena_t *arena, size_t usize)
|
||||||
{
|
{
|
||||||
index_t index = size2index(usize) - nlclasses - NBINS;
|
szind_t index = size2index(usize) - nlclasses - NBINS;
|
||||||
|
|
||||||
cassert(config_stats);
|
cassert(config_stats);
|
||||||
|
|
||||||
@ -1125,7 +1125,7 @@ arena_run_alloc_large(arena_t *arena, size_t size, bool zero)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static arena_run_t *
|
static arena_run_t *
|
||||||
arena_run_alloc_small_helper(arena_t *arena, size_t size, index_t binind)
|
arena_run_alloc_small_helper(arena_t *arena, size_t size, szind_t binind)
|
||||||
{
|
{
|
||||||
arena_run_t *run = arena_run_first_best_fit(arena, size);
|
arena_run_t *run = arena_run_first_best_fit(arena, size);
|
||||||
if (run != NULL) {
|
if (run != NULL) {
|
||||||
@ -1136,7 +1136,7 @@ arena_run_alloc_small_helper(arena_t *arena, size_t size, index_t binind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static arena_run_t *
|
static arena_run_t *
|
||||||
arena_run_alloc_small(arena_t *arena, size_t size, index_t binind)
|
arena_run_alloc_small(arena_t *arena, size_t size, szind_t binind)
|
||||||
{
|
{
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
arena_run_t *run;
|
arena_run_t *run;
|
||||||
@ -1889,7 +1889,7 @@ static arena_run_t *
|
|||||||
arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)
|
arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)
|
||||||
{
|
{
|
||||||
arena_run_t *run;
|
arena_run_t *run;
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
arena_bin_info_t *bin_info;
|
arena_bin_info_t *bin_info;
|
||||||
|
|
||||||
/* Look for a usable run. */
|
/* Look for a usable run. */
|
||||||
@ -1939,8 +1939,7 @@ arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)
|
|||||||
static void *
|
static void *
|
||||||
arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
|
arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
|
||||||
{
|
{
|
||||||
void *ret;
|
szind_t binind;
|
||||||
index_t binind;
|
|
||||||
arena_bin_info_t *bin_info;
|
arena_bin_info_t *bin_info;
|
||||||
arena_run_t *run;
|
arena_run_t *run;
|
||||||
|
|
||||||
@ -1953,6 +1952,7 @@ arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
|
|||||||
* Another thread updated runcur while this one ran without the
|
* Another thread updated runcur while this one ran without the
|
||||||
* bin lock in arena_bin_nonfull_run_get().
|
* bin lock in arena_bin_nonfull_run_get().
|
||||||
*/
|
*/
|
||||||
|
void *ret;
|
||||||
assert(bin->runcur->nfree > 0);
|
assert(bin->runcur->nfree > 0);
|
||||||
ret = arena_run_reg_alloc(bin->runcur, bin_info);
|
ret = arena_run_reg_alloc(bin->runcur, bin_info);
|
||||||
if (run != NULL) {
|
if (run != NULL) {
|
||||||
@ -1986,13 +1986,11 @@ arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, index_t binind,
|
arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, szind_t binind,
|
||||||
uint64_t prof_accumbytes)
|
uint64_t prof_accumbytes)
|
||||||
{
|
{
|
||||||
unsigned i, nfill;
|
unsigned i, nfill;
|
||||||
arena_bin_t *bin;
|
arena_bin_t *bin;
|
||||||
arena_run_t *run;
|
|
||||||
void *ptr;
|
|
||||||
|
|
||||||
assert(tbin->ncached == 0);
|
assert(tbin->ncached == 0);
|
||||||
|
|
||||||
@ -2002,6 +2000,8 @@ arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, index_t binind,
|
|||||||
malloc_mutex_lock(&bin->lock);
|
malloc_mutex_lock(&bin->lock);
|
||||||
for (i = 0, nfill = (tcache_bin_info[binind].ncached_max >>
|
for (i = 0, nfill = (tcache_bin_info[binind].ncached_max >>
|
||||||
tbin->lg_fill_div); i < nfill; i++) {
|
tbin->lg_fill_div); i < nfill; i++) {
|
||||||
|
arena_run_t *run;
|
||||||
|
void *ptr;
|
||||||
if ((run = bin->runcur) != NULL && run->nfree > 0)
|
if ((run = bin->runcur) != NULL && run->nfree > 0)
|
||||||
ptr = arena_run_reg_alloc(run, &arena_bin_info[binind]);
|
ptr = arena_run_reg_alloc(run, &arena_bin_info[binind]);
|
||||||
else
|
else
|
||||||
@ -2076,12 +2076,13 @@ arena_redzone_corruption_t *arena_redzone_corruption =
|
|||||||
static void
|
static void
|
||||||
arena_redzones_validate(void *ptr, arena_bin_info_t *bin_info, bool reset)
|
arena_redzones_validate(void *ptr, arena_bin_info_t *bin_info, bool reset)
|
||||||
{
|
{
|
||||||
size_t size = bin_info->reg_size;
|
|
||||||
size_t redzone_size = bin_info->redzone_size;
|
|
||||||
size_t i;
|
|
||||||
bool error = false;
|
bool error = false;
|
||||||
|
|
||||||
if (opt_junk_alloc) {
|
if (opt_junk_alloc) {
|
||||||
|
size_t size = bin_info->reg_size;
|
||||||
|
size_t redzone_size = bin_info->redzone_size;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
for (i = 1; i <= redzone_size; i++) {
|
for (i = 1; i <= redzone_size; i++) {
|
||||||
uint8_t *byte = (uint8_t *)((uintptr_t)ptr - i);
|
uint8_t *byte = (uint8_t *)((uintptr_t)ptr - i);
|
||||||
if (*byte != 0xa5) {
|
if (*byte != 0xa5) {
|
||||||
@ -2131,7 +2132,7 @@ arena_dalloc_junk_small_t *arena_dalloc_junk_small =
|
|||||||
void
|
void
|
||||||
arena_quarantine_junk_small(void *ptr, size_t usize)
|
arena_quarantine_junk_small(void *ptr, size_t usize)
|
||||||
{
|
{
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
arena_bin_info_t *bin_info;
|
arena_bin_info_t *bin_info;
|
||||||
cassert(config_fill);
|
cassert(config_fill);
|
||||||
assert(opt_junk_free);
|
assert(opt_junk_free);
|
||||||
@ -2149,7 +2150,7 @@ arena_malloc_small(arena_t *arena, size_t size, bool zero)
|
|||||||
void *ret;
|
void *ret;
|
||||||
arena_bin_t *bin;
|
arena_bin_t *bin;
|
||||||
arena_run_t *run;
|
arena_run_t *run;
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
|
|
||||||
binind = size2index(size);
|
binind = size2index(size);
|
||||||
assert(binind < NBINS);
|
assert(binind < NBINS);
|
||||||
@ -2233,7 +2234,7 @@ arena_malloc_large(arena_t *arena, size_t size, bool zero)
|
|||||||
ret = (void *)((uintptr_t)arena_miscelm_to_rpages(miscelm) +
|
ret = (void *)((uintptr_t)arena_miscelm_to_rpages(miscelm) +
|
||||||
random_offset);
|
random_offset);
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
index_t index = size2index(usize) - NBINS;
|
szind_t index = size2index(usize) - NBINS;
|
||||||
|
|
||||||
arena->stats.nmalloc_large++;
|
arena->stats.nmalloc_large++;
|
||||||
arena->stats.nrequests_large++;
|
arena->stats.nrequests_large++;
|
||||||
@ -2326,7 +2327,7 @@ arena_palloc_large(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment,
|
|||||||
ret = arena_miscelm_to_rpages(miscelm);
|
ret = arena_miscelm_to_rpages(miscelm);
|
||||||
|
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
index_t index = size2index(usize) - NBINS;
|
szind_t index = size2index(usize) - NBINS;
|
||||||
|
|
||||||
arena->stats.nmalloc_large++;
|
arena->stats.nmalloc_large++;
|
||||||
arena->stats.nrequests_large++;
|
arena->stats.nrequests_large++;
|
||||||
@ -2356,7 +2357,7 @@ arena_palloc(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment,
|
|||||||
&& (usize & PAGE_MASK) == 0))) {
|
&& (usize & PAGE_MASK) == 0))) {
|
||||||
/* Small; alignment doesn't require special run placement. */
|
/* Small; alignment doesn't require special run placement. */
|
||||||
ret = arena_malloc(tsd, arena, usize, zero, tcache);
|
ret = arena_malloc(tsd, arena, usize, zero, tcache);
|
||||||
} else if (usize <= arena_maxclass && alignment <= PAGE) {
|
} else if (usize <= large_maxclass && alignment <= PAGE) {
|
||||||
/*
|
/*
|
||||||
* Large; alignment doesn't require special run placement.
|
* Large; alignment doesn't require special run placement.
|
||||||
* However, the cached pointer may be at a random offset from
|
* However, the cached pointer may be at a random offset from
|
||||||
@ -2367,7 +2368,7 @@ arena_palloc(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment,
|
|||||||
if (config_cache_oblivious)
|
if (config_cache_oblivious)
|
||||||
ret = (void *)((uintptr_t)ret & ~PAGE_MASK);
|
ret = (void *)((uintptr_t)ret & ~PAGE_MASK);
|
||||||
} else {
|
} else {
|
||||||
if (likely(usize <= arena_maxclass)) {
|
if (likely(usize <= large_maxclass)) {
|
||||||
ret = arena_palloc_large(tsd, arena, usize, alignment,
|
ret = arena_palloc_large(tsd, arena, usize, alignment,
|
||||||
zero);
|
zero);
|
||||||
} else if (likely(alignment <= chunksize))
|
} else if (likely(alignment <= chunksize))
|
||||||
@ -2385,7 +2386,7 @@ arena_prof_promoted(const void *ptr, size_t size)
|
|||||||
{
|
{
|
||||||
arena_chunk_t *chunk;
|
arena_chunk_t *chunk;
|
||||||
size_t pageind;
|
size_t pageind;
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
assert(ptr != NULL);
|
assert(ptr != NULL);
|
||||||
@ -2413,7 +2414,7 @@ arena_dissociate_bin_run(arena_chunk_t *chunk, arena_run_t *run,
|
|||||||
if (run == bin->runcur)
|
if (run == bin->runcur)
|
||||||
bin->runcur = NULL;
|
bin->runcur = NULL;
|
||||||
else {
|
else {
|
||||||
index_t binind = arena_bin_index(extent_node_arena_get(
|
szind_t binind = arena_bin_index(extent_node_arena_get(
|
||||||
&chunk->node), bin);
|
&chunk->node), bin);
|
||||||
arena_bin_info_t *bin_info = &arena_bin_info[binind];
|
arena_bin_info_t *bin_info = &arena_bin_info[binind];
|
||||||
|
|
||||||
@ -2477,7 +2478,7 @@ arena_dalloc_bin_locked_impl(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
|||||||
arena_run_t *run;
|
arena_run_t *run;
|
||||||
arena_bin_t *bin;
|
arena_bin_t *bin;
|
||||||
arena_bin_info_t *bin_info;
|
arena_bin_info_t *bin_info;
|
||||||
index_t binind;
|
szind_t binind;
|
||||||
|
|
||||||
pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
||||||
rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind);
|
rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind);
|
||||||
@ -2559,7 +2560,7 @@ arena_dalloc_junk_large_t *arena_dalloc_junk_large =
|
|||||||
JEMALLOC_N(arena_dalloc_junk_large_impl);
|
JEMALLOC_N(arena_dalloc_junk_large_impl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
static void
|
||||||
arena_dalloc_large_locked_impl(arena_t *arena, arena_chunk_t *chunk,
|
arena_dalloc_large_locked_impl(arena_t *arena, arena_chunk_t *chunk,
|
||||||
void *ptr, bool junked)
|
void *ptr, bool junked)
|
||||||
{
|
{
|
||||||
@ -2574,7 +2575,7 @@ arena_dalloc_large_locked_impl(arena_t *arena, arena_chunk_t *chunk,
|
|||||||
if (!junked)
|
if (!junked)
|
||||||
arena_dalloc_junk_large(ptr, usize);
|
arena_dalloc_junk_large(ptr, usize);
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
index_t index = size2index(usize) - NBINS;
|
szind_t index = size2index(usize) - NBINS;
|
||||||
|
|
||||||
arena->stats.ndalloc_large++;
|
arena->stats.ndalloc_large++;
|
||||||
arena->stats.allocated_large -= usize;
|
arena->stats.allocated_large -= usize;
|
||||||
@ -2621,8 +2622,8 @@ arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
|||||||
arena_run_trim_tail(arena, chunk, run, oldsize + large_pad, size +
|
arena_run_trim_tail(arena, chunk, run, oldsize + large_pad, size +
|
||||||
large_pad, true);
|
large_pad, true);
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
index_t oldindex = size2index(oldsize) - NBINS;
|
szind_t oldindex = size2index(oldsize) - NBINS;
|
||||||
index_t index = size2index(size) - NBINS;
|
szind_t index = size2index(size) - NBINS;
|
||||||
|
|
||||||
arena->stats.ndalloc_large++;
|
arena->stats.ndalloc_large++;
|
||||||
arena->stats.allocated_large -= oldsize;
|
arena->stats.allocated_large -= oldsize;
|
||||||
@ -2641,42 +2642,42 @@ arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
|||||||
|
|
||||||
static bool
|
static bool
|
||||||
arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
||||||
size_t oldsize, size_t size, size_t extra, bool zero)
|
size_t oldsize, size_t usize_min, size_t usize_max, bool zero)
|
||||||
{
|
{
|
||||||
size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE;
|
||||||
size_t npages = (oldsize + large_pad) >> LG_PAGE;
|
size_t npages = (oldsize + large_pad) >> LG_PAGE;
|
||||||
size_t followsize;
|
size_t followsize;
|
||||||
size_t usize_min = s2u(size);
|
|
||||||
|
|
||||||
assert(oldsize == arena_mapbits_large_size_get(chunk, pageind) -
|
assert(oldsize == arena_mapbits_large_size_get(chunk, pageind) -
|
||||||
large_pad);
|
large_pad);
|
||||||
|
|
||||||
/* Try to extend the run. */
|
/* Try to extend the run. */
|
||||||
assert(usize_min > oldsize);
|
|
||||||
malloc_mutex_lock(&arena->lock);
|
malloc_mutex_lock(&arena->lock);
|
||||||
if (pageind+npages < chunk_npages &&
|
if (pageind+npages >= chunk_npages || arena_mapbits_allocated_get(chunk,
|
||||||
arena_mapbits_allocated_get(chunk, pageind+npages) == 0 &&
|
pageind+npages) != 0)
|
||||||
(followsize = arena_mapbits_unallocated_size_get(chunk,
|
goto label_fail;
|
||||||
pageind+npages)) >= usize_min - oldsize) {
|
followsize = arena_mapbits_unallocated_size_get(chunk, pageind+npages);
|
||||||
|
if (oldsize + followsize >= usize_min) {
|
||||||
/*
|
/*
|
||||||
* The next run is available and sufficiently large. Split the
|
* The next run is available and sufficiently large. Split the
|
||||||
* following run, then merge the first part with the existing
|
* following run, then merge the first part with the existing
|
||||||
* allocation.
|
* allocation.
|
||||||
*/
|
*/
|
||||||
arena_run_t *run;
|
arena_run_t *run;
|
||||||
size_t flag_dirty, flag_unzeroed_mask, splitsize, usize;
|
size_t usize, splitsize, size, flag_dirty, flag_unzeroed_mask;
|
||||||
|
|
||||||
usize = s2u(size + extra);
|
usize = usize_max;
|
||||||
while (oldsize + followsize < usize)
|
while (oldsize + followsize < usize)
|
||||||
usize = index2size(size2index(usize)-1);
|
usize = index2size(size2index(usize)-1);
|
||||||
assert(usize >= usize_min);
|
assert(usize >= usize_min);
|
||||||
|
assert(usize >= oldsize);
|
||||||
splitsize = usize - oldsize;
|
splitsize = usize - oldsize;
|
||||||
|
if (splitsize == 0)
|
||||||
|
goto label_fail;
|
||||||
|
|
||||||
run = &arena_miscelm_get(chunk, pageind+npages)->run;
|
run = &arena_miscelm_get(chunk, pageind+npages)->run;
|
||||||
if (arena_run_split_large(arena, run, splitsize, zero)) {
|
if (arena_run_split_large(arena, run, splitsize, zero))
|
||||||
malloc_mutex_unlock(&arena->lock);
|
goto label_fail;
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
size = oldsize + splitsize;
|
size = oldsize + splitsize;
|
||||||
npages = (size + large_pad) >> LG_PAGE;
|
npages = (size + large_pad) >> LG_PAGE;
|
||||||
@ -2700,8 +2701,8 @@ arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
|||||||
pageind+npages-1)));
|
pageind+npages-1)));
|
||||||
|
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
index_t oldindex = size2index(oldsize) - NBINS;
|
szind_t oldindex = size2index(oldsize) - NBINS;
|
||||||
index_t index = size2index(size) - NBINS;
|
szind_t index = size2index(size) - NBINS;
|
||||||
|
|
||||||
arena->stats.ndalloc_large++;
|
arena->stats.ndalloc_large++;
|
||||||
arena->stats.allocated_large -= oldsize;
|
arena->stats.allocated_large -= oldsize;
|
||||||
@ -2718,8 +2719,8 @@ arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
|
|||||||
malloc_mutex_unlock(&arena->lock);
|
malloc_mutex_unlock(&arena->lock);
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
label_fail:
|
||||||
malloc_mutex_unlock(&arena->lock);
|
malloc_mutex_unlock(&arena->lock);
|
||||||
|
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2748,98 +2749,107 @@ arena_ralloc_junk_large_t *arena_ralloc_junk_large =
|
|||||||
* always fail if growing an object, and the following run is already in use.
|
* always fail if growing an object, and the following run is already in use.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
arena_ralloc_large(void *ptr, size_t oldsize, size_t size, size_t extra,
|
arena_ralloc_large(void *ptr, size_t oldsize, size_t usize_min,
|
||||||
bool zero)
|
size_t usize_max, bool zero)
|
||||||
{
|
{
|
||||||
size_t usize;
|
arena_chunk_t *chunk;
|
||||||
|
arena_t *arena;
|
||||||
|
|
||||||
/* Make sure extra can't cause size_t overflow. */
|
if (oldsize == usize_max) {
|
||||||
if (unlikely(extra >= arena_maxclass))
|
/* Current size class is compatible and maximal. */
|
||||||
return (true);
|
|
||||||
|
|
||||||
usize = s2u(size + extra);
|
|
||||||
if (usize == oldsize) {
|
|
||||||
/* Same size class. */
|
|
||||||
return (false);
|
return (false);
|
||||||
} else {
|
|
||||||
arena_chunk_t *chunk;
|
|
||||||
arena_t *arena;
|
|
||||||
|
|
||||||
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
|
||||||
arena = extent_node_arena_get(&chunk->node);
|
|
||||||
|
|
||||||
if (usize < oldsize) {
|
|
||||||
/* Fill before shrinking in order avoid a race. */
|
|
||||||
arena_ralloc_junk_large(ptr, oldsize, usize);
|
|
||||||
arena_ralloc_large_shrink(arena, chunk, ptr, oldsize,
|
|
||||||
usize);
|
|
||||||
return (false);
|
|
||||||
} else {
|
|
||||||
bool ret = arena_ralloc_large_grow(arena, chunk, ptr,
|
|
||||||
oldsize, size, extra, zero);
|
|
||||||
if (config_fill && !ret && !zero) {
|
|
||||||
if (unlikely(opt_junk_alloc)) {
|
|
||||||
memset((void *)((uintptr_t)ptr +
|
|
||||||
oldsize), 0xa5, isalloc(ptr,
|
|
||||||
config_prof) - oldsize);
|
|
||||||
} else if (unlikely(opt_zero)) {
|
|
||||||
memset((void *)((uintptr_t)ptr +
|
|
||||||
oldsize), 0, isalloc(ptr,
|
|
||||||
config_prof) - oldsize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
|
||||||
|
arena = extent_node_arena_get(&chunk->node);
|
||||||
|
|
||||||
|
if (oldsize < usize_max) {
|
||||||
|
bool ret = arena_ralloc_large_grow(arena, chunk, ptr, oldsize,
|
||||||
|
usize_min, usize_max, zero);
|
||||||
|
if (config_fill && !ret && !zero) {
|
||||||
|
if (unlikely(opt_junk_alloc)) {
|
||||||
|
memset((void *)((uintptr_t)ptr + oldsize), 0xa5,
|
||||||
|
isalloc(ptr, config_prof) - oldsize);
|
||||||
|
} else if (unlikely(opt_zero)) {
|
||||||
|
memset((void *)((uintptr_t)ptr + oldsize), 0,
|
||||||
|
isalloc(ptr, config_prof) - oldsize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(oldsize > usize_max);
|
||||||
|
/* Fill before shrinking in order avoid a race. */
|
||||||
|
arena_ralloc_junk_large(ptr, oldsize, usize_max);
|
||||||
|
arena_ralloc_large_shrink(arena, chunk, ptr, oldsize, usize_max);
|
||||||
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
arena_ralloc_no_move(void *ptr, size_t oldsize, size_t size, size_t extra,
|
arena_ralloc_no_move(void *ptr, size_t oldsize, size_t size, size_t extra,
|
||||||
bool zero)
|
bool zero)
|
||||||
{
|
{
|
||||||
|
size_t usize_min, usize_max;
|
||||||
|
|
||||||
if (likely(size <= arena_maxclass)) {
|
usize_min = s2u(size);
|
||||||
|
usize_max = s2u(size + extra);
|
||||||
|
if (likely(oldsize <= large_maxclass && usize_min <= large_maxclass)) {
|
||||||
/*
|
/*
|
||||||
* Avoid moving the allocation if the size class can be left the
|
* Avoid moving the allocation if the size class can be left the
|
||||||
* same.
|
* same.
|
||||||
*/
|
*/
|
||||||
if (likely(oldsize <= arena_maxclass)) {
|
if (oldsize <= SMALL_MAXCLASS) {
|
||||||
if (oldsize <= SMALL_MAXCLASS) {
|
assert(arena_bin_info[size2index(oldsize)].reg_size ==
|
||||||
assert(
|
oldsize);
|
||||||
arena_bin_info[size2index(oldsize)].reg_size
|
if ((usize_max <= SMALL_MAXCLASS &&
|
||||||
== oldsize);
|
size2index(usize_max) == size2index(oldsize)) ||
|
||||||
if ((size + extra <= SMALL_MAXCLASS &&
|
(size <= oldsize && usize_max >= oldsize))
|
||||||
size2index(size + extra) ==
|
return (false);
|
||||||
size2index(oldsize)) || (size <= oldsize &&
|
} else {
|
||||||
size + extra >= oldsize))
|
if (usize_max > SMALL_MAXCLASS) {
|
||||||
|
if (!arena_ralloc_large(ptr, oldsize, usize_min,
|
||||||
|
usize_max, zero))
|
||||||
return (false);
|
return (false);
|
||||||
} else {
|
|
||||||
assert(size <= arena_maxclass);
|
|
||||||
if (size + extra > SMALL_MAXCLASS) {
|
|
||||||
if (!arena_ralloc_large(ptr, oldsize,
|
|
||||||
size, extra, zero))
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reallocation would require a move. */
|
/* Reallocation would require a move. */
|
||||||
return (true);
|
return (true);
|
||||||
} else
|
} else {
|
||||||
return (huge_ralloc_no_move(ptr, oldsize, size, extra, zero));
|
return (huge_ralloc_no_move(ptr, oldsize, usize_min, usize_max,
|
||||||
|
zero));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
arena_ralloc_move_helper(tsd_t *tsd, arena_t *arena, size_t usize,
|
||||||
|
size_t alignment, bool zero, tcache_t *tcache)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (alignment == 0)
|
||||||
|
return (arena_malloc(tsd, arena, usize, zero, tcache));
|
||||||
|
usize = sa2u(usize, alignment);
|
||||||
|
if (usize == 0)
|
||||||
|
return (NULL);
|
||||||
|
return (ipalloct(tsd, usize, alignment, zero, tcache, arena));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t size,
|
arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t size,
|
||||||
size_t extra, size_t alignment, bool zero, tcache_t *tcache)
|
size_t alignment, bool zero, tcache_t *tcache)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
size_t usize;
|
||||||
|
|
||||||
if (likely(size <= arena_maxclass)) {
|
usize = s2u(size);
|
||||||
|
if (usize == 0)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
if (likely(usize <= large_maxclass)) {
|
||||||
size_t copysize;
|
size_t copysize;
|
||||||
|
|
||||||
/* Try to avoid moving the allocation. */
|
/* Try to avoid moving the allocation. */
|
||||||
if (!arena_ralloc_no_move(ptr, oldsize, size, extra, zero))
|
if (!arena_ralloc_no_move(ptr, oldsize, usize, 0, zero))
|
||||||
return (ptr);
|
return (ptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2847,53 +2857,23 @@ arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t size,
|
|||||||
* the object. In that case, fall back to allocating new space
|
* the object. In that case, fall back to allocating new space
|
||||||
* and copying.
|
* and copying.
|
||||||
*/
|
*/
|
||||||
if (alignment != 0) {
|
ret = arena_ralloc_move_helper(tsd, arena, usize, alignment,
|
||||||
size_t usize = sa2u(size + extra, alignment);
|
zero, tcache);
|
||||||
if (usize == 0)
|
if (ret == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
ret = ipalloct(tsd, usize, alignment, zero, tcache,
|
|
||||||
arena);
|
|
||||||
} else {
|
|
||||||
ret = arena_malloc(tsd, arena, size + extra, zero,
|
|
||||||
tcache);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == NULL) {
|
|
||||||
if (extra == 0)
|
|
||||||
return (NULL);
|
|
||||||
/* Try again, this time without extra. */
|
|
||||||
if (alignment != 0) {
|
|
||||||
size_t usize = sa2u(size, alignment);
|
|
||||||
if (usize == 0)
|
|
||||||
return (NULL);
|
|
||||||
ret = ipalloct(tsd, usize, alignment, zero,
|
|
||||||
tcache, arena);
|
|
||||||
} else {
|
|
||||||
ret = arena_malloc(tsd, arena, size, zero,
|
|
||||||
tcache);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == NULL)
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Junk/zero-filling were already done by
|
* Junk/zero-filling were already done by
|
||||||
* ipalloc()/arena_malloc().
|
* ipalloc()/arena_malloc().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
copysize = (usize < oldsize) ? usize : oldsize;
|
||||||
* Copy at most size bytes (not size+extra), since the caller
|
|
||||||
* has no expectation that the extra bytes will be reliably
|
|
||||||
* preserved.
|
|
||||||
*/
|
|
||||||
copysize = (size < oldsize) ? size : oldsize;
|
|
||||||
JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, copysize);
|
JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, copysize);
|
||||||
memcpy(ret, ptr, copysize);
|
memcpy(ret, ptr, copysize);
|
||||||
isqalloc(tsd, ptr, oldsize, tcache);
|
isqalloc(tsd, ptr, oldsize, tcache);
|
||||||
} else {
|
} else {
|
||||||
ret = huge_ralloc(tsd, arena, ptr, oldsize, size, extra,
|
ret = huge_ralloc(tsd, arena, ptr, oldsize, usize, alignment,
|
||||||
alignment, zero, tcache);
|
zero, tcache);
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -3241,7 +3221,6 @@ small_run_size_init(void)
|
|||||||
bool
|
bool
|
||||||
arena_boot(void)
|
arena_boot(void)
|
||||||
{
|
{
|
||||||
size_t header_size;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
arena_lg_dirty_mult_default_set(opt_lg_dirty_mult);
|
arena_lg_dirty_mult_default_set(opt_lg_dirty_mult);
|
||||||
@ -3260,7 +3239,7 @@ arena_boot(void)
|
|||||||
*/
|
*/
|
||||||
map_bias = 0;
|
map_bias = 0;
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
header_size = offsetof(arena_chunk_t, map_bits) +
|
size_t header_size = offsetof(arena_chunk_t, map_bits) +
|
||||||
((sizeof(arena_chunk_map_bits_t) +
|
((sizeof(arena_chunk_map_bits_t) +
|
||||||
sizeof(arena_chunk_map_misc_t)) * (chunk_npages-map_bias));
|
sizeof(arena_chunk_map_misc_t)) * (chunk_npages-map_bias));
|
||||||
map_bias = (header_size + PAGE_MASK) >> LG_PAGE;
|
map_bias = (header_size + PAGE_MASK) >> LG_PAGE;
|
||||||
@ -3272,17 +3251,17 @@ arena_boot(void)
|
|||||||
|
|
||||||
arena_maxrun = chunksize - (map_bias << LG_PAGE);
|
arena_maxrun = chunksize - (map_bias << LG_PAGE);
|
||||||
assert(arena_maxrun > 0);
|
assert(arena_maxrun > 0);
|
||||||
arena_maxclass = index2size(size2index(chunksize)-1);
|
large_maxclass = index2size(size2index(chunksize)-1);
|
||||||
if (arena_maxclass > arena_maxrun) {
|
if (large_maxclass > arena_maxrun) {
|
||||||
/*
|
/*
|
||||||
* For small chunk sizes it's possible for there to be fewer
|
* For small chunk sizes it's possible for there to be fewer
|
||||||
* non-header pages available than are necessary to serve the
|
* non-header pages available than are necessary to serve the
|
||||||
* size classes just below chunksize.
|
* size classes just below chunksize.
|
||||||
*/
|
*/
|
||||||
arena_maxclass = arena_maxrun;
|
large_maxclass = arena_maxrun;
|
||||||
}
|
}
|
||||||
assert(arena_maxclass > 0);
|
assert(large_maxclass > 0);
|
||||||
nlclasses = size2index(arena_maxclass) - size2index(SMALL_MAXCLASS);
|
nlclasses = size2index(large_maxclass) - size2index(SMALL_MAXCLASS);
|
||||||
nhclasses = NSIZES - nlclasses - NBINS;
|
nhclasses = NSIZES - nlclasses - NBINS;
|
||||||
|
|
||||||
bin_info_init();
|
bin_info_init();
|
||||||
|
@ -69,8 +69,6 @@ void *
|
|||||||
chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, size_t alignment,
|
chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, size_t alignment,
|
||||||
bool *zero, bool *commit)
|
bool *zero, bool *commit)
|
||||||
{
|
{
|
||||||
void *ret;
|
|
||||||
|
|
||||||
cassert(have_dss);
|
cassert(have_dss);
|
||||||
assert(size > 0 && (size & chunksize_mask) == 0);
|
assert(size > 0 && (size & chunksize_mask) == 0);
|
||||||
assert(alignment > 0 && (alignment & chunksize_mask) == 0);
|
assert(alignment > 0 && (alignment & chunksize_mask) == 0);
|
||||||
@ -84,9 +82,6 @@ chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, size_t alignment,
|
|||||||
|
|
||||||
malloc_mutex_lock(&dss_mtx);
|
malloc_mutex_lock(&dss_mtx);
|
||||||
if (dss_prev != (void *)-1) {
|
if (dss_prev != (void *)-1) {
|
||||||
size_t gap_size, cpad_size;
|
|
||||||
void *cpad, *dss_next;
|
|
||||||
intptr_t incr;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The loop is necessary to recover from races with other
|
* The loop is necessary to recover from races with other
|
||||||
@ -94,6 +89,9 @@ chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, size_t alignment,
|
|||||||
* malloc.
|
* malloc.
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
|
void *ret, *cpad, *dss_next;
|
||||||
|
size_t gap_size, cpad_size;
|
||||||
|
intptr_t incr;
|
||||||
/* Avoid an unnecessary system call. */
|
/* Avoid an unnecessary system call. */
|
||||||
if (new_addr != NULL && dss_max != new_addr)
|
if (new_addr != NULL && dss_max != new_addr)
|
||||||
break;
|
break;
|
||||||
|
@ -6,14 +6,16 @@
|
|||||||
static void *
|
static void *
|
||||||
chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit)
|
chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit)
|
||||||
{
|
{
|
||||||
void *ret, *pages;
|
void *ret;
|
||||||
size_t alloc_size, leadsize;
|
size_t alloc_size;
|
||||||
|
|
||||||
alloc_size = size + alignment - PAGE;
|
alloc_size = size + alignment - PAGE;
|
||||||
/* Beware size_t wrap-around. */
|
/* Beware size_t wrap-around. */
|
||||||
if (alloc_size < size)
|
if (alloc_size < size)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
do {
|
do {
|
||||||
|
void *pages;
|
||||||
|
size_t leadsize;
|
||||||
pages = pages_map(NULL, alloc_size);
|
pages = pages_map(NULL, alloc_size);
|
||||||
if (pages == NULL)
|
if (pages == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
@ -126,18 +126,19 @@ huge_dalloc_junk_t *huge_dalloc_junk = JEMALLOC_N(huge_dalloc_junk_impl);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
huge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize,
|
huge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize_min,
|
||||||
size_t size, size_t extra, bool zero)
|
size_t usize_max, bool zero)
|
||||||
{
|
{
|
||||||
size_t usize_next;
|
size_t usize, usize_next;
|
||||||
extent_node_t *node;
|
extent_node_t *node;
|
||||||
arena_t *arena;
|
arena_t *arena;
|
||||||
chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;
|
chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;
|
||||||
bool zeroed;
|
bool zeroed;
|
||||||
|
|
||||||
/* Increase usize to incorporate extra. */
|
/* Increase usize to incorporate extra. */
|
||||||
while (usize < s2u(size+extra) && (usize_next = s2u(usize+1)) < oldsize)
|
for (usize = usize_min; usize < usize_max && (usize_next = s2u(usize+1))
|
||||||
usize = usize_next;
|
<= oldsize; usize = usize_next)
|
||||||
|
; /* Do nothing. */
|
||||||
|
|
||||||
if (oldsize == usize)
|
if (oldsize == usize)
|
||||||
return;
|
return;
|
||||||
@ -148,11 +149,12 @@ huge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize,
|
|||||||
/* Fill if necessary (shrinking). */
|
/* Fill if necessary (shrinking). */
|
||||||
if (oldsize > usize) {
|
if (oldsize > usize) {
|
||||||
size_t sdiff = oldsize - usize;
|
size_t sdiff = oldsize - usize;
|
||||||
zeroed = !chunk_purge_wrapper(arena, &chunk_hooks, ptr,
|
|
||||||
CHUNK_CEILING(usize), usize, sdiff);
|
|
||||||
if (config_fill && unlikely(opt_junk_free)) {
|
if (config_fill && unlikely(opt_junk_free)) {
|
||||||
memset((void *)((uintptr_t)ptr + usize), 0x5a, sdiff);
|
memset((void *)((uintptr_t)ptr + usize), 0x5a, sdiff);
|
||||||
zeroed = false;
|
zeroed = false;
|
||||||
|
} else {
|
||||||
|
zeroed = !chunk_purge_wrapper(arena, &chunk_hooks, ptr,
|
||||||
|
CHUNK_CEILING(oldsize), usize, sdiff);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
zeroed = true;
|
zeroed = true;
|
||||||
@ -194,6 +196,8 @@ huge_ralloc_no_move_shrink(void *ptr, size_t oldsize, size_t usize)
|
|||||||
arena = extent_node_arena_get(node);
|
arena = extent_node_arena_get(node);
|
||||||
chunk_hooks = chunk_hooks_get(arena);
|
chunk_hooks = chunk_hooks_get(arena);
|
||||||
|
|
||||||
|
assert(oldsize > usize);
|
||||||
|
|
||||||
/* Split excess chunks. */
|
/* Split excess chunks. */
|
||||||
cdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize);
|
cdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize);
|
||||||
if (cdiff != 0 && chunk_hooks.split(ptr, CHUNK_CEILING(oldsize),
|
if (cdiff != 0 && chunk_hooks.split(ptr, CHUNK_CEILING(oldsize),
|
||||||
@ -202,14 +206,15 @@ huge_ralloc_no_move_shrink(void *ptr, size_t oldsize, size_t usize)
|
|||||||
|
|
||||||
if (oldsize > usize) {
|
if (oldsize > usize) {
|
||||||
size_t sdiff = oldsize - usize;
|
size_t sdiff = oldsize - usize;
|
||||||
zeroed = !chunk_purge_wrapper(arena, &chunk_hooks,
|
|
||||||
CHUNK_ADDR2BASE((uintptr_t)ptr + usize),
|
|
||||||
CHUNK_CEILING(usize), CHUNK_ADDR2OFFSET((uintptr_t)ptr +
|
|
||||||
usize), sdiff);
|
|
||||||
if (config_fill && unlikely(opt_junk_free)) {
|
if (config_fill && unlikely(opt_junk_free)) {
|
||||||
huge_dalloc_junk((void *)((uintptr_t)ptr + usize),
|
huge_dalloc_junk((void *)((uintptr_t)ptr + usize),
|
||||||
sdiff);
|
sdiff);
|
||||||
zeroed = false;
|
zeroed = false;
|
||||||
|
} else {
|
||||||
|
zeroed = !chunk_purge_wrapper(arena, &chunk_hooks,
|
||||||
|
CHUNK_ADDR2BASE((uintptr_t)ptr + usize),
|
||||||
|
CHUNK_CEILING(oldsize),
|
||||||
|
CHUNK_ADDR2OFFSET((uintptr_t)ptr + usize), sdiff);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
zeroed = true;
|
zeroed = true;
|
||||||
@ -228,18 +233,11 @@ huge_ralloc_no_move_shrink(void *ptr, size_t oldsize, size_t usize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
huge_ralloc_no_move_expand(void *ptr, size_t oldsize, size_t size, bool zero) {
|
huge_ralloc_no_move_expand(void *ptr, size_t oldsize, size_t usize, bool zero) {
|
||||||
size_t usize;
|
|
||||||
extent_node_t *node;
|
extent_node_t *node;
|
||||||
arena_t *arena;
|
arena_t *arena;
|
||||||
bool is_zeroed_subchunk, is_zeroed_chunk;
|
bool is_zeroed_subchunk, is_zeroed_chunk;
|
||||||
|
|
||||||
usize = s2u(size);
|
|
||||||
if (usize == 0) {
|
|
||||||
/* size_t overflow. */
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
node = huge_node_get(ptr);
|
node = huge_node_get(ptr);
|
||||||
arena = extent_node_arena_get(node);
|
arena = extent_node_arena_get(node);
|
||||||
malloc_mutex_lock(&arena->huge_mtx);
|
malloc_mutex_lock(&arena->huge_mtx);
|
||||||
@ -280,89 +278,76 @@ huge_ralloc_no_move_expand(void *ptr, size_t oldsize, size_t size, bool zero) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size, size_t extra,
|
huge_ralloc_no_move(void *ptr, size_t oldsize, size_t usize_min,
|
||||||
bool zero)
|
size_t usize_max, bool zero)
|
||||||
{
|
{
|
||||||
size_t usize;
|
|
||||||
|
|
||||||
/* Both allocations must be huge to avoid a move. */
|
|
||||||
if (oldsize < chunksize)
|
|
||||||
return (true);
|
|
||||||
|
|
||||||
assert(s2u(oldsize) == oldsize);
|
assert(s2u(oldsize) == oldsize);
|
||||||
usize = s2u(size);
|
|
||||||
if (usize == 0) {
|
/* Both allocations must be huge to avoid a move. */
|
||||||
/* size_t overflow. */
|
if (oldsize < chunksize || usize_max < chunksize)
|
||||||
return (true);
|
return (true);
|
||||||
|
|
||||||
|
if (CHUNK_CEILING(usize_max) > CHUNK_CEILING(oldsize)) {
|
||||||
|
/* Attempt to expand the allocation in-place. */
|
||||||
|
if (!huge_ralloc_no_move_expand(ptr, oldsize, usize_max, zero))
|
||||||
|
return (false);
|
||||||
|
/* Try again, this time with usize_min. */
|
||||||
|
if (usize_min < usize_max && CHUNK_CEILING(usize_min) >
|
||||||
|
CHUNK_CEILING(oldsize) && huge_ralloc_no_move_expand(ptr,
|
||||||
|
oldsize, usize_min, zero))
|
||||||
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Avoid moving the allocation if the existing chunk size accommodates
|
* Avoid moving the allocation if the existing chunk size accommodates
|
||||||
* the new size.
|
* the new size.
|
||||||
*/
|
*/
|
||||||
if (CHUNK_CEILING(oldsize) >= CHUNK_CEILING(usize)
|
if (CHUNK_CEILING(oldsize) >= CHUNK_CEILING(usize_min)
|
||||||
&& CHUNK_CEILING(oldsize) <= CHUNK_CEILING(s2u(size+extra))) {
|
&& CHUNK_CEILING(oldsize) <= CHUNK_CEILING(usize_max)) {
|
||||||
huge_ralloc_no_move_similar(ptr, oldsize, usize, size, extra,
|
huge_ralloc_no_move_similar(ptr, oldsize, usize_min, usize_max,
|
||||||
zero);
|
zero);
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to shrink the allocation in-place. */
|
/* Attempt to shrink the allocation in-place. */
|
||||||
if (CHUNK_CEILING(oldsize) >= CHUNK_CEILING(usize))
|
if (CHUNK_CEILING(oldsize) > CHUNK_CEILING(usize_max))
|
||||||
return (huge_ralloc_no_move_shrink(ptr, oldsize, usize));
|
return (huge_ralloc_no_move_shrink(ptr, oldsize, usize_max));
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Attempt to expand the allocation in-place. */
|
static void *
|
||||||
if (huge_ralloc_no_move_expand(ptr, oldsize, size + extra, zero)) {
|
huge_ralloc_move_helper(tsd_t *tsd, arena_t *arena, size_t usize,
|
||||||
if (extra == 0)
|
size_t alignment, bool zero, tcache_t *tcache)
|
||||||
return (true);
|
{
|
||||||
|
|
||||||
/* Try again, this time without extra. */
|
if (alignment <= chunksize)
|
||||||
return (huge_ralloc_no_move_expand(ptr, oldsize, size, zero));
|
return (huge_malloc(tsd, arena, usize, zero, tcache));
|
||||||
}
|
return (huge_palloc(tsd, arena, usize, alignment, zero, tcache));
|
||||||
return (false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t size,
|
huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t usize,
|
||||||
size_t extra, size_t alignment, bool zero, tcache_t *tcache)
|
size_t alignment, bool zero, tcache_t *tcache)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
size_t copysize;
|
size_t copysize;
|
||||||
|
|
||||||
/* Try to avoid moving the allocation. */
|
/* Try to avoid moving the allocation. */
|
||||||
if (!huge_ralloc_no_move(ptr, oldsize, size, extra, zero))
|
if (!huge_ralloc_no_move(ptr, oldsize, usize, usize, zero))
|
||||||
return (ptr);
|
return (ptr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* size and oldsize are different enough that we need to use a
|
* usize and oldsize are different enough that we need to use a
|
||||||
* different size class. In that case, fall back to allocating new
|
* different size class. In that case, fall back to allocating new
|
||||||
* space and copying.
|
* space and copying.
|
||||||
*/
|
*/
|
||||||
if (alignment > chunksize) {
|
ret = huge_ralloc_move_helper(tsd, arena, usize, alignment, zero,
|
||||||
ret = huge_palloc(tsd, arena, size + extra, alignment, zero,
|
tcache);
|
||||||
tcache);
|
if (ret == NULL)
|
||||||
} else
|
return (NULL);
|
||||||
ret = huge_malloc(tsd, arena, size + extra, zero, tcache);
|
|
||||||
|
|
||||||
if (ret == NULL) {
|
copysize = (usize < oldsize) ? usize : oldsize;
|
||||||
if (extra == 0)
|
|
||||||
return (NULL);
|
|
||||||
/* Try again, this time without extra. */
|
|
||||||
if (alignment > chunksize) {
|
|
||||||
ret = huge_palloc(tsd, arena, size, alignment, zero,
|
|
||||||
tcache);
|
|
||||||
} else
|
|
||||||
ret = huge_malloc(tsd, arena, size, zero, tcache);
|
|
||||||
|
|
||||||
if (ret == NULL)
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy at most size bytes (not size+extra), since the caller has no
|
|
||||||
* expectation that the extra bytes will be reliably preserved.
|
|
||||||
*/
|
|
||||||
copysize = (size < oldsize) ? size : oldsize;
|
|
||||||
memcpy(ret, ptr, copysize);
|
memcpy(ret, ptr, copysize);
|
||||||
isqalloc(tsd, ptr, oldsize, tcache);
|
isqalloc(tsd, ptr, oldsize, tcache);
|
||||||
return (ret);
|
return (ret);
|
||||||
@ -439,3 +424,10 @@ huge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx)
|
|||||||
extent_node_prof_tctx_set(node, tctx);
|
extent_node_prof_tctx_set(node, tctx);
|
||||||
malloc_mutex_unlock(&arena->huge_mtx);
|
malloc_mutex_unlock(&arena->huge_mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
huge_prof_tctx_reset(const void *ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
huge_prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U);
|
||||||
|
}
|
||||||
|
@ -183,13 +183,24 @@ static bool malloc_initializer = NO_INITIALIZER;
|
|||||||
static malloc_mutex_t init_lock = SRWLOCK_INIT;
|
static malloc_mutex_t init_lock = SRWLOCK_INIT;
|
||||||
#else
|
#else
|
||||||
static malloc_mutex_t init_lock;
|
static malloc_mutex_t init_lock;
|
||||||
|
static bool init_lock_initialized = false;
|
||||||
|
|
||||||
JEMALLOC_ATTR(constructor)
|
JEMALLOC_ATTR(constructor)
|
||||||
static void WINAPI
|
static void WINAPI
|
||||||
_init_init_lock(void)
|
_init_init_lock(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
malloc_mutex_init(&init_lock);
|
/* If another constructor in the same binary is using mallctl to
|
||||||
|
* e.g. setup chunk hooks, it may end up running before this one,
|
||||||
|
* and malloc_init_hard will crash trying to lock the uninitialized
|
||||||
|
* lock. So we force an initialization of the lock in
|
||||||
|
* malloc_init_hard as well. We don't try to care about atomicity
|
||||||
|
* of the accessed to the init_lock_initialized boolean, since it
|
||||||
|
* really only matters early in the process creation, before any
|
||||||
|
* separate thread normally starts doing anything. */
|
||||||
|
if (!init_lock_initialized)
|
||||||
|
malloc_mutex_init(&init_lock);
|
||||||
|
init_lock_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -514,17 +525,17 @@ arena_get_hard(tsd_t *tsd, unsigned ind, bool init_if_missing)
|
|||||||
assert(ind < narenas_actual || !init_if_missing);
|
assert(ind < narenas_actual || !init_if_missing);
|
||||||
narenas_cache = (ind < narenas_actual) ? narenas_actual : ind+1;
|
narenas_cache = (ind < narenas_actual) ? narenas_actual : ind+1;
|
||||||
|
|
||||||
if (!*arenas_cache_bypassp) {
|
if (tsd_nominal(tsd) && !*arenas_cache_bypassp) {
|
||||||
*arenas_cache_bypassp = true;
|
*arenas_cache_bypassp = true;
|
||||||
arenas_cache = (arena_t **)a0malloc(sizeof(arena_t *) *
|
arenas_cache = (arena_t **)a0malloc(sizeof(arena_t *) *
|
||||||
narenas_cache);
|
narenas_cache);
|
||||||
*arenas_cache_bypassp = false;
|
*arenas_cache_bypassp = false;
|
||||||
} else
|
}
|
||||||
arenas_cache = NULL;
|
|
||||||
if (arenas_cache == NULL) {
|
if (arenas_cache == NULL) {
|
||||||
/*
|
/*
|
||||||
* This function must always tell the truth, even if
|
* This function must always tell the truth, even if
|
||||||
* it's slow, so don't let OOM or recursive allocation
|
* it's slow, so don't let OOM, thread cleanup (note
|
||||||
|
* tsd_nominal check), nor recursive allocation
|
||||||
* avoidance (note arenas_cache_bypass check) get in the
|
* avoidance (note arenas_cache_bypass check) get in the
|
||||||
* way.
|
* way.
|
||||||
*/
|
*/
|
||||||
@ -535,6 +546,7 @@ arena_get_hard(tsd_t *tsd, unsigned ind, bool init_if_missing)
|
|||||||
malloc_mutex_unlock(&arenas_lock);
|
malloc_mutex_unlock(&arenas_lock);
|
||||||
return (arena);
|
return (arena);
|
||||||
}
|
}
|
||||||
|
assert(tsd_nominal(tsd) && !*arenas_cache_bypassp);
|
||||||
tsd_arenas_cache_set(tsd, arenas_cache);
|
tsd_arenas_cache_set(tsd, arenas_cache);
|
||||||
tsd_narenas_cache_set(tsd, narenas_cache);
|
tsd_narenas_cache_set(tsd, narenas_cache);
|
||||||
}
|
}
|
||||||
@ -653,8 +665,10 @@ arenas_cache_cleanup(tsd_t *tsd)
|
|||||||
arena_t **arenas_cache;
|
arena_t **arenas_cache;
|
||||||
|
|
||||||
arenas_cache = tsd_arenas_cache_get(tsd);
|
arenas_cache = tsd_arenas_cache_get(tsd);
|
||||||
if (arenas_cache != NULL)
|
if (arenas_cache != NULL) {
|
||||||
|
tsd_arenas_cache_set(tsd, NULL);
|
||||||
a0dalloc(arenas_cache);
|
a0dalloc(arenas_cache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1301,6 +1315,9 @@ static bool
|
|||||||
malloc_init_hard(void)
|
malloc_init_hard(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if defined(_WIN32) && _WIN32_WINNT < 0x0600
|
||||||
|
_init_init_lock();
|
||||||
|
#endif
|
||||||
malloc_mutex_lock(&init_lock);
|
malloc_mutex_lock(&init_lock);
|
||||||
if (!malloc_init_hard_needed()) {
|
if (!malloc_init_hard_needed()) {
|
||||||
malloc_mutex_unlock(&init_lock);
|
malloc_mutex_unlock(&init_lock);
|
||||||
@ -1365,7 +1382,7 @@ imalloc_prof(tsd_t *tsd, size_t usize)
|
|||||||
void *p;
|
void *p;
|
||||||
prof_tctx_t *tctx;
|
prof_tctx_t *tctx;
|
||||||
|
|
||||||
tctx = prof_alloc_prep(tsd, usize, true);
|
tctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true);
|
||||||
if (unlikely((uintptr_t)tctx != (uintptr_t)1U))
|
if (unlikely((uintptr_t)tctx != (uintptr_t)1U))
|
||||||
p = imalloc_prof_sample(tsd, usize, tctx);
|
p = imalloc_prof_sample(tsd, usize, tctx);
|
||||||
else
|
else
|
||||||
@ -1455,7 +1472,7 @@ imemalign_prof(tsd_t *tsd, size_t alignment, size_t usize)
|
|||||||
void *p;
|
void *p;
|
||||||
prof_tctx_t *tctx;
|
prof_tctx_t *tctx;
|
||||||
|
|
||||||
tctx = prof_alloc_prep(tsd, usize, true);
|
tctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true);
|
||||||
if (unlikely((uintptr_t)tctx != (uintptr_t)1U))
|
if (unlikely((uintptr_t)tctx != (uintptr_t)1U))
|
||||||
p = imemalign_prof_sample(tsd, alignment, usize, tctx);
|
p = imemalign_prof_sample(tsd, alignment, usize, tctx);
|
||||||
else
|
else
|
||||||
@ -1586,7 +1603,7 @@ icalloc_prof(tsd_t *tsd, size_t usize)
|
|||||||
void *p;
|
void *p;
|
||||||
prof_tctx_t *tctx;
|
prof_tctx_t *tctx;
|
||||||
|
|
||||||
tctx = prof_alloc_prep(tsd, usize, true);
|
tctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true);
|
||||||
if (unlikely((uintptr_t)tctx != (uintptr_t)1U))
|
if (unlikely((uintptr_t)tctx != (uintptr_t)1U))
|
||||||
p = icalloc_prof_sample(tsd, usize, tctx);
|
p = icalloc_prof_sample(tsd, usize, tctx);
|
||||||
else
|
else
|
||||||
@ -1669,7 +1686,7 @@ label_return:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
irealloc_prof_sample(tsd_t *tsd, void *oldptr, size_t old_usize, size_t usize,
|
irealloc_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize,
|
||||||
prof_tctx_t *tctx)
|
prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
@ -1677,31 +1694,36 @@ irealloc_prof_sample(tsd_t *tsd, void *oldptr, size_t old_usize, size_t usize,
|
|||||||
if (tctx == NULL)
|
if (tctx == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if (usize <= SMALL_MAXCLASS) {
|
if (usize <= SMALL_MAXCLASS) {
|
||||||
p = iralloc(tsd, oldptr, old_usize, LARGE_MINCLASS, 0, false);
|
p = iralloc(tsd, old_ptr, old_usize, LARGE_MINCLASS, 0, false);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
arena_prof_promoted(p, usize);
|
arena_prof_promoted(p, usize);
|
||||||
} else
|
} else
|
||||||
p = iralloc(tsd, oldptr, old_usize, usize, 0, false);
|
p = iralloc(tsd, old_ptr, old_usize, usize, 0, false);
|
||||||
|
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE_C void *
|
JEMALLOC_ALWAYS_INLINE_C void *
|
||||||
irealloc_prof(tsd_t *tsd, void *oldptr, size_t old_usize, size_t usize)
|
irealloc_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
bool prof_active;
|
||||||
prof_tctx_t *old_tctx, *tctx;
|
prof_tctx_t *old_tctx, *tctx;
|
||||||
|
|
||||||
old_tctx = prof_tctx_get(oldptr);
|
prof_active = prof_active_get_unlocked();
|
||||||
tctx = prof_alloc_prep(tsd, usize, true);
|
old_tctx = prof_tctx_get(old_ptr);
|
||||||
|
tctx = prof_alloc_prep(tsd, usize, prof_active, true);
|
||||||
if (unlikely((uintptr_t)tctx != (uintptr_t)1U))
|
if (unlikely((uintptr_t)tctx != (uintptr_t)1U))
|
||||||
p = irealloc_prof_sample(tsd, oldptr, old_usize, usize, tctx);
|
p = irealloc_prof_sample(tsd, old_ptr, old_usize, usize, tctx);
|
||||||
else
|
else
|
||||||
p = iralloc(tsd, oldptr, old_usize, usize, 0, false);
|
p = iralloc(tsd, old_ptr, old_usize, usize, 0, false);
|
||||||
if (p == NULL)
|
if (unlikely(p == NULL)) {
|
||||||
|
prof_alloc_rollback(tsd, tctx, true);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
prof_realloc(tsd, p, usize, tctx, true, old_usize, old_tctx);
|
}
|
||||||
|
prof_realloc(tsd, p, usize, tctx, prof_active, true, old_ptr, old_usize,
|
||||||
|
old_tctx);
|
||||||
|
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
@ -1905,6 +1927,7 @@ imallocx_flags_decode_hard(tsd_t *tsd, size_t size, int flags, size_t *usize,
|
|||||||
*alignment = MALLOCX_ALIGN_GET_SPECIFIED(flags);
|
*alignment = MALLOCX_ALIGN_GET_SPECIFIED(flags);
|
||||||
*usize = sa2u(size, *alignment);
|
*usize = sa2u(size, *alignment);
|
||||||
}
|
}
|
||||||
|
assert(*usize != 0);
|
||||||
*zero = MALLOCX_ZERO_GET(flags);
|
*zero = MALLOCX_ZERO_GET(flags);
|
||||||
if ((flags & MALLOCX_TCACHE_MASK) != 0) {
|
if ((flags & MALLOCX_TCACHE_MASK) != 0) {
|
||||||
if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE)
|
if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE)
|
||||||
@ -1947,41 +1970,29 @@ imallocx_flags(tsd_t *tsd, size_t usize, size_t alignment, bool zero,
|
|||||||
tcache_t *tcache, arena_t *arena)
|
tcache_t *tcache, arena_t *arena)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (alignment != 0)
|
if (unlikely(alignment != 0))
|
||||||
return (ipalloct(tsd, usize, alignment, zero, tcache, arena));
|
return (ipalloct(tsd, usize, alignment, zero, tcache, arena));
|
||||||
if (zero)
|
if (unlikely(zero))
|
||||||
return (icalloct(tsd, usize, tcache, arena));
|
return (icalloct(tsd, usize, tcache, arena));
|
||||||
return (imalloct(tsd, usize, tcache, arena));
|
return (imalloct(tsd, usize, tcache, arena));
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE_C void *
|
|
||||||
imallocx_maybe_flags(tsd_t *tsd, size_t size, int flags, size_t usize,
|
|
||||||
size_t alignment, bool zero, tcache_t *tcache, arena_t *arena)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (likely(flags == 0))
|
|
||||||
return (imalloc(tsd, size));
|
|
||||||
return (imallocx_flags(tsd, usize, alignment, zero, tcache, arena));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
imallocx_prof_sample(tsd_t *tsd, size_t size, int flags, size_t usize,
|
imallocx_prof_sample(tsd_t *tsd, size_t usize, size_t alignment, bool zero,
|
||||||
size_t alignment, bool zero, tcache_t *tcache, arena_t *arena)
|
tcache_t *tcache, arena_t *arena)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
if (usize <= SMALL_MAXCLASS) {
|
if (usize <= SMALL_MAXCLASS) {
|
||||||
assert(((alignment == 0) ? s2u(LARGE_MINCLASS) :
|
assert(((alignment == 0) ? s2u(LARGE_MINCLASS) :
|
||||||
sa2u(LARGE_MINCLASS, alignment)) == LARGE_MINCLASS);
|
sa2u(LARGE_MINCLASS, alignment)) == LARGE_MINCLASS);
|
||||||
p = imallocx_maybe_flags(tsd, LARGE_MINCLASS, flags,
|
p = imallocx_flags(tsd, LARGE_MINCLASS, alignment, zero, tcache,
|
||||||
LARGE_MINCLASS, alignment, zero, tcache, arena);
|
arena);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
arena_prof_promoted(p, usize);
|
arena_prof_promoted(p, usize);
|
||||||
} else {
|
} else
|
||||||
p = imallocx_maybe_flags(tsd, size, flags, usize, alignment,
|
p = imallocx_flags(tsd, usize, alignment, zero, tcache, arena);
|
||||||
zero, tcache, arena);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
@ -1999,13 +2010,12 @@ imallocx_prof(tsd_t *tsd, size_t size, int flags, size_t *usize)
|
|||||||
if (unlikely(imallocx_flags_decode(tsd, size, flags, usize, &alignment,
|
if (unlikely(imallocx_flags_decode(tsd, size, flags, usize, &alignment,
|
||||||
&zero, &tcache, &arena)))
|
&zero, &tcache, &arena)))
|
||||||
return (NULL);
|
return (NULL);
|
||||||
tctx = prof_alloc_prep(tsd, *usize, true);
|
tctx = prof_alloc_prep(tsd, *usize, prof_active_get_unlocked(), true);
|
||||||
if (likely((uintptr_t)tctx == (uintptr_t)1U)) {
|
if (likely((uintptr_t)tctx == (uintptr_t)1U))
|
||||||
p = imallocx_maybe_flags(tsd, size, flags, *usize, alignment,
|
p = imallocx_flags(tsd, *usize, alignment, zero, tcache, arena);
|
||||||
zero, tcache, arena);
|
else if ((uintptr_t)tctx > (uintptr_t)1U) {
|
||||||
} else if ((uintptr_t)tctx > (uintptr_t)1U) {
|
p = imallocx_prof_sample(tsd, *usize, alignment, zero, tcache,
|
||||||
p = imallocx_prof_sample(tsd, size, flags, *usize, alignment,
|
arena);
|
||||||
zero, tcache, arena);
|
|
||||||
} else
|
} else
|
||||||
p = NULL;
|
p = NULL;
|
||||||
if (unlikely(p == NULL)) {
|
if (unlikely(p == NULL)) {
|
||||||
@ -2080,8 +2090,8 @@ label_oom:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
irallocx_prof_sample(tsd_t *tsd, void *oldptr, size_t old_usize, size_t size,
|
irallocx_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize,
|
||||||
size_t alignment, size_t usize, bool zero, tcache_t *tcache, arena_t *arena,
|
size_t usize, size_t alignment, bool zero, tcache_t *tcache, arena_t *arena,
|
||||||
prof_tctx_t *tctx)
|
prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
@ -2089,13 +2099,13 @@ irallocx_prof_sample(tsd_t *tsd, void *oldptr, size_t old_usize, size_t size,
|
|||||||
if (tctx == NULL)
|
if (tctx == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if (usize <= SMALL_MAXCLASS) {
|
if (usize <= SMALL_MAXCLASS) {
|
||||||
p = iralloct(tsd, oldptr, old_usize, LARGE_MINCLASS, alignment,
|
p = iralloct(tsd, old_ptr, old_usize, LARGE_MINCLASS, alignment,
|
||||||
zero, tcache, arena);
|
zero, tcache, arena);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
arena_prof_promoted(p, usize);
|
arena_prof_promoted(p, usize);
|
||||||
} else {
|
} else {
|
||||||
p = iralloct(tsd, oldptr, old_usize, size, alignment, zero,
|
p = iralloct(tsd, old_ptr, old_usize, usize, alignment, zero,
|
||||||
tcache, arena);
|
tcache, arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2103,28 +2113,30 @@ irallocx_prof_sample(tsd_t *tsd, void *oldptr, size_t old_usize, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE_C void *
|
JEMALLOC_ALWAYS_INLINE_C void *
|
||||||
irallocx_prof(tsd_t *tsd, void *oldptr, size_t old_usize, size_t size,
|
irallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size,
|
||||||
size_t alignment, size_t *usize, bool zero, tcache_t *tcache,
|
size_t alignment, size_t *usize, bool zero, tcache_t *tcache,
|
||||||
arena_t *arena)
|
arena_t *arena)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
bool prof_active;
|
||||||
prof_tctx_t *old_tctx, *tctx;
|
prof_tctx_t *old_tctx, *tctx;
|
||||||
|
|
||||||
old_tctx = prof_tctx_get(oldptr);
|
prof_active = prof_active_get_unlocked();
|
||||||
tctx = prof_alloc_prep(tsd, *usize, false);
|
old_tctx = prof_tctx_get(old_ptr);
|
||||||
|
tctx = prof_alloc_prep(tsd, *usize, prof_active, true);
|
||||||
if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) {
|
if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) {
|
||||||
p = irallocx_prof_sample(tsd, oldptr, old_usize, size,
|
p = irallocx_prof_sample(tsd, old_ptr, old_usize, *usize,
|
||||||
alignment, *usize, zero, tcache, arena, tctx);
|
alignment, zero, tcache, arena, tctx);
|
||||||
} else {
|
} else {
|
||||||
p = iralloct(tsd, oldptr, old_usize, size, alignment, zero,
|
p = iralloct(tsd, old_ptr, old_usize, size, alignment, zero,
|
||||||
tcache, arena);
|
tcache, arena);
|
||||||
}
|
}
|
||||||
if (unlikely(p == NULL)) {
|
if (unlikely(p == NULL)) {
|
||||||
prof_alloc_rollback(tsd, tctx, false);
|
prof_alloc_rollback(tsd, tctx, true);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == oldptr && alignment != 0) {
|
if (p == old_ptr && alignment != 0) {
|
||||||
/*
|
/*
|
||||||
* The allocation did not move, so it is possible that the size
|
* The allocation did not move, so it is possible that the size
|
||||||
* class is smaller than would guarantee the requested
|
* class is smaller than would guarantee the requested
|
||||||
@ -2135,7 +2147,8 @@ irallocx_prof(tsd_t *tsd, void *oldptr, size_t old_usize, size_t size,
|
|||||||
*/
|
*/
|
||||||
*usize = isalloc(p, config_prof);
|
*usize = isalloc(p, config_prof);
|
||||||
}
|
}
|
||||||
prof_realloc(tsd, p, *usize, tctx, false, old_usize, old_tctx);
|
prof_realloc(tsd, p, *usize, tctx, prof_active, true, old_ptr,
|
||||||
|
old_usize, old_tctx);
|
||||||
|
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
@ -2230,26 +2243,13 @@ ixallocx_helper(void *ptr, size_t old_usize, size_t size, size_t extra,
|
|||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
ixallocx_prof_sample(void *ptr, size_t old_usize, size_t size, size_t extra,
|
ixallocx_prof_sample(void *ptr, size_t old_usize, size_t size, size_t extra,
|
||||||
size_t alignment, size_t max_usize, bool zero, prof_tctx_t *tctx)
|
size_t alignment, bool zero, prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
size_t usize;
|
size_t usize;
|
||||||
|
|
||||||
if (tctx == NULL)
|
if (tctx == NULL)
|
||||||
return (old_usize);
|
return (old_usize);
|
||||||
/* Use minimum usize to determine whether promotion may happen. */
|
usize = ixallocx_helper(ptr, old_usize, size, extra, alignment, zero);
|
||||||
if (((alignment == 0) ? s2u(size) : sa2u(size, alignment)) <=
|
|
||||||
SMALL_MAXCLASS) {
|
|
||||||
if (ixalloc(ptr, old_usize, SMALL_MAXCLASS+1,
|
|
||||||
(SMALL_MAXCLASS+1 >= size+extra) ? 0 : size+extra -
|
|
||||||
(SMALL_MAXCLASS+1), alignment, zero))
|
|
||||||
return (old_usize);
|
|
||||||
usize = isalloc(ptr, config_prof);
|
|
||||||
if (max_usize < LARGE_MINCLASS)
|
|
||||||
arena_prof_promoted(ptr, usize);
|
|
||||||
} else {
|
|
||||||
usize = ixallocx_helper(ptr, old_usize, size, extra, alignment,
|
|
||||||
zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (usize);
|
return (usize);
|
||||||
}
|
}
|
||||||
@ -2258,9 +2258,11 @@ JEMALLOC_ALWAYS_INLINE_C size_t
|
|||||||
ixallocx_prof(tsd_t *tsd, void *ptr, size_t old_usize, size_t size,
|
ixallocx_prof(tsd_t *tsd, void *ptr, size_t old_usize, size_t size,
|
||||||
size_t extra, size_t alignment, bool zero)
|
size_t extra, size_t alignment, bool zero)
|
||||||
{
|
{
|
||||||
size_t max_usize, usize;
|
size_t usize_max, usize;
|
||||||
|
bool prof_active;
|
||||||
prof_tctx_t *old_tctx, *tctx;
|
prof_tctx_t *old_tctx, *tctx;
|
||||||
|
|
||||||
|
prof_active = prof_active_get_unlocked();
|
||||||
old_tctx = prof_tctx_get(ptr);
|
old_tctx = prof_tctx_get(ptr);
|
||||||
/*
|
/*
|
||||||
* usize isn't knowable before ixalloc() returns when extra is non-zero.
|
* usize isn't knowable before ixalloc() returns when extra is non-zero.
|
||||||
@ -2268,21 +2270,23 @@ ixallocx_prof(tsd_t *tsd, void *ptr, size_t old_usize, size_t size,
|
|||||||
* prof_alloc_prep() to decide whether to capture a backtrace.
|
* prof_alloc_prep() to decide whether to capture a backtrace.
|
||||||
* prof_realloc() will use the actual usize to decide whether to sample.
|
* prof_realloc() will use the actual usize to decide whether to sample.
|
||||||
*/
|
*/
|
||||||
max_usize = (alignment == 0) ? s2u(size+extra) : sa2u(size+extra,
|
usize_max = (alignment == 0) ? s2u(size+extra) : sa2u(size+extra,
|
||||||
alignment);
|
alignment);
|
||||||
tctx = prof_alloc_prep(tsd, max_usize, false);
|
assert(usize_max != 0);
|
||||||
|
tctx = prof_alloc_prep(tsd, usize_max, prof_active, false);
|
||||||
if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) {
|
if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) {
|
||||||
usize = ixallocx_prof_sample(ptr, old_usize, size, extra,
|
usize = ixallocx_prof_sample(ptr, old_usize, size, extra,
|
||||||
alignment, zero, max_usize, tctx);
|
alignment, zero, tctx);
|
||||||
} else {
|
} else {
|
||||||
usize = ixallocx_helper(ptr, old_usize, size, extra, alignment,
|
usize = ixallocx_helper(ptr, old_usize, size, extra, alignment,
|
||||||
zero);
|
zero);
|
||||||
}
|
}
|
||||||
if (unlikely(usize == old_usize)) {
|
if (usize == old_usize) {
|
||||||
prof_alloc_rollback(tsd, tctx, false);
|
prof_alloc_rollback(tsd, tctx, false);
|
||||||
return (usize);
|
return (usize);
|
||||||
}
|
}
|
||||||
prof_realloc(tsd, ptr, usize, tctx, false, old_usize, old_tctx);
|
prof_realloc(tsd, ptr, usize, tctx, prof_active, false, ptr, old_usize,
|
||||||
|
old_tctx);
|
||||||
|
|
||||||
return (usize);
|
return (usize);
|
||||||
}
|
}
|
||||||
@ -2304,6 +2308,17 @@ je_xallocx(void *ptr, size_t size, size_t extra, int flags)
|
|||||||
tsd = tsd_fetch();
|
tsd = tsd_fetch();
|
||||||
|
|
||||||
old_usize = isalloc(ptr, config_prof);
|
old_usize = isalloc(ptr, config_prof);
|
||||||
|
|
||||||
|
/* Clamp extra if necessary to avoid (size + extra) overflow. */
|
||||||
|
if (unlikely(size + extra > HUGE_MAXCLASS)) {
|
||||||
|
/* Check for size overflow. */
|
||||||
|
if (unlikely(size > HUGE_MAXCLASS)) {
|
||||||
|
usize = old_usize;
|
||||||
|
goto label_not_resized;
|
||||||
|
}
|
||||||
|
extra = HUGE_MAXCLASS - size;
|
||||||
|
}
|
||||||
|
|
||||||
if (config_valgrind && unlikely(in_valgrind))
|
if (config_valgrind && unlikely(in_valgrind))
|
||||||
old_rzsize = u2rz(old_usize);
|
old_rzsize = u2rz(old_usize);
|
||||||
|
|
||||||
|
@ -139,9 +139,16 @@ prof_tctx_comp(const prof_tctx_t *a, const prof_tctx_t *b)
|
|||||||
uint64_t b_thr_uid = b->thr_uid;
|
uint64_t b_thr_uid = b->thr_uid;
|
||||||
int ret = (a_thr_uid > b_thr_uid) - (a_thr_uid < b_thr_uid);
|
int ret = (a_thr_uid > b_thr_uid) - (a_thr_uid < b_thr_uid);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
uint64_t a_tctx_uid = a->tctx_uid;
|
uint64_t a_thr_discrim = a->thr_discrim;
|
||||||
uint64_t b_tctx_uid = b->tctx_uid;
|
uint64_t b_thr_discrim = b->thr_discrim;
|
||||||
ret = (a_tctx_uid > b_tctx_uid) - (a_tctx_uid < b_tctx_uid);
|
ret = (a_thr_discrim > b_thr_discrim) - (a_thr_discrim <
|
||||||
|
b_thr_discrim);
|
||||||
|
if (ret == 0) {
|
||||||
|
uint64_t a_tctx_uid = a->tctx_uid;
|
||||||
|
uint64_t b_tctx_uid = b->tctx_uid;
|
||||||
|
ret = (a_tctx_uid > b_tctx_uid) - (a_tctx_uid <
|
||||||
|
b_tctx_uid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -202,7 +209,7 @@ prof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx, bool updated)
|
|||||||
*/
|
*/
|
||||||
tdata = prof_tdata_get(tsd, true);
|
tdata = prof_tdata_get(tsd, true);
|
||||||
if (tdata != NULL)
|
if (tdata != NULL)
|
||||||
prof_sample_threshold_update(tctx->tdata);
|
prof_sample_threshold_update(tdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uintptr_t)tctx > (uintptr_t)1U) {
|
if ((uintptr_t)tctx > (uintptr_t)1U) {
|
||||||
@ -219,7 +226,7 @@ void
|
|||||||
prof_malloc_sample_object(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
prof_malloc_sample_object(const void *ptr, size_t usize, prof_tctx_t *tctx)
|
||||||
{
|
{
|
||||||
|
|
||||||
prof_tctx_set(ptr, tctx);
|
prof_tctx_set(ptr, usize, tctx);
|
||||||
|
|
||||||
malloc_mutex_lock(tctx->tdata->lock);
|
malloc_mutex_lock(tctx->tdata->lock);
|
||||||
tctx->cnts.curobjs++;
|
tctx->cnts.curobjs++;
|
||||||
@ -791,6 +798,7 @@ prof_lookup(tsd_t *tsd, prof_bt_t *bt)
|
|||||||
}
|
}
|
||||||
ret.p->tdata = tdata;
|
ret.p->tdata = tdata;
|
||||||
ret.p->thr_uid = tdata->thr_uid;
|
ret.p->thr_uid = tdata->thr_uid;
|
||||||
|
ret.p->thr_discrim = tdata->thr_discrim;
|
||||||
memset(&ret.p->cnts, 0, sizeof(prof_cnt_t));
|
memset(&ret.p->cnts, 0, sizeof(prof_cnt_t));
|
||||||
ret.p->gctx = gctx;
|
ret.p->gctx = gctx;
|
||||||
ret.p->tctx_uid = tdata->tctx_uid_next++;
|
ret.p->tctx_uid = tdata->tctx_uid_next++;
|
||||||
@ -1569,7 +1577,6 @@ prof_idump(void)
|
|||||||
{
|
{
|
||||||
tsd_t *tsd;
|
tsd_t *tsd;
|
||||||
prof_tdata_t *tdata;
|
prof_tdata_t *tdata;
|
||||||
char filename[PATH_MAX + 1];
|
|
||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
|
|
||||||
@ -1585,6 +1592,7 @@ prof_idump(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opt_prof_prefix[0] != '\0') {
|
if (opt_prof_prefix[0] != '\0') {
|
||||||
|
char filename[PATH_MAX + 1];
|
||||||
malloc_mutex_lock(&prof_dump_seq_mtx);
|
malloc_mutex_lock(&prof_dump_seq_mtx);
|
||||||
prof_dump_filename(filename, 'i', prof_dump_iseq);
|
prof_dump_filename(filename, 'i', prof_dump_iseq);
|
||||||
prof_dump_iseq++;
|
prof_dump_iseq++;
|
||||||
@ -1623,7 +1631,6 @@ prof_gdump(void)
|
|||||||
{
|
{
|
||||||
tsd_t *tsd;
|
tsd_t *tsd;
|
||||||
prof_tdata_t *tdata;
|
prof_tdata_t *tdata;
|
||||||
char filename[DUMP_FILENAME_BUFSIZE];
|
|
||||||
|
|
||||||
cassert(config_prof);
|
cassert(config_prof);
|
||||||
|
|
||||||
@ -1639,6 +1646,7 @@ prof_gdump(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opt_prof_prefix[0] != '\0') {
|
if (opt_prof_prefix[0] != '\0') {
|
||||||
|
char filename[DUMP_FILENAME_BUFSIZE];
|
||||||
malloc_mutex_lock(&prof_dump_seq_mtx);
|
malloc_mutex_lock(&prof_dump_seq_mtx);
|
||||||
prof_dump_filename(filename, 'u', prof_dump_useq);
|
prof_dump_filename(filename, 'u', prof_dump_useq);
|
||||||
prof_dump_useq++;
|
prof_dump_useq++;
|
||||||
|
@ -32,7 +32,7 @@ size_t tcache_salloc(const void *ptr)
|
|||||||
void
|
void
|
||||||
tcache_event_hard(tsd_t *tsd, tcache_t *tcache)
|
tcache_event_hard(tsd_t *tsd, tcache_t *tcache)
|
||||||
{
|
{
|
||||||
index_t binind = tcache->next_gc_bin;
|
szind_t binind = tcache->next_gc_bin;
|
||||||
tcache_bin_t *tbin = &tcache->tbins[binind];
|
tcache_bin_t *tbin = &tcache->tbins[binind];
|
||||||
tcache_bin_info_t *tbin_info = &tcache_bin_info[binind];
|
tcache_bin_info_t *tbin_info = &tcache_bin_info[binind];
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ tcache_event_hard(tsd_t *tsd, tcache_t *tcache)
|
|||||||
|
|
||||||
void *
|
void *
|
||||||
tcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
|
tcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
|
||||||
tcache_bin_t *tbin, index_t binind)
|
tcache_bin_t *tbin, szind_t binind)
|
||||||
{
|
{
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ tcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache,
|
|||||||
|
|
||||||
void
|
void
|
||||||
tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin,
|
tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin,
|
||||||
index_t binind, unsigned rem)
|
szind_t binind, unsigned rem)
|
||||||
{
|
{
|
||||||
arena_t *arena;
|
arena_t *arena;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
@ -166,7 +166,7 @@ tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, index_t binind,
|
tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind,
|
||||||
unsigned rem, tcache_t *tcache)
|
unsigned rem, tcache_t *tcache)
|
||||||
{
|
{
|
||||||
arena_t *arena;
|
arena_t *arena;
|
||||||
@ -496,13 +496,13 @@ tcache_boot(void)
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If necessary, clamp opt_lg_tcache_max, now that arena_maxclass is
|
* If necessary, clamp opt_lg_tcache_max, now that large_maxclass is
|
||||||
* known.
|
* known.
|
||||||
*/
|
*/
|
||||||
if (opt_lg_tcache_max < 0 || (1U << opt_lg_tcache_max) < SMALL_MAXCLASS)
|
if (opt_lg_tcache_max < 0 || (1U << opt_lg_tcache_max) < SMALL_MAXCLASS)
|
||||||
tcache_maxclass = SMALL_MAXCLASS;
|
tcache_maxclass = SMALL_MAXCLASS;
|
||||||
else if ((1U << opt_lg_tcache_max) > arena_maxclass)
|
else if ((1U << opt_lg_tcache_max) > large_maxclass)
|
||||||
tcache_maxclass = arena_maxclass;
|
tcache_maxclass = large_maxclass;
|
||||||
else
|
else
|
||||||
tcache_maxclass = (1U << opt_lg_tcache_max);
|
tcache_maxclass = (1U << opt_lg_tcache_max);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user