| 4501 | } |
| 4502 | |
| 4503 | void dlfree(void* mem) { |
| 4504 | /* |
| 4505 | Consolidate freed chunks with preceeding or succeeding bordering |
| 4506 | free chunks, if they exist, and then place in a bin. Intermixed |
| 4507 | with special cases for top, dv, mmapped chunks, and usage errors. |
| 4508 | */ |
| 4509 | |
| 4510 | if (mem != 0) { |
| 4511 | mchunkptr p = mem2chunk(mem); |
| 4512 | #if FOOTERS |
| 4513 | mstate fm = get_mstate_for(p); |
| 4514 | if (!ok_magic(fm)) { |
| 4515 | USAGE_ERROR_ACTION(fm, p); |
| 4516 | return; |
| 4517 | } |
| 4518 | #else /* FOOTERS */ |
| 4519 | #define fm gm |
| 4520 | #endif /* FOOTERS */ |
| 4521 | if (!PREACTION(fm)) { |
| 4522 | check_inuse_chunk(fm, p); |
| 4523 | if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { |
| 4524 | size_t psize = chunksize(p); |
| 4525 | mchunkptr next = chunk_plus_offset(p, psize); |
| 4526 | if (!pinuse(p)) { |
| 4527 | size_t prevsize = p->prev_foot; |
| 4528 | if ((prevsize & IS_MMAPPED_BIT) != 0) { |
| 4529 | prevsize &= ~IS_MMAPPED_BIT; |
| 4530 | psize += prevsize + MMAP_FOOT_PAD; |
| 4531 | if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) |
| 4532 | fm->footprint -= psize; |
| 4533 | goto postaction; |
| 4534 | } |
| 4535 | else { |
| 4536 | mchunkptr prev = chunk_minus_offset(p, prevsize); |
| 4537 | psize += prevsize; |
| 4538 | p = prev; |
| 4539 | if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ |
| 4540 | if (p != fm->dv) { |
| 4541 | unlink_chunk(fm, p, prevsize); |
| 4542 | } |
| 4543 | else if ((next->head & INUSE_BITS) == INUSE_BITS) { |
| 4544 | fm->dvsize = psize; |
| 4545 | set_free_with_pinuse(p, psize, next); |
| 4546 | goto postaction; |
| 4547 | } |
| 4548 | } |
| 4549 | else |
| 4550 | goto erroraction; |
| 4551 | } |
| 4552 | } |
| 4553 | |
| 4554 | if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { |
| 4555 | if (!cinuse(next)) { /* consolidate forward */ |
| 4556 | if (next == fm->top) { |
| 4557 | size_t tsize = fm->topsize += psize; |
| 4558 | fm->top = p; |
| 4559 | p->head = tsize | PINUSE_BIT; |
| 4560 | if (p == fm->dv) { |