blob: 67516c5bd3a85382d77c1519abdf1d1649a1ea93 [file] [log] [blame] [edit]
//===---------------- gc.cc - Mvm Garbage Collector -----------------------===//
//
// Mvm
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <setjmp.h>
#include <stdlib.h>
#include "mvm/GC/GC.h"
#include "gccollector.h"
#include "gcerror.h"
using namespace mvm;
#ifdef MULTIPLE_GC
#define COLLECTOR ((GCCollector*)(mvm::Thread::get()->GC))->
#else
#define COLLECTOR GCCollector::
#endif
typedef void (*memoryError_t)(unsigned int);
memoryError_t GCCollector::internMemoryError;
#ifdef MULTIPLE_GC
void gc::markAndTrace(Collector* GC) const {
((GCCollector*)GC)->markAndTrace((void*)this);
}
extern "C" void MarkAndTrace(gc* gc, Collector* GC) {
((GCCollector*)GC)->markAndTrace((void*)gc);
}
#else
void gc::markAndTrace() const {
GCCollector::markAndTrace((void*)this);
}
extern "C" void MarkAndTrace(gc* gc) {
GCCollector::markAndTrace((void*)gc);
}
#endif
size_t gc::objectSize() const {
return COLLECTOR objectSize((gc*)this);
}
void *gc::operator new(size_t sz, VirtualTable *vt) {
return COLLECTOR gcmalloc(vt, sz);
}
void *gc::operator new(size_t sz) {
return malloc(sz);
}
void gc::operator delete(void *) {
gcfatal(0, "never call directly a destructor.....");
}
void *gc::realloc(size_t n) {
return COLLECTOR gcrealloc(this, n);
}
#ifdef MULTIPLE_GC
size_t gc::objectSize(Collector* GC) const {
return ((GCCollector*)GC)->objectSize((gc*)this);
}
void *gc::operator new(size_t sz, VirtualTable *VT, Collector* GC) {
return ((GCCollector*)GC)->gcmalloc(VT, sz);
}
void *gc::operator new(size_t sz, Collector* GC) {
return malloc(sz);
}
void gc::operator delete(void *, Collector* GC) {
gcfatal(0, "never call directly a destructor.....");
}
void *gc::realloc(size_t n, Collector* GC) {
return ((GCCollector*)GC)->gcrealloc(this, n);
}
#endif
#undef COLLECTOR
#ifdef MULTIPLE_GC
#define COLLECTOR ((GCCollector*)this)->
#else
#define COLLECTOR GCCollector::
#endif
unsigned int Collector::enable(unsigned int n) {
return COLLECTOR enable(n);
}
int Collector::isStable(gc_lock_recovery_fct_t fct, int a0, int a1, int a2,
int a3, int a4, int a5, int a6, int a7) {
return COLLECTOR isStable(fct, a0, a1, a2, a3, a4, a5, a6, a7);
}
void Collector::die_if_sigsegv_occured_during_collection(void *addr) {
COLLECTOR die_if_sigsegv_occured_during_collection(addr);
}
void Collector::gcStats(size_t &no, size_t &nbb) {
COLLECTOR gcStats(&no, &nbb);
}
void Collector::initialise(markerFn marker, void *base_sp) {
#ifdef MULTIPLE_GC
GCCollector* GC = new GCCollector();
GCCollector::bootstrapGC = GC;
mvm::Thread::get()->GC = GC;
GC->initialise(marker);
GC->inject_my_thread(base_sp);
#else
GCCollector::initialise(marker);
GCCollector::inject_my_thread(base_sp);
#endif
mvm::Thread::get()->baseSP = base_sp;
}
void Collector::destroy() {
COLLECTOR destroy();
}
void Collector::inject_my_thread(void *base_sp) {
#ifdef HAVE_PTHREAD
COLLECTOR inject_my_thread(base_sp);
#endif
mvm::Thread::get()->baseSP = base_sp;
}
void Collector::maybeCollect() {
COLLECTOR maybeCollect();
}
void Collector::collect(void) {
COLLECTOR collect();
}
gc *Collector::begOf(const void *obj) {
return (gc*)COLLECTOR begOf((void*)obj);
}
int Collector::byteOffset(void *obj) {
int beg = (intptr_t)COLLECTOR begOf(obj);
intptr_t off = (intptr_t)obj;
return (off-beg);
}
void Collector::applyFunc(void (*func)(gcRoot *o, void *data), void *data) {
return COLLECTOR applyFunc(func, data);
}
int Collector::getMaxMemory(void){
return 0;
}
int Collector::getFreeMemory(void){
return 0;
}
int Collector::getTotalMemory(void){
return 0;
}
void Collector::setMaxMemory(size_t sz){
}
void Collector::setMinMemory(size_t sz){
}
void Collector::registerMemoryError(void (*func)(unsigned int)){
COLLECTOR internMemoryError = func;
//onMemoryError = &COLLECTOR defaultMemoryError;
}
void Collector::remove_my_thread() {
#ifdef HAVE_PTHREAD
COLLECTOR remove_thread(COLLECTOR threads->myloc());
#endif
}
#undef COLLECTOR
void GCThread::waitCollection() {
#if defined(MULTIPLE_GC)
#if defined(SERVICE_GC)
GCCollector* GC = GCCollector::collectingGC;
#else
GCCollector* GC = ((GCCollector*)mvm::Thread::get()->GC);
#endif
#define COLLECTOR GC->
#else
#define COLLECTOR GCCollector::
#endif
unsigned int cm = COLLECTOR current_mark;
if(Thread::self() != collector_tid) {
collectorGo();
while((COLLECTOR current_mark == cm) &&
(COLLECTOR status == COLLECTOR stat_collect))
_collectionCond.wait(&_stackLock);
}
}
#ifdef HAVE_PTHREAD
#undef COLLECTOR
void GCCollector::siggc_handler(int) {
#if defined(MULTIPLE_GC)
#if defined(SERVICE_GC)
GCCollector* GC = collectingGC;
#else
GCCollector* GC = ((GCCollector*)mvm::Thread::get()->GC);
#endif
#define COLLECTOR GC->
#else
#define COLLECTOR GCCollector::
#endif
GCThreadCollector *loc = COLLECTOR threads->myloc();
jmp_buf buf;
setjmp(buf);
COLLECTOR threads->stackLock();
if(!loc) /* a key is being destroyed */
COLLECTOR threads->another_mark();
else {
register unsigned int **cur = (unsigned int**)&buf;
register unsigned int **max = loc->base_sp();
GCChunkNode *node;
for(; cur<max; cur++) {
if((node = o2node(*cur)) && (!COLLECTOR isMarked(node))) {
node->remove();
node->append(COLLECTOR used_nodes);
COLLECTOR mark(node);
}
}
COLLECTOR threads->another_mark();
COLLECTOR threads->waitCollection();
}
COLLECTOR threads->stackUnlock();
#undef COLLECTOR
}
#endif // HAVE_PTHREAD
#ifdef MULTIPLE_GC
Collector* Collector::allocate() {
GCCollector* GC = new GCCollector();
GC->initialise(GCCollector::bootstrapGC->_marker);
return GC;
}
#endif // MULTIPLE_GC
#ifdef SERVICE_GC
Collector* Collector::getCollectorFromObject(const void* o) {
return (Collector*)GCCollector::o2node((void*)o)->meta;
}
#endif
#ifdef MULTIPLE_GC
extern "C" gc* gcmalloc(size_t sz, VirtualTable* VT, Collector* GC) {
return (gc*)((GCCollector*)GC)->gcmalloc(VT, sz);
}
#else
extern "C" gc* gcmalloc(size_t sz, VirtualTable* VT) {
return (gc*)GCCollector::gcmalloc(VT, sz);
}
#endif