This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gcjx] Patch: FYI: Class object creation update


I'm checking this in on the gcjx branch.
This is patch 2/N from the last couple week's worth of gcjx
hacking... I realize this is the second big batch of checkins, a la
Ada; most of my work on gcjx recently has been off-line I'm afraid.

This adds a bunch of improvements to Class object creation.

Tom

Index: gcjx/ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* aot/aotclass.cc (add_class): New method.
	* aot/aotclass.hh (aot_class::add_class): Declare.

	* aot/mangle.cc (mangler): New constructor.
	* aot/mangle.hh (mangler): Declare.

	* aot/aotclass.hh (aot_class::pool_entry): Now public.
	(aot_class::type_assertion_entry): Likewise.
	(aot_class::get_constant_pool): New method.

Index: gcjx/aot/aotclass.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/aot/Attic/aotclass.cc,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 aotclass.cc
--- gcjx/aot/aotclass.cc 31 Jan 2005 01:13:39 -0000 1.1.2.3
+++ gcjx/aot/aotclass.cc 8 Mar 2005 00:18:53 -0000
@@ -127,6 +127,15 @@
 }
 
 int
+aot_class::add_class (const std::string &s)
+{
+  pool_entry e;
+  e.tag = CONSTANT_Class;
+  e.value = s;
+  return add_item (e);
+}
+
+int
 aot_class::add (model_class *k)
 {
   pool_entry e;
Index: gcjx/aot/aotclass.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/aot/Attic/aotclass.hh,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 aotclass.hh
--- gcjx/aot/aotclass.hh 30 Jan 2005 03:10:41 -0000 1.1.2.2
+++ gcjx/aot/aotclass.hh 8 Mar 2005 00:18:53 -0000
@@ -36,6 +36,8 @@
 /// compiler.
 class aot_class
 {
+public:
+
   /// This represents one entry in the constant pool.
   struct pool_entry
   {
@@ -53,6 +55,8 @@
     model_class *derived;
   };
 
+private:
+
   /// The class factory.  FIXME: require it as a parameter and not
   /// keep it as state?
   aot_class_factory *factory;
@@ -105,6 +109,10 @@
   /// of the item.
   int add (model_class *);
 
+  /// Add a class reference to the constant pool, given just the
+  /// descriptor of the class.  Returns the index of the item.
+  int add_class (const std::string &);
+
   /// Add an assertion that BASE is a superclass or superinterface of
   /// DERIVED.
   void add_type_assertion (model_class *base, model_class *derived);
@@ -161,6 +169,12 @@
   {
     return klass;
   }
+
+  /// Return the constant pool.
+  const std::vector<pool_entry> &get_constant_pool () const
+  {
+    return pool;
+  }
 };
 
 #endif // GCJX_AOT_AOTCLASS_HH
Index: gcjx/aot/mangle.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/aot/Attic/mangle.cc,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 mangle.cc
--- gcjx/aot/mangle.cc 13 Feb 2005 04:08:17 -0000 1.1.2.4
+++ gcjx/aot/mangle.cc 8 Mar 2005 00:18:53 -0000
@@ -250,10 +250,17 @@
   result += "E";
 }
 
-mangler::mangler (model_class *declaring, const std::string &fieldname)
+mangler::mangler (model_class *declaring, const char *fieldname)
   : result ("_Z")
 {
   update (declaring, false);
   update (fieldname);
   result += "E";
 }
+
+mangler::mangler (model_class *klass, bool)
+  : result ("_ZTV")
+{
+  update (klass, false);
+  result += "E";
+}
Index: gcjx/aot/mangle.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/aot/Attic/mangle.hh,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 mangle.hh
--- gcjx/aot/mangle.hh 13 Feb 2005 04:08:17 -0000 1.1.2.2
+++ gcjx/aot/mangle.hh 8 Mar 2005 00:18:53 -0000
@@ -55,7 +55,11 @@
 
   // This is a way to create a mangled name for a non-existing field,
   // given its declaring class.
