Allocate chunk and prepend remainder with chunk in successor base. */
| 3933 | |
| 3934 | /* Allocate chunk and prepend remainder with chunk in successor base. */ |
| 3935 | static void* prepend_alloc(mstate m, char* newbase, char* oldbase, |
| 3936 | size_t nb) { |
| 3937 | mchunkptr p = align_as_chunk(newbase); |
| 3938 | mchunkptr oldfirst = align_as_chunk(oldbase); |
| 3939 | size_t psize = (char*)oldfirst - (char*)p; |
| 3940 | mchunkptr q = chunk_plus_offset(p, nb); |
| 3941 | size_t qsize = psize - nb; |
| 3942 | set_size_and_pinuse_of_inuse_chunk(m, p, nb); |
| 3943 | |
| 3944 | assert((char*)oldfirst > (char*)q); |
| 3945 | assert(pinuse(oldfirst)); |
| 3946 | assert(qsize >= MIN_CHUNK_SIZE); |
| 3947 | |
| 3948 | /* consolidate remainder with first chunk of old base */ |
| 3949 | if (oldfirst == m->top) { |
| 3950 | size_t tsize = m->topsize += qsize; |
| 3951 | m->top = q; |
| 3952 | q->head = tsize | PINUSE_BIT; |
| 3953 | check_top_chunk(m, q); |
| 3954 | } |
| 3955 | else if (oldfirst == m->dv) { |
| 3956 | size_t dsize = m->dvsize += qsize; |
| 3957 | m->dv = q; |
| 3958 | set_size_and_pinuse_of_free_chunk(q, dsize); |
| 3959 | } |
| 3960 | else { |
| 3961 | if (!is_inuse(oldfirst)) { |
| 3962 | size_t nsize = chunksize(oldfirst); |
| 3963 | unlink_chunk(m, oldfirst, nsize); |
| 3964 | oldfirst = chunk_plus_offset(oldfirst, nsize); |
| 3965 | qsize += nsize; |
| 3966 | } |
| 3967 | set_free_with_pinuse(q, qsize, oldfirst); |
| 3968 | insert_chunk(m, q, qsize); |
| 3969 | check_free_chunk(m, q); |
| 3970 | } |
| 3971 | |
| 3972 | check_malloced_chunk(m, chunk2mem(p), nb); |
| 3973 | return chunk2mem(p); |
| 3974 | } |
| 3975 | |
| 3976 | /* Add a segment to hold a new noncontiguous region */ |
| 3977 | static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { |