// Copyright 2011 Google Inc. All Rights Reserved.
// Author: cshapiro@google.com (Carl Shapiro)

#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) {
  LOG(FATAL) << "Unimplemented";
}

}  // namespace art
