* src/mm/cacao-gc/final.h, src/mm/cacao-gc/final.c, src/mm/cacao-gc/rootset.h,
authormichi <none@none>
Mon, 26 Feb 2007 19:03:48 +0000 (19:03 +0000)
committermichi <none@none>
Mon, 26 Feb 2007 19:03:48 +0000 (19:03 +0000)
src/mm/cacao-gc/rootset.c: Added.
* src/mm/cacao-gc/Makefile.am: See above.

* src/mm/cacao-gc/gc.h (gc_notify_finalizer): Added.
* src/mm/cacao-gc/gc.c: Added finalization support.
* src/mm/cacao-gc/mark.c: Same as above. Rootset can contain "non-marking"
references now.

* src/mm/cacao-gc/heap.h, src/mm/cacao-gc/heap.c: Severe code cleanup,
this applies to almost all files.

--HG--
branch : exact-gc

13 files changed:
src/mm/cacao-gc/Makefile.am
src/mm/cacao-gc/compact.c
src/mm/cacao-gc/final.c [new file with mode: 0644]
src/mm/cacao-gc/final.h [new file with mode: 0644]
src/mm/cacao-gc/gc.c
src/mm/cacao-gc/gc.h
src/mm/cacao-gc/heap.c
src/mm/cacao-gc/heap.h
src/mm/cacao-gc/mark.c
src/mm/cacao-gc/mark.h
src/mm/cacao-gc/rootset.c [new file with mode: 0644]
src/mm/cacao-gc/rootset.h [new file with mode: 0644]
src/vm/jit/s390/md-asm.h

index b4ba11f116c83164b444ceeef3f916e707931332..fe27aa30668f1d3e007358823eebbf80a67885fe 100644 (file)
@@ -41,6 +41,8 @@ noinst_LTLIBRARIES = libgc.la
 libgc_la_SOURCES = \
        compact.c \
        compact.h \
+       final.c \
+       final.h \
        gc.c \
        gc.h \
        heap.c \
@@ -48,7 +50,9 @@ libgc_la_SOURCES = \
        mark.c \
        mark.h \
        region.c \
-       region.h
+       region.h \
+       rootset.c \
+       rootset.h
 
 
 ## Local variables:
index cb08a8ae57c05516da5e7b657358ca2d4aef1f7c..260146f37a8173809bf5bce6ef69c9f02575102a 100644 (file)
@@ -74,19 +74,27 @@ void compact_thread_rootset(rootset_t *rs, void *start, void *end)
        java_objectheader **refptr;
        int i;
 
-       GC_LOG2( printf("threading in rootset\n"); );
+       GC_LOG2( printf("threading in rootsets\n"); );
 
-       /* walk through the references of this rootset */
-       for (i = 0; i < rs->refcount; i++) {
+       /* walk through all rootsets */
+       while (rs) {
 
-               /* load the reference */
-               refptr = rs->refs[i];
-               ref = *( refptr );
+               /* walk through the references of this rootset */
+               for (i = 0; i < rs->refcount; i++) {
+
+                       /* load the reference */
+                       refptr = rs->refs[i];
+                       ref = *( refptr );
 
-               GC_LOG2( printf("\troot pointer to %p\n", (void *) ref); );
+                       GC_LOG2( printf("\troot pointer to %p\n", (void *) ref); );
 
-               /* thread the references */
-               GC_THREAD(ref, refptr, start, end);
+                       /* thread the references */
+                       GC_THREAD(ref, refptr, start, end);
+
+               }
+
+               /* skip to next rootset in chain */
+               rs = rs->next;
 
        }
 }
@@ -94,8 +102,7 @@ void compact_thread_rootset(rootset_t *rs, void *start, void *end)
 
 /* compact_thread_classes ******************************************************
 
-   Threads all the references from classinfo structures (static fields and
-   classloaders)
+   Threads all the references from classinfo structures (static fields)
 
    IN:
       start.....Region to be compacted start here
@@ -109,7 +116,7 @@ void compact_thread_classes(void *start, void *end)
        java_objectheader **refptr;
        classinfo          *c;
        fieldinfo          *f;
-       hashtable_classloader_entry *cle;
+       /*hashtable_classloader_entry *cle;*/
        void *sys_start, *sys_end;
        int i;
 
@@ -119,6 +126,7 @@ void compact_thread_classes(void *start, void *end)
        sys_start = heap_region_sys->base;
        sys_end = heap_region_sys->ptr;
 
+#if 0
        /* walk through all classloaders */
        for (i = 0; i < hashtable_classloader->size; i++) {
                cle = hashtable_classloader->ptr[i];
@@ -134,6 +142,7 @@ void compact_thread_classes(void *start, void *end)
                        cle = cle->hashlink;
                }
        }
