X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fmm%2Fboehm.c;h=e7c44aa65dee3861c4c8673d1d60982450e8dcce;hb=7beb1bd2aaeaaed65d9b7eb7ca6fcba6036f0800;hp=4cbc9f80e89588c1b9f3c67b546464628a90e5a7;hpb=b5da742cef33e6a7614ae1b58345e8461ef8bef8;p=cacao.git diff --git a/src/mm/boehm.c b/src/mm/boehm.c index 4cbc9f80e..e7c44aa65 100644 --- a/src/mm/boehm.c +++ b/src/mm/boehm.c @@ -1,62 +1,110 @@ -/* 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 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 211 2003-02-03 13:06:27Z 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., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. -*******************************************************************************/ + Contact: cacao@complang.tuwien.ac.at + + Authors: Stefan Ring + + Changes: Christian Thalinger + + $Id: boehm.c 2896 2005-07-04 20:38:33Z twisti $ + +*/ -#include "global.h" -#include "threads/thread.h" +#if defined(USE_THREADS) && defined(NATIVE_THREADS) && defined(__LINUX__) +#define GC_LINUX_THREADS +#endif +#if defined(USE_THREADS) && defined(NATIVE_THREADS) && defined(__IRIX__) +#define GC_IRIX_THREADS +#endif -#include "gc.h" +#include "boehm-gc/include/gc.h" +#include "mm/boehm.h" -void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, void *); +#if defined(USE_THREADS) +# if defined(NATIVE_THREADS) +# include "threads/native/threads.h" +# else +# include "threads/green/threads.h" +# endif +#endif -struct otherstackcall; +#include "toolbox/logging.h" +#include "vm/options.h" +#include "vm/builtin.h" +#include "vm/exceptions.h" +#include "vm/global.h" +#include "vm/loader.h" +#include "vm/stringlocal.h" +#include "vm/tables.h" +#include "vm/jit/asmpart.h" -typedef void *(*calltwoargs)(void *, u4); -struct otherstackcall { - calltwoargs p2; - void *p; - u4 l; -}; +static bool in_gc_out_of_memory = false; /* is GC out of memory? */ -static void *stackcall_twoargs(struct otherstackcall *p) + +static void +#ifdef __GNUC__ + __attribute__ ((unused)) +#endif +*stackcall_twoargs(struct otherstackcall *p) { return (*p->p2)(p->p, p->l); } + static void *stackcall_malloc(void *p, u4 bytelength) { return GC_MALLOC(bytelength); } + static void *stackcall_malloc_atomic(void *p, u4 bytelength) { return GC_MALLOC_ATOMIC(bytelength); } + static void *stackcall_malloc_uncollectable(void *p, u4 bytelength) { return GC_MALLOC_UNCOLLECTABLE(bytelength); } + static void *stackcall_realloc(void *p, u4 bytelength) { return GC_REALLOC(p, bytelength); } +static void *stackcall_free(void *p, u4 bytelength) +{ + GC_FREE(p); + return NULL; +} + + +#if defined(USE_THREADS) && !defined(NATIVE_THREADS) #define MAINTHREADCALL(r,m,pp,ll) \ if (currentThread == NULL || currentThread == mainThread) { \ r = m(pp, ll); \ @@ -69,6 +117,11 @@ static void *stackcall_realloc(void *p, u4 bytelength) 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) { @@ -77,46 +130,155 @@ void *heap_alloc_uncollectable(u4 bytelength) return result; } -void *heap_allocate (u4 bytelength, bool references, methodinfo *finalizer) + +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; +} + + +void *heap_allocate(u4 bytelength, bool references, methodinfo *finalizer) { void *result; - if (references, 1) - { MAINTHREADCALL(result, stackcall_malloc, NULL, bytelength); } - else - { MAINTHREADCALL(result, stackcall_malloc_atomic, NULL, bytelength); } + + if (references) { + MAINTHREADCALL(result, stackcall_malloc, NULL, bytelength); + + } else { + MAINTHREADCALL(result, stackcall_malloc_atomic, NULL, bytelength); + } + + if (!result) { + return NULL; + } + + if (finalizer) + GC_REGISTER_FINALIZER(result, runboehmfinalizer, 0, 0, 0); + return (u1*) result; } + void *heap_reallocate(void *p, u4 bytelength) { void *result; + MAINTHREADCALL(result, stackcall_realloc, p, bytelength); + return result; } -void heap_init (u4 size, u4 startsize, void **stackbottom) +void heap_free(void *p) +{ + void *result; + + MAINTHREADCALL(result, stackcall_free, p, 0); +} + +static void gc_ignore_warnings(char *msg, GC_word arg) +{ +} + +void gc_init(u4 heapmaxsize, u4 heapstartsize) +{ + size_t heapcurrentsize; + + 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); + } + + /* define OOM function */ + GC_oom_fn = gc_out_of_memory; + + /* suppress warnings */ + GC_set_warn_proc(gc_ignore_warnings); +} + + +void gc_call(void) { + if (opt_verbosegc) + dolog("Garbage Collection: previous/now = %d / %d ", + 0, 0); + + GC_gcollect(); } -void heap_close() + +s8 gc_get_heap_size(void) { + return GC_get_heap_size(); } -void heap_addreference (void **reflocation) + +s8 gc_get_free_bytes(void) { + return GC_get_free_bytes(); } -int collectverbose; -void gc_init() +s8 gc_get_max_heap_size(void) { + return GC_get_max_heap_size(); } -void gc_call() + +void gc_invoke_finalizers(void) { - GC_gcollect(); + GC_invoke_finalizers(); } + +void gc_finalize_all(void) +{ + GC_finalize_all(); +} + + +/* 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... */ + throw_cacao_exception_exit(string_java_lang_InternalError, + "Out of memory"); + } + + in_gc_out_of_memory = true; + + /* try to release some memory */ + + gc_call(); + + /* now instantiate the exception */ + + *exceptionptr = new_exception(string_java_lang_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