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]

[ecj] Patch: FYI: fix ordering bugs, others


I'm checking this in on the gcj-eclipse branch.

This patch is a bit messy since it is conceptually a few different
fixes in one.  I forgot how they interact, though, and there didn't
seem to be much reason to try to separate them all out again.

* PR 27643, a bug involving the order in which we read class files.
  This is fixed by moving around the java_mark_class_local logic.
  Note that this breaks .java compilation; I didn't look into this
  because...
* This patch removes the ability to compile .java files.
* This patch fixes is_compiled_class to return the correct results.
  Right now it is sometimes wrong, e.g. it assumes that any file
  coming from a .zip must be compiled into this object.
* We disable the gnu.gcj.gcj-compiled attribute warning for now.
  ecj doesn't emit this attribute.  We can salvage this idea later by
  adding a gcj-specific annotation.
* There is a lurking bug where if you compile Class along with some
  other files, you will get bad results unless Class happens to come
  first.  This is a logic error in make_class_data; fixed in this
  patch.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>
	* jcf-io.c (find_class): Set source_ok to 0.
	* jcf-parse.c (jcf_parse): Disable gnu.gcj.gcj-compiled warning.
	(parse_class_file): Don't call java_mark_class_local.
	(java_parse_file): Skip .java files.  Call java_mark_class_local
	before lowering any code.
	(parse_zip_file_entries): Don't call duplicate_class_warning
	here.
	(process_zip_dir): ... call it here.
	* class.c (add_field): Don't mark field external if it is being
	compiled into this object.
	(make_class_data): Handle situation where class_dtable_decl is
	created before Class is compiled.
	(is_compiled_class): Don't assume files in zip are compiled into
	this object.
	(layout_class_method): Don't mark method external if it is being
	compiled into this object.

