cp-tools-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Cp-tools-discuss] Javap: constant pool numbers and sorting methods


From: Daniel Bonniot
Subject: [Cp-tools-discuss] Javap: constant pool numbers and sorting methods
Date: Sat, 26 Jun 2004 17:19:24 +0200
User-agent: Mozilla Thunderbird 0.5 (X11/20040306)


Hi,

I'm interested in using javap to compare two class files compiled for the same source file (and thus supposed to be similar). Basically, run javap on both and use diff. This kind of stuff is useful to debug or compare java compilers (or other languages compiling to java bytecode).

A first problem is that currently javap prints constant pool numbers. For instance the 87 in
 #87=<Method java.lang.Object.<init> ()void>
This generates extraneous diffs if the constant pools are in different orders, or numbers are somehow shifted. I believe these numbers are rarely useful, especially as the constant pool itself is not printed as a header. So I think the default (and possibly only) behaviour should be to print
 <Method java.lang.Object.<init> ()void>
This functionality is already present in gnu.bytecode, so it's a matter of setting a boolean (although I had to add constructors, because that option was not public).

A second problem is that methods might appear in different orders in the two classfiles. This also makes diffing basically useless. So it is useful to choose some canonical order. I chose to sort methods by alphabetical order.

Attach is a patch that does both of these things. They are not controlled by command-line options at this point. The new behaviour is as acceptable as the old one if one does not want to diff, so it might be as well to do it in all cases. I could add options if there is a reason why this would not be OK (but then i'd like to hear option names).

Feel free to apply the patch if it's acceptable as is, or to indicate if there is any issue with it.

(Please CC me on replies)

Cheers,

Daniel

The Nice programming language: http://nice.sf.net

diff -ru classpath-tools-0.0.20020812/src/gnu/bytecode/ClassTypeWriter.java 
classpath-tools-0.0.20020812-NEW/src/gnu/bytecode/ClassTypeWriter.java
--- classpath-tools-0.0.20020812/src/gnu/bytecode/ClassTypeWriter.java  
2002-08-13 15:19:22.000000000 +0200
+++ classpath-tools-0.0.20020812-NEW/src/gnu/bytecode/ClassTypeWriter.java      
2004-06-26 16:48:56.000000000 +0200
@@ -16,18 +16,32 @@
   int flags;
   boolean printConstants = true;
 
-  public ClassTypeWriter (ClassType ctype, PrintWriter stream, int flags)
+  public ClassTypeWriter (ClassType ctype, PrintWriter stream, int flags,
+                         boolean printConstants)
   {
     super(stream);
     this.ctype = ctype;
     this.flags = flags;
+    this.printConstants = printConstants;
   }
 
-  public ClassTypeWriter (ClassType ctype, PrintStream stream, int flags)
+  public ClassTypeWriter (ClassType ctype, PrintStream stream, int flags,
+                         boolean printConstants)
   {
     super(stream);
     this.ctype = ctype;
     this.flags = flags;
+    this.printConstants = printConstants;
+  }
+
+  public ClassTypeWriter (ClassType ctype, PrintWriter stream, int flags)
+  {
+    this(ctype, stream, flags, true);
+  }
+
+  public ClassTypeWriter (ClassType ctype, PrintStream stream, int flags)
+  {
+    this(ctype, stream, flags, true);
   }
 
   public static void print (ClassType ctype, PrintWriter stream, int flags)
diff -ru classpath-tools-0.0.20020812/src/gnu/classpath/tools/Javap.java 
classpath-tools-0.0.20020812-NEW/src/gnu/classpath/tools/Javap.java
--- classpath-tools-0.0.20020812/src/gnu/classpath/tools/Javap.java     
2001-10-14 04:54:38.000000000 +0200
+++ classpath-tools-0.0.20020812-NEW/src/gnu/classpath/tools/Javap.java 
2004-06-26 16:50:20.000000000 +0200
@@ -58,6 +58,8 @@
 
   private boolean print_compiled_from = false;
 
+  private boolean sort_methods = true;
+
   private static String classpath = null;
   private static String user_classpath = null;
   private static String boot_classpath = null;
@@ -996,9 +998,10 @@
     
     // output methods
     buf = null;
-    Method method = classType.getMethods ();
-    while (method != null)
+    Method[] methods = getMethods (classType, sort_methods);
+    for (int m = 0; m < methods.length; m++)
       {
+       Method method = methods[m];
        buf = new StringBuffer();
        buf.append (TABBING);
        
@@ -1007,7 +1010,6 @@
        String methodStr = getMethod (classType, method, flags);
        if (methodStr == null)
          {
-           method = method.getNext ();
            continue;
          }
        buf.append (getMethod (classType, method, flags));
@@ -1065,8 +1067,6 @@
                buf = null;
              }
          }
-       
-       method = method.getNext ();
       }
     
     InnerClassesAttr innerClassAttr = (InnerClassesAttr)Attribute.get 
(classType, "InnerClasses");
@@ -1142,10 +1142,10 @@
 
     // end of class
     out.println (CLASS_TABBING + "}");
-    
-    method = classType.getMethods ();
-    while (method != null)
+
+    for (int m = 0; m < methods.length; m++)
       {
+       Method method = methods[m];
        if (disassemble || print_line_numbers || print_local_variables)
          {
            try
@@ -1364,7 +1364,7 @@
   {
     swriter = new StringWriter ();
     PrintWriter pwriter = new PrintWriter (swriter, true);
-    ClassTypeWriter cwriter = new ClassTypeWriter (ctype, pwriter, 0);
+    ClassTypeWriter cwriter = new ClassTypeWriter (ctype, pwriter, 0, false);
     return cwriter;
   }
 
@@ -1389,5 +1389,31 @@
       s = s + "$" + anon;
 
     return s;
-  } 
+  }
+
+  private Method[] getMethods (ClassType ctype, boolean sorted)
+  {
+    Method[] methods = new Method[ctype.getMethodCount()];
+
+    int n = 0;
+    for (Method m = ctype.getMethods(); m != null; m = m.getNext())
+      methods[n++] = m;
+
+    if (sorted)
+      java.util.Arrays.sort(methods, new MethodComparator());
+
+    return methods;
+  }
+
+  private static class MethodComparator implements java.util.Comparator
+  {
+    public int compare(Object o1, Object o2)
+    {
+      Method m1 = (Method) o1;
+      Method m2 = (Method) o2;
+
+      return m1.getName().compareTo(m2.getName());
+    }
+  }
 }
+

reply via email to

[Prev in Thread] Current Thread [Next in Thread]