mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-01 08:48:29 +00:00
Make emacs not croak when editing dlmalloc
This commit is contained in:
parent
3c7ae0fc72
commit
fa1e8a3e65
21 changed files with 3019 additions and 2985 deletions
142
third_party/dlmalloc/management.inc
vendored
Normal file
142
third_party/dlmalloc/management.inc
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
// clang-format off
|
||||
|
||||
/* -------------------------- mspace management -------------------------- */
|
||||
|
||||
/* Initialize top chunk and its size */
|
||||
static void init_top(mstate m, mchunkptr p, size_t psize) {
|
||||
/* Ensure alignment */
|
||||
size_t offset = align_offset(chunk2mem(p));
|
||||
p = (mchunkptr)((char*)p + offset);
|
||||
psize -= offset;
|
||||
|
||||
m->top = p;
|
||||
m->topsize = psize;
|
||||
p->head = psize | PINUSE_BIT;
|
||||
/* set size of fake trailing chunk holding overhead space only once */
|
||||
chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
|
||||
m->trim_check = mparams.trim_threshold; /* reset on each update */
|
||||
}
|
||||
|
||||
/* Initialize bins for a new mstate that is otherwise zeroed out */
|
||||
static void init_bins(mstate m) {
|
||||
/* Establish circular links for smallbins */
|
||||
bindex_t i;
|
||||
for (i = 0; i < NSMALLBINS; ++i) {
|
||||
sbinptr bin = smallbin_at(m,i);
|
||||
bin->fd = bin->bk = bin;
|
||||
}
|
||||
}
|
||||
|
||||
#if PROCEED_ON_ERROR
|
||||
|
||||
/* default corruption action */
|
||||
static void reset_on_error(mstate m) {
|
||||
int i;
|
||||
++malloc_corruption_error_count;
|
||||
/* Reinitialize fields to forget about all memory */
|
||||
m->smallmap = m->treemap = 0;
|
||||
m->dvsize = m->topsize = 0;
|
||||
m->seg.base = 0;
|
||||
m->seg.size = 0;
|
||||
m->seg.next = 0;
|
||||
m->top = m->dv = 0;
|
||||
for (i = 0; i < NTREEBINS; ++i)
|
||||
*treebin_at(m, i) = 0;
|
||||
init_bins(m);
|
||||
}
|
||||
#endif /* PROCEED_ON_ERROR */
|
||||
|
||||
/* Allocate chunk and prepend remainder with chunk in successor base. */
|
||||
static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
|
||||
size_t nb) {
|
||||
mchunkptr p = align_as_chunk(newbase);
|
||||
mchunkptr oldfirst = align_as_chunk(oldbase);
|
||||
size_t psize = (char*)oldfirst - (char*)p;
|
||||
mchunkptr q = chunk_plus_offset(p, nb);
|
||||
size_t qsize = psize - nb;
|
||||
set_size_and_pinuse_of_inuse_chunk(m, p, nb);
|
||||
|
||||
assert((char*)oldfirst > (char*)q);
|
||||
assert(pinuse(oldfirst));
|
||||
assert(qsize >= MIN_CHUNK_SIZE);
|
||||
|
||||
/* consolidate remainder with first chunk of old base */
|
||||
if (oldfirst == m->top) {
|
||||
size_t tsize = m->topsize += qsize;
|
||||
m->top = q;
|
||||
q->head = tsize | PINUSE_BIT;
|
||||
check_top_chunk(m, q);
|
||||
}
|
||||
else if (oldfirst == m->dv) {
|
||||
size_t dsize = m->dvsize += qsize;
|
||||
m->dv = q;
|
||||
set_size_and_pinuse_of_free_chunk(q, dsize);
|
||||
}
|
||||
else {
|
||||
if (!is_inuse(oldfirst)) {
|
||||
size_t nsize = chunksize(oldfirst);
|
||||
unlink_chunk(m, oldfirst, nsize);
|
||||
oldfirst = chunk_plus_offset(oldfirst, nsize);
|
||||
qsize += nsize;
|
||||
}
|
||||
set_free_with_pinuse(q, qsize, oldfirst);
|
||||
insert_chunk(m, q, qsize);
|
||||
check_free_chunk(m, q);
|
||||
}
|
||||
|
||||
check_malloced_chunk(m, chunk2mem(p), nb);
|
||||
return chunk2mem(p);
|
||||
}
|
||||
|
||||
/* Add a segment to hold a new noncontiguous region */
|
||||
static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
|
||||
/* Determine locations and sizes of segment, fenceposts, old top */
|
||||
char* old_top = (char*)m->top;
|
||||
msegmentptr oldsp = segment_holding(m, old_top);
|
||||
char* old_end = oldsp->base + oldsp->size;
|
||||
size_t ssize = pad_request(sizeof(struct malloc_segment));
|
||||
char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
|
||||
size_t offset = align_offset(chunk2mem(rawsp));
|
||||
char* asp = rawsp + offset;
|
||||
char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
|
||||
mchunkptr sp = (mchunkptr)csp;
|
||||
msegmentptr ss = (msegmentptr)(chunk2mem(sp));
|
||||
mchunkptr tnext = chunk_plus_offset(sp, ssize);
|
||||
mchunkptr p = tnext;
|
||||
int nfences = 0;
|
||||
|
||||
/* reset top to new space */
|
||||
init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
|
||||
|
||||
/* Set up segment record */
|
||||
assert(is_aligned(ss));
|
||||
set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
|
||||
*ss = m->seg; /* Push current record */
|
||||
m->seg.base = tbase;
|
||||
m->seg.size = tsize;
|
||||
m->seg.sflags = mmapped;
|
||||
m->seg.next = ss;
|
||||
|
||||
/* Insert trailing fenceposts */
|
||||
for (;;) {
|
||||
mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
|
||||
p->head = FENCEPOST_HEAD;
|
||||
++nfences;
|
||||
if ((char*)(&(nextp->head)) < old_end)
|
||||
p = nextp;
|
||||
else
|
||||
break;
|
||||
}
|
||||
assert(nfences >= 2);
|
||||
|
||||
/* Insert the rest of old top into a bin as an ordinary free chunk */
|
||||
if (csp != old_top) {
|
||||
mchunkptr q = (mchunkptr)old_top;
|
||||
size_t psize = csp - old_top;
|
||||
mchunkptr tn = chunk_plus_offset(q, psize);
|
||||
set_free_with_pinuse(q, psize, tn);
|
||||
insert_chunk(m, q, psize);
|
||||
}
|
||||
|
||||
check_top_chunk(m, m->top);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue