aboutsummaryrefslogtreecommitdiff
path: root/libjava/boehm.cc
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2003-07-23 09:53:53 +0000
committerTom Tromey <tromey@gcc.gnu.org>2003-07-23 09:53:53 +0000
commite1a4d10fc073997cf9d6abc835d295e50e92f770 (patch)
treec95f1a561d15eef08aaefa8f0d22ac7220eda79b /libjava/boehm.cc
parent5c798f921aa4118b8189aed1ab4f1dced24340dd (diff)
downloadgcc-e1a4d10fc073997cf9d6abc835d295e50e92f770.zip
gcc-e1a4d10fc073997cf9d6abc835d295e50e92f770.tar.gz
gcc-e1a4d10fc073997cf9d6abc835d295e50e92f770.tar.bz2
boehm.cc (_Jv_BuildGCDescr): Wrote.
* boehm.cc (_Jv_BuildGCDescr): Wrote. Include limits.h. From-SVN: r69700
Diffstat (limited to 'libjava/boehm.cc')
-rw-r--r--libjava/boehm.cc46
1 files changed, 42 insertions, 4 deletions
diff --git a/libjava/boehm.cc b/libjava/boehm.cc
index 5006059..8e62159 100644
--- a/libjava/boehm.cc
+++ b/libjava/boehm.cc
@@ -1,6 +1,6 @@
// boehm.cc - interface between libjava and Boehm GC.
-/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
This file is part of libgcj.
@@ -11,6 +11,7 @@ details. */
#include <config.h>
#include <stdio.h>
+#include <limits.h>
#include <jvm.h>
#include <gcj/cni.h>
@@ -325,11 +326,48 @@ _Jv_MarkArray (void *addr, void *msp, void *msl, void * /*env*/)
// since another one could be registered first. But the compiler also
// knows this, so in that case everything else will break, too.
#define GCJ_DEFAULT_DESCR GC_MAKE_PROC(GC_GCJ_RESERVED_MARK_PROC_INDEX,0)
+
void *
-_Jv_BuildGCDescr(jclass)
+_Jv_BuildGCDescr(jclass self)
{
- /* FIXME: We should really look at the class and build the descriptor. */
- return (void *)(GCJ_DEFAULT_DESCR);
+ jlong desc = 0;
+
+ // Note: for now we only consider a bitmap mark descriptor. We
+ // could also handle the case where the first N fields of a type are
+ // references. However, this is not very likely to be used by many
+ // classes, and it is easier to compute things this way.
+
+ for (jclass klass = self; klass != NULL; klass = klass->getSuperclass())
+ {
+ jfieldID field = JvGetFirstInstanceField(klass);
+ int count = JvNumInstanceFields(klass);
+
+ for (int i = 0; i < count; ++i)
+ {
+ if (field->isRef())
+ {
+ unsigned int off = field->getOffset();
+ // If we run into a weird situation, we bail.
+ if (off % sizeof (void *) != 0)
+ return (void *) (GCJ_DEFAULT_DESCR);
+ off /= sizeof (void *);
+ // Bottom 2 bits are reserved.
+ off += 2;
+ // If we find a field outside the range of our bitmap,
+ // fall back to procedure marker.
+ if (off > CHAR_BIT * sizeof (void *))
+ return (void *) (GCJ_DEFAULT_DESCR);
+ desc |= 1 << off;
+ }
+
+ field = field->getNextField();
+ }
+ }
+
+ // For bitmap mark type, bottom bits are 01.
+ desc |= 1;
+ // Bogus warning avoidance (on many platforms).
+ return (void *) (unsigned long) desc;
}
// Allocate some space that is known to be pointer-free.