-  mangler (model_class *, const std::string &);
+  mangler (model_class *, const char *);
+
+  /// This is slightly bogus: the bool argument is ignored; this
+  /// constructor is used to create the name of the class' vtable.
+  mangler (model_class *, bool);
 
   std::string get () const
   {
Index: gcc/java/ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* builtins.cc (map_utf8const): Use 'type', not 'type_utf8const'.

	* abi.cc (build_class_reference): Wrote.

	* classobj.cc (create_class_instance): Use new get_vtable
	argument.
	* abi.cc (get_vtable): Updated.
	* abi.hh (gcj_abi::get_vtable): Added argument.
	(cxx_abi::get_vtable): Likewise.
	(bc_abi::get_vtable): Likewise.
	* builtins.cc (get_vtable_decl): Updated.
	* builtins.hh (tree_builtins::get_vtable): Added argument.

	* classobj.cc (handle_interfaces): Updated.
	(create_class_instance): Updated.
	* abi.cc (build_class_reference): Rewrote.
	* abi.hh (gcj_abi::build_class_ref): Changed argument type.
	(cxx_abi::build_class_ref): Likewise.
	(bc_abi::build_class_ref): Likewise.
	* tree.hh (tree_generator::build_class_ref): Updated.
	* tree.cc (build_class_ref): Rewrote.
	(build_class_ref): Likewise.  Changed argument type.
	(build_new_array): Updated.
	* builtins.hh (tree_builtins::find_abi): Updated.
	* builtins.cc (find_abi): Removed argument.
	(map_field_ref): Updated.
	(map_method_call): Likewise.
	(map_new): Likewise.

	* abi.cc (get_vtable): New method.
	* abi.hh (gcj_abi::get_vtable): New abstract method.
	(cxx_abi::get_vtable): Declare.
	(bc_abi::get_vtable): Likewise.
	* glue.hh: Include version.h.
	* decl.cc (initialize_version): Rewrote.
	(GCJ_BINARYCOMPAT_ADDITION): New define.
	(build_class_type): Changed name of field to "dtable".
	* classobj.hh (class_object_creator::create_constants): Declare.
	* classobj.cc (create_constants): New method.
	(make_decl): Don't set DECL_ASSEMBLER_NAME.
	(create_method_throws): Use make_decl.
	(create_index_table): Likewise.  Handle case where table is
	empty.
	(create_class_instance): Set vtable fields.
	* builtins.cc (tree_builtins): Initialize new field.
	(get_symbol): New method.
	(get_vtable_decl): New method.
	(find_abi): Rewrote.
	* builtins.hh (tree_builtins::symbol_count): New field.
	(tree_builtins::get_symbol): Declare.
	(tree_builtins::get_vtable_decl): Likewise.

	* glue.hh: Include output.h.
	* builtins.hh (tree_builtins::utf8typemap): New field.
	(tree_builtins::build_utf8const_type): Declare.
	(tree_builtins::hash_utf8): Likewise.
	* builtins.cc (build_utf8const_type): New method.
	(hash_utf8): Likewise.
	(map_utf8const): Finished.
	* hooks.hh (push_field): Declare.
	* decl.cc (build_utf8_record): Fix length of "data" field.
	(push_field): No longer static.
	(build_method_symbol_type): Fixed field name.
	* classobj.cc (create_one_method_record): Compute values of
	"ncode" and "throws".
	(create_method_throws): New method.

Index: gcc/java/abi.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/abi.cc,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 abi.cc
--- gcc/java/abi.cc 13 Feb 2005 04:11:33 -0000 1.1.2.5
+++ gcc/java/abi.cc 8 Mar 2005 00:19:03 -0000
@@ -147,20 +147,28 @@
 
 tree
 cxx_abi::build_class_reference (tree_builtins *builtins,
-				aot_class *,
-				tree klass)
+				aot_class *current,
+				const std::string &classname)
 {
-  assert (TREE_CODE (klass) == POINTER_TYPE);
-  tree decl = TYPE_STUB_DECL (TREE_TYPE (klass));
-  return build1 (ADDR_EXPR, type_class_ptr, decl);
+  // Turn the class name into a reference to a real class in the
+  // model.
+  model_class *klass = current->get ();
+  // We know that any call to this method necessarily comes from a
+  // .class file.
+  model_unit_class *unit
+    = assert_cast<model_unit_class *> (klass->get_compilation_unit ());
+  model_type *type = unit->find_class_from_descriptor (NULL, klass, classname);
+  return build_class_reference (builtins, current, type);
 }
 
 tree
 cxx_abi::build_class_reference (tree_builtins *builtins,
 				aot_class *,
-				model_class *klass)
+				model_type *klass)
 {
-  tree class_obj = builtins->map_class_object (klass);
+  // FIXME: handle primitive type.
+  tree class_obj
+    = builtins->map_class_object (assert_cast<model_class *> (klass));
   return build1 (ADDR_EXPR, type_class_ptr, class_obj);
 }
 
@@ -173,7 +181,8 @@
   tree n = build3 (CALL_EXPR, klass, allocator,
 		   build_tree_list (NULL_TREE,
 				    build_class_reference (builtins, current,
-							   klass)),
+							   // FIXME
+							   NULL)),
 		   NULL_TREE);
   TREE_SIDE_EFFECTS (n) = 1;
   // Call the constructor.
@@ -185,6 +194,13 @@
   return n;
 }
 
+tree
+cxx_abi::get_vtable (tree_builtins *builtins, model_class *klass,
+		     bool lay_out)
+{
+  return build_address_of (builtins->get_vtable_decl (klass, lay_out));
+}
+
 
 
 tree
@@ -230,17 +246,30 @@
 }
 
 tree
-bc_abi::build_class_reference (tree_builtins *, aot_class *current, tree klass)
+bc_abi::build_class_reference (tree_builtins *, aot_class *current,
+			       const std::string &classname)
 {
-  abort ();
+  // FIXME: handle primitive classes
+  int index = current->add_class (classname);
+  // FIXME: find the constant pool
+  tree cpool = NULL_TREE;
+  return build4 (ARRAY_REF, type_class_ptr,
+		 cpool, build_int_cst (type_jint, index),
+		 NULL_TREE, NULL_TREE);
 }
 
 tree
-bc_abi::build_class_reference (tree_builtins *,
-			       aot_class *,
-			       model_class *)
+bc_abi::build_class_reference (tree_builtins *builtins,
+			       aot_class *current,
+			       model_type *klass)
 {
-  abort ();
+  // FIXME: handle primitive classes
+  int index = current->add (assert_cast<model_class *> (klass));
+  // FIXME: find the constant pool
+  tree cpool = NULL_TREE;
+  return build4 (ARRAY_REF, type_class_ptr,
+		 cpool, build_int_cst (type_jint, index),
+		 NULL_TREE, NULL_TREE);
 }
 
 tree
