X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fmm%2Fboehm.c;h=411cb6c70d9e5d6aa2ff3f0ceb1374c9e9875619;hb=c4a562a04fbf744add618b217deca1a4c6461d8b;hp=fb9800452155b8fe24f93672ddcbd3444f39f5ff;hpb=d6f3d91d455659f715248fb1727274c05f8c0b84;p=cacao.git diff --git a/src/mm/boehm.c b/src/mm/boehm.c index fb9800452..411cb6c70 100644 --- a/src/mm/boehm.c +++ b/src/mm/boehm.c @@ -1,9 +1,7 @@ -/* mm/boehm.c - interface for boehm gc +/* src/mm/boehm.c - interface for boehm gc - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 - R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, - M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, - P. Tomsich, J. Wenninger + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -19,166 +17,246 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. - Contact: cacao@complang.tuwien.ac.at +*/ - Authors: Stefan Ring - $Id: boehm.c 897 2004-01-21 00:49:42Z stefan $ +#include "config.h" -*/ +#include +#if defined(ENABLE_THREADS) && defined(__LINUX__) +#define GC_LINUX_THREADS +#endif +#if defined(ENABLE_THREADS) && defined(__IRIX__) +#define GC_IRIX_THREADS +#endif +#if defined(ENABLE_THREADS) && defined(__DARWIN__) +#define GC_DARWIN_THREADS +#endif -#include "main.h" -#include "boehm.h" -#include "global.h" -#include "native.h" -#include "asmpart.h" -#include "builtin.h" -#include "threads/thread.h" -#include "toolbox/loging.h" +#include "boehm-gc/include/gc.h" +#include "mm/gc-common.h" +#include "mm/memory.h" -/* this is temporary workaround */ -#if defined(__X86_64__) -#define GC_DEBUG -#endif +#include "toolbox/logging.h" -#include "gc.h" +#include "vm/builtin.h" +#include "vm/exceptions.h" +#include "vm/finalizer.h" +#include "vm/global.h" +#include "vm/stringlocal.h" +#include "vm/vm.h" +#include "vmcore/loader.h" +#include "vmcore/options.h" +#include "vmcore/rt-timing.h" -static void *stackcall_twoargs(struct otherstackcall *p) -{ - return (*p->p2)(p->p, p->l); -} +/* global variables ***********************************************************/ -static void *stackcall_malloc(void *p, u4 bytelength) -{ - return GC_MALLOC(bytelength); -} +static bool in_gc_out_of_memory = false; /* is GC out of memory? */ -static void *stackcall_malloc_atomic(void *p, u4 bytelength) -{ - return GC_MALLOC_ATOMIC(bytelength); -} +/* prototype static functions *************************************************/ + +static void gc_ignore_warnings(char *msg, GC_word arg); + +/* gc_init ********************************************************************* -static void *stackcall_malloc_uncollectable(void *p, u4 bytelength) + Initializes the boehm garbage collector. + +*******************************************************************************/ + +void gc_init(size_t heapmaxsize, size_t heapstartsize) { - return GC_MALLOC_UNCOLLECTABLE(bytelength); + size_t heapcurrentsize; + + TRACESUBSYSTEMINITIALIZATION("gc_init"); + + /* just to be sure (should be set to 1 by JAVA_FINALIZATION macro) */ + + GC_java_finalization = 1; + + /* Ignore pointers that do not point to the start of an object. */ + + GC_all_interior_pointers = 0; + + /* suppress warnings */ + + GC_set_warn_proc(gc_ignore_warnings); + + /* install a GC notifier */ + + GC_finalize_on_demand = 1; + GC_finalizer_notifier = finalizer_notify; + + /* define OOM function */ + + GC_oom_fn = gc_out_of_memory; + + GC_INIT(); + + /* set the maximal heap size */ + + GC_set_max_heap_size(heapmaxsize); + + /* set the initial heap size */ + + heapcurrentsize = GC_get_heap_size(); + + if (heapstartsize > heapcurrentsize) + GC_expand_hp(heapstartsize - heapcurrentsize); } -static void *stackcall_realloc(void *p, u4 bytelength) +static void gc_ignore_warnings(char *msg, GC_word arg) { - return GC_REALLOC(p, bytelength); } -static void *stackcall_free(void *p, u4 bytelength) + +void *heap_alloc_uncollectable(size_t size) { - GC_FREE(p); - return NULL; -} + void *p; + p = GC_MALLOC_UNCOLLECTABLE(size); -#if defined(USE_THREADS) && !defined(NATIVE_THREADS) -#define MAINTHREADCALL(r,m,pp,ll) \ - if (currentThread == NULL || currentThread == mainThread) { \ - r = m(pp, ll); \ - } else { \ - struct otherstackcall sc; \ - sc.p2 = m; \ - sc.p = pp; \ - sc.l = ll; \ - r = (*asm_switchstackandcall)(CONTEXT(mainThread).usedStackTop, \ - stackcall_twoargs, \ - (void**)&(CONTEXT(currentThread).usedStackTop), &sc); \ - } -#else -#define MAINTHREADCALL(r,m,pp,ll) \ - { r = m(pp, ll); } -#endif + /* clear allocated memory region */ + MSET(p, 0, uint8_t, size); -void *heap_alloc_uncollectable(u4 bytelength) -{ - void *result; - MAINTHREADCALL(result, stackcall_malloc_uncollectable, NULL, bytelength); - return result; + return p; } -void runboehmfinalizer(void *o, void *p) -{ - java_objectheader *ob = (java_objectheader *) o; - asm_calljavafunction(ob->vftbl->class->finalizer, ob, NULL, NULL, NULL); - - /* if we had an exception in the finalizer, ignore it */ - *exceptionptr = NULL; -} +/* heap_alloc ****************************************************************** + Allocates memory on the Java heap. -void *heap_allocate(u4 bytelength, bool references, methodinfo *finalizer) +*******************************************************************************/ + +void *heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect) { - void *result; + void *p; +#if defined(ENABLE_RT_TIMING) + struct timespec time_start, time_end; +#endif - if (references) { - MAINTHREADCALL(result, stackcall_malloc, NULL, bytelength); + RT_TIMING_GET_TIME(time_start); - } else { - MAINTHREADCALL(result, stackcall_malloc_atomic, NULL, bytelength); - } + /* We can't use a bool here for references, as it's passed as a + bitmask in builtin_new. Thus we check for != 0. */ + + if (references != 0) + p = GC_MALLOC(size); + else + p = GC_MALLOC_ATOMIC(size); + + if (p == NULL) + return NULL; + + if (finalizer != NULL) + GC_REGISTER_FINALIZER_NO_ORDER(p, finalizer_run, 0, 0, 0); - if (finalizer) - GC_REGISTER_FINALIZER(result, runboehmfinalizer, 0, 0, 0); + /* clear allocated memory region */ - return (u1*) result; + MSET(p, 0, uint8_t, size); + + RT_TIMING_GET_TIME(time_end); + RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_GC_ALLOC); + + return p; } -void *heap_reallocate(void *p, u4 bytelength) +void heap_free(void *p) { - void *result; + GC_FREE(p); +} - MAINTHREADCALL(result, stackcall_realloc, p, bytelength); +void gc_call(void) +{ + if (opt_verbosegc) + dolog("Garbage Collection: previous/now = %d / %d ", + 0, 0); - return result; + GC_gcollect(); } -void heap_free(void *p) + +int64_t gc_get_heap_size(void) { - void *result; + return GC_get_heap_size(); +} + - MAINTHREADCALL(result, stackcall_free, p, 0); +int64_t gc_get_free_bytes(void) +{ + return GC_get_free_bytes(); } -void heap_init(u4 size, u4 startsize, void **stackbottom) +/* gc_get_total_bytes ********************************************************** + + Returns the number of total bytes currently used on the Java heap. + +*******************************************************************************/ + +int64_t gc_get_total_bytes(void) { - GC_INIT(); + return GC_get_total_bytes(); } -void heap_close() +int64_t gc_get_max_heap_size(void) { + return GC_get_max_heap_size(); } -void gc_init() +void gc_invoke_finalizers(void) { + GC_invoke_finalizers(); } -void gc_call() +void gc_finalize_all(void) { - if (collectverbose) - dolog("Garbage Collection: previous/now = %d / %d ", - 0, 0); + GC_finalize_all(); +} - GC_gcollect(); + +/* gc_out_of_memory ************************************************************ + + This function is called when boehm detects that it is OOM. + +*******************************************************************************/ + +void *gc_out_of_memory(size_t bytes_requested) +{ + /* if this happens, we are REALLY out of memory */ + + if (in_gc_out_of_memory) { + /* this is all we can do... */ + vm_abort("gc_out_of_memory: out of memory"); + } + + in_gc_out_of_memory = true; + + /* try to release some memory */ + + gc_call(); + + /* now instantiate the exception */ + + exceptions_throw_outofmemoryerror(); + + in_gc_out_of_memory = false; + + return NULL; }