//===----------- VmkitGC.cpp - Garbage Collection Interface -----------------===//
//
//                     The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "VmkitGC.h"
#include "MutatorThread.h"
#include "vmkit/VirtualMachine.h"

#include <set>

using namespace vmkit;

static vmkit::SpinLock lock;
std::set<gc*> __InternalSet__;
int Collector::verbose = 0;

extern "C" void* prealloc(uint32_t sz) {
  gc* res = 0;
  llvm_gcroot(res, 0);
  gcHeader* head = 0;

  sz = llvm::RoundUpToAlignment(sz, sizeof(void*));
  head = (gcHeader*) malloc(sz);
  memset((void*)head, 0, sz);
  res = head->toReference();

  lock.acquire();
  __InternalSet__.insert(res);
  lock.release();

  return res;
}

extern "C" void postalloc(gc* obj, void* type, uint32_t size) {
	llvm_gcroot(obj, 0);
	vmkit::Thread::get()->MyVM->setType(obj, type);
}

extern "C" void* vmkitgcmalloc(uint32_t sz, void* type) {
  gc* res = 0;
  llvm_gcroot(res, 0);
  sz += gcHeader::hiddenHeaderSize();
  res = (gc*) prealloc(sz);
  postalloc(res, type, sz);
  return res;
}

extern "C" void* vmkitgcmallocUnresolved(uint32_t sz, void* type) {
	gc* res = NULL;
	llvm_gcroot(res, 0);
	res = (gc*)vmkitgcmalloc(sz, type);
	vmkit::Thread::get()->MyVM->addFinalizationCandidate(res);
	return res;
}

/******************************************************************************
 * Optimized gcmalloc for VT based object layout.                             *
 *****************************************************************************/

extern "C" void* VTgcmalloc(uint32_t sz, void* VT) {
  gc* res = 0;
  llvm_gcroot(res, 0);
  gcHeader* head = 0;
  sz += gcHeader::hiddenHeaderSize();
  sz = llvm::RoundUpToAlignment(sz, sizeof(void*));
  head = (gcHeader*) malloc(sz);
  memset((void*)head, 0, sz);
  res = head->toReference();

  lock.acquire();
  __InternalSet__.insert(res);
  lock.release();

  VirtualTable::setVirtualTable(res, (VirtualTable*)VT);
  return res;
}

extern "C" void* VTgcmallocUnresolved(uint32_t sz, void* VT) {
	gc* res = NULL;
	llvm_gcroot(res, 0);
	res = (gc*)VTgcmalloc(sz, VT);
	if (((VirtualTable*)VT)->hasDestructor())
		vmkit::Thread::get()->MyVM->addFinalizationCandidate(res);
	return res;
}

/*****************************************************************************/

// Do not insert MagicArray ref to InternalSet of references.
extern "C" void* AllocateMagicArray(int32_t sz, void* length) {
	gc* res = 0;
	llvm_gcroot(res, 0);
	gcHeader* head = 0;
	sz += gcHeader::hiddenHeaderSize();
	head = (gcHeader*)malloc(sz);
	memset((void*)head, 0, sz);
	res = head->toReference();
	vmkit::Thread::get()->MyVM->setType(res, length);
	return res;
}

extern "C" void addFinalizationCandidate(gc* obj) {
  llvm_gcroot(obj, 0);
  vmkit::Thread::get()->MyVM->addFinalizationCandidate(obj);
}

void* Collector::begOf(gc* obj) {
  llvm_gcroot(obj, 0);
  lock.acquire();
  std::set<gc*>::iterator I = __InternalSet__.find(obj);
  std::set<gc*>::iterator E = __InternalSet__.end();
  lock.release();
    
  if (I != E) return obj;
  return 0;
}

void MutatorThread::init(Thread* _th) {
  MutatorThread* th = (MutatorThread*)_th;
  th->realRoutine(_th);
}

bool Collector::isLive(gc* ptr, word_t closure) {
  abort();
  return false;
}

void Collector::scanObject(FrameInfo* FI, void** ptr, word_t closure) {
  abort();
}
 
void Collector::markAndTrace(void* source, void* ptr, word_t closure) {
  abort();
}
  
void Collector::markAndTraceRoot(void* source, void* ptr, word_t closure) {
  abort();
}

gc* Collector::retainForFinalize(gc* val, word_t closure) {
  abort();
  return NULL;
}
  
gc* Collector::retainReferent(gc* val, word_t closure) {
  abort();
  return NULL;
}
  
gc* Collector::getForwardedFinalizable(gc* val, word_t closure) {
  abort();
  return NULL;
}
  
gc* Collector::getForwardedReference(gc* val, word_t closure) {
  abort();
  return NULL;
}
  
gc* Collector::getForwardedReferent(gc* val, word_t closure) {
  abort();
  return NULL;
}

extern "C" void arrayWriteBarrier(void* ref, void** ptr, void* value) {
  *ptr = value;
}

extern "C" void fieldWriteBarrier(void* ref, void** ptr, void* value) {
  *ptr = value;
}

extern "C" void nonHeapWriteBarrier(void** ptr, void* value) {
  *ptr = value;
}


void Collector::objectReferenceWriteBarrier(gc* ref, gc** slot, gc* value) {
  llvm_gcroot(ref, 0);
  llvm_gcroot(value, 0);
  *slot = value;
}

void Collector::objectReferenceArrayWriteBarrier(gc* ref, gc** slot, gc* value) {
  llvm_gcroot(ref, 0);
  llvm_gcroot(value, 0);
  *slot = value;
}

void Collector::objectReferenceNonHeapWriteBarrier(gc** slot, gc* value) {
  llvm_gcroot(value, 0);
  *slot = value;
}

bool Collector::objectReferenceTryCASBarrier(gc*ref, gc** slot, gc* old, gc* value) {
  gc* res = NULL;
  llvm_gcroot(res, 0);
  llvm_gcroot(ref, 0);
  llvm_gcroot(old, 0);
  llvm_gcroot(value, 0);
  res = __sync_val_compare_and_swap(slot, old, value);
  return (old == res);
}

void Collector::collect() {
  // Do nothing.
}

void Collector::initialise(int argc, char** argv) {
}

bool Collector::needsWriteBarrier() {
  return false;
}

bool Collector::needsNonHeapWriteBarrier() {
  return false;
}