Index: gcc/java/abi.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/abi.hh,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 abi.hh
--- gcc/java/abi.hh 13 Feb 2005 04:11:33 -0000 1.1.2.3
+++ gcc/java/abi.hh 8 Mar 2005 00:19:03 -0000
@@ -87,13 +87,12 @@
   /// Return a tree representing a reference to some other class.
   virtual tree build_class_reference (tree_builtins *builtins,
 				      aot_class *current,
-				      // FIXME: should take a string here
-				      tree other) = 0;
+				      const std::string &class_name) = 0;
 
   /// Return a tree representing a reference to some other class.
   virtual tree build_class_reference (tree_builtins *builtins,
 				      aot_class *current,
-				      model_class *other) = 0;
+				      model_type *other) = 0;
 
   /// Return an expression that is used to create a new object given
   /// its type, constructor, and arguments to the constructor.
@@ -108,6 +107,12 @@
   /// Return the initial 'state' value for a class compiled with this
   /// ABI.
   virtual int get_class_state () = 0;
+
+  /// Return a pointer to the vtable for the indicated class.  If the
+  /// bool argument is true, we are creating the Class object for
+  /// KLASS and need a fully-filled-in vtable, not just a decl.
+  virtual tree get_vtable (tree_builtins *builtins, model_class *klass,
+			   bool lay_out = false) = 0;
 };
 
 /// This class handles C++ ABI code.
@@ -126,11 +131,12 @@
   tree build_field_reference (tree_builtins *, aot_class *,
 			      tree, model_field *);
 
-  tree build_class_reference (tree_builtins *, aot_class *, tree);
+  tree build_class_reference (tree_builtins *, aot_class *,
+			      const std::string &);
 
   tree build_class_reference (tree_builtins *builtins,
 			      aot_class *current,
-			      model_class *other);
+			      model_type *other);
 
   tree build_new (tree_builtins *, aot_class *, tree, tree, tree);
 
@@ -143,6 +149,8 @@
   {
     return JV_STATE_COMPILED;
   }
+
+  tree get_vtable (tree_builtins *, model_class *, bool);
 };
 
 /// This class handles the binary compatibility ABI.
@@ -161,11 +169,12 @@
   tree build_field_reference (tree_builtins *, aot_class *,
 			      tree, model_field *);
 
-  tree build_class_reference (tree_builtins *, aot_class *, tree);
+  tree build_class_reference (tree_builtins *, aot_class *,
+			      const std::string &);
 
   tree build_class_reference (tree_builtins *builtins,
 			      aot_class *current,
-			      model_class *other);
+			      model_type *other);
 
   tree build_new (tree_builtins *, aot_class *, tree, tree, tree);
 
@@ -178,6 +187,12 @@
   {
     return JV_STATE_PRELOADING;
   }
+
+  tree get_vtable (tree_builtins *, model_class *, bool)
+  {
+    // The BC ABI lays out all vtables at runtime.
+    return null_pointer_node;
+  }
 };
 
 #endif // GCC_TREE_ABI_HH
Index: gcc/java/builtins.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.cc,v
retrieving revision 1.1.2.10
diff -u -r1.1.2.10 builtins.cc
--- gcc/java/builtins.cc 13 Feb 2005 04:14:58 -0000 1.1.2.10
+++ gcc/java/builtins.cc 8 Mar 2005 00:19:03 -0000
@@ -24,7 +24,8 @@
 #include "aot/mangle.hh"
 
 tree_builtins::tree_builtins ()
-  : aot_class_factory ()
+  : aot_class_factory (),
+    symbol_count (0)
 {
 }
 
@@ -35,9 +36,10 @@
 
 
 gcj_abi *
-tree_builtins::find_abi (model_type *)
+tree_builtins::find_abi ()
 {
-  // FIXME: implement
+  if (flag_indirect_dispatch)
+    return &new_abi;
   return &old_abi;
 }
 
