/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program 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 for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include "util.h"
#include "HeapMap.h"

#define HEAPCHUNKSZ     1024 // number of HeapObj's in a chunk
#define HEAPCHAINS      9192 // number of address-based chains
#define hash(x)         (((x) >> 6) % HEAPCHAINS)

typedef struct HeapObj
{
  uint64_t addr;
  uint64_t size;
  long val;
  HeapObj *next;
} HeapObj;

typedef struct HeapChunk
{
  void *addr;
  HeapChunk *next;
} HeapChunk;

HeapMap::HeapMap ()
{
  chunks = NULL;
  empty = NULL;
  chain = new HeapObj*[HEAPCHAINS];
  for (int i = 0; i < HEAPCHAINS; i++)
    chain[i] = NULL;

  mmaps = new HeapObj;
  mmaps->addr = (uint64_t) 0;
  mmaps->size = (uint64_t) 0;
  mmaps->val = -1;
  mmaps->next = NULL;
}

HeapMap::~HeapMap ()
{
  // free up all the chunks
  HeapChunk *c = chunks;
  while (c != NULL)
    {
      HeapChunk *next = c->next;
      delete c;
      c = next;
    }
  delete[] chain;
  delete mmaps;
}

void
HeapMap::allocate (uint64_t addr, long val)
{
  // get a HeapObj, and set it up for the allocated block
  HeapObj *incoming = getHeapObj ();
  incoming->addr = addr;
  incoming->val = val;
  incoming->next = NULL;

  // determine which chain the block belongs on
  int ichain = (int) hash (addr);

  // if this is the first, just set it up and return
  if (chain[ichain] == NULL)
    {
      chain[ichain] = incoming;
      return;
    }
  // chain is non-empty -- find the slot for this one
  //  chain is maintained in reverse address order
  HeapObj *prev = NULL;
  HeapObj *next = chain[ichain];

  for (;;)
    {
      if ((next == NULL) || (next->addr < incoming->addr))
	{
	  // we've found the spot
	  incoming->next = next;
	  if (prev == NULL)
	    chain[ichain] = incoming;
	  else
	    prev->next = incoming;
	  return;
	}
      if (next->addr == incoming->addr)
	{
	  // error -- two blocks with same address active
	  //   ignore the new one
	  releaseHeapObj (incoming);
	  return;
	}
      // not yet, keep looking
      prev = next;
      next = next->next;
    }
}

long
HeapMap::deallocate (uint64_t addr)
{
  int ichain = (int) hash (addr);
  HeapObj *cur = chain[ichain];
  HeapObj *prev = NULL;
  while (cur != NULL)
    {
      if (cur->addr == addr)
	{
	  // we've found the block
	  long val = cur->val;

	  // delete the block from the chain
	  if (prev == NULL)
	    chain[ichain] = cur->next;
	  else
	    prev->next = cur->next;
	  releaseHeapObj (cur);
	  return val;
	}
      prev = cur;
      cur = cur->next;
    }

  // block not found
  return 0;
}

void
HeapMap::allocateChunk ()
{
  // allocate the memory
  HeapChunk *c = new HeapChunk;
  HeapObj *newc = new HeapObj[HEAPCHUNKSZ];

  // set up the chunk, and queue it for destructor's use
  c->addr = (void *) newc;
  c->next = chunks;
  chunks = c;

  // Initialize the HeapObj's in the chunk to one chain
  // last entry is left NULL, terminating the chain
  for (int i = 0; i < (HEAPCHUNKSZ - 1); i++)
    newc[i].next = newc + i + 1;
  newc[HEAPCHUNKSZ - 1].next = NULL;

  // put that chain on the empty queue
  empty = newc;
}

HeapObj *
HeapMap::getHeapObj ()
{
  if (empty == NULL)
    allocateChunk ();
  HeapObj *ret = empty;
  empty = ret->next;
  return ret;
}

void
HeapMap::releaseHeapObj (HeapObj *obj)
{
  obj->next = empty;
  empty = obj;
}

UnmapChunk*
HeapMap::mmap (uint64_t addr, int64_t size, long val)
{
  HeapObj *incoming = getHeapObj ();
  incoming->addr = addr;
  incoming->size = size;
  incoming->val = val;
  incoming->next = NULL;
  UnmapChunk* list = process (incoming, addr, size);
  return list;
}

UnmapChunk*
HeapMap::munmap (uint64_t addr, int64_t size)
{
  UnmapChunk* list = process (NULL, addr, size);
  return list;
}

UnmapChunk*
HeapMap::process (HeapObj *obj, uint64_t addr, int64_t size)
{
  // Some graphics are used to clarify the alignment of mmap regions
  // obj, shown as consecutive pages: "NNNNNN"
  // cur, shown as consecutive pages: "CCCCCC"

  // Find the first overlap, start of N is before end of C.  Examples:
  //   CCCCC
  //     NNNNN
  // or
  //   CCCCC
  //    NNN
  // or
  //   CCCCC
  //  NNNNN
  // or
  //   CCCCC
  //  NNNNNNN
  HeapObj *prev = mmaps;
  HeapObj *cur = prev->next;
  while (cur)
    {
      if (addr < cur->addr + cur->size)
	break;
      prev = cur;
      cur = prev->next;
    }

  // None found
  if (cur == NULL)
    {
      prev->next = obj;
      return NULL;
    }

  UnmapChunk* list = NULL;
  if (addr > cur->addr)
    {
      if (cur->addr + cur->size <= addr + size)
	{
	  // Process overlap on the left (low side) of new allocation
	  // New range: N-start to C-end (gets freed below)
	  prev = cur;
	  cur = getHeapObj ();
	  cur->addr = addr;
	  cur->size = prev->addr + prev->size - addr;
	  cur->val = prev->val;
	  cur->next = prev->next;

	  // Truncate range: C-start to N-start
	  prev->size = addr - prev->addr;
	}
      else
	{
	  // Process new allocation that fits completely within old allocation
	  // New range: N-start to N-end (freed below)
	  int64_t c_end = cur->addr + cur->size;
	  prev = cur;
	  cur = getHeapObj ();
	  cur->addr = addr;
	  cur->size = size;
	  cur->val = prev->val;
	  cur->next = prev->next;

	  // Truncate range: C-start to N-start
	  prev->size = addr - prev->addr;

	  // New range: N-end to C-end.
	  HeapObj *next = getHeapObj ();
	  next->addr = addr + size;
	  next->size = c_end - next->addr;
	  next->val = cur->val;
	  next->next = cur->next;
	  cur->next = next;
	}
    }

  // Process all full overlaps.
  // Copy details of cur to UnmapChunk list, remove cur from mmaps
  while (cur && cur->addr + cur->size <= addr + size)
    {

      UnmapChunk* uc = new UnmapChunk;
      uc->val = cur->val;
      uc->size = cur->size;
      uc->next = list;
      list = uc;

      HeapObj *t = cur;
      cur = cur->next;
      releaseHeapObj (t);
    }

  if (cur && cur->addr < addr + size)
    {
      // Process the last overlap (right side of new allocation)
      // Copy details of cur to UnmapChunk list
      UnmapChunk* uc = new UnmapChunk;
      uc->val = cur->val;
      uc->size = addr + size - cur->addr;
      uc->next = list;
      list = uc;

      // Truncate left side of cur
      cur->size -= uc->size;
      cur->addr = addr + size;
    }

  // Insert new allocation
  if (obj)
    {
      prev->next = obj;
      obj->next = cur;
    }
  else
    prev->next = cur;
  return list;
}