+#endif
 
        /* walk through all classinfo blocks */
        for (c = sys_start; c < (classinfo *) sys_end; c++) {
@@ -327,6 +336,8 @@ u4 compact_move(u1 *old, u1 *new, u4 size)
        /* check if we need to attach the hashcode to the object */
        if (GC_TEST_FLAGS((java_objectheader *) new, HDRFLAG_HASH_TAKEN)) {
 
+               /* TODO: move this whole bunch to heap_attach_hashcode() */
+
                /* change the flags accordingly */
                GC_CLEAR_FLAGS((java_objectheader *) new, HDRFLAG_HASH_TAKEN);
                GC_SET_FLAGS((java_objectheader *) new, HDRFLAG_HASH_ATTACHED);
@@ -337,7 +348,7 @@ u4 compact_move(u1 *old, u1 *new, u4 size)
                *( (s4 *) (new + new_size - SIZEOF_VOID_P) ) = hashcode; /* TODO: clean this up */
 
                GC_ASSERT(new + SIZEOF_VOID_P < old);
-               GC_LOG( dolog("GC: Hash attached: %d (0x%08x) to new object at %p", hashcode, hashcode, new); );
+               GC_LOG2( dolog("GC: Hash attached: %d (0x%08x) to new object at %p", hashcode, hashcode, new); );
 
        }
 
@@ -365,7 +376,7 @@ void compact_me(rootset_t *rs, regioninfo_t *region)
        u4 o_size_new;
        u4 used;
 
-       GC_LOG( dolog("GC: Compaction Phase 1 started ..."); );
+       GC_LOG( dolog("GC: Compaction Phase 0 started ..."); );
 
        /* Phase 0:
         *  - thread all references in classes
@@ -373,6 +384,8 @@ void compact_me(rootset_t *rs, regioninfo_t *region)
        compact_thread_classes(region->base, region->ptr);
        compact_thread_rootset(rs, region->base, region->ptr);
 
+       GC_LOG( dolog("GC: Compaction Phase 1 started ..."); );
+
        /* Phase 1:
         *  - scan the heap
         *  - thread all references
@@ -382,7 +395,7 @@ void compact_me(rootset_t *rs, regioninfo_t *region)
                o = (java_objectheader *) ptr;
 
                /* uncollectable items should never be compacted */
-               GC_ASSERT(!GC_TEST_FLAGS(o, GC_FLAG_UNCOLLECTABLE));
+               GC_ASSERT(!GC_TEST_FLAGS(o, HDRFLAG_UNCOLLECTABLE));
 
                /* if this object is already part of a threaded chain ... */
                if (GC_IS_THREADED(o->vftbl)) {
diff --git a/src/mm/cacao-gc/final.c b/src/mm/cacao-gc/final.c
new file mode 100644 (file)
index 0000000..cce1975
--- /dev/null
@@ -0,0 +1,113 @@
+/* mm/cacao-gc/final.c - GC module for finalization and weak references
+
+   Copyright (C) 2006 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
+
+   This file is part of CACAO.
+
+   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.
+
+   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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Michael Starzinger
+
+   $Id$
+
+*/
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "gc.h"
+#include "final.h"
+#include "heap.h"
+#include "mm/memory.h"
+#include "vm/finalizer.h"
+
+
+/* Global Variables ***********************************************************/
+
+list *final_list;
+
+
+
+void final_init()
+{
+       final_list = list_create(OFFSET(final_entry, linkage));
+}
+
+void final_register(java_objectheader *o, methodinfo *finalizer)
+{
+       final_entry *fe;
+
+       fe = NEW(final_entry);
+       fe->type      = FINAL_REACHABLE;
+       fe->o         = o;
+       fe->finalizer = finalizer;
+
+       list_add_last(final_list, fe);
+
+       GC_LOG( printf("Finalizer registered for: %p\n", (void *) o); );
+}
+
+void final_invoke()
+{
+       final_entry *fe;
+       final_entry *fe_next;
+
+       fe = list_first(final_list);
+       fe_next = NULL;
+       while (fe) {
+               fe_next = list_next(final_list, fe);
+
+               if (fe->type == FINAL_RECLAIMABLE) {
+
+                       GC_LOG( printf("Finalizer starting for: ");
+                                       heap_print_object(fe->o); printf("\n"); );
+
+                       GC_ASSERT(fe->finalizer == fe->o->vftbl->class->finalizer);
+
+                       fe->type = FINAL_FINALIZING;
+
+                       finalizer_run(fe->o, NULL);
+
+                       fe->type = FINAL_FINALIZED;
+
+                       list_remove(final_list, fe);
+                       FREE(fe, final_entry);
+               }
+
+               fe = fe_next;
+       }
+}
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/mm/cacao-gc/final.h b/src/mm/cacao-gc/final.h
new file mode 100644 (file)
index 0000000..f500cf3
--- /dev/null
@@ -0,0 +1,86 @@
+/* mm/cacao-gc/final.h - GC header for finalization and weak references
+
+   Copyright (C) 2006 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
+
+   This file is part of CACAO.
+
+   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.
+
+   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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Michael Starzinger
+
+   $Id$
+
+*/
+
+
+#ifndef _FINAL_H
+#define _FINAL_H
+
+#include "vm/types.h"
+
+#include "toolbox/list.h"
+#include "vmcore/method.h"
+
+
+/* Global Variables ***********************************************************/
+
+extern list *final_list;
+
+
+/* Structures *****************************************************************/
+
+typedef struct final_entry final_entry;
+
+#define FINAL_REACHABLE   1
+#define FINAL_RECLAIMABLE 2
+#define FINAL_FINALIZING  3
+#define FINAL_FINALIZED   4
+
+struct final_entry {
+       listnode           linkage;
+       u4                 type;
+       java_objectheader *o;
+       methodinfo        *finalizer;
+};
+
+
+/* Prototypes *****************************************************************/
+
+void final_init();
+void final_register(java_objectheader *o, methodinfo *finalizer);
+void final_invoke();
+
+
+#endif /* _FINAL_H */
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index aa96ef574bf31ae2a07fa161ea63f0aad9a33a22..ed5197ce879f38f88163b4aacb427ade64cc5702 100644 (file)
 #endif
 
 #include "compact.h"
+#include "final.h"
 #include "gc.h"
 #include "heap.h"
 #include "mark.h"
 #include "region.h"
+#include "rootset.h"
 #include "mm/memory.h"
 #include "toolbox/logging.h"
-#include "vm/exceptions.h"
-/*#include "vm/options.h"*/
+#include "vm/finalizer.h"
+#include "vm/vm.h"
+
+
+/* Global Variables ***********************************************************/
+
+bool gc_running;
+bool gc_notify_finalizer;
 
 
 /* gc_init *********************************************************************
@@ -66,15 +74,21 @@ void gc_init(u4 heapmaxsize, u4 heapstartsize)
                dolog("GC: Initialising with heap-size %d (max. %d)",
                        heapstartsize, heapmaxsize);
 
+       /* finalizer stuff */
+       final_init();
+
+       /* set global variables */
+       gc_running = false;
+
        /* region for uncollectable objects */
        heap_region_sys = NEW(regioninfo_t);
        if (!region_create(heap_region_sys, GC_SYS_SIZE))
-               exceptions_throw_outofmemory_exit();
+               vm_abort("gc_init: region_create failed: out of memory");
 
        /* region for java objects */
        heap_region_main = NEW(regioninfo_t);
        if (!region_create(heap_region_main, heapstartsize))
-               exceptions_throw_outofmemory_exit();
+               vm_abort("gc_init: region_create failed: out of memory");
 
        heap_current_size = heapstartsize;
        heap_maximal_size = heapmaxsize;
@@ -101,21 +115,32 @@ void gc_init(u4 heapmaxsize, u4 heapstartsize)
 void gc_collect(s4 level)
 {
        rootset_t    *rs;
-       regioninfo_t *src, *dst;
        s4            dumpsize;
 
        /* remember start of dump memory area */
        dumpsize = dump_size();
 
+       /* finalizer is not notified, unless marking tells us to do so */
+       gc_notify_finalizer = false;
+
        GC_LOG( heap_println_usage(); );
        /*GC_LOG( heap_dump_region(heap_base, heap_ptr, false); );*/
 
        /* find the global rootset and the rootset for the current thread */
-       rs = DNEW(rootset_t);
-       /*TODO: mark_rootset_create(rs);*/
-       /*TODO: mark_rootset_from_globals(rs);*/
-       mark_rootset_from_thread(THREADOBJECT, rs);
-       GC_LOG( mark_rootset_print(rs); );
+       rs = rootset_create();
+       rootset_from_globals(rs);
+       rs->next = rootset_create();
+       rootset_from_thread(THREADOBJECT, rs->next);
+       GC_LOG( rootset_print(rs); );
+
+       /* check for reentrancy here */
+       if (gc_running) {
+               dolog("GC: REENTRANCY DETECTED, aborting ...");
+               goto gc_collect_abort;
+       }
+
+       /* once the rootset is complete, we consider ourselves running */
+       gc_running = true;
 
 #if 1
 
@@ -126,7 +151,7 @@ void gc_collect(s4 level)
        /* compact the heap */
        compact_me(rs, heap_region_main);
        /*GC_LOG( heap_dump_region(heap_region_main, false); );
-       GC_LOG( mark_rootset_print(rs); );*/
+       GC_LOG( rootset_print(rs); );*/
 
 #if defined(ENABLE_MEMCHECK)
        /* invalidate the rest of the main region */
@@ -136,9 +161,13 @@ void gc_collect(s4 level)
 #else
 
        /* copy the heap to new region */
-       dst = DNEW(regioninfo_t);
-       region_init(dst, heap_current_size);
-       gc_copy(heap_region_main, dst, rs);
+       {
+               regioninfo_t *src, *dst;
+
+               dst = DNEW(regioninfo_t);
+               region_init(dst, heap_current_size);
+               gc_copy(heap_region_main, dst, rs);
+       }
 
        /* invalidate old heap */
        /*memset(heap_base, 0x5a, heap_current_size);*/
@@ -149,14 +178,23 @@ void gc_collect(s4 level)
        /*heap_increase_size();*/
 
        /* write back the rootset to update root references */
-       GC_LOG( mark_rootset_print(rs); );
-       mark_rootset_writeback(rs);
+       GC_LOG( rootset_print(rs); );
+       rootset_writeback(rs);
 
 #if defined(ENABLE_STATISTICS)
        if (opt_verbosegc)
                gcstat_println();
 #endif
 
+       /* does the finalizer need to be notified */
+       if (gc_notify_finalizer)
+               finalizer_notify();
+
+       /* we are no longer running */
+       /* REMEBER: keep this below the finalizer notification */
+       gc_running = false;
+
+gc_collect_abort:
     /* free dump memory area */
     dump_release(dumpsize);
 
@@ -182,6 +220,25 @@ void gc_call(void)
 }
 
 
+/* gc_invoke_finalizers ********************************************************
+
+   Forces invocation of all the finalizers for objects which are reclaimable.
+   This is the function which is called by the finalizer thread.
+
+*******************************************************************************/
+
+void gc_invoke_finalizers(void)
+{
+       if (opt_verbosegc)
+               dolog("GC: Invoking finalizers ...");
+
+       final_invoke();
+
+       if (opt_verbosegc)
+               dolog("GC: Invoking finalizers finished.");
+}
+
+
 /* Informational getter functions *********************************************/
 
 s8 gc_get_heap_size(void)     { return heap_current_size; }
index e16b0f29d2a768d31d1ae452ae22bcc720cd2ed6..3390c6a61ca44f8dd4f0f7fdacebd6acae8ae057 100644 (file)
@@ -64,7 +64,7 @@
 
 /* Development Break **********************************************************/
 
-#if 1 && defined(ENABLE_THREADS)
+#if 0 && defined(ENABLE_THREADS)
 # error "GC does not work with threads enabled!"
 #endif
 
 #endif
 
 
-/* Global Variables ***********************************************************/
-
-static bool gc_pending;
-
-
 /* Helper Macros **************************************************************/
 
 #define GC_SET_FLAGS(obj, flags)   ((obj)->hdrflags |=  (flags))
@@ -100,6 +95,11 @@ static bool gc_pending;
        ((void *) (ptr) > (ptr_start) && (void *) (ptr) < (ptr_end))
 
 
+/* Global Variables ***********************************************************/
+
+extern bool gc_notify_finalizer;
+
+
 /* Statistics *****************************************************************/
 
 #if defined(ENABLE_STATISTICS)
index 333e64c3d92f548b8fbf94f96890b5f35d177328..21293454a7913726807fba6d368bffa9a4bcc0f1 100644 (file)
 #include "mark.h"
 #include "region.h"
 #include "mm/memory.h"
-#include "native/jni.h"
 #include "src/native/include/java_lang_String.h" /* TODO: fix me! */
 #include "toolbox/logging.h"
-#include "vm/exceptions.h"
 #include "vm/global.h"
-/*#include "vm/options.h"*/
-#include "vm/jit/stacktrace.h"
 
 
 /* Global Variables ***********************************************************/
@@ -66,6 +62,7 @@ regioninfo_t *heap_region_main;
 #define GC_ALIGN(length,size) ((((length) + (size) - 1) / (size)) * (size))
 
 
+
 void heap_init_objectheader(java_objectheader *o, u4 bytelength)
 {
        u4 wordcount;
@@ -155,14 +152,14 @@ s4 heap_get_hashcode(java_objectheader *o)
        if (GC_TEST_FLAGS(o, HDRFLAG_HASH_ATTACHED)) {
 
                hashcode = *( (s4 *) ( ((u1 *) o) + get_object_size(o) - SIZEOF_VOID_P ) ); /* TODO: clean this up!!! */
-               GC_LOG( dolog("GC: Hash re-taken: %d (0x%08x)", hashcode, hashcode); );
+               GC_LOG2( dolog("GC: Hash re-taken: %d (0x%08x)", hashcode, hashcode); );
 
        } else {
 
                GC_SET_FLAGS(o, HDRFLAG_HASH_TAKEN);
 
                hashcode = (s4) (ptrint) o;
-               GC_LOG( dolog("GC: Hash taken: %d (0x%08x)", hashcode, hashcode); );
+               GC_LOG2( dolog("GC: Hash taken: %d (0x%08x)", hashcode, hashcode); );
 
        }
 
@@ -190,7 +187,7 @@ java_objectheader *heap_alloc_intern(u4 bytelength, regioninfo_t *region)
        }
 
        /* allocate the object in this region */
-       p = region->ptr;
+       p = (java_objectheader *) region->ptr;
        region->ptr += bytelength;
        region->free -= bytelength;
 
@@ -226,10 +223,16 @@ void *heap_allocate(u4 bytelength, u4 references, methodinfo *finalizer)
        if (p == NULL)
                return NULL;
 
-       /* TODO: can this be overwritten by cloning??? */
+       /* take care of finalization stuff */
        if (finalizer != NULL) {
-               GC_LOG( log_text("GC: Finalizer not yet implemented!"); );
+
+               /* set the header bit */
+               /* TODO: do we really need this??? */
+               /* TODO: can this be overwritten by cloning??? */
                GC_SET_FLAGS(p, GC_FLAG_FINALIZER);
+
+               /* register the finalizer for this object */
+               final_register(p, finalizer);
        }
 
        return p;
@@ -251,7 +254,7 @@ void *heap_alloc_uncollectable(u4 bytelength)
 
        /* TODO: can this be overwritten by cloning??? */
        /* remember this object as uncollectable */
-       GC_SET_FLAGS(p, GC_FLAG_UNCOLLECTABLE);
+       GC_SET_FLAGS(p, HDRFLAG_UNCOLLECTABLE);
 
        return p;
 }
@@ -285,7 +288,7 @@ void heap_print_object_flags(java_objectheader *o)
                GC_TEST_FLAGS(o, GC_FLAG_FINALIZER)     ? "F" : " ",
                GC_TEST_FLAGS(o, HDRFLAG_HASH_ATTACHED) ? "A" : " ",
                GC_TEST_FLAGS(o, HDRFLAG_HASH_TAKEN)    ? "T" : " ",
-               GC_TEST_FLAGS(o, GC_FLAG_UNCOLLECTABLE) ? "U" : " ",
+               GC_TEST_FLAGS(o, HDRFLAG_UNCOLLECTABLE) ? "U" : " ",
                GC_TEST_FLAGS(o, GC_FLAG_MARKED)        ? "M" : " ");
 }
 #endif
