| 4770 | /* ---------------------------- free --------------------------- */ |
| 4771 | |
| 4772 | void dlfree(void* mem) { |
| 4773 | /* |
| 4774 | Consolidate freed chunks with preceeding or succeeding bordering |
| 4775 | free chunks, if they exist, and then place in a bin. Intermixed |
| 4776 | with special cases for top, dv, mmapped chunks, and usage errors. |
| 4777 | */ |
| 4778 | |
| 4779 | if (mem != 0) { |
| 4780 | #if __EMSCRIPTEN__ |
| 4781 | /* XXX Emscripten Tracing API. */ |
| 4782 | emscripten_trace_record_free(mem); |
| 4783 | #endif |
| 4784 | mchunkptr p = mem2chunk(mem); |
| 4785 | #if FOOTERS |
| 4786 | mstate fm = get_mstate_for(p); |
| 4787 | if (!ok_magic(fm)) { |
| 4788 | USAGE_ERROR_ACTION(fm, p); |
| 4789 | return; |
| 4790 | } |
| 4791 | #else /* FOOTERS */ |
| 4792 | #define fm gm |
| 4793 | #endif /* FOOTERS */ |
| 4794 | if (!PREACTION(fm)) { |
| 4795 | check_inuse_chunk(fm, p); |
| 4796 | if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { |
| 4797 | size_t psize = chunksize(p); |
| 4798 | mchunkptr next = chunk_plus_offset(p, psize); |
| 4799 | if (!pinuse(p)) { |
| 4800 | size_t prevsize = p->prev_foot; |
| 4801 | if (is_mmapped(p)) { |
| 4802 | psize += prevsize + MMAP_FOOT_PAD; |
| 4803 | if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) |
| 4804 | fm->footprint -= psize; |
| 4805 | goto postaction; |
| 4806 | } |
| 4807 | else { |
| 4808 | mchunkptr prev = chunk_minus_offset(p, prevsize); |
| 4809 | psize += prevsize; |
| 4810 | p = prev; |
| 4811 | if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ |
| 4812 | if (p != fm->dv) { |
| 4813 | unlink_chunk(fm, p, prevsize); |
| 4814 | } |
| 4815 | else if ((next->head & INUSE_BITS) == INUSE_BITS) { |
| 4816 | fm->dvsize = psize; |
| 4817 | set_free_with_pinuse(p, psize, next); |
| 4818 | goto postaction; |
| 4819 | } |
| 4820 | } |
| 4821 | else |
| 4822 | goto erroraction; |
| 4823 | } |
| 4824 | } |
| 4825 | |
| 4826 | if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { |
| 4827 | if (!cinuse(next)) { /* consolidate forward */ |
| 4828 | if (next == fm->top) { |
| 4829 | size_t tsize = fm->topsize += psize; |
no test coverage detected