/* Copyright 2006 The Android Open Source Project */

/* A wrapper file for dlmalloc.c that compiles in the
 * mspace_*() functions, which provide an interface for
 * creating multiple heaps.
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/ioctl.h>

/* It's a pain getting the mallinfo stuff to work
 * with Linux, OSX, and klibc, so just turn it off
 * for now.
 * TODO: make mallinfo work
 */
#define NO_MALLINFO 1

/* Allow setting the maximum heap footprint.
 */
#define USE_MAX_ALLOWED_FOOTPRINT 1

/* Don't try to trim memory.
 * TODO: support this.
 */
#define MORECORE_CANNOT_TRIM 1

/* Use mmap()d anonymous memory to guarantee
 * that an mspace is contiguous.
 *
 * create_mspace() won't work right if this is
 * defined, so hide the definition of it and
 * break any users at build time.
 */
#define USE_CONTIGUOUS_MSPACES 1
#if USE_CONTIGUOUS_MSPACES
/* This combination of settings forces sys_alloc()
 * to always use MORECORE().  It won't expect the
 * results to be contiguous, but we'll guarantee
 * that they are.
 */
#define HAVE_MMAP 0
#define HAVE_MORECORE 1
#define MORECORE_CONTIGUOUS 0
/* m is always the appropriate local when MORECORE() is called. */
#define MORECORE(S) contiguous_mspace_morecore(m, S)
#define create_mspace   HIDDEN_create_mspace_HIDDEN
#define destroy_mspace   HIDDEN_destroy_mspace_HIDDEN
typedef struct malloc_state *mstate0;
static void *contiguous_mspace_morecore(mstate0 m, ssize_t nb);
#endif /* USE_CONTIGUOUS_MSPACES */

#define MSPACES 1
#define ONLY_MSPACES 1
#include "dlmalloc.c"

#ifndef PAGESIZE
#define PAGESIZE  mparams.page_size
#endif

#define ALIGN_UP(p, alignment) \
    (((uintptr_t)(p) + (alignment)-1) & ~((alignment)-1))

/* A direct copy of dlmalloc_usable_size(),
 * which isn't compiled in when ONLY_MSPACES is set.
 * The mspace parameter isn't actually necessary,
 * but we include it to be consistent with the
 * rest of the mspace_*() functions.
 */
size_t mspace_usable_size(mspace _unused, const void* mem) {
  if (mem != 0) {
    const mchunkptr p = mem2chunk(mem);
    if (cinuse(p))
      return chunksize(p) - overhead_for(p);
  }
  return 0;
}

#if USE_CONTIGUOUS_MSPACES
#include <sys/mman.h>
#include <limits.h>

#define CONTIG_STATE_MAGIC  0xf00dd00d
struct mspace_contig_state {
  unsigned int magic;
  char *brk;
  char *top;
  mspace m;
};

static void *contiguous_mspace_morecore(mstate m, ssize_t nb) {
  struct mspace_contig_state *cs;
  char *oldbrk;
  const unsigned int pagesize = PAGESIZE;

  cs = (struct mspace_contig_state *)((uintptr_t)m & ~(pagesize-1));
  assert(cs->magic == CONTIG_STATE_MAGIC);
  assert(cs->m == m);
assert(nb >= 0);  //xxx deal with the trim case

  oldbrk = cs->brk;
  if (nb > 0) {
    /* Break to the first page boundary that satisfies the request.
     */
    char *newbrk = (char *)ALIGN_UP(oldbrk + nb, pagesize);
    if (newbrk > cs->top)
      return CMFAIL;

    /* Update the protection on the underlying memory.
     * Pages we've given to dlmalloc are read/write, and
     * pages we haven't are not accessable (read or write
     * will cause a seg fault).
     */
    if (mprotect(cs, newbrk - (char *)cs, PROT_READ | PROT_WRITE) < 0)
      return CMFAIL;
    if (newbrk != cs->top) {
      if (mprotect(newbrk, cs->top - newbrk, PROT_NONE) < 0)
        return CMFAIL;
    }

    cs->brk = newbrk;

    /* Make sure that dlmalloc will merge this block with the
     * initial block that was passed to create_mspace_with_base().
     * We don't care about extern vs. non-extern, so just clear it.
     */
    m->seg.sflags &= ~EXTERN_BIT;
  }

  return oldbrk;
}

mspace create_contiguous_mspace_with_base(size_t starting_capacity,
    size_t max_capacity, int locked, void *base) {
  struct mspace_contig_state *cs;
  unsigned int pagesize;
  mstate m;

  init_mparams();
  pagesize = PAGESIZE;
  assert(starting_capacity <= max_capacity);
  assert(((uintptr_t)base & (pagesize-1)) == 0);
  assert(((uintptr_t)max_capacity & (pagesize-1)) == 0);
  starting_capacity = (size_t)ALIGN_UP(starting_capacity, pagesize);

  /* Make the first page read/write. dlmalloc needs to use that page.
   */
  if (mprotect(base, starting_capacity, PROT_READ | PROT_WRITE) < 0) {
    goto error;
  }

  /* Create the mspace, pointing to the memory given.
   */
  m = create_mspace_with_base((char *)base + sizeof(*cs), starting_capacity,
                              locked);
  if (m == (mspace)0) {
    goto error;
  }
  /* Make sure that m is in the same page as base.
   */
  assert(((uintptr_t)m & (uintptr_t)~(pagesize-1)) == (uintptr_t)base);
  /* Use some space for the information that our MORECORE needs.
   */
  cs = (struct mspace_contig_state *)base;

  /* Find out exactly how much of the memory the mspace
   * is using.
   */
  cs->brk = m->seg.base + m->seg.size;
  cs->top = (char *)base + max_capacity;

  assert((char *)base <= cs->brk);
  assert(cs->brk <= cs->top);
  /* Prevent access to the memory we haven't handed out yet.
   */
  if (cs->brk != cs->top) {
    /* mprotect() requires page-aligned arguments, but it's possible
     * for cs->brk not to be page-aligned at this point.
     */
    char *prot_brk = (char *)ALIGN_UP(cs->brk, pagesize);
    if ((mprotect(base, prot_brk - (char *)base, PROT_READ | PROT_WRITE) < 0) ||
        (mprotect(prot_brk, cs->top - prot_brk, PROT_NONE) < 0)) {
      goto error;
    }
  }

  cs->m = m;
  cs->magic = CONTIG_STATE_MAGIC;

  return (mspace)m;

error:
  return (mspace)0;
}

size_t destroy_contiguous_mspace(mspace msp) {
  mstate ms = (mstate)msp;

  if (ok_magic(ms)) {
    struct mspace_contig_state *cs;
    size_t length;
    const unsigned int pagesize = PAGESIZE;

    cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1));
    assert(cs->magic == CONTIG_STATE_MAGIC);
    assert(cs->m == ms);

    length = cs->top - (char *)cs;
    if (munmap((char *)cs, length) != 0)
      return length;
  }
  else {
    USAGE_ERROR_ACTION(ms, ms);
  }
  return 0;
}

void *contiguous_mspace_sbrk0(mspace msp) {
    struct mspace_contig_state *cs;
    mstate ms;
    const unsigned int pagesize = PAGESIZE;

    ms = (mstate)msp;
    cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1));
    assert(cs->magic == CONTIG_STATE_MAGIC);
    assert(cs->m == ms);
    return cs->brk;
}
#endif /* USE_CONTIGUOUS_MSPACES */
