| 4675 | /* ---------------------------- free --------------------------- */ |
| 4676 | |
| 4677 | void dlfree(void* mem) { |
| 4678 | /* |
| 4679 | Consolidate freed chunks with preceeding or succeeding bordering |
| 4680 | free chunks, if they exist, and then place in a bin. Intermixed |
| 4681 | with special cases for top, dv, mmapped chunks, and usage errors. |
| 4682 | */ |
| 4683 | |
| 4684 | if (mem != 0) { |
| 4685 | mchunkptr p = mem2chunk(mem); |
| 4686 | #if FOOTERS |
| 4687 | mstate fm = get_mstate_for(p); |
| 4688 | if (!ok_magic(fm)) { |
| 4689 | USAGE_ERROR_ACTION(fm, p); |
| 4690 | return; |
| 4691 | } |
| 4692 | #else /* FOOTERS */ |
| 4693 | #define fm gm |
| 4694 | #endif /* FOOTERS */ |
| 4695 | if (!PREACTION(fm)) { |
| 4696 | check_inuse_chunk(fm, p); |
| 4697 | if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { |
| 4698 | size_t psize = chunksize(p); |
| 4699 | mchunkptr next = chunk_plus_offset(p, psize); |
| 4700 | if (!pinuse(p)) { |
| 4701 | size_t prevsize = p->prev_foot; |
| 4702 | if (is_mmapped(p)) { |
| 4703 | psize += prevsize + MMAP_FOOT_PAD; |
| 4704 | if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) |
| 4705 | fm->footprint -= psize; |
| 4706 | goto postaction; |
| 4707 | } |
| 4708 | else { |
| 4709 | mchunkptr prev = chunk_minus_offset(p, prevsize); |
| 4710 | psize += prevsize; |
| 4711 | p = prev; |
| 4712 | if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ |
| 4713 | if (p != fm->dv) { |
| 4714 | unlink_chunk(fm, p, prevsize); |
| 4715 | } |
| 4716 | else if ((next->head & INUSE_BITS) == INUSE_BITS) { |
| 4717 | fm->dvsize = psize; |
| 4718 | set_free_with_pinuse(p, psize, next); |
| 4719 | goto postaction; |
| 4720 | } |
| 4721 | } |
| 4722 | else |
| 4723 | goto erroraction; |
| 4724 | } |
| 4725 | } |
| 4726 | |
| 4727 | if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { |
| 4728 | if (!cinuse(next)) { /* consolidate forward */ |
| 4729 | if (next == fm->top) { |
| 4730 | size_t tsize = fm->topsize += psize; |
| 4731 | fm->top = p; |
| 4732 | p->head = tsize | PINUSE_BIT; |
| 4733 | if (p == fm->dv) { |
| 4734 | fm->dv = 0; |
no test coverage detected