@@ -306,7 +308,7 @@
 tree
 tree_builtins::map_field_ref (aot_class *wrapper, tree obj, model_field *field)
 {
-  gcj_abi *abi = find_abi (field->get_declaring_class ());
+  gcj_abi *abi = find_abi ();
 
   tree result
     = abi->build_field_reference (this, wrapper,
@@ -344,7 +346,7 @@
 				tree obj, tree args, model_method *meth,
 				bool is_super)
 {
-  gcj_abi *abi = find_abi (meth->get_declaring_class ());
+  gcj_abi *abi = find_abi ();
   tree result = abi->build_method_call (this, wrapper,
 					meth->static_p () ? NULL_TREE : obj,
 					args, meth, is_super);
@@ -365,35 +367,163 @@
 tree
 tree_builtins::map_new (model_class *klass, tree constructor, tree arguments)
 {
-  gcj_abi *abi = find_abi (klass);
+  gcj_abi *abi = find_abi ();
   return abi->build_new (this, get_class (klass),
 			 map_type (klass), constructor, arguments);
 }
 
 tree
+tree_builtins::build_utf8const_type (int len)
+{
+  if (utf8typemap.find (len) == utf8typemap.end ())
+    {
+      tree field = NULL_TREE;
+      tree new_type = make_node (RECORD_TYPE);
+      push_field (new_type, field, "hash", type_jushort);
+      push_field (new_type, field, "length", type_jushort);
+      push_field (new_type, field, "data",
+		  build_array_type (char_type_node,
+				    build_index_type (build_int_cst (type_jint,
+								     len))));
+      layout_type (new_type);
+      utf8typemap[len] = new_type;
+    }
+  return utf8typemap[len];
+}
+
+int
+tree_builtins::hash_utf8 (const char *s, int len)
+{
+  const unsigned char *ptr = (const unsigned char *) s;
+  const unsigned char *limit = ptr + len;
+  int hash = 0;
+  while (ptr < limit)
+    {
+      // FIXME
+      // int ch = UTF8_GET (ptr, limit);
+      int ch = *ptr++;
+      /* Updated specification from
+	 http://www.javasoft.com/docs/books/jls/clarify.html. */
+      hash = (31 * hash) + ch;
+    }
+  return hash;
+}
+
+tree
 tree_builtins::map_utf8const (const std::string &value)
 {
-  std::map<std::string, tree>::const_iterator it = utf8map.find (value);
-  if (it == utf8map.end ())
+  if (utf8map.find (value) == utf8map.end ())
     {
-      record_creator utf (type_utf8const);
-      utf.set_field ("hash", build_int_cst (type_jushort, 0)); // FIXME
+      // Note: add 1 to length here for trailing \0.
+      tree type = build_utf8const_type (value.length () + 1);
+      int hash = hash_utf8 (value.c_str (), value.length ());
+
+      record_creator utf (type);
+      utf.set_field ("hash", build_int_cst (type_jushort, hash & 0xffff));
       utf.set_field ("length", build_int_cst (type_jushort, value.length ()));
 
-      tree str = build_string (value.length (), value.c_str ());
-      tree strtype = build_index_type (build_int_cst (type_jushort,
-						      value.length ()));
+      tree str = build_string (value.length () + 1, value.c_str ());
+      tree strtype = TREE_TYPE (find_decl (type, "data"));
       TREE_TYPE (str) = strtype;
       TREE_CONSTANT (str) = 1;
+      TREE_INVARIANT (str) = 1;
       TREE_READONLY (str) = 1;
       TREE_STATIC (str) = 1;
       utf.set_field ("data", str);
 
-      utf8map[value] = build_address_of (utf.finish_record ());
+      tree init = utf.finish_record ();
+      TREE_CONSTANT (init) = 1;
+      TREE_INVARIANT (init) = 1;
+      TREE_READONLY (init) = 1;
+
+      char buf[20];
+      sprintf (buf, "_Utf%d", utf8map.size ());
+
+      tree decl = build_decl (VAR_DECL, get_identifier (buf), type);
+      TREE_STATIC (decl) = 1;
+      DECL_ARTIFICIAL (decl) = 1;
+      DECL_IGNORED_P (decl) = 1;
+      TREE_READONLY (decl) = 1;
+      DECL_INITIAL (decl) = init;
+
+      if (HAVE_GAS_SHF_MERGE)
+	{
+	  int decl_size;
+	  // Ensure decl_size is a multiple of utf8const_type's alignment.
+	  decl_size = ((value.length () + 5 + TYPE_ALIGN_UNIT (type) - 1)
+		       & ~(TYPE_ALIGN_UNIT (type) - 1));
+	  if (flag_merge_constants && decl_size < 256)
+	    {
+	      char buf[32];
+	      int flags = (SECTION_OVERRIDE
+			   | SECTION_MERGE | (SECTION_ENTSIZE & decl_size));
+	      sprintf (buf, ".rodata.jutf8.%d", decl_size);
+	      named_section_flags (buf, flags);
+	      DECL_SECTION_NAME (decl) = build_string (strlen (buf), buf);
+	    }
+	}
+
+      layout_decl (decl, 0);
+      rest_of_decl_compilation (decl, 1, 0);
+      make_decl_rtl (decl);
+
+      utf8map[value] = build_address_of (decl);
     }
   return utf8map[value];
 }
 
+tree
+tree_builtins::get_vtable_decl (model_class *klass, bool lay_out)
+{
+  if (vtable_map.find (klass) == vtable_map.end ())
+    {
+      tree decl = build_decl (VAR_DECL, NULL_TREE, type_dtable);
+      TREE_STATIC (decl) = 1;
+      DECL_ARTIFICIAL (decl) = 1;
+      DECL_IGNORED_P (decl) = 1;
+      mangler m (klass, true);
+      SET_DECL_ASSEMBLER_NAME (decl,
+			       get_identifier (m.get ().c_str ()));
+
+      if (lay_out)
+	{
+	  lay_out_class (klass);
+
+	  tree klass_ptr_type = map_type (klass);
+	  tree vtable = BINFO_VTABLE (TYPE_BINFO (TREE_TYPE (klass_ptr_type)));
+
+	  // FIXME: this isn't really correct.
+	  // it fails where a pointer-to-function is wider.
+	  tree vtype
+	    = build_array_type (type_nativecode_ptr,
+				build_index_type (build_int_cst (type_jint,
+								 TREE_VEC_LENGTH (vtable))));
+	  tree cons = NULL_TREE;
+
+	  TREE_TYPE (decl) = vtype;
+
+	  // FIXME: set these on the initializer when we make it.
+	  // Also set them on the decl?
+	  // TREE_CONSTANT (init) = 1;
+	  // TREE_INVARIANT (init) = 1;
+	  // TREE_READONLY (init) = 1;
+
+	  // FIXME: make a helper method for this sequence.
+	  // Is it even correct?  We do something with cgraph in
+	  // treegen.cc.
+	  layout_decl (decl, 0);
+	  rest_of_decl_compilation (decl, 1, 0);
+	  make_decl_rtl (decl);
+	}
+
+      vtable_map[klass] = decl;
+    }
+  return vtable_map[klass];
+}
+
+// FIXME: this whole method should probably migrate into the ABI or
+// into classobj.cc.  There's no need, I think, for it to be a generic
+// part of the builtins.
 void
 tree_builtins::lay_out_vtable (model_class *mklass)
 {
@@ -508,3 +638,12 @@
   mangler m (klass, "class$");
   return m.get ();
 }
+
+tree
+tree_builtins::get_symbol ()
+{
+  char buf[50];
+  sprintf (buf, "_temp_%d", symbol_count);
+  ++symbol_count;
+  return get_identifier (buf);
+}
Index: gcc/java/builtins.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.hh,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 builtins.hh
--- gcc/java/builtins.hh 13 Feb 2005 04:11:33 -0000 1.1.2.7
+++ gcc/java/builtins.hh 8 Mar 2005 00:19:03 -0000
@@ -33,6 +33,9 @@
   // FIXME: perhaps this should be attached to the gcc type somehow?
   std::map<model_class *, tree> classobj_map;
 
+  // This maps classes to their vtable decls
+  std::map<model_class *, tree> vtable_map;
+
   // This maps a method to its corresponding gcc tree.
   std::map<model_method *, tree> methodmap;
 
@@ -42,10 +45,16 @@
   // This maps a variable or parameter to its corresponding gcc tree.
   std::map<model_variable_decl *, tree> varmap;
 
+  // This maps a length to a concrete Utf8Const type.
+  std::map<int, tree> utf8typemap;
+
   // This maps a string to a gcc tree representing the corresponding
   // Utf8Const.
   std::map<std::string, tree> utf8map;
 
+  // Used when creating symbol names.
+  int symbol_count;
+
   // ABI instances.
   cxx_abi old_abi;
   bc_abi new_abi;
@@ -54,6 +63,8 @@
   void add (tree, model_field *);
   tree map_param_or_var (tree_code, tree, model_variable_decl *);
   void lay_out_vtable (model_class *);
+  tree build_utf8const_type (int);
+  int hash_utf8 (const char *, int);
 
 
   friend class cxx_abi;
@@ -101,10 +112,18 @@
   /// called once, before any classes are entered into the type map.
   void initialize_type_map ();
 
-  gcj_abi *find_abi (model_type *);
+  gcj_abi *find_abi ();
 
   /// Return the mangled name of the class object for a given class.
   std::string get_class_object_name (model_class *);
+
+  /// Return a new unique symbol name.
+  tree get_symbol ();
+
+  /// Return the decl for a given class' vtable.  If the second
+  /// argument is true, assume we are laying out the vtable, so go
+  /// ahead and fill it in.
+  tree get_vtable_decl (model_class *, bool = false);
 };
 
 #endif // GCC_TREE_BUILTINS_HH
Index: gcc/java/classobj.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/classobj.cc,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 classobj.cc
--- gcc/java/classobj.cc 13 Feb 2005 04:19:49 -0000 1.1.2.11
+++ gcc/java/classobj.cc 8 Mar 2005 00:19:03 -0000
@@ -84,13 +84,11 @@
 tree
 class_object_creator::make_decl (tree type, tree value)
 {
-  tree decl = build_decl (VAR_DECL, NULL_TREE, type);
+  tree decl = build_decl (VAR_DECL, builtins->get_symbol (), type);
   DECL_INITIAL (decl) = value;
   TREE_STATIC (decl) = 1;
   DECL_ARTIFICIAL (decl) = 1;
   DECL_IGNORED_P (decl) = 1;
-  SET_DECL_ASSEMBLER_NAME (decl,
-			   get_identifier (builtins->get_class_object_name (klass->get ()).c_str ()));
   rest_of_decl_compilation (decl, 1, 0);
 
   return build1 (ADDR_EXPR, build_pointer_type (type), decl);
@@ -165,6 +163,32 @@
 }
 
 tree
+class_object_creator::create_method_throws (model_method *method)
+{
+  std::list<ref_forwarding_type> throw_list = method->get_throws ();
+
+  if (throw_list.empty ())
+    return null_pointer_node;
+
+  tree cons_list = tree_cons (NULL_TREE, null_pointer_node, NULL_TREE);
+  for (std::list<ref_forwarding_type>::const_iterator i = throw_list.begin ();
+       i != throw_list.end ();
+       ++i)
+    {
+      tree utf = builtins->map_utf8const ((*i)->type ()->get_descriptor ());
+      cons_list = tree_cons (NULL_TREE, utf, cons_list);
+    }
+
+  tree type
+    = build_array_type (type_utf8const_ptr,
+			build_index_type (build_int_cst (type_jint,
+							 throw_list.size () + 1)));
+  cons_list = build_constructor (type, cons_list);
+
+  return make_decl (type, cons_list);
+}
+
+tree
 class_object_creator::create_one_method_record (model_method *method)
 {
   record_creator inst (type_method);
@@ -174,9 +198,9 @@
 		  builtins->map_utf8const (method->get_descriptor ()));
   inst.set_field ("accflags",
 		  build_int_cst (type_jushort, method->get_modifiers ()));
-  inst.set_field ("index", integer_zero_node); // FIXME
-  inst.set_field ("ncode", null_pointer_node); // FIXME
-  inst.set_field ("throws", null_pointer_node);	// FIXME
+  inst.set_field ("index", integer_minus_one_node); // FIXME
+  inst.set_field ("ncode", build_address_of (mdecl));
+  inst.set_field ("throws", create_method_throws (method));
   return inst.finish_record ();
 }
 
