blob: 95acfb6ee99b8cdcfcbb8c3e25ddf1aaddb6e4d7 [file] [log] [blame]
//===----------- 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;
}