1#define JEMALLOC_QUARANTINE_C_ 2#include "jemalloc/internal/jemalloc_internal.h" 3 4/* 5 * Quarantine pointers close to NULL are used to encode state information that 6 * is used for cleaning up during thread shutdown. 7 */ 8#define QUARANTINE_STATE_REINCARNATED ((quarantine_t *)(uintptr_t)1) --- 9 unchanged lines hidden (view full) --- 18 size_t upper_bound); 19 20/******************************************************************************/ 21 22static quarantine_t * 23quarantine_init(tsd_t *tsd, size_t lg_maxobjs) 24{ 25 quarantine_t *quarantine; |
26 size_t size; |
27 28 assert(tsd_nominal(tsd)); 29 |
30 size = offsetof(quarantine_t, objs) + ((ZU(1) << lg_maxobjs) * 31 sizeof(quarantine_obj_t)); 32 quarantine = (quarantine_t *)iallocztm(tsd, size, size2index(size), 33 false, tcache_get(tsd, true), true, NULL, true); |
34 if (quarantine == NULL) 35 return (NULL); 36 quarantine->curbytes = 0; 37 quarantine->curobjs = 0; 38 quarantine->first = 0; 39 quarantine->lg_maxobjs = lg_maxobjs; 40 41 return (quarantine); --- 10 unchanged lines hidden (view full) --- 52 quarantine = quarantine_init(tsd, LG_MAXOBJS_INIT); 53 /* 54 * Check again whether quarantine has been initialized, because 55 * quarantine_init() may have triggered recursive initialization. 56 */ 57 if (tsd_quarantine_get(tsd) == NULL) 58 tsd_quarantine_set(tsd, quarantine); 59 else |
60 idalloctm(tsd, quarantine, tcache_get(tsd, false), true, true); |
61} 62 63static quarantine_t * 64quarantine_grow(tsd_t *tsd, quarantine_t *quarantine) 65{ 66 quarantine_t *ret; 67 68 ret = quarantine_init(tsd, quarantine->lg_maxobjs + 1); --- 15 unchanged lines hidden (view full) --- 84 quarantine->first; 85 size_t ncopy_b = quarantine->curobjs - ncopy_a; 86 87 memcpy(ret->objs, &quarantine->objs[quarantine->first], ncopy_a 88 * sizeof(quarantine_obj_t)); 89 memcpy(&ret->objs[ncopy_a], quarantine->objs, ncopy_b * 90 sizeof(quarantine_obj_t)); 91 } |
92 idalloctm(tsd, quarantine, tcache_get(tsd, false), true, true); |
93 94 tsd_quarantine_set(tsd, ret); 95 return (ret); 96} 97 98static void 99quarantine_drain_one(tsd_t *tsd, quarantine_t *quarantine) 100{ 101 quarantine_obj_t *obj = &quarantine->objs[quarantine->first]; 102 assert(obj->usize == isalloc(obj->ptr, config_prof)); |
103 idalloctm(tsd, obj->ptr, NULL, false, true); |
104 quarantine->curbytes -= obj->usize; 105 quarantine->curobjs--; 106 quarantine->first = (quarantine->first + 1) & ((ZU(1) << 107 quarantine->lg_maxobjs) - 1); 108} 109 110static void 111quarantine_drain(tsd_t *tsd, quarantine_t *quarantine, size_t upper_bound) --- 8 unchanged lines hidden (view full) --- 120{ 121 quarantine_t *quarantine; 122 size_t usize = isalloc(ptr, config_prof); 123 124 cassert(config_fill); 125 assert(opt_quarantine); 126 127 if ((quarantine = tsd_quarantine_get(tsd)) == NULL) { |
128 idalloctm(tsd, ptr, NULL, false, true); |
129 return; 130 } 131 /* 132 * Drain one or more objects if the quarantine size limit would be 133 * exceeded by appending ptr. 134 */ 135 if (quarantine->curbytes + usize > opt_quarantine) { 136 size_t upper_bound = (opt_quarantine >= usize) ? opt_quarantine --- 22 unchanged lines hidden (view full) --- 159 if ((!config_valgrind || likely(!in_valgrind)) 160 && usize <= SMALL_MAXCLASS) 161 arena_quarantine_junk_small(ptr, usize); 162 else 163 memset(ptr, 0x5a, usize); 164 } 165 } else { 166 assert(quarantine->curbytes == 0); |
167 idalloctm(tsd, ptr, NULL, false, true); |
168 } 169} 170 171void 172quarantine_cleanup(tsd_t *tsd) 173{ 174 quarantine_t *quarantine; 175 176 if (!config_fill) 177 return; 178 179 quarantine = tsd_quarantine_get(tsd); 180 if (quarantine != NULL) { 181 quarantine_drain(tsd, quarantine, 0); |
182 idalloctm(tsd, quarantine, tcache_get(tsd, false), true, true); |
183 tsd_quarantine_set(tsd, NULL); 184 } 185} |