Index: jcf-io.c
===================================================================
--- jcf-io.c	(revision 114362)
+++ jcf-io.c	(working copy)
@@ -1,5 +1,5 @@
 /* Utility routines for finding and reading Java(TM) .class files.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -450,6 +450,9 @@
   char *buffer;
   hashval_t hash;
 
+  /* FIXME: ecj hack.  */
+  source_ok = 0;
+
   /* Create the hash table, if it does not already exist.  */
   if (!memoized_class_lookups)
     memoized_class_lookups = htab_create (37, 
Index: jcf-parse.c
===================================================================
--- jcf-parse.c	(revision 114362)
+++ jcf-parse.c	(working copy)
@@ -1,5 +1,5 @@
 /* Parser for Java(TM) .class files.
-   Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -804,9 +804,12 @@
       /* If we don't have the right archive, emit a verbose warning.
 	 If we're generating bytecode, emit the warning only if
 	 -fforce-classes-archive-check was specified. */
+#if 0
+      /* ECJ HACK: ignore this.  */
       if (!jcf->right_zip
 	  && (!flag_emit_class_files || flag_force_classes_archive_check))
 	fatal_error ("the %<java.lang.Object%> that was found in %qs didn't have the special zero-length %<gnu.gcj.gcj-compiled%> attribute.  This generally means that your classpath is incorrectly set.  Use %<info gcj \"Input Options\"%> to see the info page describing how to set the classpath", jcf->filename);
+#endif
     }
   else
     all_class_list = tree_cons (NULL_TREE,
@@ -857,8 +860,6 @@
 
   gen_indirect_dispatch_tables (current_class);
 
-  java_mark_class_local (current_class);
-
   for (method = TYPE_METHODS (current_class);
        method != NULL_TREE; method = TREE_CHAIN (method))
     {
@@ -1151,8 +1152,13 @@
 	  next++;
 	}
 
-      if (list[0]) 
+      /* Exclude .java files.  */
+      if (strlen (list) > 5 && ! strcmp (list + strlen (list) - 5, ".java"))
 	{
+	  /* Nothing. */
+	}
+      else if (list[0]) 
+	{
 	  node = get_identifier (list);
 
 	  filename_count++;
@@ -1293,8 +1299,15 @@
       parse_source_file_3 ();
     }
 
+  /* Do this before lowering any code.  */
   for (node = current_file_list; node; node = TREE_CHAIN (node))
     {
+      if (CLASS_FILE_P (node))
+	java_mark_class_local (TREE_TYPE (node));
+    }
+
+  for (node = current_file_list; node; node = TREE_CHAIN (node))
+    {
       input_location = DECL_SOURCE_LOCATION (node);
       if (CLASS_FILE_P (node))
 	{
@@ -1409,15 +1422,6 @@
 	    current_jcf = TYPE_JCF (class);
 	    output_class = current_class = class;
 
-	    if (CLASS_FROM_CURRENTLY_COMPILED_P (current_class))
-	      {
-	        /* We've already compiled this class.  */
-		duplicate_class_warning (current_jcf->filename);
-		break;
-	      }
-	    
-	    CLASS_FROM_CURRENTLY_COMPILED_P (current_class) = 1;
-
 	    /* This is a dummy class, and now we're compiling it for
 	       real.  */
 	    gcc_assert (! TYPE_DUMMY (class));
@@ -1532,6 +1536,16 @@
 
       class = lookup_class (get_identifier (class_name));
 
+      if (CLASS_FROM_CURRENTLY_COMPILED_P (class))
+	{
+	  /* We've already compiled this class.  */
+	  duplicate_class_warning (file_name);
+	  continue;
+	}
+      /* This function is only called when processing a zip file seen
+	 on the command line.  */
+      CLASS_FROM_CURRENTLY_COMPILED_P (class) = 1;
+
       jcf->read_state  = finput;
       jcf->filbuf      = jcf_filbuf_from_stdio;
       jcf->java_source = 0;
Index: class.c
===================================================================
--- class.c	(revision 114362)
+++ class.c	(working copy)
@@ -793,9 +793,9 @@
       /* Always make field externally visible.  This is required so
 	 that native methods can always access the field.  */
       TREE_PUBLIC (field) = 1;
-      /* Considered external until we know what classes are being
-	 compiled into this object file.  */
-      DECL_EXTERNAL (field) = 1;
+      /* Considered external unless we are compiling it into this
+	 object file.  */
+      DECL_EXTERNAL (field) = (is_compiled_class (class) != 2);
     }
 
   return field;
@@ -1650,15 +1650,28 @@
     {
       tree dtable = get_dispatch_table (type, this_class_addr);
       uses_jv_markobj = uses_jv_markobj_p (dtable);
-      dtable_decl = build_dtable_decl (type);
+      if (type == class_type_node && class_dtable_decl != NULL_TREE)
+	{
+	  /* We've already created some other class, and consequently
+	     we made class_dtable_decl.  Now we just want to fill it
+	     in.  */
+	  dtable_decl = class_dtable_decl;
+	}
+      else
+	{
+	  dtable_decl = build_dtable_decl (type);
+	  TREE_STATIC (dtable_decl) = 1;
+	  DECL_ARTIFICIAL (dtable_decl) = 1;
+	  DECL_IGNORED_P (dtable_decl) = 1;
+	}
+
+      TREE_PUBLIC (dtable_decl) = 1;
       DECL_INITIAL (dtable_decl) = dtable;
-      TREE_STATIC (dtable_decl) = 1;
-      DECL_ARTIFICIAL (dtable_decl) = 1;
-      DECL_IGNORED_P (dtable_decl) = 1;
-      TREE_PUBLIC (dtable_decl) = 1;
       if (! flag_indirect_classes)
 	rest_of_decl_compilation (dtable_decl, 1, 0);
-      if (type == class_type_node)
+      /* Maybe we're compiling Class as the first class.  If so, set
+	 class_dtable_decl to the decl we just made.  */
+      if (type == class_type_node && class_dtable_decl == NULL_TREE)
 	class_dtable_decl = dtable_decl;
     }
 
@@ -1776,8 +1789,10 @@
       DECL_ARTIFICIAL (class_dtable_decl) = 1;
       DECL_IGNORED_P (class_dtable_decl) = 1;
       if (is_compiled_class (class_type_node) != 2)
-	DECL_EXTERNAL (class_dtable_decl) = 1;
-      rest_of_decl_compilation (class_dtable_decl, 1, 0);
+	{
+	  DECL_EXTERNAL (class_dtable_decl) = 1;
+	  rest_of_decl_compilation (class_dtable_decl, 1, 0);
+	}
     }
 
   super = CLASSTYPE_SUPER (type);
@@ -2059,11 +2074,9 @@
     return 1;
   if (TYPE_ARRAY_P (class))
     return 0;
-  if (class == current_class)
-    return 2;
 
   seen_in_zip = (TYPE_JCF (class) && JCF_SEEN_IN_ZIP (TYPE_JCF (class)));
-  if (CLASS_FROM_CURRENTLY_COMPILED_P (class) || seen_in_zip)
+  if (CLASS_FROM_CURRENTLY_COMPILED_P (class))
     {
       /* The class was seen in the current ZIP file and will be
 	 available as a compiled class in the future but may not have
@@ -2443,9 +2456,10 @@
   tree method_name = DECL_NAME (method_decl);
 
   TREE_PUBLIC (method_decl) = 1;
-  /* Considered external until we know what classes are being
-     compiled into this object file.  */
-  DECL_EXTERNAL (method_decl) = 1;
+  /* Considered external unless it is being compiled into this object
+     file.  */
+  DECL_EXTERNAL (method_decl) = ((is_compiled_class (this_class) != 2)
+				 || METHOD_NATIVE (method_decl));
 
   if (ID_INIT_P (method_name))
     {


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