/*
 * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "adlc.hpp"

void* AdlAllocateHeap(size_t size) {
  unsigned char* ptr = (unsigned char*) malloc(size);
  if (ptr == nullptr && size != 0) {
    fprintf(stderr, "Error: Out of memory in ADLC\n"); // logging can cause crash!
    fflush(stderr);
    exit(1);
  }
  return ptr;
}

void* AdlReAllocateHeap(void* old_ptr, size_t size) {
  unsigned char* ptr = (unsigned char*) realloc(old_ptr, size);
  if (ptr == nullptr && size != 0) {
    fprintf(stderr, "Error: Out of memory in ADLC\n"); // logging can cause crash!
    fflush(stderr);
    exit(1);
  }
  return ptr;
}

void* AdlChunk::operator new(size_t requested_size, size_t length) throw() {
  assert(requested_size <= SIZE_MAX - length, "overflow");
  return AdlCHeapObj::operator new(requested_size + length);
}

void  AdlChunk::operator delete(void* p, size_t length) {
  AdlCHeapObj::operator delete(p);
}

AdlChunk::AdlChunk(size_t length) {
  _next = nullptr;      // Chain on the linked list
  _len  = length;       // Save actual size
}

//------------------------------chop-------------------------------------------
void AdlChunk::chop() {
  AdlChunk *k = this;
  while( k ) {
    AdlChunk *tmp = k->_next;
    free(k);                    // Free chunk (was malloc'd)
    k = tmp;
  }
}

void AdlChunk::next_chop() {
  _next->chop();
  _next = nullptr;
}

//------------------------------AdlArena------------------------------------------
AdlArena::AdlArena( size_t init_size ) {
  init_size = (init_size+3) & ~3;
  _first = _chunk = new (init_size) AdlChunk(init_size);
  _hwm = _chunk->bottom();      // Save the cached hwm, max
  _max = _chunk->top();
  set_size_in_bytes(init_size);
}

AdlArena::AdlArena() {
  _first = _chunk = new (AdlChunk::init_size) AdlChunk(AdlChunk::init_size);
  _hwm = _chunk->bottom();      // Save the cached hwm, max
  _max = _chunk->top();
  set_size_in_bytes(AdlChunk::init_size);
}

AdlArena::AdlArena( AdlArena *a )
: _chunk(a->_chunk), _hwm(a->_hwm), _max(a->_max), _first(a->_first) {
  set_size_in_bytes(a->size_in_bytes());
}

//------------------------------used-------------------------------------------
// Total of all AdlChunks in arena
size_t AdlArena::used() const {
  size_t sum = _chunk->_len - (_max-_hwm); // Size leftover in this AdlChunk
  AdlChunk *k = _first;
  while( k != _chunk) {         // Whilst have AdlChunks in a row
    sum += k->_len;             // Total size of this AdlChunk
    k = k->_next;               // Bump along to next AdlChunk
  }
  return sum;                   // Return total consumed space.
}

//------------------------------grow-------------------------------------------
// Grow a new AdlChunk
void* AdlArena::grow( size_t x ) {
  // Get minimal required size.  Either real big, or even bigger for giant objs
  size_t len = max(x, AdlChunk::size);

  AdlChunk *k = _chunk;         // Get filled-up chunk address
  _chunk = new (len) AdlChunk(len);

  if( k ) k->_next = _chunk;    // Append new chunk to end of linked list
  else _first = _chunk;
  _hwm  = _chunk->bottom();     // Save the cached hwm, max
  _max =  _chunk->top();
  set_size_in_bytes(size_in_bytes() + len);
  void* result = _hwm;
  _hwm += x;
  return result;
}

//------------------------------calloc-----------------------------------------
// Allocate zeroed storage in AdlArena
void *AdlArena::Acalloc( size_t items, size_t x ) {
  assert(items <= SIZE_MAX / x, "overflow");
  size_t z = items*x;   // Total size needed
  void *ptr = Amalloc(z);       // Get space
  memset( ptr, 0, z );          // Zap space
  return ptr;                   // Return space
}

//------------------------------realloc----------------------------------------
static size_t pointer_delta(const void *left, const void *right) {
  assert(left >= right, "pointer delta underflow");
  return (uintptr_t)left - (uintptr_t)right;
}

// Reallocate storage in AdlArena.
void *AdlArena::Arealloc( void *old_ptr, size_t old_size, size_t new_size ) {
  char *c_old = (char*)old_ptr; // Handy name

  // Reallocating the latest allocation?
  if (c_old + old_size == _hwm) {
    assert(_chunk->bottom() <= c_old, "invariant");

    // Reallocate in place if it fits. Also handles shrinking
    if (pointer_delta(_max, c_old) >= new_size) {
      _hwm = c_old + new_size;
      return c_old;
    }
  } else if (new_size <= old_size) { // Shrink in place
    return c_old;
  }

  // Oops, got to relocate guts
  void *new_ptr = Amalloc(new_size);
  memcpy( new_ptr, c_old, old_size );
  Afree(c_old,old_size);        // Mostly done to keep stats accurate
  return new_ptr;
}

//------------------------------reset------------------------------------------
// Reset this AdlArena to empty, and return this AdlArenas guts in a new AdlArena.
AdlArena *AdlArena::reset(void) {
  AdlArena *a = new AdlArena(this);   // New empty arena
  _first = _chunk = nullptr;    // Normal, new-arena initialization
  _hwm = _max = nullptr;
  return a;                     // Return AdlArena with guts
}

//------------------------------contains---------------------------------------
// Determine if pointer belongs to this AdlArena or not.
bool AdlArena::contains( const void *ptr ) const {
  if( (void*)_chunk->bottom() <= ptr && ptr < (void*)_hwm )
    return true;                // Check for in this chunk
  for( AdlChunk *c = _first; c; c = c->_next )
    if( (void*)c->bottom() <= ptr && ptr < (void*)c->top())
      return true;              // Check for every chunk in AdlArena
  return false;                 // Not in any AdlChunk, so not in AdlArena
}

//-----------------------------------------------------------------------------
// CHeapObj

void* AdlCHeapObj::operator new(size_t size) throw() {
  return (void *) AdlAllocateHeap(size);
}

void AdlCHeapObj::operator delete(void* p){
 free(p);
}
