if
(__builtin_expect (chunk_at_offset (p, size)->size <=
2
* SIZE_SZ,
0
)
|| __builtin_expect (chunksize (chunk_at_offset (p, size))
>= av->system_mem,
0
))
{
if
(have_lock
|| ({
assert
(locked ==
0
);
mutex_lock(&av->mutex);
locked =
1
;
chunk_at_offset (p, size)->size <=
2
* SIZE_SZ
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem;
}))
{
errstr =
"free(): invalid next size (fast)"
;
goto
errout;
}
if
(! have_lock)
{
(
void
)mutex_unlock(&av->mutex);
locked =
0
;
}
}
free_perturb (chunk2mem(p), size -
2
* SIZE_SZ);
set_fastchunks(av);
unsigned
int
idx = fastbin_index(size);
fb = &fastbin (av, idx);
mchunkptr old = *fb, old2;
unsigned
int
old_idx = ~0u;
do
{
if
(__builtin_expect (old == p,
0
))
{
errstr =
"double free or corruption (fasttop)"
;
goto
errout;
}
if
(have_lock && old != NULL)
old_idx = fastbin_index(chunksize(old));
p->fd = old2 = old;
}
while
((old = catomic_compare_and_exchange_val_rel (fb, p, old2)) != old2);
if
(have_lock && old != NULL && __builtin_expect (old_idx != idx,
0
))
{
errstr =
"invalid fastbin entry (free)"
;
goto
errout;
}
}
else
if
(!chunk_is_mmapped(p)) {
if
(! have_lock) {
(
void
)mutex_lock(&av->mutex);
locked =
1
;
}
nextchunk = chunk_at_offset(p, size);
if
(__glibc_unlikely (p == av->top))
{
errstr =
"double free or corruption (top)"
;
goto
errout;
}
if
(__builtin_expect (contiguous (av)
&& (
char
*) nextchunk
>= ((
char
*) av->top + chunksize(av->top)),
0
))
{
errstr =
"double free or corruption (out)"
;
goto
errout;
}
if
(__glibc_unlikely (!prev_inuse(nextchunk)))
{
errstr =
"double free or corruption (!prev)"
;
goto
errout;
}
nextsize = chunksize(nextchunk);
if
(__builtin_expect (nextchunk->size <=
2
* SIZE_SZ,
0
)
|| __builtin_expect (nextsize >= av->system_mem,
0
))
{
errstr =
"free(): invalid next size (normal)"
;
goto
errout;
}
free_perturb (chunk2mem(p), size -
2
* SIZE_SZ);
if
(!prev_inuse(p)) {
prevsize = p->prev_size;
size += prevsize;
p = chunk_at_offset(p, -((
long
) prevsize));
unlink(av, p, bck, fwd);
}
if
(nextchunk != av->top) {
nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
if
(!nextinuse) {
unlink(av, nextchunk, bck, fwd);
size += nextsize;
}
else
clear_inuse_bit_at_offset(nextchunk,
0
);
bck = unsorted_chunks(av);
fwd = bck->fd;
if
(__glibc_unlikely (fwd->bk != bck))
{
errstr =
"free(): corrupted unsorted chunks"
;
goto
errout;
}