static mspace createMspace(void *base, size_t startSize, size_t maximumSize)
{
    /* Create an unlocked dlmalloc mspace to use as
     * a heap source.
     *
     * We start off reserving startSize / 2 bytes but
     * letting the heap grow to startSize.  This saves
     * memory in the case where a process uses even less
     * than the starting size.
     */
    LOGV_HEAP("Creating VM heap of size %zu", startSize);
    errno = 0;

    mspace msp = create_contiguous_mspace_with_base(startSize/2,
            maximumSize, /*locked=*/false, base);
    if (msp != NULL) {
        /* Don't let the heap grow past the starting size without
         * our intervention.
         */
        mspace_set_max_allowed_footprint(msp, startSize);
    } else {
        /* There's no guarantee that errno has meaning when the call
         * fails, but it often does.
         */
        LOGE_HEAP("Can't create VM heap of size (%zu,%zu): %s",
            startSize/2, maximumSize, strerror(errno));
    }

    return msp;
}
mspace create_contiguous_mspace_with_name(size_t starting_capacity,
    size_t max_capacity, int locked, char const *name) {
  int fd, ret;
  char buf[ASHMEM_NAME_LEN] = "mspace";
  void *base;
  unsigned int pagesize;
  mstate m;

  if (starting_capacity > max_capacity)
    return (mspace)0;

  init_mparams();
  pagesize = PAGESIZE;

  /* Create the anonymous memory that will back the mspace.
   * This reserves all of the virtual address space we could
   * ever need.  Physical pages will be mapped as the memory
   * is touched.
   *
   * Align max_capacity to a whole page.
   */
  max_capacity = (size_t)ALIGN_UP(max_capacity, pagesize);

  if (name)
    snprintf(buf, sizeof(buf), "mspace/%s", name);
  fd = ashmem_create_region(buf, max_capacity);
  if (fd < 0)
    return (mspace)0;

  base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
  close(fd);
  if (base == MAP_FAILED)
    return (mspace)0;

  /* Make sure that base is at the beginning of a page.
   */
  assert(((uintptr_t)base & (pagesize-1)) == 0);

  m = create_contiguous_mspace_with_base(starting_capacity, max_capacity,
                                         locked, base);
  if (m == 0) {
    munmap(base, max_capacity);
  }
  return m;
}