brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE));  if (brk != MAP_FAILED) {
char *mbrk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE));  if (mbrk != MAP_FAILED) {
static Void_t* sYSMALLOc(INTERNAL_SIZE_T nb, mstate av)#elsestatic Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;#endif{  mchunkptr       old_top;        /* incoming value of av->top */  INTERNAL_SIZE_T old_size;       /* its size */  char*           old_end;        /* its end address */  long            size;           /* arg to first MORECORE or mmap call */  char*           brk;            /* return value from MORECORE */  long            correction;     /* arg to 2nd MORECORE call */  char*           snd_brk;        /* 2nd return val */  INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */  INTERNAL_SIZE_T end_misalign;   /* partial page left at end of new space */  char*           aligned_brk;    /* aligned offset into brk */  mchunkptr       p;              /* the allocated/returned chunk */  mchunkptr       remainder;      /* remainder from allocation */  unsigned long   remainder_size; /* its size */  unsigned long   sum;            /* for updating stats */  size_t          pagemask  = mp_.pagesize - 1;#if HAVE_MMAP  /*    If have mmap, and the request size meets the mmap threshold, and    the system supports mmap, and there are few enough currently    allocated mmapped regions, try to directly map this request    rather than expanding top.  */  if ((unsigned long)(nb) >= (unsigned long)(mp_.mmap_threshold) &&      (mp_.n_mmaps < mp_.n_mmaps_max)) {    char* mm;             /* return value from mmap call*/    /*      Round up size to nearest page.  For mmapped chunks, the overhead      is one SIZE_SZ unit larger than for normal chunks, because there      is no following chunk whose prev_size field could be used.    */    size = (nb + SIZE_SZ + MALLOC_ALIGN_MASK + pagemask) & ~pagemask;    /* Don't try if size wraps around 0 */    if ((unsigned long)(size) > (unsigned long)(nb)) {      mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE));      if (mm != MAP_FAILED) {        /*          The offset to the start of the mmapped region is stored          in the prev_size field of the chunk. This allows us to adjust          returned start address to meet alignment requirements here          and in memalign(), and still be able to compute proper          address argument for later munmap in free() and realloc().        */        front_misalign = (INTERNAL_SIZE_T)chunk2mem(mm) & MALLOC_ALIGN_MASK;        if (front_misalign > 0) {          correction = MALLOC_ALIGNMENT - front_misalign;          p = (mchunkptr)(mm + correction);          p->prev_size = correction;          set_head(p, (size - correction) |IS_MMAPPED);        }        else {          p = (mchunkptr)mm;          set_head(p, size|IS_MMAPPED);        }        /* update statistics */        if (++mp_.n_mmaps > mp_.max_n_mmaps)          mp_.max_n_mmaps = mp_.n_mmaps;        sum = mp_.mmapped_mem += size;        if (sum > (unsigned long)(mp_.max_mmapped_mem))          mp_.max_mmapped_mem = sum;#ifdef NO_THREADS        sum += av->system_mem;        if (sum > (unsigned long)(mp_.max_total_mem))          mp_.max_total_mem = sum;#endif        check_chunk(av, p);        return chunk2mem(p);      }    }  }#endif  /* Record incoming configuration of top */  old_top  = av->top;  old_size = chunksize(old_top);  old_end  = (char*)(chunk_at_offset(old_top, old_size));  brk = snd_brk = (char*)(MORECORE_FAILURE);  /*     If not the first time through, we require old_size to be     at least MINSIZE and to have prev_inuse set.  */  assert((old_top == initial_top(av) && old_size == 0) ||         ((unsigned long) (old_size) >= MINSIZE &&          prev_inuse(old_top) &&	  ((unsigned long)old_end & pagemask) == 0));  /* Precondition: not enough current space to satisfy nb request */  assert((unsigned long)(old_size) < (unsigned long)(nb + MINSIZE));  /* Precondition: all fastbins are consolidated */  assert(!have_fastchunks(av));  if (av != &main_arena) {    heap_info *old_heap, *heap;    size_t old_heap_size;    /* First try to extend the current heap. */    old_heap = heap_for_ptr(old_top);    old_heap_size = old_heap->size;    if (grow_heap(old_heap, MINSIZE + nb - old_size) == 0) {      av->system_mem += old_heap->size - old_heap_size;      arena_mem += old_heap->size - old_heap_size;#if 0      if(mmapped_mem + arena_mem + sbrked_mem > max_total_mem)        max_total_mem = mmapped_mem + arena_mem + sbrked_mem;#endif      set_head(old_top, (((char *)old_heap + old_heap->size) - (char *)old_top)	       | PREV_INUSE);    } else {      /* A new heap must be created. */      heap = new_heap(nb + (MINSIZE + sizeof(*heap)), mp_.top_pad);      if(heap) {	heap->ar_ptr = av;	heap->prev = old_heap;	av->system_mem += heap->size;	arena_mem += heap->size;#if 0	if((unsigned long)(mmapped_mem + arena_mem + sbrked_mem) > max_total_mem)	  max_total_mem = mmapped_mem + arena_mem + sbrked_mem;#endif      }      /* Set up the new top.  */      top(av) = chunk_at_offset(heap, sizeof(*heap));      set_head(top(av), (heap->size - sizeof(*heap)) | PREV_INUSE);      /* Setup fencepost and free the old top chunk. */      /* The fencepost takes at least MINSIZE bytes, because it might	 become the top chunk again later.  Note that a footer is set	 up, too, although the chunk is marked in use. */      old_size -= MINSIZE;      set_head(chunk_at_offset(old_top, old_size + 2*SIZE_SZ), 0|PREV_INUSE);      if (old_size >= MINSIZE) {	set_head(chunk_at_offset(old_top, old_size), (2*SIZE_SZ)|PREV_INUSE);	set_foot(chunk_at_offset(old_top, old_size), (2*SIZE_SZ));	set_head(old_top, old_size|PREV_INUSE|NON_MAIN_ARENA);	_int_free(av, chunk2mem(old_top));      } else {	set_head(old_top, (old_size + 2*SIZE_SZ)|PREV_INUSE);	set_foot(old_top, (old_size + 2*SIZE_SZ));      }    }  } else { /* av == main_arena */  /* Request enough space for nb + pad + overhead */  size = nb + mp_.top_pad + MINSIZE;  /*    If contiguous, we can subtract out existing space that we hope to    combine with new space. We add it back later only if    we don't actually get contiguous space.  */  if (contiguous(av))    size -= old_size;  /*    Round to a multiple of page size.    If MORECORE is not contiguous, this ensures that we only call it    with whole-page arguments.  And if MORECORE is contiguous and    this is not first time through, this preserves page-alignment of    previous calls. Otherwise, we correct to page-align below.  */  size = (size + pagemask) & ~pagemask;  /*    Don't try to call MORECORE if argument is so big as to appear    negative. Note that since mmap takes size_t arg, it may succeed    below even if we cannot call MORECORE.  */  if (size > 0)    brk = (char*)(MORECORE(size));  if (brk != (char*)(MORECORE_FAILURE)) {    /* Call the `morecore' hook if necessary.  */    if (__after_morecore_hook)      (*__after_morecore_hook) ();  } else {  /*    If have mmap, try using it as a backup when MORECORE fails or    cannot be used. This is worth doing on systems that have "holes" in    address space, so sbrk cannot extend to give contiguous space, but    space is available elsewhere.  Note that we ignore mmap max count    and threshold limits, since the space will not be used as a    segregated mmap region.  */#if HAVE_MMAP    /* Cannot merge with old top, so add its size back in */    if (contiguous(av))      size = (size + old_size + pagemask) & ~pagemask;    /* If we are relying on mmap as backup, then use larger units */    if ((unsigned long)(size) < (unsigned long)(MMAP_AS_MORECORE_SIZE))      size = MMAP_AS_MORECORE_SIZE;    /* Don't try if size wraps around 0 */    if ((unsigned long)(size) > (unsigned long)(nb)) {      brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE));      if (brk != MAP_FAILED) {        /* We do not need, and cannot use, another sbrk call to find end */        snd_brk = brk + size;        /*           Record that we no longer have a contiguous sbrk region.           After the first time mmap is used as backup, we do not           ever rely on contiguous space since this could incorrectly           bridge regions.        */        set_noncontiguous(av);      }    }#endif  }  if (brk != (char*)(MORECORE_FAILURE)) {    if (mp_.sbrk_base == 0)      mp_.sbrk_base = brk;    av->system_mem += size;    /*      If MORECORE extends previous space, we can likewise extend top size.    */    if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE))      set_head(old_top, (size + old_size) | PREV_INUSE);    else if (old_size && brk < old_end) {      /* Oops!  Someone else killed our space..  Can't touch anything.  */      assert(0);    }    /*      Otherwise, make adjustments:      * If the first time through or noncontiguous, we need to call sbrk        just to find out where the end of memory lies.      * We need to ensure that all returned chunks from malloc will meet        MALLOC_ALIGNMENT      * If there was an intervening foreign sbrk, we need to adjust sbrk        request size to account for fact that we will not be able to        combine new space with existing space in old_top.      * Almost all systems internally allocate whole pages at a time, in        which case we might as well use the whole last page of request.        So we allocate enough more memory to hit a page boundary now,        which in turn causes future contiguous calls to page-align.    */    else {      /* Count foreign sbrk as system_mem.  */      if (old_size)	av->system_mem += brk - old_end;      front_misalign = 0;      end_misalign = 0;      correction = 0;      aligned_brk = brk;      /* handle contiguous cases */      if (contiguous(av)) {        /* Guarantee alignment of first new chunk made from this space */        front_misalign = (INTERNAL_SIZE_T)chunk2mem(brk) & MALLOC_ALIGN_MASK;        if (front_misalign > 0) {          /*            Skip over some bytes to arrive at an aligned position.            We don't need to specially mark these wasted front bytes.            They will never be accessed anyway because            prev_inuse of av->top (and any chunk created from its start)            is always true after initialization.          */          correction = MALLOC_ALIGNMENT - front_misalign;          aligned_brk += correction;        }        /*          If this isn't adjacent to existing space, then we will not          be able to merge with old_top space, so must add to 2nd request.        */        correction += old_size;        /* Extend the end address to hit a page boundary */        end_misalign = (INTERNAL_SIZE_T)(brk + size + correction);        correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign;        assert(correction >= 0);        snd_brk = (char*)(MORECORE(correction));        /*          If can't allocate correction, try to at least find out current          brk.  It might be enough to proceed without failing.          Note that if second sbrk did NOT fail, we assume that space          is contiguous with first sbrk. This is a safe assumption unless          program is multithreaded but doesn't use locks and a foreign sbrk          occurred between our first and second calls.        */        if (snd_brk == (char*)(MORECORE_FAILURE)) {          correction = 0;          snd_brk = (char*)(MORECORE(0));        } else	  /* Call the `morecore' hook if necessary.  */	  if (__after_morecore_hook)	    (*__after_morecore_hook) ();      }      /* handle non-contiguous cases */      else {        /* MORECORE/mmap must correctly align */        assert(((unsigned long)chunk2mem(brk) & MALLOC_ALIGN_MASK) == 0);        /* Find out current end of memory */        if (snd_brk == (char*)(MORECORE_FAILURE)) {          snd_brk = (char*)(MORECORE(0));        }      }      /* Adjust top based on results of second sbrk */      if (snd_brk != (char*)(MORECORE_FAILURE)) {        av->top = (mchunkptr)aligned_brk;        set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE);        av->system_mem += correction;        /*          If not the first time through, we either have a          gap due to foreign sbrk or a non-contiguous region.  Insert a          double fencepost at old_top to prevent consolidation with space          we don't own. These fenceposts are artificial chunks that are          marked as inuse and are in any case too small to use.  We need          two to make sizes and alignments work out.        */        if (old_size != 0) {          /*             Shrink old_top to insert fenceposts, keeping size a             multiple of MALLOC_ALIGNMENT. We know there is at least             enough space in old_top to do this.          */          old_size = (old_size - 4*SIZE_SZ) & ~MALLOC_ALIGN_MASK;          set_head(old_top, old_size | PREV_INUSE);          /*            Note that the following assignments completely overwrite            old_top when old_size was previously MINSIZE.  This is            intentional. We need the fencepost, even if old_top otherwise gets            lost.          */          chunk_at_offset(old_top, old_size            )->size =            (2*SIZE_SZ)|PREV_INUSE;          chunk_at_offset(old_top, old_size + 2*SIZE_SZ)->size =            (2*SIZE_SZ)|PREV_INUSE;          /* If possible, release the rest. */          if (old_size >= MINSIZE) {            _int_free(av, chunk2mem(old_top));          }        }      }    }    /* Update statistics */#ifdef NO_THREADS    sum = av->system_mem + mp_.mmapped_mem;    if (sum > (unsigned long)(mp_.max_total_mem))      mp_.max_total_mem = sum;#endif  }  } /* if (av !=  &main_arena) */  if ((unsigned long)av->system_mem > (unsigned long)(av->max_system_mem))    av->max_system_mem = av->system_mem;  check_malloc_state(av);  /* finally, do the allocation */  p = av->top;  size = chunksize(p);  /* check that one of the above allocation paths succeeded */  if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) {    remainder_size = size - nb;    remainder = chunk_at_offset(p, nb);    av->top = remainder;    set_head(p, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0));    set_head(remainder, remainder_size | PREV_INUSE);    check_malloced_chunk(av, p, nb);    return chunk2mem(p);  }  /* catch all failure paths */  MALLOC_FAILURE_ACTION;  return 0;}