// Copyright 2011 Google Inc. All Rights Reserved.

#include "space.h"

#include <sys/mman.h>

#include "logging.h"
#include "mspace.h"
#include "scoped_ptr.h"
#include "utils.h"

namespace art {

Space* Space::Create(size_t startup_size, size_t maximum_size) {
  scoped_ptr<Space> space(new Space(startup_size, maximum_size));
  bool success = space->Init();
  if (!success) {
    return NULL;
  } else {
    return space.release();
  }
}

void* Space::CreateMallocSpace(void* base,
                               size_t startup_size,
                               size_t maximum_size) {
  errno = 0;
  bool is_locked = false;
  size_t commit_size = startup_size / 2;
  void* msp = create_contiguous_mspace_with_base(commit_size, maximum_size,
                                                 is_locked, base);
  if (msp != NULL) {
    // Do not permit the heap grow past the starting size without our
    // intervention.
    mspace_set_max_allowed_footprint(msp, startup_size);
  } else {
    // There is no guarantee that errno has meaning when the call
    // fails, but it often does.
    PLOG(ERROR) << "create_contiguous_mspace_with_base failed";
  }
  return msp;
}

bool Space::Init() {
  if (!(startup_size_ <= maximum_size_)) {
    return false;
  }
  size_t length = RoundUp(maximum_size_, kPageSize);
  int prot = PROT_READ | PROT_WRITE;
  int flags = MAP_PRIVATE | MAP_ANONYMOUS;
  void* base = mmap(NULL, length, prot, flags, -1, 0);
  if (base == MAP_FAILED) {
    PLOG(ERROR) << "mmap failed";
    return false;
  }
  base_ = static_cast<byte*>(base);
  limit_ = base_ + length;
  mspace_ = CreateMallocSpace(base, startup_size_, maximum_size_);
  if (mspace_ == NULL) {
    munmap(base_, length);
    return false;
  }
  return true;
}

Space::~Space() {
  if (base_ == NULL) {
    return;
  }
  int result = munmap(base_, limit_ - base_);
  if (result == -1) {
    PLOG(WARNING) << "munmap failed";
  }
}

Object* Space::AllocWithoutGrowth(size_t num_bytes) {
  return reinterpret_cast<Object*>(mspace_calloc(mspace_, 1, num_bytes));
}

Object* Space::AllocWithGrowth(size_t num_bytes) {
  // Grow as much as possible within the mspace.
  size_t max_allowed = maximum_size_;
  mspace_set_max_allowed_footprint(mspace_, max_allowed);
  // Try the allocation.
  void* ptr = AllocWithoutGrowth(num_bytes);
  // Shrink back down as small as possible.
  size_t footprint = mspace_footprint(mspace_);
  mspace_set_max_allowed_footprint(mspace_, footprint);
  // Return the new allocation or NULL.
  return reinterpret_cast<Object*>(ptr);
}

size_t Space::Free(void* ptr) {
  DCHECK(ptr != NULL);
  size_t num_bytes = mspace_usable_size(mspace_, ptr);
  mspace_free(mspace_, ptr);
  return num_bytes;
}

size_t Space::AllocationSize(const Object* obj) {
  return mspace_usable_size(mspace_, obj) + kChunkOverhead;
}

void Space::DontNeed(void* start, void* end, void* num_bytes) {
  start = (void*)RoundUp((uintptr_t)start, kPageSize);
  end = (void*)RoundDown((uintptr_t)end, kPageSize);
  if (start >= end) {
    return;
  }
  size_t length = reinterpret_cast<byte*>(end) - reinterpret_cast<byte*>(start);
  int result = madvise(start, length, MADV_DONTNEED);
  if (result == -1) {
    PLOG(WARNING) << "madvise failed";
  } else {
    *reinterpret_cast<size_t*>(num_bytes) += length;
  }
}

void Space::Trim() {
  CHECK(mspace_ != NULL);
  mspace_trim(mspace_, 0);
  size_t num_bytes_released = 0;
  mspace_walk_free_pages(mspace_, DontNeed, &num_bytes_released);
}

size_t Space::MaxAllowedFootprint() {
  return mspace_max_allowed_footprint(mspace_);
}

void Space::Grow(size_t new_size) {
  UNIMPLEMENTED(FATAL);
}

}  // namespace art
