105 lines
2.8 KiB
C
105 lines
2.8 KiB
C
#include "jemalloc/internal/jemalloc_preamble.h"
|
|
#include "jemalloc/internal/jemalloc_internal_includes.h"
|
|
|
|
#include "jemalloc/internal/san_bump.h"
|
|
#include "jemalloc/internal/pac.h"
|
|
#include "jemalloc/internal/san.h"
|
|
#include "jemalloc/internal/ehooks.h"
|
|
#include "jemalloc/internal/edata_cache.h"
|
|
|
|
static bool
|
|
san_bump_grow_locked(tsdn_t *tsdn, san_bump_alloc_t *sba, pac_t *pac,
|
|
ehooks_t *ehooks, size_t size);
|
|
|
|
edata_t *
|
|
san_bump_alloc(tsdn_t *tsdn, san_bump_alloc_t* sba, pac_t *pac,
|
|
ehooks_t *ehooks, size_t size, bool zero) {
|
|
assert(san_bump_enabled());
|
|
|
|
edata_t* to_destroy;
|
|
size_t guarded_size = san_one_side_guarded_sz(size);
|
|
|
|
malloc_mutex_lock(tsdn, &sba->mtx);
|
|
|
|
if (sba->curr_reg == NULL ||
|
|
edata_size_get(sba->curr_reg) < guarded_size) {
|
|
/*
|
|
* If the current region can't accommodate the allocation,
|
|
* try replacing it with a larger one and destroy current if the
|
|
* replacement succeeds.
|
|
*/
|
|
to_destroy = sba->curr_reg;
|
|
bool err = san_bump_grow_locked(tsdn, sba, pac, ehooks,
|
|
guarded_size);
|
|
if (err) {
|
|
goto label_err;
|
|
}
|
|
} else {
|
|
to_destroy = NULL;
|
|
}
|
|
assert(guarded_size <= edata_size_get(sba->curr_reg));
|
|
size_t trail_size = edata_size_get(sba->curr_reg) - guarded_size;
|
|
|
|
edata_t* edata;
|
|
if (trail_size != 0) {
|
|
edata_t* curr_reg_trail = extent_split_wrapper(tsdn, pac,
|
|
ehooks, sba->curr_reg, guarded_size, trail_size,
|
|
/* holding_core_locks */ true);
|
|
if (curr_reg_trail == NULL) {
|
|
goto label_err;
|
|
}
|
|
edata = sba->curr_reg;
|
|
sba->curr_reg = curr_reg_trail;
|
|
} else {
|
|
edata = sba->curr_reg;
|
|
sba->curr_reg = NULL;
|
|
}
|
|
|
|
malloc_mutex_unlock(tsdn, &sba->mtx);
|
|
|
|
assert(!edata_guarded_get(edata));
|
|
assert(sba->curr_reg == NULL || !edata_guarded_get(sba->curr_reg));
|
|
assert(to_destroy == NULL || !edata_guarded_get(to_destroy));
|
|
|
|
if (to_destroy != NULL) {
|
|
extent_destroy_wrapper(tsdn, pac, ehooks, to_destroy);
|
|
}
|
|
|
|
san_guard_pages(tsdn, ehooks, edata, pac->emap, /* left */ false,
|
|
/* right */ true, /* remap */ true);
|
|
|
|
if (extent_commit_zero(tsdn, ehooks, edata, /* commit */ true, zero,
|
|
/* growing_retained */ false)) {
|
|
extent_record(tsdn, pac, ehooks, &pac->ecache_retained,
|
|
edata);
|
|
return NULL;
|
|
}
|
|
|
|
if (config_prof) {
|
|
extent_gdump_add(tsdn, edata);
|
|
}
|
|
|
|
return edata;
|
|
label_err:
|
|
malloc_mutex_unlock(tsdn, &sba->mtx);
|
|
return NULL;
|
|
}
|
|
|
|
static bool
|
|
san_bump_grow_locked(tsdn_t *tsdn, san_bump_alloc_t *sba, pac_t *pac,
|
|
ehooks_t *ehooks, size_t size) {
|
|
malloc_mutex_assert_owner(tsdn, &sba->mtx);
|
|
|
|
bool committed = false, zeroed = false;
|
|
size_t alloc_size = size > SBA_RETAINED_ALLOC_SIZE ? size :
|
|
SBA_RETAINED_ALLOC_SIZE;
|
|
assert((alloc_size & PAGE_MASK) == 0);
|
|
sba->curr_reg = extent_alloc_wrapper(tsdn, pac, ehooks, NULL,
|
|
alloc_size, PAGE, zeroed, &committed,
|
|
/* growing_retained */ true);
|
|
if (sba->curr_reg == NULL) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|