//===----------- MvmGC.h - Garbage Collection Interface -------------------===//
//
//                     The Micro Virtual Machine
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//


#ifndef MVM_BOEHM_GC_H
#define MVM_BOEHM_GC_H

//#define GC_REDIRECT_TO_LOCAL
#include <stdlib.h>
#include <gc/gc_allocator.h>
//#include "gc/gc_local_alloc.h"
#include "gc/gc.h"

#define TRACER tracer()
#define PARENT_TRACER tracer()
#define MARK_AND_TRACE markAndTrace()

extern "C" void * GC_dlopen(const char *path, int mode) throw ();

#include "mvm/GC/GC.h"

#define  gc_new(Class)  __gc_new(Class::VT) Class
#define __gc_new new

class gc : public gcRoot {
public:

  void markAndTrace() const {}

  size_t  objectSize() const {
    gc_header * res = (gc_header*)(GC_base((void*)this));
    return (GC_size(res) - sizeof(gc_header));
  }

  void *  operator new(size_t sz, VirtualTable *VT) {
    gc_header * res = (gc_header*) GC_MALLOC(sz + sizeof(gc_header));
    res -> _XXX_vt= VT;
    
    destructor_t dest = res->getDestructor();
    if (dest)
      GC_register_finalizer_no_order(res, (void (*)(void*, void*))dest, NULL,
                                     NULL, NULL); 
    return res->_2gc();
  }

  void *  operator new(size_t sz) {
    return malloc(sz);
  }

  void    operator delete(void * p) {
    //GC_FREE(p);
  }

  void *  realloc(size_t n) {
    void * old = GC_base(this);
    gc_header * res = (gc_header*) GC_REALLOC(old, n + sizeof(gc_header));
    return res->_2gc();
  }

};
  
static int maxMem = 0;

class Collector {
public:

  typedef void (*markerFn)(void*);
  
  static void initialise(markerFn mark, void *base_sp);
  static void destroy() {}

  static void die_if_sigsegv_occured_during_collection(void *addr){}
  static int isStable(gc_lock_recovery_fct_t, int, int, int, int,
                                 int, int, int, int) { 
    return 1;
  }
  static unsigned int enable(unsigned int n) {
    int old = GC_dont_gc;
    if(n)
      GC_enable();
    else
      GC_disable();
    return !old;
  }

  static void gcStats(size_t &no, size_t &nbb) {
    no = 0;
    nbb = GC_get_heap_size(); 
  }
  
  static void maybeCollect() {
    GC_collect_a_little();
  }

  static void collect(void) {
    GC_gcollect();
  }
  
  static void inject_my_thread(void *sp);
  
  static void remove_my_thread() {}
  static Collector* allocate() { return 0; }

  static gc* begOf(const void *obj) {
    gc_header * a = (gc_header*)GC_base((void*)obj);
    if(a == NULL) return NULL;
    else return (gc*)a->_2gc();
  }

  inline static bool isObject(const void *o) {
    return begOf((void*)o);
  }
  

  static int getMaxMemory(void) { return maxMem; }
  
  static int getFreeMemory(void) {
    return GC_get_free_bytes(); 
  }

  static int getTotalMemory(void) {
    return GC_get_heap_size();
  }
  
  static void setMaxMemory(size_t size) {
    GC_set_max_heap_size(size);
    maxMem = size;
  }
  
  static void     setMinMemory(size_t size) {
    if(GC_get_heap_size() < size)
    GC_expand_hp(size - GC_get_heap_size());
  }
};


#endif
