Patch: gcj -vs- Boehm GC, take 2

Tom Tromey tromey@cygnus.com
Tue Feb 29 09:41:00 GMT 2000


Here is take 2 of my patch to add bitmap object descriptors (for the
Boehm GC) to gcj.  I addressed rth's comments in this one.

Ok to commit?

2000-02-17  Tom Tromey  <tromey@cygnus.com>

	* Makefile.in (JAVA_OBJS): Added boehm.o.
	(boehm.o): New target.
	* Make-lang.in (JAVA_SRCS): Added boehm.c.
	* java-tree.h (flag_use_boehm_gc): Declare.
	(get_boehm_type_descriptor): Declare.
	* lang.c (lang_f_options): Added `use-boehm-gc'.
	(flag_use_boehm_gc): New global.
	* lang-options.h: Added -fuse-boehm-gc.
	* boehm.c: New file.
	* class.c (get_dispatch_table): If class uses a Boehm type
	descriptor, put it in the vtable.
	(make_class_data): Removed dead code.

Tom

Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/Makefile.in,v
retrieving revision 1.49
diff -u -r1.49 Makefile.in
--- Makefile.in	2000/02/26 19:56:22	1.49
+++ Makefile.in	2000/02/29 17:37:55
@@ -166,7 +166,7 @@
 #
 JAVA_OBJS = parse.o class.o decl.o expr.o constants.o lang.o typeck.o \
   except.o verify.o zextract.o jcf-io.o jcf-parse.o mangle.o jcf-write.o \
-  buffer.o check-init.o jcf-depend.o jcf-path.o xref.o
+  buffer.o check-init.o jcf-depend.o jcf-path.o xref.o boehm.o
 
 JAVA_OBJS_LITE = parse-scan.o jv-scan.o
 
@@ -268,6 +268,8 @@
   jcf-reader.c jcf.h javaop.h javaop.def $(srcdir)/../version.h
 gjavah.o : $(CONFIG_H) $(srcdir)/../system.h $(JAVA_TREE_H) gjavah.c \
   jcf-reader.c jcf.h javaop.h $(srcdir)/../version.h
+boehm.o: boehm.c $(CONFIG_H) $(srcdir)/../system.h $(TREE_H) $(JAVA_TREE_H) \
+  $(PARSE_H)
 buffer.o : buffer.c $(CONFIG_H) buffer.h $(srcdir)/../gansidecl.h \
   $(srcdir)/../system.h $(srcdir)/../toplev.h
 check-init.o : check-init.c $(CONFIG_H) $(srcdir)/../gansidecl.h \
Index: boehm.c
===================================================================
RCS file: boehm.c
diff -N boehm.c
--- /dev/null	Tue May  5 13:32:27 1998
+++ boehm.c	Tue Feb 29 09:37:56 2000
@@ -0,0 +1,152 @@
+/* Functions related to the Boehm garbage collector.
+   Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+Java and all Java-based marks are trademarks or registered trademarks
+of Sun Microsystems, Inc. in the United States and other countries.
+The Free Software Foundation is independent of Sun Microsystems, Inc.  */
+
+/* Written by Tom Tromey <tromey@cygnus.com>.  */
+
+#include <config.h>
+
+#include "system.h"
+#include "tree.h"
+#include "java-tree.h"
+#include "parse.h"
+
+/* Compute a procedure-based object descriptor.  We know that our
+   `kind' is 0, and `env' is likewise 0, so we have a simple
+   computation.  From the GC sources:
+	    (((((env) << LOG_MAX_MARK_PROCS) | (proc_index)) << DS_TAG_BITS) \
+	    | DS_PROC)
+   Here DS_PROC == 2.  */
+#define PROCEDURE_OBJECT_DESCRIPTOR build_int_2 (2, 0)
+
+/* Treat two HOST_WIDE_INT's as a contiguous bitmap, with bit 0 being
+   the least significant.  This function sets bit N in the bitmap.  */
+static void
+set_bit (unsigned HOST_WIDE_INT *low, unsigned HOST_WIDE_INT *high,
+	 unsigned int n)
+{
+  HOST_WIDE_INT *which;
+
+  if (n >= HOST_BITS_PER_WIDE_INT)
+    {
+      n -= HOST_BITS_PER_WIDE_INT;
+      which = high;
+    }
+  else
+    which = low;
+
+  *which |= (HOST_WIDE_INT) 1 << n;
+}
+
+/* Return the marking bitmap for the class TYPE.  For now this is a
+   single word describing the type.  */
+tree
+get_boehm_type_descriptor (tree type)
+{
+  unsigned int count, log2_size, ubit;
+  int bit;
+  int all_bits_set = 1;
+  int last_set_index = 0;
+  int pointer_after_end = 0;
+  unsigned HOST_WIDE_INT low = 0, high = 0;
+  tree field, value;
+
+  /* If the GC wasn't requested, just use a null pointer.  */
+  if (! flag_use_boehm_gc)
+    return null_pointer_node;
+
+  /* If we have a type of unknown size, use a proc.  */
+  if (int_size_in_bytes (type) == -1)
+    return PROCEDURE_OBJECT_DESCRIPTOR;
+
+  bit = POINTER_SIZE;
+  /* The size of this node has to be known.  And, we only support 32
+     and 64 bit targets, so we need to know that the log2 is one of
+     our values.  */
+  log2_size = exact_log2 (bit);
+  if (bit == -1 || (log2_size != 2 && log2_size != 3))
+    {
+      /* This means the GC isn't supported.  We should probably
+	 abort or give an error.  Instead, for now, we just silently
+	 revert.  FIXME.  */
+      return null_pointer_node;
+    }
+  bit *= BITS_PER_UNIT;
+
+  /* Warning avoidance.  */
+  ubit = (unsigned int) bit;
+
+  field = TYPE_FIELDS (type);
+  if (DECL_NAME (field) == NULL_TREE)
+    field = TREE_CHAIN (field);  /* Skip dummy field for inherited data. */
+  for (count = 0; field != NULL_TREE; field = TREE_CHAIN (field))
+    {
+      if (FIELD_STATIC (field))
+	continue;
+
+      if (JREFERENCE_TYPE_P (TREE_TYPE (field)))
+	{
+	  last_set_index = count;
+	  /* First word in object corresponds to most significant byte
+	     of bitmap.  */
+	  set_bit (&low, &high, ubit - count);
+	  if (count > ubit - 2)
+	    pointer_after_end = 1;
+	}
+      else
+	all_bits_set = 0;
+
+      ++count;
+    }
+
+  /* If the object is all pointers, or if the part with pointers fits
+     in our bitmap, then we are ok.  Otherwise we have to allocate it
+     a different way.  */
+  if (all_bits_set)
+    {
+      /* In the GC the computation looks something like this:
+	 value = DS_LENGTH | WORDS_TO_BYTES (last_set_index + 1);
+	 DS_LENGTH is 0.
+	 WORDS_TO_BYTES shifts by log2(bytes-per-pointer).  */
+      count = 0;
+      ++last_set_index;
+      while (last_set_index)
+	{
+	  if ((last_set_index & 1))
+	    set_bit (&low, &high, log2_size + count);
+	  last_set_index >>= 1;
+	  ++count;
+	}
+      value = build_int_2 (low, high);
+    }
+  else if (! pointer_after_end)
+    {
+      /* Bottom two bits for bitmap mark type are 01.  */
+      set_bit (&low, &high, 0);
+      value = build_int_2 (low, high);
+    }
+  else
+    value = PROCEDURE_OBJECT_DESCRIPTOR;
+
+  return value;
+}
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/java-tree.h,v
retrieving revision 1.54
diff -u -r1.54 java-tree.h
--- java-tree.h	2000/02/26 19:56:23	1.54
+++ java-tree.h	2000/02/29 17:37:59
@@ -141,6 +141,9 @@
 /* When non zero, call a library routine to do integer divisions. */
 extern int flag_use_divide_subroutine;
 