@@ -214,6 +238,15 @@
 					  tree &result_table,
 					  tree &result_syms)
 {
+  tree result_list = NULL_TREE;
+
+  if (table.empty ())
+    {
+      result_table = null_pointer_node;
+      result_syms = null_pointer_node;
+      return;
+    }
+
   for (std::vector<model_element *>::const_iterator i = table.begin ();
        i != table.end ();
        ++i)
@@ -237,13 +270,31 @@
 	  descriptor = method->get_descriptor ();
 	}
 
-      // FIXME: enter new utf8consts.
-      
+      tree class_tree = builtins->map_utf8const (class_desc);
+      tree name_tree = builtins->map_utf8const (name);
+      tree desc_tree = builtins->map_utf8const (descriptor);
+
+      record_creator item (type_method_symbol);
+      item.set_field ("class_name", class_tree);
+      item.set_field ("name", name_tree);
+      item.set_field ("signature", desc_tree);
+      tree item_tree = item.finish_record ();
+
+      result_list = tree_cons (NULL_TREE, item_tree, result_list);
     }
 
-  // FIXME create the tables and update the arguments
-  result_table = null_pointer_node;
-  result_syms = null_pointer_node;
+  tree type
+    = build_array_type (type_method_symbol,
+			build_index_type (build_int_cst (type_jint, table.size ())));
+  result_syms = make_decl (type, result);
+
+  tree symtype
+    = build_array_type (ptr_type_node,
+			build_index_type (build_int_cst (type_jint,
+							 table.size ())));
+  // FIXME: we need a decl for this somewhere else so that the ABI can
+  // emit references to it...
+  result_table = make_decl (symtype, NULL_TREE);
 }
 
 void
