Allocate chunk and prepend remainder with chunk in successor base. */
| 3313 | |
| 3314 | /* Allocate chunk and prepend remainder with chunk in successor base. */ |
| 3315 | static void* prepend_alloc(mstate m, char* newbase, char* oldbase, |
| 3316 | size_t nb) { |
| 3317 | mchunkptr p = align_as_chunk(newbase); |
| 3318 | mchunkptr oldfirst = align_as_chunk(oldbase); |
| 3319 | size_t psize = (char*)oldfirst - (char*)p; |
| 3320 | mchunkptr q = chunk_plus_offset(p, nb); |
| 3321 | size_t qsize = psize - nb; |
| 3322 | set_size_and_pinuse_of_inuse_chunk(m, p, nb); |
| 3323 | |
| 3324 | assert((char*)oldfirst > (char*)q); |
| 3325 | assert(pinuse(oldfirst)); |
| 3326 | assert(qsize >= MIN_CHUNK_SIZE); |
| 3327 | |
| 3328 | /* consolidate remainder with first chunk of old base */ |
| 3329 | if (oldfirst == m->top) { |
| 3330 | size_t tsize = m->topsize += qsize; |
| 3331 | m->top = q; |
| 3332 | q->head = tsize | PINUSE_BIT; |
| 3333 | check_top_chunk(m, q); |
| 3334 | } |
| 3335 | else if (oldfirst == m->dv) { |
| 3336 | size_t dsize = m->dvsize += qsize; |
| 3337 | m->dv = q; |
| 3338 | set_size_and_pinuse_of_free_chunk(q, dsize); |
| 3339 | } |
| 3340 | else { |
| 3341 | if (!cinuse(oldfirst)) { |
| 3342 | size_t nsize = chunksize(oldfirst); |
| 3343 | unlink_chunk(m, oldfirst, nsize); |
| 3344 | oldfirst = chunk_plus_offset(oldfirst, nsize); |
| 3345 | qsize += nsize; |
| 3346 | } |
| 3347 | set_free_with_pinuse(q, qsize, oldfirst); |
| 3348 | insert_chunk(m, q, qsize); |
| 3349 | check_free_chunk(m, q); |
| 3350 | } |
| 3351 | |
| 3352 | check_malloced_chunk(m, chunk2mem(p), nb); |
| 3353 | return chunk2mem(p); |
| 3354 | } |
| 3355 | |
| 3356 | |
| 3357 | /* Add a segment to hold a new noncontiguous region */ |