+/* When non zero, generate code for the Boehm GC.  */
+extern int flag_use_boehm_gc;
+
 /* The Java .class file that provides main_class;  the main input file. */
 extern struct JCF *current_jcf;
 
@@ -662,6 +665,8 @@
 # endif /* JCF_USE_STDIO */
 #endif
 void java_debug_context PARAMS ((void));
+
+extern tree get_boehm_type_descriptor PARAMS ((tree));
 
 /* We use ARGS_SIZE_RTX to indicate that gcc/expr.h has been included
    to declare `enum expand_modifier'. */
Index: lang.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/lang.c,v
retrieving revision 1.36
diff -u -r1.36 lang.c
--- lang.c	2000/02/26 19:56:23	1.36
+++ lang.c	2000/02/29 17:38:00
@@ -110,6 +110,9 @@
 /* When non zero, call a library routine to do integer divisions. */
 int flag_use_divide_subroutine = 1;
 
+/* When non zero, generate code for the Boehm GC.  */
+int flag_use_boehm_gc = 0;
+
 /* From gcc/flags.h, and indicates if exceptions are turned on or not.  */
 
 extern int flag_new_exceptions;
@@ -127,6 +130,7 @@
   {"emit-class-file", &flag_emit_class_files, 1},
   {"emit-class-files", &flag_emit_class_files, 1},
   {"use-divide-subroutine", &flag_use_divide_subroutine, 1},