@@ -264,10 +315,9 @@
 	   ++i)
 	{
 	  ++len;
-	  gcj_abi *abi = builtins->find_abi ((*i)->type ());
-	  tree one_iface
-	    = abi->build_class_reference (builtins, klass,
-					  builtins->map_type ((*i)->type ()));
+	  gcj_abi *abi = builtins->find_abi ();
+	  tree one_iface = abi->build_class_reference (builtins, klass,
+						       (*i)->type ());
 	  result = tree_cons (NULL_TREE, one_iface, result);
 	}
       result = nreverse (result);
@@ -285,19 +335,60 @@
 
 }
 
+tree
+class_object_creator::create_constants ()
+{
+  const std::vector<aot_class::pool_entry> &pool (klass->get_constant_pool ());
+
+  if (pool.empty ())
+    return null_pointer_node;
+
+  record_creator inst (type_constants);
+  inst.set_field ("size", build_int_cst (type_juint, pool.size ()));
+
+  tree type_tags
+    = build_array_type (type_jbyte,
+			build_index_type (build_int_cst (type_jint,
+							 pool.size ())));
+  tree type_data
+    = build_array_type (ptr_type_node,
+			build_index_type (build_int_cst (type_jint,
+							 pool.size ())));
+
+  tree tags_list = NULL_TREE;
+  tree data_list = NULL_TREE;
+  for (std::vector<aot_class::pool_entry>::const_iterator i = pool.begin ();
+       i != pool.end ();
+       ++i)
+    {
+      tags_list = tree_cons (NULL_TREE, build_int_cst (type_jbyte, (*i).tag),
+			     tags_list);
+      data_list = tree_cons (NULL_TREE, builtins->map_utf8const ((*i).value),
+			     data_list);
+    }
+
+  tags_list = nreverse (tags_list);
+  data_list = nreverse (data_list);
+
+  inst.set_field ("tags", make_decl (type_tags, tags_list));
+  inst.set_field ("data", make_decl (type_data, data_list));
+
+  return inst.finish_record ();
+}
+
 void
 class_object_creator::create_class_instance (tree class_tree)
 {
   assert (TREE_CODE (class_tree) == RECORD_TYPE);
 
-  // FIXME: handle fields in Object.
-
   model_class *real_class = klass->get ();
-  gcj_abi *abi = builtins->find_abi (real_class);
+  gcj_abi *abi = builtins->find_abi ();
   record_creator inst (type_class);
 
   // First the fields from Object.
-  inst.set_field ("vtable", null_pointer_node);	// FIXME
+  inst.set_field ("vtable",
+		  abi->get_vtable (builtins,
+				   global->get_compiler ()->java_lang_Class ()));
   if (! flag_hash_synchronization)
     inst.set_field ("sync_info", null_pointer_node);
 
@@ -318,13 +409,10 @@
   if (real_class->interface_p ())
     super = global->get_compiler ()->java_lang_Object ();
   if (super)
-    {
-      gcj_abi *abi = builtins->find_abi (super);
-      super_tree = abi->build_class_reference (builtins, klass, super);
-    }
+    super_tree = abi->build_class_reference (builtins, klass, super);
   inst.set_field ("superclass", super_tree);
 
-  inst.set_field ("constants", null_pointer_node);  // FIXME
+  inst.set_field ("constants", create_constants ());
 
   int method_len;
   tree methods = create_method_array (real_class, method_len);
@@ -344,8 +432,7 @@
   inst.set_field ("static_field_count",
 		  build_int_cst (type_jshort, num_static_fields));
 
-  // FIXME abi->get_vtable (blah));
-  inst.set_field ("vtable", null_pointer_node);
+  inst.set_field ("dtable", abi->get_vtable (builtins, klass->get (), true));
 
   tree table, syms;
   create_index_table (klass->get_otable (), table, syms);
Index: gcc/java/classobj.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/classobj.hh,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 classobj.hh
--- gcc/java/classobj.hh 13 Feb 2005 04:13:23 -0000 1.1.2.4
+++ gcc/java/classobj.hh 8 Mar 2005 00:19:03 -0000
@@ -67,11 +67,13 @@
   tree create_one_field_record (model_field *);
   tree create_field_array (model_class *, int &, int &);
   tree create_one_method_record (model_method *);
+  tree create_method_throws (model_method *);
   tree create_method_array (model_class *, int &);
   void handle_interfaces (model_class *, tree &, tree &);
   void create_index_table (const std::vector<model_element *> &,
 			   tree &, tree &);
   void create_class_instance (tree);
+  tree create_constants ();
 
 public:
 
Index: gcc/java/decl.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/decl.cc,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 decl.cc
--- gcc/java/decl.cc 13 Feb 2005 04:19:49 -0000 1.1.2.9
+++ gcc/java/decl.cc 8 Mar 2005 00:19:03 -0000
@@ -26,6 +26,9 @@
 // this explicitly.
 extern "C" rtx init_one_libfunc (const char *);
 
+// Used when computing the ABI version.
+#define GCJ_BINARYCOMPAT_ADDITION 5
+
 // FIXME: do we need this?  Global decl list.
 tree all_decls;
 
@@ -164,9 +167,9 @@
 // It appends a new field to the type.  It is invalid to call this
 // after layout_type has been called on the type.  FIELD is updated to
 // be the new field, it can be modified after return.
-static void
+void
 push_field (tree record, tree &field, const char *name,
-	    tree field_type, bool is_private = false)
+	    tree field_type, bool is_private)
 {
   assert (record != NULL_TREE);
   assert (field_type != NULL_TREE);
@@ -203,7 +206,8 @@
   push_field (type_utf8const, field, "hash", type_jushort);
   push_field (type_utf8const, field, "length", type_jushort);
   push_field (type_utf8const, field, "data",
-	      build_array_type (char_type_node, integer_type_node));
+	      build_array_type (char_type_node,
+				build_index_type (integer_zero_node)));
   layout_type (type_utf8const);
 
   type_utf8const_ptr = build_pointer_type (type_utf8const);
