mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
79 lines
2.8 KiB
C++
79 lines
2.8 KiB
C++
// clang-format off
|
|
|
|
/* ----------------------- Direct-mmapping chunks ----------------------- */
|
|
|
|
/*
|
|
Directly mmapped chunks are set up with an offset to the start of
|
|
the mmapped region stored in the prev_foot field of the chunk. This
|
|
allows reconstruction of the required argument to MUNMAP when freed,
|
|
and also allows adjustment of the returned chunk to meet alignment
|
|
requirements (especially in memalign).
|
|
*/
|
|
|
|
/* Malloc using mmap */
|
|
static void* mmap_alloc(mstate m, size_t nb) {
|
|
size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
|
|
if (m->footprint_limit != 0) {
|
|
size_t fp = m->footprint + mmsize;
|
|
if (fp <= m->footprint || fp > m->footprint_limit)
|
|
return 0;
|
|
}
|
|
if (mmsize > nb) { /* Check for wrap around 0 */
|
|
char* mm = (char*)(dlmalloc_requires_more_vespene_gas(mmsize));
|
|
if (mm != CMFAIL) {
|
|
size_t offset = align_offset(chunk2mem(mm));
|
|
size_t psize = mmsize - offset - MMAP_FOOT_PAD;
|
|
mchunkptr p = (mchunkptr)(mm + offset);
|
|
p->prev_foot = offset;
|
|
p->head = psize;
|
|
mark_inuse_foot(m, p, psize);
|
|
chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
|
|
chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
|
|
|
|
if (m->least_addr == 0 || mm < m->least_addr)
|
|
m->least_addr = mm;
|
|
if ((m->footprint += mmsize) > m->max_footprint)
|
|
m->max_footprint = m->footprint;
|
|
assert(is_aligned(chunk2mem(p)));
|
|
check_mmapped_chunk(m, p);
|
|
return chunk2mem(p);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* Realloc using mmap */
|
|
static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) {
|
|
size_t oldsize = chunksize(oldp);
|
|
(void)flags; /* placate people compiling -Wunused */
|
|
if (is_small(nb)) /* Can't shrink mmap regions below small size */
|
|
return 0;
|
|
/* Keep old chunk if big enough but not too big */
|
|
if (oldsize >= nb + SIZE_T_SIZE &&
|
|
(oldsize - nb) <= (mparams.granularity << 1))
|
|
return oldp;
|
|
else {
|
|
size_t offset = oldp->prev_foot;
|
|
size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
|
|
size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
|
|
char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
|
|
oldmmsize, newmmsize, flags);
|
|
if (cp != CMFAIL) {
|
|
mchunkptr newp = (mchunkptr)(cp + offset);
|
|
size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
|
|
newp->head = psize;
|
|
mark_inuse_foot(m, newp, psize);
|
|
chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
|
|
chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
|
|
|
|
if (cp < m->least_addr)
|
|
m->least_addr = cp;
|
|
if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
|
|
m->max_footprint = m->footprint;
|
|
check_mmapped_chunk(m, newp);
|
|
return newp;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|