X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fmm%2Fboehm.c;h=ebb9952ef75e395c19adc0a3d5808508ea9a2ced;hb=7681234b501eb1f9a7fb8fdcfec42368c807a8a8;hp=78d6e8716202966961a1ea4a51e57e50253362e5;hpb=a8ae43a22e6534a7c4ca44bba47456151fe4899c;p=cacao.git diff --git a/src/mm/boehm.c b/src/mm/boehm.c index 78d6e8716..ebb9952ef 100644 --- a/src/mm/boehm.c +++ b/src/mm/boehm.c @@ -1,127 +1,263 @@ -/* boehm.c ********************************************************************* +/* src/mm/boehm.c - interface for boehm gc - Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst + Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel, + C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, + E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, + J. Wenninger, Institut f. Computersprachen - TU Wien - See file COPYRIGHT for information on usage and disclaimer of warranties + This file is part of CACAO. - Contains the interface to the Boehm GC + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. - Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at - Changes: Andi Krall EMAIL: cacao@complang.tuwien.ac.at - Mark Probst EMAIL: cacao@complang.tuwien.ac.at - Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - Last Change: $Id: boehm.c 239 2003-02-27 09:56:30Z stefan $ + 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., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. + + $Id: boehm.c 8179 2007-07-05 11:21:08Z michi $ + +*/ -*******************************************************************************/ -#include "global.h" -#include "threads/thread.h" +#include "config.h" +#include "vm/types.h" -#include "gc.h" +#if defined(ENABLE_THREADS) && defined(__LINUX__) +#define GC_LINUX_THREADS +#endif +#if defined(ENABLE_THREADS) && defined(__IRIX__) +#define GC_IRIX_THREADS +#endif -void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, void *); +#include "boehm-gc/include/gc.h" +#include "mm/gc-common.h" +#include "mm/memory.h" -struct otherstackcall; +#include "toolbox/logging.h" -typedef void *(*calltwoargs)(void *, u4); +#include "vm/builtin.h" +#include "vm/exceptions.h" +#include "vm/finalizer.h" +#include "vm/global.h" +#include "vm/stringlocal.h" +#include "vm/vm.h" -struct otherstackcall { - calltwoargs p2; - void *p; - u4 l; -}; +#include "vmcore/loader.h" +#include "vmcore/options.h" +#include "vmcore/rt-timing.h" + + +/* global variables ***********************************************************/ + +static bool in_gc_out_of_memory = false; /* is GC out of memory? */ + + +/* prototype static functions *************************************************/ + +static void gc_ignore_warnings(char *msg, GC_word arg); -static void *stackcall_twoargs(struct otherstackcall *p) + +/* gc_init ********************************************************************* + + Initializes the boehm garbage collector. + +*******************************************************************************/ + +void gc_init(u4 heapmaxsize, u4 heapstartsize) { - return (*p->p2)(p->p, p->l); + size_t heapcurrentsize; + + /* 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_malloc(void *p, u4 bytelength) + +static void gc_ignore_warnings(char *msg, GC_word arg) { - return GC_MALLOC(bytelength); } -static void *stackcall_malloc_atomic(void *p, u4 bytelength) + +void *heap_alloc_uncollectable(u4 size) { - return GC_MALLOC_ATOMIC(bytelength); + void *p; + + p = GC_MALLOC_UNCOLLECTABLE(size); + + /* clear allocated memory region */ + + MSET(p, 0, u1, bytelength); + + return p; } -static void *stackcall_malloc_uncollectable(void *p, u4 bytelength) + +/* heap_alloc ****************************************************************** + + Allocates memory on the Java heap. + +*******************************************************************************/ + +void *heap_alloc(u4 size, u4 references, methodinfo *finalizer, bool collect) { - return GC_MALLOC_UNCOLLECTABLE(bytelength); + void *p; +#if defined(ENABLE_RT_TIMING) + struct timespec time_start, time_end; +#endif + + RT_TIMING_GET_TIME(time_start); + + /* 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(p, finalizer_run, 0, 0, 0); + + /* clear allocated memory region */ + + MSET(p, 0, u1, size); + + RT_TIMING_GET_TIME(time_end); + RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_GC_ALLOC); + + return p; } -static void *stackcall_realloc(void *p, u4 bytelength) + +void heap_free(void *p) { - return GC_REALLOC(p, bytelength); + GC_FREE(p); } -#ifdef USE_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 - -void *heap_alloc_uncollectable(u4 bytelength) +void gc_call(void) { - void *result; - MAINTHREADCALL(result, stackcall_malloc_uncollectable, NULL, bytelength); - return result; + if (opt_verbosegc) + dolog("Garbage Collection: previous/now = %d / %d ", + 0, 0); + + GC_gcollect(); } -void *heap_allocate (u4 bytelength, bool references, methodinfo *finalizer) + +s8 gc_get_heap_size(void) { - void *result; - if (references, 1) - { MAINTHREADCALL(result, stackcall_malloc, NULL, bytelength); } - else - { MAINTHREADCALL(result, stackcall_malloc_atomic, NULL, bytelength); } - return (u1*) result; + return GC_get_heap_size(); } -void *heap_reallocate(void *p, u4 bytelength) + +s8 gc_get_free_bytes(void) { - void *result; - MAINTHREADCALL(result, stackcall_realloc, p, bytelength); - return result; + 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. + +*******************************************************************************/ + +s8 gc_get_total_bytes(void) { + return GC_get_total_bytes(); } -void heap_close() + +s8 gc_get_max_heap_size(void) { + return GC_get_max_heap_size(); } -void heap_addreference (void **reflocation) + +void gc_invoke_finalizers(void) { + GC_invoke_finalizers(); } -int collectverbose; -void gc_init() +void gc_finalize_all(void) { + GC_finalize_all(); } -void gc_call() + +/* gc_out_of_memory ************************************************************ + + This function is called when boehm detects that it is OOM. + +*******************************************************************************/ + +void *gc_out_of_memory(size_t bytes_requested) { - GC_gcollect(); + /* 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; } + /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where