allocate a large request from the best fitting chunk in a treebin */
| 4427 | |
| 4428 | /* allocate a large request from the best fitting chunk in a treebin */ |
| 4429 | static void* tmalloc_large(mstate m, size_t nb) { |
| 4430 | tchunkptr v = 0; |
| 4431 | size_t rsize = -nb; /* Unsigned negation */ |
| 4432 | tchunkptr t; |
| 4433 | bindex_t idx; |
| 4434 | compute_tree_index(nb, idx); |
| 4435 | if ((t = *treebin_at(m, idx)) != 0) { |
| 4436 | /* Traverse tree for this bin looking for node with size == nb */ |
| 4437 | size_t sizebits = nb << leftshift_for_tree_index(idx); |
| 4438 | tchunkptr rst = 0; /* The deepest untaken right subtree */ |
| 4439 | for (;;) { |
| 4440 | tchunkptr rt; |
| 4441 | size_t trem = chunksize(t) - nb; |
| 4442 | if (trem < rsize) { |
| 4443 | v = t; |
| 4444 | if ((rsize = trem) == 0) |
| 4445 | break; |
| 4446 | } |
| 4447 | rt = t->child[1]; |
| 4448 | t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; |
| 4449 | if (rt != 0 && rt != t) |
| 4450 | rst = rt; |
| 4451 | if (t == 0) { |
| 4452 | t = rst; /* set t to least subtree holding sizes > nb */ |
| 4453 | break; |
| 4454 | } |
| 4455 | sizebits <<= 1; |
| 4456 | } |
| 4457 | } |
| 4458 | if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ |
| 4459 | binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; |
| 4460 | if (leftbits != 0) { |
| 4461 | bindex_t i; |
| 4462 | binmap_t leastbit = least_bit(leftbits); |
| 4463 | compute_bit2idx(leastbit, i); |
| 4464 | t = *treebin_at(m, i); |
| 4465 | } |
| 4466 | } |
| 4467 | |
| 4468 | while (t != 0) { /* find smallest of tree or subtree */ |
| 4469 | size_t trem = chunksize(t) - nb; |
| 4470 | if (trem < rsize) { |
| 4471 | rsize = trem; |
| 4472 | v = t; |
| 4473 | } |
| 4474 | t = leftmost_child(t); |
| 4475 | } |
| 4476 | |
| 4477 | /* If dv is a better fit, return 0 so malloc will use it */ |
| 4478 | if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { |
| 4479 | if (RTCHECK(ok_address(m, v))) { /* split */ |
| 4480 | mchunkptr r = chunk_plus_offset(v, nb); |
| 4481 | assert(chunksize(v) == rsize + nb); |
| 4482 | if (RTCHECK(ok_next(v, r))) { |
| 4483 | unlink_large_chunk(m, v); |
| 4484 | if (rsize < MIN_CHUNK_SIZE) |
| 4485 | set_inuse_and_pinuse(m, v, (rsize + nb)); |
| 4486 | else { |
no outgoing calls
no test coverage detected