This is the mail archive of the java@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]

Patch for gcjlib ant task


Hi,

This is a patch against libgcj ant task 0.7 which fixes some problems
and adds some features. I hope you find it useful enough to include
some or all of it in the next gcjlib release. I'm also CCing this to
the gcj list in case somebody else has some need for it.

* Fix bug in DepClassLister which expected class file constant pools
to be ordered in the sense that entries were defined first and
referenced later. This is true for class files generated by gcj, but
not for files compiled with Sun javac and possibly other compilers.
The fix is to extract constant names first and then do the lookup work
in a second loop, rather than doing all in one go.

* Add boolean indirectDispatch attribute to gcjlib task to cause
classes to be compiled with -findirect-dispatch flag.

* Enable compilation of .jar files in addition to .class and .java files.

* Implement special single source file compilation mode where the .o
file isn't deleted after compilation, and the input file is only
compiled if no .o file exists or if it is newer than the .o file. This
is particularly handy when compiling large third party .jar files
which do not change a lot and don't need to be recompiled in each
build.

Especially the last item is a bit of a hack, but I find it
indispensable for the kind of project I'm working on.

best,
Hannes
diff -Nur ../gcjlib-0.7/build.xml ./build.xml
--- ../gcjlib-0.7/build.xml	1972-02-13 15:29:50.000000000 +0100
+++ ./build.xml	2005-08-02 12:12:56.743398329 +0200
@@ -1,5 +1,5 @@
 <?xml version="1.0" ?>
-<project name="tasks" default="main">
+<project name="gcjlib" default="main">
 
   <property name="project.name" value="gcjlib" />
   <property name="project.version" value="0.7" />
@@ -79,7 +79,7 @@
              classpath="${build.dir}"
     />
 
-    <gcjlib name="lib-org-spindazzle-ant-taskdefs">
+    <gcjlib name="lib-org-spindazzle-ant-taskdefs" indirectDispatch="true">
      <!-- classpath location="${build.dir}" -->
      <fileset dir="${build.dir}">
        <include name="**/*.class" />
diff -Nur ../gcjlib-0.7/src/org/spindazzle/gcjlib/DepClassLister.java src/org/spindazzle/gcjlib/DepClassLister.java
--- ../gcjlib-0.7/src/org/spindazzle/gcjlib/DepClassLister.java	1979-12-24 11:11:38.000000000 +0100
+++ src/org/spindazzle/gcjlib/DepClassLister.java	2005-05-13 11:44:22.000000000 +0200
@@ -42,7 +42,8 @@
 	// constants pool
 	int size = fp.readUnsignedShort();
 	String[] constants = new String[size];
-	String[] types = new String[size];
+	int[] types = new int[size];
+	int[] names = new int[size];
 	constants[0] = null;
 
 	for (int i = 1; i < size; i++) {
@@ -55,21 +56,12 @@
 		break;
 
 	    case CONSTANT_Class:
-		s = constants[fp.readUnsignedShort()];
-		types[i] = s;
-		if (s.charAt(0) == '[')
-		    handleFieldDescriptor(s.substring(1));
-		else
-		    handler.handle(s);
+		types[i] = fp.readUnsignedShort();
 		break;
 
 	    case CONSTANT_NameAndType:
 		fp.skipBytes(2);
-		s = constants[fp.readUnsignedShort()];
-		if (s.charAt(0) == '(')
-		    handleMethodDescriptor(s);
-		else
-		    handleFieldDescriptor(s);
+		names[i] = fp.readUnsignedShort();
 		break;
 		    
 	    case CONSTANT_Integer:
@@ -93,8 +85,25 @@
 		    "unknown tag " + tag + " in constant pool");
 	    }
 	}
+
+	for (int i = 1; i < size; i++) {
+	    if (types[i] > 0) {
+		String s = constants[types[i]];
+		if (s.charAt(0) == '[')
+		    handleFieldDescriptor(s.substring(1));
+		else
+		    handler.handle(s);
+	    } else if (names[i] > 0) {
+		String s = constants[names[i]];
+		if (s.charAt(0) == '(')
+		    handleMethodDescriptor(s);
+		else
+		    handleFieldDescriptor(s);
+	    }
+	}
+
 	fp.skipBytes(2);
-	handler.registerLocalClass (types[fp.readUnsignedShort ()]);
+	handler.registerLocalClass (constants[types[fp.readUnsignedShort ()]]);
 	fp.skipBytes(2);
 	fp.skipBytes(2 * fp.readUnsignedShort()); // interfaces
 
diff -Nur ../gcjlib-0.7/src/org/spindazzle/gcjlib/GcjLib.java src/org/spindazzle/gcjlib/GcjLib.java
--- ../gcjlib-0.7/src/org/spindazzle/gcjlib/GcjLib.java	1972-02-13 15:35:46.000000000 +0100
+++ src/org/spindazzle/gcjlib/GcjLib.java	2005-08-02 12:17:22.064985551 +0200
@@ -48,6 +48,9 @@
   // Classpath to be used a build time.
   private Path classpath;
   
+  // Use -findirect-dispatch compiler flag
+  private boolean indirectDispatch;
+  
   // Files we need to build.
   private Vector filesets = new Vector ();
   
@@ -221,68 +224,83 @@
 	DirectoryScanner ds = fs.getDirectoryScanner(fs.getProject());
 	
 	String[] files = ds.getIncludedFiles();
