MCPcopy Create free account
hub / github.com/emscripten-core/emscripten / dlmalloc

Function dlmalloc

system/lib/dlmalloc.c:4630–4768  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4628#if !ONLY_MSPACES
4629
4630void* dlmalloc(size_t bytes) {
4631 /*
4632 Basic algorithm:
4633 If a small request (< 256 bytes minus per-chunk overhead):
4634 1. If one exists, use a remainderless chunk in associated smallbin.
4635 (Remainderless means that there are too few excess bytes to
4636 represent as a chunk.)
4637 2. If it is big enough, use the dv chunk, which is normally the
4638 chunk adjacent to the one used for the most recent small request.
4639 3. If one exists, split the smallest available chunk in a bin,
4640 saving remainder in dv.
4641 4. If it is big enough, use the top chunk.
4642 5. If available, get memory from system and use it
4643 Otherwise, for a large request:
4644 1. Find the smallest available binned chunk that fits, and use it
4645 if it is better fitting than dv chunk, splitting if necessary.
4646 2. If better fitting than any binned chunk, use the dv chunk.
4647 3. If it is big enough, use the top chunk.
4648 4. If request size >= mmap threshold, try to directly mmap this chunk.
4649 5. If available, get memory from system and use it
4650
4651 The ugly goto's here ensure that postaction occurs along all paths.
4652 */
4653
4654#if USE_LOCKS
4655 ensure_initialization(); /* initialize in sys_alloc if not using locks */
4656#endif
4657
4658 if (!PREACTION(gm)) {
4659 void* mem;
4660 size_t nb;
4661 if (bytes <= MAX_SMALL_REQUEST) {
4662 bindex_t idx;
4663 binmap_t smallbits;
4664 nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
4665 idx = small_index(nb);
4666 smallbits = gm->smallmap >> idx;
4667
4668 if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
4669 mchunkptr b, p;
4670 idx += ~smallbits & 1; /* Uses next bin if idx empty */
4671 b = smallbin_at(gm, idx);
4672 p = b->fd;
4673 assert(chunksize(p) == small_index2size(idx));
4674 unlink_first_small_chunk(gm, b, p, idx);
4675 set_inuse_and_pinuse(gm, p, small_index2size(idx));
4676 mem = chunk2mem(p);
4677 check_malloced_chunk(gm, mem, nb);
4678 goto postaction;
4679 }
4680
4681 else if (nb > gm->dvsize) {
4682 if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
4683 mchunkptr b, p, r;
4684 size_t rsize;
4685 bindex_t i;
4686 binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
4687 binmap_t leastbit = least_bit(leftbits);

Callers 4

dlcallocFunction · 0.85
dlreallocFunction · 0.85
dlmemalignFunction · 0.85
dlposix_memalignFunction · 0.85

Calls 4

tmalloc_smallFunction · 0.85
tmalloc_largeFunction · 0.85
sys_allocFunction · 0.85
assertFunction · 0.50

Tested by

no test coverage detected