Allocate chunk and prepend remainder with chunk in successor base. */
| 4019 | |
| 4020 | /* Allocate chunk and prepend remainder with chunk in successor base. */ |
| 4021 | static void* prepend_alloc(mstate m, char* newbase, char* oldbase, |
| 4022 | size_t nb) { |
| 4023 | mchunkptr p = align_as_chunk(newbase); |
| 4024 | mchunkptr oldfirst = align_as_chunk(oldbase); |
| 4025 | size_t psize = (char*)oldfirst - (char*)p; |
| 4026 | mchunkptr q = chunk_plus_offset(p, nb); |
| 4027 | size_t qsize = psize - nb; |
| 4028 | set_size_and_pinuse_of_inuse_chunk(m, p, nb); |
| 4029 | |
| 4030 | assert((char*)oldfirst > (char*)q); |
| 4031 | assert(pinuse(oldfirst)); |
| 4032 | assert(qsize >= MIN_CHUNK_SIZE); |
| 4033 | |
| 4034 | /* consolidate remainder with first chunk of old base */ |
| 4035 | if (oldfirst == m->top) { |
| 4036 | size_t tsize = m->topsize += qsize; |
| 4037 | m->top = q; |
| 4038 | q->head = tsize | PINUSE_BIT; |
| 4039 | check_top_chunk(m, q); |
| 4040 | } |
| 4041 | else if (oldfirst == m->dv) { |
| 4042 | size_t dsize = m->dvsize += qsize; |
| 4043 | m->dv = q; |
| 4044 | set_size_and_pinuse_of_free_chunk(q, dsize); |
| 4045 | } |
| 4046 | else { |
| 4047 | if (!is_inuse(oldfirst)) { |
| 4048 | size_t nsize = chunksize(oldfirst); |
| 4049 | unlink_chunk(m, oldfirst, nsize); |
| 4050 | oldfirst = chunk_plus_offset(oldfirst, nsize); |
| 4051 | qsize += nsize; |
| 4052 | } |
| 4053 | set_free_with_pinuse(q, qsize, oldfirst); |
| 4054 | insert_chunk(m, q, qsize); |
| 4055 | check_free_chunk(m, q); |
| 4056 | } |
| 4057 | |
| 4058 | check_malloced_chunk(m, chunk2mem(p), nb); |
| 4059 | return chunk2mem(p); |
| 4060 | } |
| 4061 | |
| 4062 | /* Add a segment to hold a new noncontiguous region */ |
| 4063 | static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { |