You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by dl...@apache.org on 2005/10/28 23:08:00 UTC

svn commit: r329302 - in /incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM: config.sh jvm/src/gc.h jvm/src/gc_refcount.c jvm/src/gc_stub.c

Author: dlydick
Date: Fri Oct 28 14:07:35 2005
New Revision: 329302

URL: http://svn.apache.org/viewcvs?rev=329302&view=rev
Log:
Added simple reference counter GC algorithm.

Added:
    incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_refcount.c
Modified:
    incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/config.sh
    incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc.h
    incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_stub.c

Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/config.sh
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/config.sh?rev=329302&r1=329301&r2=329302&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/config.sh (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/config.sh Fri Oct 28 14:07:35 2005
@@ -797,8 +797,10 @@
 echo ""
 echo "$PGMNAME:  Choose a garbage collection method:"
 echo ""
-echo "            stub--  Only the API calls, no content"
-echo "            other-- Roll your own, generates unresolved externals"
+echo "            stub--     Only the API calls, no content"
+echo "            refcount-- Simple reference counter"
+echo \
+  "            other--    Roll your own, generates unresolved externals"
 
 while true
 do
@@ -807,8 +809,9 @@
     read gcmethod
 
     case $gcmethod in
-        stub)    GCMETHOD="GC_TYPE_STUB";;
-        other)   GCMETHOD="GC_TYPE_OTHER";;
+        stub)     GCMETHOD="GC_TYPE_STUB";;
+        refcount) GCMETHOD="GC_TYPE_REFCOUNT";;
+        other)    GCMETHOD="GC_TYPE_OTHER";;
 
         *)       echo ""
                  echo "Garbage collection method '$gcmethod' invalid"
@@ -1278,8 +1281,6 @@
     echo "DO NOT MODIFY!"
     echo ""
     echo "Instead, run $PGMNAME to change _anything_ at all!"
-    echo "(The same goes for the '*.gcc' and '*.gccld' files in this"
-    echo "directory, but notice that they cannot contain any comments.)"
     echo ""
 
 ) > $CRME
@@ -1294,7 +1295,7 @@
     echo " * @brief Boot JVM build configuration."
     echo " *"
     echo " * Top-level configuration declarations."
- echo " * Auto-generated by @link ./config.sh $PGMNAME@endlink"
+    echo " * Auto-generated by @link ./config.sh $PGMNAME@endlink"
     echo " * on $THISDATE:"
     echo " * <b>@verbatim"
     echo ""
@@ -1625,9 +1626,11 @@
     echo " * @def CONFIG_$GCMETHOD"
     echo " * @brief Garbage collection method"
     echo " *"
-    echo " * This value may be @b stub or @b other."
+    echo " * This value may be @b stub or @b refcount or @b other."
     echo " *"
     echo " * @b stub means API only, no content"
