diff options
Diffstat (limited to 'glib/gslice.c')
-rw-r--r-- | glib/gslice.c | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/glib/gslice.c b/glib/gslice.c index 6b0f22687..87330a49b 100644 --- a/glib/gslice.c +++ b/glib/gslice.c @@ -19,6 +19,12 @@ #include "config.h" #include "glibconfig.h" +#ifdef ENABLE_JEMALLOC +/* Do not demangle; it's cleaner to use the je_* API */ +# define JEMALLOC_NO_DEMANGLE +# include <jemalloc/jemalloc.h> +#endif + #if defined HAVE_POSIX_MEMALIGN && defined POSIX_MEMALIGN_WITH_COMPLIANT_ALLOCS # define HAVE_COMPLIANT_POSIX_MEMALIGN 1 #endif @@ -238,6 +244,7 @@ typedef struct { } ThreadMemory; typedef struct { gboolean always_malloc; + gboolean use_jemalloc; gboolean bypass_magazines; gboolean debug_blocks; gsize working_set_msecs; @@ -286,6 +293,7 @@ static gsize sys_page_size = 0; static Allocator allocator[1] = { { 0, }, }; static SliceConfig slice_config = { FALSE, /* always_malloc */ + FALSE, /* use_jemalloc */ FALSE, /* bypass_magazines */ FALSE, /* debug_blocks */ 15 * 1000, /* working_set_msecs */ @@ -304,6 +312,9 @@ g_slice_set_config (GSliceConfig ckey, case G_SLICE_CONFIG_ALWAYS_MALLOC: slice_config.always_malloc = value != 0; break; + case G_SLICE_CONFIG_USE_JEMALLOC: + slice_config.use_jemalloc = value != 0; + break; case G_SLICE_CONFIG_BYPASS_MAGAZINES: slice_config.bypass_magazines = value != 0; break; @@ -323,6 +334,8 @@ g_slice_get_config (GSliceConfig ckey) { case G_SLICE_CONFIG_ALWAYS_MALLOC: return slice_config.always_malloc; + case G_SLICE_CONFIG_USE_JEMALLOC: + return slice_config.use_jemalloc; case G_SLICE_CONFIG_BYPASS_MAGAZINES: return slice_config.bypass_magazines; case G_SLICE_CONFIG_WORKING_SET_MSECS: @@ -372,6 +385,9 @@ slice_config_init (SliceConfig *config) const GDebugKey keys[] = { { "always-malloc", 1 << 0 }, { "debug-blocks", 1 << 1 }, +#ifdef ENABLE_JEMALLOC + { "use-jemalloc", 1 << 2 }, +#endif }; flags = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys)); @@ -379,6 +395,8 @@ slice_config_init (SliceConfig *config) config->always_malloc = TRUE; if (flags & (1 << 1)) config->debug_blocks = TRUE; + if (flags & (1 << 2)) + config->use_jemalloc = TRUE; } else { @@ -389,7 +407,10 @@ slice_config_init (SliceConfig *config) * valgrind just by setting G_SLICE to the empty string. */ if (RUNNING_ON_VALGRIND) - config->always_malloc = TRUE; + { + config->always_malloc = TRUE; + config->use_jemalloc = FALSE; + } } } @@ -429,7 +450,7 @@ g_slice_init_nomessage (void) /* we can only align to system page size */ allocator->max_page_size = sys_page_size; #endif - if (allocator->config.always_malloc) + if (allocator->config.always_malloc || allocator->config.use_jemalloc) { allocator->contention_counters = NULL; allocator->magazines = NULL; @@ -449,7 +470,7 @@ g_slice_init_nomessage (void) magazine_cache_update_stamp(); /* values cached for performance reasons */ allocator->max_slab_chunk_size_for_magazine_cache = MAX_SLAB_CHUNK_SIZE (allocator); - if (allocator->config.always_malloc || allocator->config.bypass_magazines) + if (allocator->config.always_malloc || allocator->config.bypass_magazines || allocator->config.use_jemalloc) allocator->max_slab_chunk_size_for_magazine_cache = 0; /* non-optimized cases */ } @@ -460,6 +481,9 @@ allocator_categorize (gsize aligned_chunk_size) if (G_LIKELY (aligned_chunk_size && aligned_chunk_size <= allocator->max_slab_chunk_size_for_magazine_cache)) return 1; /* use magazine cache */ + if (allocator->config.use_jemalloc) + return 3; + if (!allocator->config.always_malloc && aligned_chunk_size && aligned_chunk_size <= MAX_SLAB_CHUNK_SIZE (allocator)) @@ -1021,6 +1045,12 @@ g_slice_alloc (gsize mem_size) mem = slab_allocator_alloc_chunk (chunk_size); g_mutex_unlock (&allocator->slab_mutex); } +#ifdef ENABLE_JEMALLOC + else if (acat == 3) + { + mem = je_malloc (mem_size); + } +#endif else /* delegate to system malloc */ mem = g_malloc (mem_size); if (G_UNLIKELY (allocator->config.debug_blocks)) @@ -1129,6 +1159,14 @@ g_slice_free1 (gsize mem_size, slab_allocator_free_chunk (chunk_size, mem_block); g_mutex_unlock (&allocator->slab_mutex); } +#ifdef ENABLE_JEMALLOC + else if (acat == 3) + { + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (mem_block, 0, mem_size); + je_free (mem_block); + } +#endif else /* delegate to system malloc */ { if (G_UNLIKELY (g_mem_gc_friendly)) @@ -1219,18 +1257,37 @@ g_slice_free_chain_with_offset (gsize mem_size, } g_mutex_unlock (&allocator->slab_mutex); } - else /* delegate to system malloc */ - while (slice) - { - guint8 *current = slice; - slice = *(gpointer*) (current + next_offset); - if (G_UNLIKELY (allocator->config.debug_blocks) && - !smc_notify_free (current, mem_size)) - abort(); - if (G_UNLIKELY (g_mem_gc_friendly)) - memset (current, 0, mem_size); - g_free (current); - } +#ifdef ENABLE_JEMALLOC + else if (acat == 3) + { + while (slice) + { + guint8 *current = slice; + slice = *(gpointer*) (current + next_offset); + if (G_UNLIKELY (allocator->config.debug_blocks) && + !smc_notify_free (current, mem_size)) + abort(); + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (current, 0, mem_size); + je_free (current); + } + } +#endif + else + { + /* delegate to system malloc */ + while (slice) + { + guint8 *current = slice; + slice = *(gpointer*) (current + next_offset); + if (G_UNLIKELY (allocator->config.debug_blocks) && + !smc_notify_free (current, mem_size)) + abort(); + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (current, 0, mem_size); + g_free (current); + } + } } /* --- single page allocator --- */ |