@@ -214,7 +218,7 @@
 {
   tree field = NULL_TREE;
   type_method_symbol = make_node (RECORD_TYPE);
-  push_field (type_method_symbol, field, "clname", type_utf8const_ptr);
+  push_field (type_method_symbol, field, "class_name", type_utf8const_ptr);
   push_field (type_method_symbol, field, "name", type_utf8const_ptr);
   // A misnomer as of 1.5.
   push_field (type_method_symbol, field, "signature", type_utf8const_ptr);
@@ -312,7 +316,7 @@
   push_field (type_class, field, "size_in_bytes", type_jint, true);
   push_field (type_class, field, "field_count", type_jshort, true);
   push_field (type_class, field, "static_field_count", type_jshort, true);
-  push_field (type_class, field, "vtable", type_dtable_ptr, true);
+  push_field (type_class, field, "dtable", type_dtable_ptr, true);
   push_field (type_class, field, "otable", type_otable_ptr, true);
   push_field (type_class, field, "otable_syms", 
 	      build_pointer_type (type_method_symbol_array), true);
@@ -712,13 +716,44 @@
 static void
 initialize_version ()
 {
-  // FIXME: this is wrong, must parse version.c.
-  // Take from gcj.
-  int version = __GNUC__ * 10000 + __GNUC_MINOR__ * 10;
+  const char *p = version_string;
+  unsigned int major = 0, minor = 0;
+  unsigned int abi_version;
+
+  /* Skip leading junk.  */
+  while (*p && !ISDIGIT (*p))
+    ++p;
+  gcc_assert (*p);
+
+  /* Extract major version.  */
+  while (ISDIGIT (*p))
+    {
+      major = major * 10 + *p - '0';
+      ++p;
+    }
+
+  gcc_assert (*p == '.' && ISDIGIT (p[1]));
+  ++p;
+
+  /* Extract minor version.  */
+  while (ISDIGIT (*p))
+    {
+      minor = minor * 10 + *p - '0';
+      ++p;
+    }
+
+  /* Implicit in this computation is the idea that we won't break the
+     old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to
+     4.0.1).  */
+  abi_version = 10000 * major + 10 * minor;
+  /* It is helpful to distinguish BC ABI from ordinary ABI at this
+     level, since at some point we will recognize a variety of BC ABIs
+     (objects generated by different version of gcj), but will
+     probably always require strict matching for ordinary ABI.  */
   if (flag_indirect_dispatch)
-    version += 5;
-  gcj_abi_version = build1 (NOP_EXPR, type_class_ptr,
-			    build_int_cst (type_jint, version));
+    abi_version += GCJ_BINARYCOMPAT_ADDITION;
+
+  gcj_abi_version = build_int_cstu (ptr_type_node, abi_version);
 }
 
 tree
Index: gcc/java/glue.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/glue.hh,v
retrieving revision 1.1.2.7
diff -u -r1.1.2.7 glue.hh
--- gcc/java/glue.hh 13 Feb 2005 03:46:44 -0000 1.1.2.7
+++ gcc/java/glue.hh 8 Mar 2005 00:19:04 -0000
@@ -60,6 +60,7 @@
 #include "langhooks-def.h"
 #include "options.h"
 #include "toplev.h"
+  //#include "output.h"
 #include "except.h"
 #include "flags.h"
 #include "tree-inline.h"
@@ -68,6 +69,7 @@
 #include "convert.h"
 #include "ggc.h"
 #include "debug.h"
+#include "version.h"
 
 // This gets us alloc_stmt_list().  Shouldn't that be in
 // tree-iterator.h?
Index: gcc/java/hooks.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/hooks.hh,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 hooks.hh
--- gcc/java/hooks.hh 13 Feb 2005 04:19:49 -0000 1.1.2.4
+++ gcc/java/hooks.hh 8 Mar 2005 00:19:04 -0000
@@ -101,6 +101,8 @@
 
 
 extern tree build_address_of (tree);
+extern void push_field (tree record, tree &field, const char *name,
+			tree field_type, bool is_private = false);
 
 namespace gcjx
 {
Index: gcc/java/lower.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/lower.cc,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 lower.cc
--- gcc/java/lower.cc 31 Jan 2005 02:26:01 -0000 1.1.2.4
+++ gcc/java/lower.cc 8 Mar 2005 00:19:04 -0000
@@ -1327,11 +1327,12 @@
 
 	case op_new:
 	  {
-	    tree klass = find_class (cpool->get_class (get2u (bytes, pc)));
-	    insn = push (build3 (CALL_EXPR, klass,
+	    tree klass_ref
+	      = build_class_ref (cpool->get_class (get2u (bytes, pc)));
+	    insn = push (build3 (CALL_EXPR,
+				 NULL_TREE, // FIXME!
 				 builtin_Jv_AllocObject,
-				 build_tree_list (NULL_TREE,
-						  build_class_ref (klass)),
+				 build_tree_list (NULL_TREE, klass_ref),
 				 NULL_TREE));
 	  }
 	  break;
@@ -1457,8 +1458,8 @@
 		args = tree_cons (NULL_TREE, next, args);
 	      }
 
-	    tree klass = find_class (cpool->get_class (kind_index));
-	    args = tree_cons (NULL_TREE, klass, args);
+	    tree klassref = build_class_ref (cpool->get_class (kind_index));
+	    args = tree_cons (NULL_TREE, klassref, args);
 
 	    insn = push (build3 (CALL_EXPR, type_object,
 				 builtin_Jv_NewMultiArray,
@@ -1873,11 +1874,9 @@
       }
 
     case CONSTANT_Class:
-      // 1.5 only.
-      {
-	tree klass = find_class (cpool->get_class (index));
-	result = build_class_ref (klass);
-      }
+      // 1.5 only.  The verifier will reject this for pre-1.5 class
+      // 1.files.
+      result = build_class_ref (cpool->get_class (index));
       break;
 
     default:
Index: gcc/java/tree.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.cc,v
retrieving revision 1.1.2.10
diff -u -r1.1.2.10 tree.cc
--- gcc/java/tree.cc 13 Feb 2005 03:58:29 -0000 1.1.2.10
+++ gcc/java/tree.cc 8 Mar 2005 00:19:04 -0000
@@ -1330,12 +1330,6 @@
     }
 }
 
-tree
-tree_generator::build_class_ref (model_type *t)
-{
-  return build_class_ref (gcc_builtins->map_type (t));
-}
-
 void
 tree_generator::visit_class_ref (model_class_ref *,
 				 const ref_forwarding_type &req)
@@ -1871,13 +1865,12 @@
   assert (elt_type->primitive_p ());
   model_type *array_type = elt_type->array ();
 
-  tree elt_type_tree = gcc_builtins->map_type (elt_type);
   tree array_type_tree = gcc_builtins->map_type (array_type);
 
   tree insn = build3 (CALL_EXPR, array_type_tree, 
 		      builtin_Jv_NewPrimArray,
 		      tree_cons (NULL_TREE,
-				 build_class_ref (elt_type_tree),
+				 build_class_ref (elt_type),
 				 tree_cons (NULL_TREE, size, NULL_TREE)),
 		      NULL_TREE);
   TREE_SIDE_EFFECTS (insn) = 1;
@@ -1926,11 +1919,19 @@
 }
 
 tree
-tree_generator::build_class_ref (tree klass)
+tree_generator::build_class_ref (model_type *t)
+{
+  gcj_abi *abi = gcc_builtins->find_abi ();
+  // FIXME: we can see "int.class".
+  return abi->build_class_reference (gcc_builtins, class_wrapper,
+				     assert_cast<model_class *> (t));
+}
+
+tree
+tree_generator::build_class_ref (const std::string &classname)
 {
-  // FIXME.
-  gcj_abi *abi = gcc_builtins->find_abi (NULL);
-  return abi->build_class_reference (gcc_builtins, class_wrapper, klass);
+  gcj_abi *abi = gcc_builtins->find_abi ();
+  return abi->build_class_reference (gcc_builtins, class_wrapper, classname);
 }
 
 tree
Index: gcc/java/tree.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.hh,v
retrieving revision 1.1.2.3
diff -u -r1.1.2.3 tree.hh
--- gcc/java/tree.hh 31 Jan 2005 02:26:01 -0000 1.1.2.3
+++ gcc/java/tree.hh 8 Mar 2005 00:19:04 -0000
@@ -1,6 +1,6 @@
 // Tree generation.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -104,7 +104,7 @@
   tree wrap_synchronized (tree, tree);
   tree add_var (const ref_variable_decl &);
   tree build_class_ref (model_type *);
-  tree build_class_ref (tree);
+  tree build_class_ref (const std::string &);
   tree handle_instanceof (tree, tree);
   void handle_inc_dec (tree_code, const ref_expression &);
   void handle_op_assignment (tree_code, const ref_expression &,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]