| 4628 | #if !ONLY_MSPACES |
| 4629 | |
| 4630 | void* 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); |
no test coverage detected