@@ -363,8 +366,8 @@ void heap_dump_region(regioninfo_t *region, bool marked_only)
        printf("Heap-Dump:\n");
 
        /* walk the region in a linear style */
-       o = region->base;
-       while ((void *) o < region->ptr) {
+       o = (java_objectheader *) region->base;
+       while (o < region->ptr) {
 
                if (!marked_only || GC_IS_MARKED(o)) {
                        printf("\t");
index ecff8e70fda4915ee4b80768fa3c35e3a67c6af5..cd341265d1c20db412227289f6f5d8b598880ec0 100644 (file)
 
 /* TODO: maybe move this to global.h */
 #define GC_FLAG_FINALIZER     0x40
-#define GC_FLAG_UNCOLLECTABLE HDRFLAG_UNCOLLECTABLE
-#define GC_FLAG_MARKED        (HDRFLAG_MARK1 | HDRFLAG_MARK2)
-
-#define GC_IS_MARKED(obj)    GC_TEST_FLAGS(obj, GC_FLAG_MARKED)
-#define GC_SET_MARKED(obj)   GC_SET_FLAGS(obj, GC_FLAG_MARKED)
-#define GC_CLEAR_MARKED(obj) GC_CLEAR_FLAGS(obj, GC_FLAG_MARKED)
 
 
 #define GC_SIZE_DUMMY 0xff
 
-
 #if SIZEOF_VOID_P == 8
 # define GC_GET_SIZE(obj)       ((u4) (((obj)->hdrflags >> 56) & 0xff))
 # define GC_SET_SIZE(obj, size) ((obj)->hdrflags |= ((u8) ((size) & 0xff)) << 56)
@@ -75,8 +68,8 @@ extern regioninfo_t *heap_region_main;
 
 s4 get_object_size(java_objectheader *o);
 
-
 #if !defined(NDEBUG)
+void heap_println_usage();
 void heap_print_object(java_objectheader *o);
 void heap_dump_region(regioninfo_t *region, bool marked_only);
 #endif
index c30bd592a0ce6e092bde53cecde1ccdd80174d8f..679de392635c4bf003c5f167e227f741f9d82877 100644 (file)
 #endif
 
 #include "gc.h"
+#include "final.h"
 #include "heap.h"
 #include "mark.h"
+#include "rootset.h"
 #include "mm/memory.h"
 #include "toolbox/logging.h"
 #include "vm/global.h"
-#include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
 #include "vmcore/linker.h"
 
 
-/* mark_rootset_from_globals ***************************************************
-
-   Searches global variables to compile the global root set out of references
-   contained in them.
-
-   SEARCHES IN:
-     - global reference table (jni.c)
-
-*******************************************************************************/
-
-void mark_rootset_from_globals(rootset_t *rs)
-{
-       GC_ASSERT(0);
-}
-
-
-/* mark_rootset_from_thread ****************************************************
-
-   Searches the stack of the current thread for references and compiles a
-   root set out of them.
-
-   NOTE: uses dump memory!
-
-   IN:
-         TODO!!!
-
-   OUT:
-         TODO!!!
-
-*******************************************************************************/
-
-stacktracebuffer *stacktrace_create(threadobject* thread, bool rplpoints);
-void replace_read_executionstate(rplpoint *rp,
-                                        executionstate_t *es,
-                                        sourcestate_t *ss,
-                                        bool topframe);
-void replace_write_executionstate(rplpoint *rp,
-                                                                                executionstate_t *es,
-                                                                                sourcestate_t *ss,
-                                                                                bool topframe);
-
-void mark_rootset_from_thread(threadobject *thread, rootset_t *rs)
-{
-       stacktrace_entry *ste;
-       stacktracebuffer *stb;
-       executionstate_t *es;
-       sourcestate_t    *ss;
-       sourceframe_t    *sf;
-       rplpoint         *rp;
-       rplpoint         *rp_search;
-       s4                rpcount;
-       int               i;
-
-       /* TODO: remove these */
-    java_objectheader *o;
-    int refcount;
-
-       GC_LOG( printf("Walking down stack of current thread:\n");
-                       stacktrace_dump_trace(thread); );
-
-       /* create empty execution state */
-       es = DNEW(executionstate_t);
-       es->pc = 0;
-       es->sp = 0;
-       es->pv = 0;
-       es->code = NULL;
-
-       /* TODO: we assume we are in a native and in current thread! */
-       ss = replace_recover_source_state(NULL, NULL, es);
-
-       /* print our full source state */
-       GC_LOG( replace_sourcestate_println(ss); );
-
-       /* initialize the rootset struct */
-       GC_ASSERT(rs);
-       rs->thread = thread;
-       rs->ss = ss;
-       rs->es = es;
-       rs->stb = stb;
-       rs->refcount = 0;
-
-       /* now inspect the source state to compile the root set */
-       refcount = rs->refcount;
-       for (sf = ss->frames; sf != NULL; sf = sf->down) {
-
-               GC_ASSERT(sf->javastackdepth == 0);
-
-               for (i = 0; i < sf->javalocalcount; i++) {
-
-                       if (sf->javalocaltype[i] != TYPE_ADR)
-                               continue;
-
-                       o = sf->javalocals[i].a;
-
-                       /* check for outside or null pointer */
-                       if (!POINTS_INTO(o, heap_region_main->base, heap_region_main->ptr))
-                               continue;
-
-                       /* add this reference to the root set */
-                       GC_LOG2( printf("Found Reference: %p\n", (void *) o); );
-                       GC_ASSERT(refcount < RS_REFS); /* TODO: UGLY!!! */
-                       rs->refs[refcount] = (java_objectheader **) &( sf->javalocals[i] );
-
-                       refcount++;
-
-               }
-
-       }
-
-       /* remeber how many references there are inside this root set */
-       rs->refcount = refcount;
-
-       GC_LOG( printf("Walking done.\n"); );
-}
-
-
-void mark_rootset_writeback(rootset_t *rs)
-{
-       sourcestate_t    *ss;
-       executionstate_t *es;
-       rplpoint         *rp;
-       stacktracebuffer *stb;
-       stacktrace_entry *ste;
-       int i;
-
-       ss = rs->ss;
-       es = rs->es;
-
-       replace_build_execution_state_intern(ss, es);
-
-}
-
-
-/* mark_recursice **************************************************************
+/* mark_recursive **************************************************************
 
    Recursively mark all objects (including this) which are referenced.
 
+   TODO, XXX: We need to implement a non-recursive version of this!!!
+
    IN:
          o.....heap-object to be marked (either OBJECT or ARRAY)
 
@@ -210,7 +79,7 @@ void mark_recursive(java_objectheader *o)
        /* uncollectable objects should never get marked this way */
        /* the reference should point into the heap */
        GC_ASSERT(o);
-       GC_ASSERT(!GC_TEST_FLAGS(o, GC_FLAG_UNCOLLECTABLE));
+       GC_ASSERT(!GC_TEST_FLAGS(o, HDRFLAG_UNCOLLECTABLE));
        GC_ASSERT(POINTS_INTO(o, start, end));
 
        /* mark this object */
@@ -224,9 +93,6 @@ void mark_recursive(java_objectheader *o)
        c = t->class;
        GC_ASSERT(c);
 
-       /* TODO: should we mark the class of the object as well? */
-       /*GC_ASSERT(GC_IS_MARKED((java_objectheader *) c));*/
-
        /* does this object has pointers? */
        /* TODO: check how often this happens, maybe remove this check! */
        /*if (!GC_IS_REFERENCING(o))
@@ -299,6 +165,16 @@ void mark_recursive(java_objectheader *o)
 }
 
 
+/* mark_classes ****************************************************************
+
+   Marks all the references from classinfo structures (static fields)
+
+   IN:
+      start.....Region to be marked starts here
+      end.......Region to be marked ends here 
+
+*******************************************************************************/
+
 void mark_classes(void *start, void *end)
 {
        java_objectheader *ref;
@@ -307,7 +183,7 @@ void mark_classes(void *start, void *end)
        void *sys_start, *sys_end;
        int i;
 
-       GC_LOG( printf("Marking from classes\n"); );
+       GC_LOG( dolog("GC: Marking from classes ..."); );
 
        /* TODO: cleanup!!! */
        sys_start = heap_region_sys->base;
@@ -345,6 +221,8 @@ void mark_classes(void *start, void *end)
 
    Marks all Heap Objects which are reachable from a given root-set.
 
+   REMEMBER: Assumes all threads are stopped!
+
    IN:
          rs.....root set containing the references
 
@@ -353,6 +231,8 @@ void mark_classes(void *start, void *end)
 void mark_me(rootset_t *rs)
 {
        java_objectheader *ref;
+       final_entry       *fe;
+       u4                 f_type;
        int i;
 
        GCSTAT_INIT(gcstat_mark_count);
@@ -362,47 +242,102 @@ void mark_me(rootset_t *rs)
        /* recursively mark all references from classes */
        mark_classes(heap_region_main->base, heap_region_main->ptr);
 
-       GC_LOG( printf("Marking from rootset (%d entries)\n", rs->refcount); );
+       while (rs) {
+               GC_LOG( dolog("GC: Marking from rootset (%d entries) ...", rs->refcount); );
 
-       /* recursively mark all references of the rootset */
-       GCSTAT_COUNT_MAX(gcstat_mark_depth, gcstat_mark_depth_max);
-       for (i = 0; i < rs->refcount; i++) {
+               /* recursively mark all references of the rootset */
+               GCSTAT_COUNT_MAX(gcstat_mark_depth, gcstat_mark_depth_max);
+               for (i = 0; i < rs->refcount; i++) {
 
-               ref = *( rs->refs[i] );
-               mark_recursive(ref);
+                       /* is this a marking reference? */
+                       if (!rs->ref_marks[i])
+                               continue;
+
+                       /* do the marking here */
+                       ref = *( rs->refs[i] );
+                       mark_recursive(ref);
 
+               }
+               GCSTAT_DEC(gcstat_mark_depth);
+
+               rs = rs->next;
        }
-       GCSTAT_DEC(gcstat_mark_depth);
 
-       GC_ASSERT(gcstat_mark_depth == 0);
-       GC_ASSERT(gcstat_mark_depth_max > 0);
-}
+       /* objects with finalizers will also be marked here. if they have not been
+        * marked before the finalization is triggered */
+       /* REMEMBER: all threads are stopped, so we can use unsynced access here */
+       fe = list_first_unsynced(final_list);
+       while (fe) {
+               f_type = fe->type;
+               ref    = fe->o;
 
+               /* object not marked, but was reachable before */
+               if (f_type == FINAL_REACHABLE && !GC_IS_MARKED(ref)) {
+                       GC_LOG2( printf("Finalizer triggered for: ");
+                                       heap_print_object(ref); printf("\n"); );
 
-#if !defined(NDEBUG)
-void mark_rootset_print(rootset_t *rs)
-{
-       java_objectheader *o;
-       int i;
+                       /* object is now reclaimable */
+                       fe->type = FINAL_RECLAIMABLE;
+
+                       /* keep the object alive until finalizer finishes */
+                       mark_recursive(ref);
+
+                       /* notify the finalizer after collection finished */
+                       gc_notify_finalizer = true;
+               } else
+
+#if 0
+               /* object not marked, but was not finalized yet */
+               if (f_type == FINAL_RECLAIMABLE && !GC_IS_MARKED(ref)) {
+                       GC_LOG2( printf("Finalizer not yet started for: ");
+                                       heap_print_object(ref); printf("\n"); );
+
+                       /* keep the object alive until finalizer finishes */
+                       mark_recursive(ref);
+               } else
 
-       printf("Root Set:\n");
+               /* object not marked, but was not finalized yet */
+               if (f_type == FINAL_RECLAIMABLE && !GC_IS_MARKED(ref)) {
+                       GC_LOG2( printf("Finalizer not yet finished for: ");
+                                       heap_print_object(ref); printf("\n"); );
 
-       printf("\tThread: %p\n", rs->thread);
-       printf("\tReferences (%d):\n", rs->refcount);
+                       /* keep the object alive until finalizer finishes */
+                       mark_recursive(ref);
+               } else
+
+               /* object marked, but finalizer already ran */
+               /* TODO: nothing has to be done here, remove me! */
+               if (f_type == FINAL_FINALIZED && GC_IS_MARKED(ref)) {
+                       GC_LOG2( printf("Finalizer resurrected object: ");
+                                       heap_print_object(ref); printf("\n"); );
+
+                       /* do nothing */
+               } else
 
-       for (i = 0; i < rs->refcount; i++) {
+               /* object not marked, finalizer already ran */
+               if (f_type == FINAL_FINALIZED && !GC_IS_MARKED(ref)) {
+                       GC_LOG2( printf("Finalizer already finished!\n"); );
+
+                       /* do nothing */
+               } else
+#endif
 
-               o = *( rs->refs[i] );
+               /* object marked, finalizer not yet run */
+               if (f_type == FINAL_REACHABLE && GC_IS_MARKED(ref)) {
+                       /* do nothing */
+               } else
 
-               /*printf("\t\tReference at %p points to ...\n", (void *) rs->refs[i]);*/
-               printf("\t\t");
-               heap_print_object(o);
-               printf("\n");
+               /* case not yet covered */
+               { assert(0); }
 
+               fe = list_next_unsynced(final_list, fe);
        }
 
+       GC_LOG( dolog("GC: Marking finished."); );
+
+       GC_ASSERT(gcstat_mark_depth == 0);
+       GC_ASSERT(gcstat_mark_depth_max > 0);
 }
-#endif
 
 
 /*
index 24ffb4f036871b61845a41e2c040658eabb8cca7..22d5282e3e84bd31fea58dca9f49473d3c495a38 100644 (file)
 #ifndef _MARK_H
 #define _MARK_H
 
-typedef struct rootset_t rootset_t;
 
 #include "config.h"
 #include "vm/types.h"
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#else
-/*# include "threads/none/threads.h"*/
-#endif
+#include "rootset.h"
 
-#include "vm/jit/replace.h"
-#include "vm/jit/stacktrace.h"
 
-#include "vmcore/method.h"
+/* Helper Macros **************************************************************/
 
+#define GC_FLAG_MARKED        (HDRFLAG_MARK1 | HDRFLAG_MARK2)
 
-/* Structures *****************************************************************/
-
-#define RS_REFS 10
-
-/* rootset is passed as array of pointers, which point to the location of
-   the reference */
-
-struct rootset_t {
-       threadobject       *thread;         /* thread this rootset belongs to */
-       sourcestate_t      *ss;             /* sourcestate of the thread */
-       executionstate_t   *es;             /* executionstate of the thread */
-       stacktracebuffer   *stb;            /* stacktrace of the thread */
-       s4                  refcount;       /* number of references */
-       java_objectheader **refs[RS_REFS];  /* list of references */
-};
+#define GC_IS_MARKED(obj)    GC_TEST_FLAGS(obj, GC_FLAG_MARKED)
+#define GC_SET_MARKED(obj)   GC_SET_FLAGS(obj, GC_FLAG_MARKED)
+#define GC_CLEAR_MARKED(obj) GC_CLEAR_FLAGS(obj, GC_FLAG_MARKED)
 
 
 /* Prototypes *****************************************************************/
 
-void mark_rootset_from_thread(threadobject *thread, rootset_t *rs);
 void mark_me(rootset_t *rs);
 
 
diff --git a/src/mm/cacao-gc/rootset.c b/src/mm/cacao-gc/rootset.c
new file mode 100644 (file)
index 0000000..633f243
--- /dev/null
@@ -0,0 +1,307 @@
+/* mm/cacao-gc/rootset.c - GC module for root set management
+
+   Copyright (C) 2006 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
+
+   This file is part of CACAO.
+
+   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.
+
+   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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Michael Starzinger
+
+   $Id$
+
+*/
+
+
+#include "config.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
+#else
+/*# include "threads/none/threads.h"*/
+#endif
+
+#include "gc.h"
+#include "final.h"
+#include "heap.h"
+#include "mark.h"
+#include "mm/memory.h"
+#include "toolbox/logging.h"
+#include "vm/global.h"
+#include "vm/jit/replace.h"
+#include "vm/jit/stacktrace.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+
+
+rootset_t *rootset_create(void)
+{
+       rootset_t *rs;
+
+       rs = DNEW(rootset_t);
+
+       rs->next     = NULL;
+       rs->refcount = 0;
+
+       return rs;
+}
+
+
+/* rootset_from_globals ********************************************************
+
+   Searches global variables to compile the global root set out of references
+   contained in them.
+
+   SEARCHES IN:
+     - classloader objects (loader.c)
+     - global reference table (jni.c)
+     - finalizer entries (final.c)
+
+*******************************************************************************/
+
+void rootset_from_globals(rootset_t *rs)
+{
+       hashtable_classloader_entry *cle;
+       final_entry *fe;
+       int refcount;
+       int i;
+
+       GC_LOG( dolog("GC: Acquiring Root-Set from globals ..."); );
+
+       /* initialize the rootset struct */
+       GC_ASSERT(rs);
+       GC_ASSERT(rs->refcount == 0);
+       rs->thread = ROOTSET_DUMMY_THREAD;
+       rs->ss     = NULL;
+       rs->es     = NULL;
+       rs->stb    = NULL;
+
+    /* walk through all classloaders */
+       refcount = rs->refcount;
+       for (i = 0; i < hashtable_classloader->size; i++) {
+               cle = hashtable_classloader->ptr[i];
+
+               while (cle) {
+
+                       GC_LOG2( printf("Found Classloader: %p\n", (void *) cle->object); );
+
+                       /* add this classloader to the root set */
+                       GC_ASSERT(refcount < RS_REFS); /* TODO: UGLY!!! */
+                       rs->refs[refcount] = &( cle->object );
+                       rs->ref_marks[refcount] = true;
+                       refcount++;
+
+                       cle = cle->hashlink;
+               }
+       }
+
+       /* walk through all finalizer entries */
+       /* REMEMBER: all threads are stopped, so we can use unsynced access here */
+       fe = list_first_unsynced(final_list);
+       while (fe) {
+
+               GC_LOG2( printf("Found Finalizer Entry: %p\n", (void *) fe->o); );
+
+               /* add this object with finalizer to the root set */
+               GC_ASSERT(refcount < RS_REFS); /* TODO: UGLY!!! */
+               rs->refs[refcount] = &( fe->o );
+               rs->ref_marks[refcount] = false;
+               refcount++;
+
+               fe = list_next_unsynced(final_list, fe);
+       }
+
+       /* remeber how many references there are inside this root set */
+       rs->refcount = refcount;
+
+}
+
+
+/* rootset_from_thread *********************************************************
+
+   Searches the stack of the passed thread for references and compiles a
+   root set out of them.
+
+   NOTE: uses dump memory!
+
+   IN:
+         thread...TODO
+      rs.......TODO
+
+   OUT:
+         TODO!!!
+
+*******************************************************************************/
+
+void rootset_from_thread(threadobject *thread, rootset_t *rs)
+{
+       stacktracebuffer *stb;
+       executionstate_t *es;
+       sourcestate_t    *ss;
+       sourceframe_t    *sf;
+       rplpoint         *rp;
+       s4                rpcount;
+       int               i;
+
+       /* TODO: remove these */
+    java_objectheader *o;
+    int refcount;
+
+       GC_LOG( dolog("GC: Acquiring Root-Set from thread (%p) ...", (void *) thread); );
+
+       GC_LOG2( printf("Stacktrace of current thread:\n");
+                       stacktrace_dump_trace(thread); );
+
+       /* create empty execution state */
+       es = DNEW(executionstate_t);
+       es->pc = 0;
+       es->sp = 0;
+       es->pv = 0;
+       es->code = NULL;
+
+       /* TODO: we assume we are in a native and in current thread! */
+       ss = replace_recover_source_state(NULL, NULL, es);
+
+       /* print our full source state */
+       GC_LOG2( replace_sourcestate_println(ss); );
+
+       /* initialize the rootset struct */
+       GC_ASSERT(rs);
+       GC_ASSERT(rs->refcount == 0);
+       rs->thread = thread;
+       rs->ss = ss;
+       rs->es = es;
+       rs->stb = stb;
+
+       /* now inspect the source state to compile the root set */
+       refcount = rs->refcount;
+       for (sf = ss->frames; sf != NULL; sf = sf->down) {
+
+               GC_ASSERT(sf->javastackdepth == 0);
+
+               for (i = 0; i < sf->javalocalcount; i++) {
+
+                       if (sf->javalocaltype[i] != TYPE_ADR)
+                               continue;
+
+                       o = sf->javalocals[i].a;
+
+                       /* check for outside or null pointer */
+                       if (!POINTS_INTO(o, heap_region_main->base, heap_region_main->ptr))
+                               continue;
+
+                       /* add this reference to the root set */
+                       GC_LOG2( printf("Found Reference: %p\n", (void *) o); );
+                       GC_ASSERT(refcount < RS_REFS); /* TODO: UGLY!!! */
+                       rs->refs[refcount] = (java_objectheader **) &( sf->javalocals[i] );
+                       rs->ref_marks[refcount] = true;
+
+                       refcount++;
+
+               }
+
+       }
+
+       /* remeber how many references there are inside this root set */
+       rs->refcount = refcount;
+
+}
+
+
+void rootset_writeback(rootset_t *rs)
+{
+       sourcestate_t    *ss;
+       executionstate_t *es;
+       rplpoint         *rp;
+       stacktracebuffer *stb;
+
+       /* TODO: only a dirty hack! */
+       GC_ASSERT(rs->next->thread == THREADOBJECT);
+       ss = rs->next->ss;
+       es = rs->next->es;
+
+       replace_build_execution_state_intern(ss, es);
+
+}
+
+
+/* Debugging ******************************************************************/
+
+#if !defined(NDEBUG)
+void rootset_print(rootset_t *rs)
+{
+       java_objectheader *o;
+       int i;
+
+       /* walk through all rootsets in the chain */
+       printf("Root Set Chain:\n");
+       while (rs) {
+
+               /* print the thread this rootset belongs to */
+               if (rs->thread == ROOTSET_DUMMY_THREAD) {
+                       printf("\tGlobal Root Set:\n");
+               } else {
+#if defined(ENABLE_THREADS)
+                       printf("\tLocal Root Set with Thread-Id %p:\n", (void *) rs->thread->tid);
+#else
+                       printf("\tLocal Root Set:\n");
+#endif
+               }
+
+               /* print the references in this rootset */
+               printf("\tReferences (%d):\n", rs->refcount);
+               for (i = 0; i < rs->refcount; i++) {
+
+                       o = *( rs->refs[i] );
+
+                       /*printf("\t\tReference at %p points to ...\n", (void *) rs->refs[i]);*/
+                       printf("\t\t");
+                       if (rs->ref_marks[i])
+                               printf("MRK");
+                       else
+                               printf("UPD");
+                       printf(" ");
+                       heap_print_object(o);
+                       printf("\n");
+
+               }
+
+               rs = rs->next;
+
+       }
+
+}
+#endif
+
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
diff --git a/src/mm/cacao-gc/rootset.h b/src/mm/cacao-gc/rootset.h
new file mode 100644 (file)
index 0000000..4273390
--- /dev/null
@@ -0,0 +1,100 @@
+/* mm/cacao-gc/rootset.h - GC header for root set management
+
+   Copyright (C) 2006 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
+
+   This file is part of CACAO.
+
+   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.
+
+   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.
+
+   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.
+
+   Contact: cacao@cacaojvm.org
+
+   Authors: Michael Starzinger
+
+   $Id$
+
+*/
+
+
+#ifndef _ROOTSET_H
+#define _ROOTSET_H
+
+typedef struct rootset_t rootset_t;
+
+#include "config.h"
+#include "vm/types.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
+#else
+/*# include "threads/none/threads.h"*/
+#endif
+
+#include "vm/jit/replace.h"
+#include "vm/jit/stacktrace.h"
+
+#include "vmcore/method.h"
+
+
+/* Structures *****************************************************************/
+
+#define ROOTSET_DUMMY_THREAD ((threadobject *) (ptrint) -1)
+#define RS_REFS 32
+
+/* rootset is passed as array of pointers, which point to the location of
+   the reference */
+
+struct rootset_t {
+       rootset_t          *next;           /* link to the next chain element */
+       threadobject       *thread;         /* thread this rootset belongs to */
+       sourcestate_t      *ss;             /* sourcestate of the thread */
+       executionstate_t   *es;             /* executionstate of the thread */
+       stacktracebuffer   *stb;            /* stacktrace of the thread */
+       s4                  refcount;       /* number of references */
+       java_objectheader **refs[RS_REFS];  /* list of references */
+       bool                ref_marks[RS_REFS]; /* indicates if a reference marks */
+};
+
+
+/* Prototypes *****************************************************************/
+
+rootset_t *rootset_create(void);
+void rootset_from_globals(rootset_t *rs);
+void rootset_from_thread(threadobject *thread, rootset_t *rs);
+void rootset_writeback(rootset_t *rs);
+
+#if !defined(NDEBUG)
+void rootset_print(rootset_t *rs);
+#endif
+
+
+#endif /* _ROOTSET_H */
+
+/*
+ * 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
index d42135adc7bafe1be07bcd355a670d16ed3fee6f..41447ae18594c49ea78103499e28ab5a44058dbf 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes:
 
-   $Id: md-asm.h 7355 2007-02-14 10:57:32Z twisti $
+   $Id: md-asm.h 7300 2007-02-07 22:06:53Z pm $
 
 */