-	StringBuffer sb = new StringBuffer();
-	
+
 	for (int i = 0; i < files.length; i++) 
 	  {
 	    String file = files[i];
 
-	    if (file.endsWith (".class") || file.endsWith (".java"))
+	    if (file.endsWith (".class") || file.endsWith (".java") ||
+		file.endsWith (".jar"))
 	      sources.add (dirname + fileSeparator + file);
 	    else
 	      resources.add (new Resource (dirname, file));
 	  }
       }
 
-    DepLibraryFinder libfinder = new DepLibraryFinder ();
-    DepClassLister lister = new DepClassLister (libfinder);
-    try 
+    String linkflags = null;
+
+    if (!indirectDispatch)
       {
-	for (int li = 0; li < sources.size (); li++)
+	DepLibraryFinder libfinder = new DepLibraryFinder();
+	DepClassLister lister = new DepClassLister(libfinder);
+	try
 	  {
-	    String cname = (String) sources.elementAt (li);
-	    if (cname.endsWith (".class"))
-	      lister.parseClassfile (new FileInputStream ((String) sources.elementAt (li)));
+	    for (int li = 0; li < sources.size(); li++)
+	      {
+		String cname = (String) sources.elementAt(li);
+		if (cname.endsWith(".class"))
+		  lister.parseClassfile(new FileInputStream((String) sources.elementAt(li)));
+	      }
+	  } catch (java.io.IOException ex)
+	  {
+	    throw new BuildException("Could not create read class file: " + ex, getLocation());
 	  }
+	linkflags = libfinder.getLinkArgument();
       }
-    catch (java.io.IOException ex)
-      {
-	throw new BuildException ("Could not create read class file: " + ex, getLocation ());
-      }
-    String linkflags = libfinder.getLinkArgument ();
 
     // Compile all of the source files first.
     if (sources.size () > 0)
       {
 	int index = 0;
+	boolean singleSource = sources.size() == 1;
 
-	log ("Compiling " + sources.size () + " class file"
-	     + (sources.size () == 1 ? "" : "s")
-	     + " to native code");
+	if (!singleSource)
+	  log ("Compiling " + sources.size () + " files"
+	    + " to native code");
 
 	while (index < sources.size ())
 	  {
 	    Commandline cmdline = new Commandline ();
 	    File ofile;
 	    int length = 0;
+	    long lastModified = 0;
 	    cmdline.setExecutable ("gcj");
+	    if (indirectDispatch)
+	      cmdline.createArgument().setValue("-findirect-dispatch");
 	    cmdline.createArgument().setValue ("-c");
 	    cmdline.createArgument().setLine (flags);
 	    if (classpath != null)
 	      cmdline.createArgument().setValue ("--classpath=" + classpath.toString ());
 	    cmdline.createArgument().setValue ("-o");
-	    try 
+	    if (singleSource)
 	      {
-		ofile = File.createTempFile("gcj", ".o");
-		ofile.deleteOnExit ();
+		ofile = new File(name + ".o");
 		ofiles.add (ofile);
-	      } 
-	    catch (java.io.IOException ex)
+	      }
+	    else
 	      {
-		throw new BuildException ("Could not create temporary object file: " + ex, getLocation ());
+		try
+		  {
+		    ofile = File.createTempFile("gcj", ".o");
+		    ofile.deleteOnExit();
+		    ofiles.add(ofile);
+		  } catch (java.io.IOException ex)
+		  {
+		    throw new BuildException("Could not create temporary object file: " + ex, getLocation());
+		  }
 	      }
 	    cmdline.createArgument().setValue (ofile.toString ());
-	    length = 20;
+	    length = 40;
 
 	    boolean done = false;
 	    while (! done)
@@ -292,6 +310,10 @@
 		    fname = (String) sources.elementAt (index);
 		    if (length + fname.length () < MAX_COMMAND_LINE_LENGTH)
 		      {
+			if (singleSource)
+			  {
+			    lastModified = new File(fname).lastModified();
+			  }
 			cmdline.createArgument().setValue (fname);
 			index++;
 			length += fname.length () + 1;
@@ -303,7 +325,15 @@
 		  done = true;
 	      }
 
-	    LogStreamHandler streamHandler = 
+	    if (singleSource)
+	      {
+		if (lastModified < ofile.lastModified())
+		  continue;
+		log("Compiling " + sources.firstElement()
+		  + " to " + name + ".o");
+	      }
+
+	    LogStreamHandler streamHandler =
 	      new LogStreamHandler (this, Project.MSG_INFO, Project.MSG_ERR);
 	    Execute runner = new Execute (streamHandler, null);
 	    String env[] = { "LD_PRELOAD=" };
@@ -389,7 +419,8 @@
 	for (int i = 0; i < ofiles.size (); i++)
 	  cmdline.createArgument().setValue (((File) ofiles.elementAt (i)).toString ());
 
-	cmdline.createArgument().setLine (linkflags);
+	if (linkflags != null)
+	  cmdline.createArgument().setLine (linkflags);
 	
 	LogStreamHandler streamHandler = 
 	  new LogStreamHandler (this, Project.MSG_INFO, Project.MSG_ERR);
@@ -454,6 +485,15 @@
     filesets.add (fileset);
   }
 
+  /**
+   * Switch -findirect-dispatch mode on or off
+   *
+   * @param indispatch true if -findirect-dispatch flag is to be used
+   */
+  public void setIndirectdispatch(boolean indispatch) {
+    indirectDispatch = indispatch;
+  }
+
   public static void main (String[] args)
   {
     System.out.println ("gcjlib (c) 2004  Anthony Green");

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