+  {"use-boehm-gc", &flag_use_boehm_gc, 1}
 };
 
 JCF *current_jcf;
Index: lang-options.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/lang-options.h,v
retrieving revision 1.11
diff -u -r1.11 lang-options.h
--- lang-options.h	1999/07/21 14:51:24	1.11
+++ lang-options.h	2000/02/29 17:38:00
@@ -1,5 +1,5 @@
 /* Switch definitions for the GNU compiler for the Java(TM) language.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -33,6 +33,7 @@
   { "-fno-assume-compiled", "" },
   { "-femit-class-file", "" },
   { "-femit-class-files", "Dump class files to <name>.class" },
+  { "-fuse-boehm-gc", "Generate code for Boehm GC" },
 #if ! USE_CPPLIB
   { "-MD", "Print dependencies to FILE.d" },
   { "-MMD", "Print dependencies to FILE.d" },
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/class.c,v
retrieving revision 1.55
diff -u -r1.55 class.c
--- class.c	2000/02/26 05:12:27	1.55
+++ class.c	2000/02/29 17:38:04
@@ -1172,8 +1172,11 @@
 			build1 (ADDR_EXPR, nativecode_ptr_type_node, method),
 			list);
     }
-  /* Dummy entry for compatibility with G++ -fvtable-thunks. */
-  list = tree_cons (integer_zero_node, null_pointer_node, list);
+  /* Dummy entry for compatibility with G++ -fvtable-thunks.  When
+     using the Boehm GC we sometimes stash a GC type descriptor
+     there.  */
+  list = tree_cons (integer_zero_node, get_boehm_type_descriptor (type),
+		    list);
   list = tree_cons (integer_zero_node, this_class_addr, list);
   return build (CONSTRUCTOR, build_prim_array_type (nativecode_ptr_type_node,
 						    nvirtuals + 2),
@@ -1343,12 +1346,8 @@
   constant_pool_constructor = build_constants_constructor ();
 
   START_RECORD_CONSTRUCTOR (temp, object_type_node);
-#if 0
-  PUSH_FIELD_VALUE (temp, "vtable", NULL_TREE);
-#else
   PUSH_FIELD_VALUE (temp, "vtable",
 		    build1 (ADDR_EXPR, dtable_ptr_type, class_dtable_decl));
-#endif
   PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
   FINISH_RECORD_CONSTRUCTOR (temp);
   START_RECORD_CONSTRUCTOR (cons, class_type_node);


More information about the Gcc-patches mailing list