| //===----------- 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 STATIC_TRACER(type) staticTracer(type* obj) |
| #define TRACER tracer() |
| #define PARENT_TRACER tracer() |
| #define MARK_AND_TRACE markAndTrace() |
| #define CALL_TRACER tracer() |
| |
| namespace mvm { |
| class Thread; |
| } |
| |
| 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: |
| |
| static void initialise(); |
| static void destroy() {} |
| |
| 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(mvm::Thread*); |
| |
| static void remove_my_thread(mvm::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()); |
| } |
| |
| static bool isLive() { |
| return true; |
| } |
| }; |
| |
| |
| #endif |