+    echo " *"
+    echo " * @b stub means a simple reference counter"
     echo " *"
     echo " * @b other means roll your own-- generates unresolved"
     echo " *          external symbols."

Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc.h?rev=329302&r1=329301&r2=329302&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc.h (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc.h Fri Oct 28 14:07:35 2005
@@ -118,6 +118,55 @@
 #endif
 
 
+#ifdef CONFIG_GC_TYPE_REFCOUNT
+/*!
+ * @name Reference counter garbage collection model definitions
+ *
+ * @brief Expand the @b GC_xxx() macros into the simple heap model as
+ * implemented by @link jvm/src/gc_refcount.c gc_refcount.c@endlink.
+ *
+ * Each garbage collection algorithm will have a section just
+ * like this here in this file so that these macros will expand
+ * to point to the API as implemented by that algoritm.  For
+ * some examples as to how this is done for other modules,
+ * please refer to @link jvm/src/heap.h heap.h@endlink .
+ *
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+#define GC_INIT gc_init_refcount
+#define GC_RUN  gc_run_refcount
+
+#define GC_CLASS_NEW                gc_class_new_refcount
+#define GC_CLASS_RELOAD             gc_class_reload_refcount
+
+#define GC_CLASS_MKREF_FROM_CLASS   gc_class_mkref_from_class_refcount
+#define GC_CLASS_MKREF_FROM_OBJECT  gc_class_mkref_from_object_refcount
+#define GC_CLASS_RMREF_FROM_CLASS   gc_class_rmref_from_class_refcount
+#define GC_CLASS_RMREF_FROM_OBJECT  gc_class_rmref_from_object_refcount
+#define GC_CLASS_FIELD_MKREF        gc_class_field_mkref_refcount
+#define GC_CLASS_FIELD_RMREF        gc_class_field_rmref_refcount
+#define GC_CLASS_DELETE             gc_class_delete_refcount
+
+#define GC_OBJECT_NEW               gc_object_new_refcount
+#define GC_OBJECT_MKREF_FROM_CLASS  gc_object_mkref_from_class_refcount
+#define GC_OBJECT_MKREF_FROM_OBJECT gc_object_mkref_from_object_refcount
+#define GC_OBJECT_RMREF_FROM_CLASS  gc_object_rmref_from_class_refcount
+#define GC_OBJECT_RMREF_FROM_OBJECT gc_object_rmref_from_object_refcount
+#define GC_OBJECT_FIELD_MKREF       gc_object_field_mkref_refcount
+#define GC_OBJECT_FIELD_RMREF       gc_object_field_rmref_refcount
+#define GC_OBJECT_DELETE            gc_object_delete_refcount
+
+#define GC_STACK_NEW                gc_stack_new_refcount
+#define GC_STACK_MKREF_FROM_JVM     gc_stack_mkref_from_jvm_refcount
+#define GC_STACK_RMREF_FROM_JVM     gc_stack_rmref_from_jvm_refcount
+#define GC_STACK_DELETE             gc_stack_delete_refcount
+
+/*@} */ /* End of grouped definitions */
+#endif
+
+
 /* Prototypes for functions in 'gc_XXX.c' */
 
 extern rvoid GC_INIT(rvoid);

Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_refcount.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_refcount.c?rev=329302&view=auto
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_refcount.c (added)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_refcount.c Fri Oct 28 14:07:35 2005
@@ -0,0 +1,1525 @@
+/*!
+ * @file gc_refcount.c
+ *
+ * @brief JVM @b refcount garbage collector,
+ * performs role of @c @b System.gc() .
+ *
+ * The logic of these structures and functions is a simple counting
+ * scheme that tracks only the @e number of references to an object,
+ * the object's GC area holding that number.  It also holds a
+ * @link #rtrue rtrue@endlink/@link #rfalse rfalse@endlink for local
+ * variables as to whether or not a local is a reference that will
+ * need to be counted (down) when that stack frame goes away.
+ *
+ * This is the second of hopefully a number of garbage collection
+ * schemes.  Others should be named @b gc_somename.c  and should
+ * be configured into @link ./config.sh ./config.sh@endlink.
+ *
+ * The common header file @link jvm/src/gc.h gc.h@endlink defines
+ * the prototypes for all garbage collection implementations by way
+ * of the @link #CONFIG_GC_TYPE_STUB CONFIG_GC_TYPE_xxx@endlink
+ * symbol definitions.
+ *
+ *
+ * @section Control
+ *
+ * \$URL: https://svn.apache.org/repos/asf/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_refcount.c $
+ *
+ * \$Id: gc_refcount.c 326482 2005-10-19 08:44:42Z dlydick $
+ *
+ * Copyright 2005 The Apache Software Foundation
+ * or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 ("the License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied.
+ *
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * @version \$LastChangedRevision: 326482 $
+ *
+ * @date \$LastChangedDate: 2005-10-19 03:44:42 -0500 (Wed, 19 Oct 2005) $
+ *
+ * @author \$LastChangedBy: dlydick $
+ *
+ *         Original code contributed by Daniel Lydick on 09/28/2005.
+ *
+ * @section Reference
+ *
+ */
+
+#include "arch.h"
+ARCH_SOURCE_COPYRIGHT_APACHE(gc_refcount, c,
+"$URL: https://svn.apache.org/repos/asf/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_refcount.c $",
+"$Id: gc_refcount.c 326482 2005-10-19 08:44:42Z dlydick $");
+
+#if defined(CONFIG_GC_TYPE_REFCOUNT) || defined(CONFIG_COMPILE_ALL_OPTIONS)
+
+
+#include "jvmcfg.h"
+#include "classfile.h"
+#include "exit.h"
+#include "heap.h"
+#include "jvm.h"
+#include "jvmclass.h"
+#include "linkage.h"
+
+/*!
+ * @name Garbage collection accounting areas
+ *
+ * @brief Type definition for references to garbage collection
+ * in several major JVM structure areas, namely classes,
+ * objects, and stack frames.
+ *
+ * Notice the @e exact same definition for:
+ *
+ *     @link #CLASS_STATUS_REFERENCE CLASS_STATUS_REFERENCE@endlink,
+ *     @link #OBJECT_STATUS_REFERENCE OBJECT_STATUS_REFERENCE@endlink,
+ *     and
+ *     @link #LOCAL_STATUS_REFERENCE LOCAL_STATUS_REFERENCE@endlink
+ *
+ * These are made to be the @e same across all three categories
+ * of GC items.
+ * @link #OBJECT_STATUS_REFERENCE OBJECT_STATUS_REFERENCE@endlink
+ * is defined to be the same as
+ * the value in @link src/object.h object.h@endlink and the the
+ * other two are defined to be the same as this one.  The compiler
+ * will let you if someone changes something so these two definitions
+ * are not identical.  Notice that the status byte is @b rbyte, so the
+ * definition must be of byte scope.  The compiler will, of course,
+ * let you know if you violate this rule.
+ */
+
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @struct gc_class_refcount
+ *
+ * @brief Type definition for references to garbage collection in
+ * Java classes
+ *
+ */
+
+typedef struct
+{
+    /* Count number of references to this class instance */
+    jint refcount;
+
+    /* Garbage collect status of each class static variable */
+    rbyte *status;
+
+} gc_class_refcount;
+
+
+/*!
+ * @struct gc_object_refcount
+ *
+ * @brief Type definition for references to garbage collection in
+ * Java objects
+ *
+ */
+
+typedef struct
+{
+    /* Count number of references to this object instance */
+    jint refcount;
+
+    /* Garbage collect status of each class static variable */
+    rbyte *status;
+
+} gc_object_refcount;
+
+
+/*!
+ * @struct gc_stack_refcount
+ *
+ * @brief Type definition for references to garbage collection in
+ * Java stack frames
+ *
+ */
+
+typedef struct
+{
+    jint  num_local_variables;
+    rbyte status[1];   /* Array of size status[num_locals] */
+
+} gc_stack_refcount;
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @name GC naming shortcut macros
+ *
+ * @brief Map the GC accounting area @link #rvoid (rvoid *)@endlink
+ * onto a @link #gc_stack_refcount (gc_stack_refcount *)@endlink.
+ *
+ *
+ * @param clsidx   Class index of a class slot to reference
+ *
+ */
+/*@{ */ /* Begin grouped definitions */
+
+/*!
+ * @brief Reference a class slot garbage collection accounting area
+ *
+ */
+#define CLASS_GARBAGE(clsidx) \
+    ((gc_class_refcount *)   CLASS(clsidx).pgarbage)
+
+/*!
+ * @brief Reference an object slot garbage collection accounting area
+ *
+ *
+ * @returns @link #gc_class_refcount (gc_class_refcount *)@endlink
+ *          version of @link #rvoid rvoid@endlink GC pointer
+ *          @link #robject.pgarbage robject.pgarbage@endlink
+ *
+ */
+#define OBJECT_GARBAGE(objhash) \
+    ((gc_object_refcount *) OBJECT(objhash).pgarbage)
+
+/*!
+ * @brief Reference a stack frame garbage collection accounting area
+ *
+ *
+ * @returns @link #gc_stack_refcount (gc_stack_refcount *)@endlink
+ *          version of @link #rvoid rvoid@endlink GC pointer
+ *          @link #GET_GC() GET_GC()@endlink
+ *
+ */
+#define GET_STACK_GARBAGE(thridx) \
+    ((gc_stack_refcount *)   GET_GC(thridx))
+
+/*@} */ /* End of grouped definitions */
+
+
+/*!
+ * @brief Initialize garbage collection
+ *
+ *
+ * @b Parameters: @link #rvoid rvoid@endlink
+ *
+ *
+ *       @returns @link #rvoid rvoid@endlink
+ *
+ */
+rvoid gc_init_refcount()
+{
+    /* Nothing to do in this model */
+
+    return;
+
+} /* END of gc_init_refcount() */
+
+
+/*!
+ * @brief Review collection status of all objects and clean them up.
+ *
+ * Scan through object table for objects that need
+ * be deallocated and free up those resources for
+ * reuse by the JVM.
+ *
+ *
+ * @param rmref  @link #rtrue rtrue@endlink when class and object
+ *               references are to be removed during processing.
+ *               This is @link #rfalse rfalse@endlink during
+ *               JVM shutdown.
+ *
+ *
+ * @returns @link #rvoid rvoid@endlink
+ *
+ */
+
+rvoid gc_run_refcount(rboolean rmref)
+{
+    jvm_class_index clsidx;
+
+    for (clsidx = jvm_class_index_null;
+         clsidx < JVMCFG_MAX_CLASSES;
+         clsidx++)
+    {
+        rushort status = CLASS(clsidx).status;
+
+        /* Skip free object table slots */
+        if (!(CLASS_STATUS_INUSE & status))
+        {
+            continue;
+        }
+
+        /* Skip null slots (the JVMCFG_NULL_CLASS and any slot that
+           is currently being intialized. */
+        if (CLASS_STATUS_NULL & status)
+        {
+            continue;
+        }
+
+        /* Look only at slots marked as ready for garbage collection */
+        if (CLASS_STATUS_GCREQ & status)
+        {
+            class_static_delete(clsidx, rmref);
+            continue;
+        }
+
+    } /* for clsidx */
+
+    jvm_object_hash objhash;
+
+    for (objhash = jvm_object_hash_null;
+         objhash < JVMCFG_MAX_OBJECTS;
+         objhash++)
+    {
+        rushort status = OBJECT(objhash).status;
+
+        /* Skip free object table slots */
+        if (!(OBJECT_STATUS_INUSE & status))
+        {
+            continue;
+        }
+
+        /* Skip null slots (the JVMCFG_NULL_OBJECT and any slot that
+           is currently being intialized). */
+        if (OBJECT_STATUS_NULL & status)
+        {
+            continue;
+        }
+
+        /* Look only at slots marked as ready for garbage collection */
+        if (OBJECT_STATUS_GCREQ & status)
+        {
+            object_instance_finalize(objhash, JVMCFG_GC_THREAD);
+            (rvoid) object_instance_delete(objhash, rmref);
+            continue;
+        }
+
+    } /* for objhash */
+
+    /* Done with this pass */
+    return;
+
+} /* END of gc_run_refcount() */
+
+
+/*!
+ * @brief Start up garbage collection for a class.
+ *
+ * Initialize garbage collection for a new class static
+ * instance, as set up in class_static_new().  The reverse of
+ * gc_class_delete_refcount().
+ *
+ *
+ * @param  clsidxNEW   Class table index of new class static instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if garbage
+ *          collection was initialized for this class static instance,
+ *          otherwise @link #rfalse false@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null class index or if a garbage collection
+           accounting area has already been
+           allocated for this class@endlink.
+ *
+ *
+ */
+rboolean gc_class_new_refcount(jvm_class_index clsidxNEW)
+{
+    if (jvm_class_index_null == clsidxNEW)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /* Make sure a pointer has not already been allocated */
+    if (rnull != CLASS_GARBAGE(clsidxNEW))
+    {
+        exit_throw_exception(EXIT_GC_ALLOC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /* Allocate heap , do not bother setting to zeroes */
+    CLASS_GARBAGE(clsidxNEW) = HEAP_GET_DATA(sizeof(gc_class_refcount),
+                                                    rfalse);
+
+    /*
+     * Set up list to mark garbage collection status of static fields.
+     * Initialize the list to ZEROES-- no status items set.
+     */
+    u2 ncsfl = CLASS(clsidxNEW).num_class_static_field_lookups;
+    CLASS_GARBAGE(clsidxNEW)->status =
+        HEAP_GET_DATA(sizeof(rbyte) * ncsfl, rtrue);
+
+    /* Start out with no references */
+    CLASS_GARBAGE(clsidxNEW)->refcount = 0;
+
+    /* Should always be false */
+    if ((0 != ncsfl) && (rnull == CLASS_GARBAGE(clsidxNEW)->status))
+    {
+        return(rfalse);
+    }
+
+    return(rtrue);
+
+} /* END of gc_class_new_refcount() */
+
+
+/*!
+ * @brief Shut down and restart garbage collection for a class.
+ *
+ * Reinitialize garbage collection for a reloaded class static instance,
+ * as set up in class_reload().
+ *
+ *
+ * @param  clsidxOLD   Class table index of old class static instance.
+ *
+ * @param  clsidxNEW   Class table index of reloaded class static
+ *                     instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if garbage collection was
+ *          reinitialized for this reloaded class static instance,
+ *          otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target class index@endlink.
+ *
+ */
+rboolean gc_class_reload_refcount(jvm_class_index clsidxOLD,
+                                  jvm_class_index clsidxNEW)
+{
+    if (jvm_class_index_null == clsidxOLD)
+    {
+        return(rfalse);
+    }
+
+    if (jvm_class_index_null == clsidxNEW)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /*
+     * This particular GC algorithm has nothing to adjust since
+     * class_reload() copies the GC pointer and everything else
+     * is still valid in that pointed-to structure.  However,
+     * other GC algorithms might need this hook.
+     */
+
+    return(rtrue);
+
+} /* END of gc_class_reload_refcount() */
+
+
+/*!
+ * @brief Add a class static reference to a class.
+ *
+ * Mark class as having another class static instance reference to it,
+ * namely a @b lower_dim_array or @b initiating_ClassLoader or
+ * @b defining_ClasslLoader The reverse of
+ * gc_class_rmref_from_class_refcount().
+ *
+ *
+ * @param  clsidxFROM Class table index of source class static instance.
+ *                    If @link #jvm_class_index_null
+                      jvm_class_index_null@endlink, this is the class
+ *                    table entry itself.
+ *
+ * @param  clsidxTO   Class table index of target class static instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if class static instance was
+ *          marked, otherwise @link #rfalse rfalse@endlink.
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target class index@endlink.
+ */
+rboolean gc_class_mkref_from_class_refcount(jvm_class_index clsidxFROM,
+                                            jvm_class_index clsidxTO)
+{
+    /* @b clsidxFROM is not used in this implementation */
+
+    if (jvm_class_index_null == clsidxTO)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    CLASS_GARBAGE(clsidxTO)->refcount++;
+
+    return(rtrue);
+
+} /* END of gc_class_mkref_from_class_refcount() */
+
+
+/*
+ * Mark class as having another class object instance reference to it,
+ * namely where OBJECT_STATUS_CLASS is set for that object.  (Usually
+ * marked only one time over the life of the class.)
+ * The reverse of gc_class_rmref_from_object_refcount().
+ *
+ *
+ * @param  objhashFROM Object hash of source object instance.
+ *
+ * @param  clsidxTO    Class table index of target class static instance
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if class static instance was
+ *          marked, otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target class index@endlink.
+ *
+ */
+rboolean
+    gc_class_mkref_from_object_refcount(jvm_object_hash objhashFROM,
+                                        jvm_class_index  clsidxTO)
+{
+    /* @b objhashFROM is not used in this implementation */
+
+    return(gc_class_mkref_from_class_refcount(
+               jvm_class_index_null /* meaningless */,
+               clsidxTO));
+
+} /* END of gc_class_mkref_from_object_refcount() */
+
+
+/*!
+ * @brief Remove a class static reference from a class.
+ *
+ * Unmark class as having a class static instance reference to it.
+ * The reverse of gc_class_mkref_from_class_refcount().
+ *
+ *
+ * @param  clsidxFROM Class table index of source class static instance.
+ *                    If @link #jvm_class_index_null
+                      jvm_class_index_null@endlink, this is the class
+ *                    table entry itself.
+ *
+ * @param  clsidxTO   Class table index of target class static instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if class static instance was
+ *          unmarked, otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target class index@endlink.
+ *
+ */
+rboolean gc_class_rmref_from_class_refcount(jvm_class_index clsidxFROM,
+                                            jvm_class_index clsidxTO)
+{
+    /* @b clsidxFROM is not used in this implementation */
+
+    if (jvm_class_index_null == clsidxTO)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+
+    /* Limit decrement to lower bound of zero */
+    if (0 < CLASS_GARBAGE(clsidxTO)->refcount)
+    {
+        CLASS_GARBAGE(clsidxTO)->refcount--;
+    }
+
+    /* Flag class ready for GC */
+    if (0 == CLASS_GARBAGE(clsidxTO)->refcount)
+    {
+        CLASS(clsidxTO).status |= CLASS_STATUS_GCREQ;
+    }
+
+
+    return(rtrue);
+
+} /* END of gc_class_rmref_from_class_refcount() */
+
+
+/*
+ * Unmark class as having a class object reference to it, namely
+ * where OBJECT_STATUS_CLASS is set for that object.  (Usually marked
+ * only one time over the life of the class, so this will effectively
+ * mark the class itself as being ready for garbage collection.)
+ * The reverse of gc_class_mkref_refcount().
+ *
+ *
+ * @param  objhashFROM Object hash of source object instance.
+ *
+ * @param  clsidxTO    Class table index of target class static instance
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if class static instance was
+ *          unmarked, otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target class index@endlink.
+ *
+ */
+rboolean
+    gc_class_rmref_from_object_refcount(jvm_object_hash objhashFROM,
+                                        jvm_class_index clsidxTO)
+{
+    /* @b objhashFROM is not used in this implementation */
+
+    return(gc_class_rmref_from_class_refcount(
+               jvm_class_index_null /* meaningless*/,
+               clsidxTO));
+
+} /* END of gc_class_rmref_from_object_refcount() */
+
+
+/*!
+ * @brief Add a class static field reference to a class.
+ *
+ * Mark class static field as being a reference type (typically
+ * after loading the class).  The reverse of
+ * gc_class_field_rmref_refcount().
+ *
+ *
+ * @param  clsidxTO   Class table index of target class static instance.
+ *
+ * @param  csflidxTO  Class static field lookup index to field in
+ *                    target class static instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if class static field was marked,
+ *          otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target class index@endlink.
+ *
+ */
+rboolean gc_class_field_mkref_refcount(jvm_class_index        clsidxTO,
+                                       jvm_field_lookup_index csflidxTO)
+{
+    if (jvm_class_index_null == clsidxTO)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /* Perform range check */
+    if (CLASS(clsidxTO).num_class_static_field_lookups >= csflidxTO)
+    {
+        return(rfalse);
+    }
+
+    jvm_object_hash objhash =
+        CLASS(clsidxTO).class_static_field_data[csflidxTO]._jobjhash;
+
+    if (jvm_object_hash_null == objhash)
+    {
+        return(rfalse);
+    }
+
+    /* This object instance field is a reference type */
+    CLASS_GARBAGE(clsidxTO)->status[csflidxTO] |= CLASS_STATUS_REFERENCE;
+
+    OBJECT_GARBAGE(objhash)->refcount++;
+
+    return(rtrue);
+
+} /* END of gc_class_field_mkref_refcount() */
+
+
+/*!
+ * @brief Remove a class static field reference from a class.
+ *
+ * Mark class static field as @e not being a reference type (typically
+ * before unloading the class.  The reverse of
+ * gc_class_field_mkref_refcount().
+ *
+ *
+ * @param  clsidxTO   Class table index of target class static instance.
+ *
+ * @param  csflidxTO  Class static field lookup index to field in
+ *                    target class.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if class static field was marked,
+ *          otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null class index@endlink.
+ *
+ */
+rboolean gc_class_field_rmref_refcount(jvm_class_index        clsidxTO,
+                                       jvm_field_lookup_index csflidxTO)
+{
+    if (jvm_class_index_null == clsidxTO)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /* Perform range check */
+    if (CLASS(clsidxTO).num_class_static_field_lookups >= csflidxTO)
+    {
+        return(rfalse);
+    }
+
+    jvm_object_hash objhash =
+        CLASS(clsidxTO).class_static_field_data[csflidxTO]._jobjhash;
+
+    if (jvm_object_hash_null == objhash)
+    {
+        return(rfalse);
+    }
+
+    /* Honor removal request only if it was marked in the first place */
+    if (CLASS_GARBAGE(clsidxTO)->status[csflidxTO] &
+        CLASS_STATUS_REFERENCE)
+    {
+        /* Limit decrement to lower bound of zero */
+        if (0 < OBJECT_GARBAGE(objhash)->refcount)
+        {
+            OBJECT_GARBAGE(objhash)->refcount--;
+        }
+
+        /* Flag class static field ready for GC */
+        if (0 == OBJECT_GARBAGE(objhash)->refcount)
+        {
+            CLASS(clsidxTO).status |= CLASS_STATUS_GCREQ;
+        }
+
+        return(rtrue);
+    }
+
+    return(rfalse);
+
+} /* END of gc_class_field_rmref_refcount() */
+
+
+/*!
+ * @brief Garbage collect a class static instance.
+ *
+ * Finalize garbage collection for a class static instance that will
+ * no longer be used, as set up in class_static_delete().  If there
+ * are any outstanding references to this class, those must first
+ * be removed, at which time gc_run_refcount() will perform the
+ * finalization instead.  The reverse of gc_class_new_refcount().
+ *
+ * @note Since this function is the reverse of gc_class_new_refcount(),
+ *       the @link #rclass.pgarbage rclass.pgarbage@endlink pointer must
+ *       be freed by @link #HEAP_DATA_FREE() HEAP_DATA_FREE@endlink.
+ *
+ * @param  clsidxOLD     Class table index of defunct class static
+ *                       instance.
+ *
+ * @param  delete_class  If @link #rtrue rtrue@endlink, attempt
+ *                       class_static_delete() when finished with
+ *                       garbage collection.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if garbage collection was
+ *          finalized for this class static instance, otherwise
+ *          @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null source source class index@endlink.
+ *
+ */
+rboolean gc_class_delete_refcount(jvm_class_index clsidxOLD,
+                                  rboolean        delete_class)
+{
+    if (jvm_class_index_null == clsidxOLD)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    u2 csflidx;
+    for (csflidx = 0;
+         csflidx < CLASS(clsidxOLD).num_class_static_field_lookups;
+         csflidx++)
+    {
+        /* If more than zero class static fields, @b status != NULL */
+        if (CLASS_GARBAGE(clsidxOLD)->status[csflidx] &
+            CLASS_STATUS_REFERENCE)
+        {
+            (rvoid) gc_class_field_rmref_refcount(clsidxOLD, csflidx);
+
+            /*
+             * Don't have to know any other data, or whether it might
+             * be an array, for only arrays and references will mark
+             * this field.  Furthermore, since arrays @e are references,
+             * both the @link jvalue#_jarray _jarray@endlink and
+             * @link jvalue#_jobjhash _jobjhash@endlink mean the
+             * same thing semantically.
+             */
+            CLASS(clsidxOLD)
+              .class_static_field_data[csflidx]
+              ._jobjhash =
+                jvm_object_hash_null;
+            CLASS_GARBAGE(clsidxOLD)->status[csflidx] &=
+                ~CLASS_STATUS_REFERENCE;
+        }
+    }
+
+    /* Should never happen */
+    if (rfalse ==
+        gc_class_rmref_from_class_refcount(jvm_class_index_null,
+                                           clsidxOLD))
+    {
+        return(rfalse);
+    }
+
+    /* If gc_class_rmref_refcount() marked class for deletion,go do it*/
+    if (CLASS(clsidxOLD).status & CLASS_STATUS_GCREQ)
+    {
+        /* Also get rid of the class GC accounting area */
+        HEAP_FREE_DATA(CLASS_GARBAGE(clsidxOLD));
+        CLASS_GARBAGE(clsidxOLD) = rnull;
+
+        /* Attempt to actually delete the class itself, if requested */
+        if (rtrue == delete_class)
+        {
+            return(class_static_delete(clsidxOLD, rfalse));
+        }
+    }
+
+    /* There are still outstanding references to this class */
+    return(rfalse);
+
+} /* END of gc_class_delete_refcount() */
+
+
+/*!
+ * @brief Start up garbage collection for an object.
+ *
+ * Initialize garbage collection for a new object instance, as
+ * set up in object_new().  The reverse of gc_object_delete_refcount().
+ *
+ *
+ * @param  objhashNEW  Object table hash of new object instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if garbage collection was
+ *          initialized for this object instance, otherwise
+ *          @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null object hash@endlink.
+ *
+ */
+rboolean gc_object_new_refcount(jvm_object_hash objhashNEW)
+{
+    if (jvm_object_hash_null == objhashNEW)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /* Make sure a pointer has not already been allocated */
+    if (rnull != OBJECT_GARBAGE(objhashNEW))
+    {
+        exit_throw_exception(EXIT_GC_ALLOC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /* Allocate heap , do not bother setting to zeroes */
+    OBJECT_GARBAGE(objhashNEW) =
+        HEAP_GET_DATA(sizeof(gc_object_refcount), rfalse);
+
+
+    /* Find class table entry for this object */
+    jvm_class_index clsidx = OBJECT_OBJECT_LINKAGE(objhashNEW)->clsidx;
+
+    /*
+     * Set up list to mark garbage collection status of static fields.
+     * Initialize the list to ZEROES-- no status items set.
+     */
+    u2 noifl = CLASS(clsidx).num_object_instance_field_lookups;
+    OBJECT_GARBAGE(objhashNEW)->status =
+        HEAP_GET_DATA(sizeof(rbyte) * noifl, rtrue);
+
+    /* Start out with no references */
+    OBJECT_GARBAGE(objhashNEW)->refcount = 0;
+
+    /* Should always be false */
+    if ((0 != noifl) && (rnull == OBJECT_GARBAGE(objhashNEW)->status))
+    {
+        return(rfalse);
+    }
+
+    return(rtrue);
+
+} /* END of gc_object_new_refcount() */
+
+
+/*!
+ * @brief Add a class static reference to an object.
+ *
+ * Mark object as having another class static instance reference to it.
+ * The reverse of gc_object_rmref_from_class_refcount().
+ *
+ *
+ * @param  clsidxFROM Class table index of source class static instance.
+ *
+ * @param  objhashTO  Object table hash of target object instance
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if object instance was marked,
+ *          otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target object hash@endlink.
+ *
+ */
+rboolean gc_object_mkref_from_class_refcount(jvm_class_index clsidxFROM,
+                                             jvm_object_hash objhashTO)
+{
+    /* @b clsidxFROM is not used in this implementation */
+
+    if (jvm_object_hash_null == objhashTO)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    OBJECT_GARBAGE(objhashTO)->refcount++;
+
+    return(rtrue);
+
+} /* END of gc_object_mkref_from_class_refcount() */
+
+
+/*!
+ * @brief Add an object instance reference to an object.
+ *
+ * Mark object as having another object instance reference to it.
+ * The reverse of gc_object_rmref_from_object_refcount().
+ *
+ *
+ * @param  objhashFROM  Object table hash of source object instance.
+ *                      If @link #jvm_object_hash_null
+                        jvm_object_hash_null@endlink, this is the object
+ *                      table entry itself.
+ *
+ * @param  objhashTO    Object table hash of target object instance
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if object instance was marked,
+ *          otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target object hash@endlink.
+ *
+ */
+rboolean
+    gc_object_mkref_from_object_refcount(jvm_object_hash objhashFROM,
+                                        jvm_object_hash objhashTO)
+{
+    /* @b objhashFROM is not used in this implementation */
+
+    return(gc_object_mkref_from_class_refcount(jvm_class_index_null,
+                                               objhashTO));
+
+} /* END of gc_object_mkref_from_object_refcount() */
+
+
+/*!
+ * @brief Remove a class static reference from an object.
+ *
+ * Unmark object as having a class static instance reference to it.
+ * The reverse of gc_object_mkref_from_class_refcount().
+ *
+ *
+ * @param  clsidxFROM Class table index of source class static instance.
+ *
+ * @param  objhashTO  Object table hash of target object instance
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if class static instance was
+ *          unmarked, otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target object hash@endlink.
+ *
+ */
+rboolean gc_object_rmref_from_class_refcount(jvm_class_index clsidxFROM,
+                                    jvm_object_hash objhashTO)
+{
+    /* @b clsidxFROM is not used in this implementation */
+
+    if (jvm_object_hash_null == objhashTO)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /* Limit decrement to lower bound of zero */
+    if (0 < OBJECT_GARBAGE(objhashTO)->refcount)
+    {
+        OBJECT_GARBAGE(objhashTO)->refcount--;
+    }
+
+    /* Flag object instance ready for GC */
+    if (0 == OBJECT_GARBAGE(objhashTO)->refcount)
+    {
+        OBJECT(objhashTO).status |= OBJECT_STATUS_GCREQ;
+    }
+
+    return(rtrue);
+
+} /* END of gc_object_rmref_from_class_refcount() */
+
+
+/*
+ * Unmark object as having an object instance reference to it.
+ * The reverse of gc_object_mkref_from_object_refcount().
+ *
+ *
+ * @param  objhashFROM  Object table hash of source object instance.
+ *                      If @link #jvm_object_hash_null
+                        jvm_object_hash_null@endlink, this is the object
+ *                      table entry itself.
+ *
+ * @param  objhashTO    Object table hash of target object instance
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if object instance was
+ *          unmarked, otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target object hash@endlink.
+ *
+ */
+rboolean
+    gc_object_rmref_from_object_refcount(jvm_object_hash objhashFROM,
+                                         jvm_object_hash objhashTO)
+{
+    /* @b objhashFROM is not used in this implementation */
+
+    return(gc_object_rmref_from_class_refcount(jvm_class_index_null,
+                                               objhashTO));
+
+} /* END of gc_object_rmref_from_object_refcount() */
+
+
+/*!
+ * @brief Add an object instance field reference to an object.
+ *
+ * Mark object instance field as being a reference type (typically
+ * after loading the class and instantiating an object of that
+ * class type).  The reverse of gc_object_field_rmref_refcount().
+ *
+ *
+ * @param  objhashTO   Object table hash of target object instance.
+ *
+ * @param  oiflidxTO   Object instance field lookup index to field
+ *                     in target object instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if object instance field was
+ *          marked, otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target object hash@endlink.
+ *
+ */
+rboolean gc_object_field_mkref_refcount(jvm_object_hash objhashTO,
+                                       jvm_field_lookup_index oiflidxTO)
+{
+    if (jvm_object_hash_null == objhashTO)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    jvm_class_index clsidx = OBJECT_OBJECT_LINKAGE(objhashTO)->clsidx;
+    u2 noifl = CLASS(clsidx).num_object_instance_field_lookups;
+
+    /* Perform range check */
+    if (noifl >= oiflidxTO)
+    {
+        return(rfalse);
+    }
+
+    jvm_object_hash objhashFLD =
+        OBJECT(objhashTO)
+          .object_instance_field_data[oiflidxTO]
+          ._jobjhash;
+
+    if (jvm_object_hash_null == objhashFLD)
+    {
+        return(rfalse);
+    }
+
+    /* This object instance field is a reference type */
+    OBJECT_GARBAGE(objhashTO)->status[oiflidxTO] |=
+        OBJECT_STATUS_REFERENCE;
+
+    OBJECT_GARBAGE(objhashFLD)->refcount++;
+
+    return(rtrue);
+
+} /* END of gc_object_field_mkref_refcount() */
+
+
+/*!
+ * @brief Add an object instance field reference to an object.
+ *
+ * Mark object instance field as @e not being a reference type any more
+ * (typically before unloading the class).  The reverse of
+ * gc_object_field_rmref_refcount().
+ *
+ *
+ * @param  objhashTO    Object table hash of target object instance.
+ *
+ * @param  oiflidxTO    Object instance field lookup index to field
+ *                      in target object instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if class static field was
+ *          unmarked, otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null target object hash@endlink.
+ *
+ */
+rboolean gc_object_field_rmref_refcount(jvm_object_hash objhashTO,
+                                       jvm_field_lookup_index oiflidxTO)
+{
+    if (jvm_object_hash_null == objhashTO)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    jvm_class_index clsidx = OBJECT_OBJECT_LINKAGE(objhashTO)->clsidx;
+    u2 noifl = CLASS(clsidx).num_object_instance_field_lookups;
+
+    /* Perform range check */
+    if (noifl >= oiflidxTO)
+    {
+        return(rfalse);
+    }
+
+    jvm_object_hash objhashFLD =
+        CLASS(clsidx).class_static_field_data[oiflidxTO]._jobjhash;
+
+    if (jvm_object_hash_null == objhashFLD)
+    {
+        return(rfalse);
+    }
+
+    /* Honor removal request only if it was marked in the first place */
+    if (OBJECT_GARBAGE(objhashTO)->status[oiflidxTO] &
+        OBJECT_STATUS_REFERENCE)
+    {
+        /* Limit decrement to lower bound of zero */
+        if (0 < OBJECT_GARBAGE(objhashFLD)->refcount)
+        {
+            OBJECT_GARBAGE(objhashFLD)->refcount--;
+        }
+
+        /* Flag object instance field ready for GC */
+        if (0 == OBJECT_GARBAGE(objhashFLD)->refcount)
+        {
+            OBJECT_GARBAGE(objhashFLD)->status[oiflidxTO] |= 
+                                                    OBJECT_STATUS_GCREQ;
+        }
+        return(rtrue);
+    }
+
+    return(rfalse);
+
+} /* END of gc_object_field_rmref_refcount() */
+
+
+/*!
+ * @brief Garbage collect an object instance.
+ *
+ * Finalize garbage collection for an object instance that will no
+ * longer be used, as set up in object_instance_delete().  If there
+ * are any outstanding references to this class, those must first
+ * be removed, at which time gc_run_refcount() will perform the
+ * finalization instead.  The reverse of gc_object_new_refcount().
+ *
+ * @note Since this function is the reverse of gc_object_new_refcount(),
+ * the @link #rclass.pgarbage rclass.pgarbage@endlink pointer must be
+ * freed by @link #HEAP_DATA_FREE() HEAP_DATA_FREE@endlink.
+ *
+ *
+ * @param  objhashOLD  Object table hash of defunct object instance.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if garbage collection was
+ *          finalized for this object instance, otherwise
+ *          @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null object hash@endlink.
+ *
+ */
+rboolean gc_object_delete_refcount(jvm_object_hash objhashOLD)
+{
+    if (jvm_object_hash_null == objhashOLD)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    jvm_class_index clsidx = OBJECT_OBJECT_LINKAGE(objhashOLD)->clsidx;
+
+    u2 oiflidx;
+    for (oiflidx = 0;
+         oiflidx < CLASS(clsidx).num_object_instance_field_lookups;
+         oiflidx++)
+    {
+        /*If more than zero object instance fields,@b status != NULL */
+        if (OBJECT_GARBAGE(objhashOLD)->status[oiflidx] &
+            OBJECT_STATUS_REFERENCE)
+        {
+            (rvoid) gc_object_field_rmref_refcount(objhashOLD, oiflidx);
+
+            /*
+             * Don't have to know any other data, or whether it might
+             * be an array, for only arrays and references will mark
+             * this field.  Furthermore, since arrays @e are references,
+             * both the @link jvalue#_jarray _jarray@endlink and
+             * @link jvalue#_jobjhash _jobjhash@endlink mean the
+             * same thing semantically.
+             */
+            OBJECT(objhashOLD)
+                .object_instance_field_data[oiflidx]
+                    ._jobjhash = jvm_object_hash_null;
+
+            OBJECT_GARBAGE(objhashOLD)->status[oiflidx] &=
+                ~OBJECT_STATUS_REFERENCE;
+        }
+    }
+
+    /* Should never happen */
+    if (rfalse == gc_object_rmref_from_object_refcount(
+                      jvm_object_hash_null,
+                      objhashOLD))
+    {
+        return(rfalse);
+    }
+
+    /*
+     * If gc_object_rmref_refcount() marked object for deletion,
+     * go do it
+     */
+    if (OBJECT(objhashOLD).status & OBJECT_STATUS_GCREQ)
+    {
+        /* Also get rid of the class GC accounting area */
+        HEAP_FREE_DATA(CLASS_GARBAGE(objhashOLD));
+        CLASS_GARBAGE(objhashOLD) = rnull;
+
+        /* Finalize object before removing it */
+        object_instance_finalize(objhashOLD, JVMCFG_GC_THREAD);
+        return(object_instance_delete(objhashOLD, rfalse));
+    }
+
+    /* There are still outstanding references to this object */
+    return(rfalse);
+
+} /* END of gc_object_delete_refcount() */
+
+
+/*!
+ * @brief Start up garbage collection for a new Java virtual
+ * method stack frame.
+ *
+ * Initialize garbage collection for a new stack frame for a
+ * virtual Java method invocation, as set up in PUSH_GC().
+ * The reverse of gc_stack_delete_refcount().
+ *
+ * Initializing to zeroes during heap allocation means that
+ * all status bits will be turned OFF, so no local variables
+ * are marked with any status until later.
+ *
+ *
+ * @param  thridxNEW    Thread table index to thread that is setting
+ *                      up a new stack frame for a method invocation.
+ *
+ * @param  num_locals   Number of local variables in this method.
+ *
+ *
+ * @returns Pointer to (gc_stack) for this object instance
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null thread index@endlink.
+ *
+ *
+ * @attention Due to the fact that there may be any number of garbage
+ *            collection algorithms implemented for the JVM, and with
+ *            the need to keep the API to the GC system constant, this
+ *            return value is @b not defined to be related to
+ *            any particular type of GC.  Instead it is a simple
+ *            @link #rvoid rvoid@endlink pointer.
+ *
+ *
+ */
+rvoid *gc_stack_new_refcount(jvm_thread_index thridxNEW,rint num_locals)
+{
+    if (jvm_thread_index_null == thridxNEW)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    /* Allocate heap AND INITIALIZED TO ZEROES */
+    gc_stack_refcount *rc =
+        HEAP_GET_DATA(sizeof(gc_stack_refcount) -
+                                 sizeof(rbyte) +
+                                 (sizeof(rbyte) * num_locals),
+                             rtrue);
+
+    rc->num_local_variables = num_locals;
+
+    return((rvoid *) rc);
+
+} /* END of gc_stack_new_refcount() */
+
+
+/*!
+ * @brief Add local variable reference to an object.
+ * 
+ * Mark object as having another local variable instance reference
+ * to it.  The reverse of gc_stack_rmref_refcount().
+ *
+ *
+ * @param  thridxFROM Thread table index to thread that is setting
+ *                    up new stack from for a method invocation.
+ *
+ * @param  frmidxTO   Index into current frame of local variable
+ *                    that is an object reference.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if object instance was marked,
+ *          otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null thread index@endlink.
+ *
+ */
+rboolean gc_stack_mkref_from_jvm_refcount(jvm_thread_index thridxFROM,
+                                          jint             frmidxTO)
+{
+    if (jvm_thread_index_null == thridxFROM)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    gc_stack_refcount *pgcs = GET_GC(thridxFROM);
+
+    /* Range check frame index */
+    if (pgcs->num_local_variables <= frmidxTO)
+    {
+        return(rfalse);
+    }
+
+    /* Mark local var as a reference */
+    pgcs->status[frmidxTO] |= LOCAL_STATUS_REFERENCE;
+
+    return(gc_object_mkref_from_object_refcount(
+               jvm_object_hash_null,
+               (jvm_object_hash) GET_LOCAL_VAR(thridxFROM, frmidxTO)));
+
+} /* END of gc_stack_mkref_from_jvm_refcount() */
+
+
+/*!
+ * @brief Remove local variable reference from an object.
+ *
+ * Unmark object from having another local variable instance
+ * references to it.  The reverse of gc_stack_mkref_refcount().
+ *
+ *
+ * @param  thridxFROM Thread table index to thread that is setting
+ *                    up new stack from for a method invocation.
+ *
+ * @param  frmidxTO   Index into current frame of local variable
+ *                    that is an object reference.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if object instance was marked,
+ *          otherwise @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null thread index@endlink.
+ *
+ */
+rboolean gc_stack_rmref_from_jvm_refcount(jvm_thread_index thridxFROM,
+                                          jint             frmidxTO)
+{
+    if (jvm_thread_index_null == thridxFROM)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    gc_stack_refcount *pgcs = GET_GC(thridxFROM);
+
+    /* Range check frame index */
+    if (pgcs->num_local_variables <= frmidxTO)
+    {
+        return(rfalse);
+    }
+
+    /* Honor removal request only if it was marked in the first place */
+    if (pgcs->status[frmidxTO] & LOCAL_STATUS_REFERENCE)
+    {
+        return(gc_object_rmref_from_object_refcount(
+                   jvm_object_hash_null,
+                   (jvm_object_hash) GET_LOCAL_VAR(thridxFROM,
+                                                   frmidxTO)));
+    }
+
+    /* Complain if not marked in the first place */
+    return(rfalse);
+
+} /* END of gc_stack_rmref_from_jvm_refcount() */
+
+
+/*!
+ * @brief Garbage collect a Java virtual method stack frame.
+ *
+ * Finalize garbage collection for a stack frame that will no
+ * longer be used by a virtual Java method, as set up in PUSH_GC().
+ * This function is called from POP_GC().  It is the reverse
+ * of gc_stack_new_refcount().
+ *
+ *
+ * @param  thridxOLD  Thread table index to thread that is tearing
+ *                    down an old stack frame from a method invocation.
+ *
+ * @param  ppgcs      Pointer to GC stack area pointer for this frame
+ *
+ * @param  plocal_teardown  Pointer to local area of partially popped
+ *                          frame.
+ *
+ *
+ * @returns @link #rtrue rtrue@endlink if garbage collection was
+ *          finalized for this method return, otherwise
+ *          @link #rfalse rfalse@endlink.
+ *
+ *
+ * @throws JVMCLASS_JAVA_LANG_INTERNALERROR 
+           @link #JVMCLASS_JAVA_LANG_INTERNALERROR
+           if null thread index@endlink.
+ *
+ *
+ * @attention Due to the fact that there may be any number of garbage
+ *            collection algorithms implemented for the JVM, and with
+ *            the need to keep the API to the GC system constant, the
+ *            parameter @b ppgcs is @b not defined to be related to
+ *            any particular type of GC.  Instead it is a simple
+ *            @link #rvoid rvoid@endlink pointer.
+ *
+ */
+rboolean gc_stack_delete_refcount(jvm_thread_index   thridxOLD,
+                                  rvoid            **ppgcs,
+                                  jint              *plocal_teardown)
+{
+    if (jvm_thread_index_null == thridxOLD)
+    {
+        exit_throw_exception(EXIT_JVM_GC,
+                             JVMCLASS_JAVA_LANG_INTERNALERROR);
+/*NOTREACHED*/
+    }
+
+    gc_stack_refcount *pgcs = *((gc_stack_refcount **) ppgcs);
+
+    jint frmidx;
+    for (frmidx = 0; frmidx < pgcs->num_local_variables; frmidx++)
+    {
+        if (pgcs->status[frmidx] & LOCAL_STATUS_REFERENCE)
+        {
+            /* WARNING:  Working with a NEGATIVE INDEX here!!! */
+            (rvoid) gc_object_rmref_from_object_refcount(
+                        jvm_object_hash_null,
+                        (jvm_object_hash) plocal_teardown[0 - frmidx]);
+
+            /*
+             * Since stack is now being popped, and furthermore
+             * since this @link gc_stack_refcount#status status@endlink array
+             * will soon have HEAP_FREE_DATA() run against it, these
+             * are not needed:
+             */
+
+            /* PUT_LOCAL_VAR(thridx, frmidx, jvm_object_hash_null); */
+            /* pgcs->status[frmidx] &= ~LOCAL_STATUS_REFERENCE;     */
+        }
+    }
+
+    HEAP_FREE_DATA(pgcs);
+
+    return(rtrue);
+
+} /* END of gc_stack_delete_refcount() */
+
+#endif /* CONFIG_GC_TYPE_REFCOUNT || CONFIG_OPTIONS_COMPILE_ALL */
+
+
+/* EOF */

Modified: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_stub.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_stub.c?rev=329302&r1=329301&r2=329302&view=diff
==============================================================================
--- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_stub.c (original)
+++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/gc_stub.c Fri Oct 28 14:07:35 2005
@@ -8,7 +8,8 @@
  * a memory allocation and garbage collection design for the project.
  *
  * This is the first of hopefully a number of garbage collection
- * schemes.  Others should be named @b gc_somename.c .
+ * schemes.  Others should be named @b gc_somename.c and should
+ * be configured into @link ./config.sh ./config.sh@endlink.
  *
  * The common header file @link jvm/src/gc.h gc.h@endlink defines
  * the prototypes for all garbage collection implementations by way