way better
[org.ibex.core.git] / src / org / ibex / util / BytecodePruner.java
index 6243ffa..d8aff54 100644 (file)
@@ -7,8 +7,6 @@ import org.apache.bcel.generic.*;
 import org.apache.bcel.classfile.*;
 import org.apache.bcel.util.*;
 
-// can we drop nio?  in natibex.a?
-
 public class BytecodePruner {
 
     public static final boolean deleteMethods = false;
@@ -91,17 +89,15 @@ public class BytecodePruner {
         bcp.loadAllMethods("gnu.gcj.protocol.core.Handler");
         bcp.loadAllMethods("gnu.gcj.protocol.jar.Handler");
 
-        /*
-        bcp.loadAllMethods("java.util.Date");
-        bcp.loadAllMethods("java.text.DateFormat");
-        bcp.loadAllMethods("java.text.NumberFormat");
-        */
+        // to ensure we get all the stuff that might be called from CNI
+        bcp.loadAllMethods("org.ibex.plat.Linux");
+        bcp.loadAllMethods("org.ibex.plat.X11");
+        bcp.loadAllMethods("org.ibex.Surface");
+        bcp.loadAllMethods("org.ibex.Picture");
+        bcp.loadAllMethods("org.ibex.PixelBuffer");
 
-        Method[] meths = getMethods(repo.loadClass("org.ibex.plat.Linux"));
-        for(int i=0; i<meths.length; i++) {
-            if (meths[i].getName().equals("main"))
-                bcp.visitJavaMethod(repo.loadClass("org.ibex.plat.Linux"), meths[i]);
-        }
+        // primary entry point
+        bcp.loadMethod("org.ibex.plat.Linux.main");
         System.out.println();
 
         // FIXME: insert "the null class" when eliminating?
@@ -145,10 +141,12 @@ public class BytecodePruner {
                 System.out.println("  pruning field " + clazz.getClassName() + "." + fields[i].getName());
                 cg.removeField(fields[i]);
             }
+            /*  -- there's really no point to this --
             if (!constructed && !fields[i].isStatic()) {
                 System.out.println("  unconstructed: pruning field " + clazz.getClassName() + "." + fields[i].getName());
-                //cg.removeField(fields[i]);
+                cg.removeField(fields[i]);
             }
+            */
         }
 
         int numMethods = 0;
@@ -160,7 +158,8 @@ public class BytecodePruner {
                 if (methods[i].getCode() == null) {
                     System.out.println("  empty codeblock: " + clazz.getClassName() + "." + methods[i].getName());
                 } else {
-                    System.out.println("  pruning " + clazz.getClassName() + "." + methods[i].getName());
+                    System.out.println("  pruning " +(constructed?"":"unconstructed")+ " method " +
+                                       clazz.getClassName() + "." + methods[i].getName());
                     if (deleteMethods) { cg.removeMethod(methods[i]); continue; }
                     MethodGen mg = new MethodGen(methods[i], clazz.getClassName(), newcpg);
                     mg.removeExceptions();
@@ -182,17 +181,23 @@ public class BytecodePruner {
                 }
             }
         }
-                               
-        // FIXME: remove this
-        good = true;
 
         if (!good) {
             System.out.println("DROPPING " + clazz.getClassName());
+            JavaClass[] ifaces = clazz.getInterfaces();
+            String[] ifacestrings = new String[ifaces.length];
+            for(int i=0; i<ifaces.length; i++) ifacestrings[i] = ifaces[i].getClassName();
+            cg = new ClassGen(clazz.getClassName(),
+                              clazz.getSuperClass().getClassName(),
+                              clazz.getFileName(),
+                              clazz.getAccessFlags(),
+                              ifacestrings,
+                              newcpg);
         } else {
-            new File(outdir + "/" + new File(clazz.getClassName().replace('.', '/')).getParent()).mkdirs();
             System.out.println("dumping " + clazz.getClassName());
-            cg.getJavaClass().dump(outdir + "/" + clazz.getClassName().replace('.', '/') + ".class");
         }
+        new File(outdir + "/" + new File(clazz.getClassName().replace('.', '/')).getParent()).mkdirs();
+        cg.getJavaClass().dump(outdir + "/" + clazz.getClassName().replace('.', '/') + ".class");
     }
 
     public JavaClass sig2class(String sig) throws Exception {
@@ -278,9 +283,6 @@ public class BytecodePruner {
                 String ii_sig = getMethodSignature(ii, cpg);
                 JavaClass c = sig2class(ii.getLoadClassType(cpg).getSignature());
 
-                // FIXME: removable?
-                load(ii.getReturnType(cpg));
-
                 load(ii.getType(cpg));
                 Method[] meths = getMethods(c);
                 boolean good = false;
@@ -297,9 +299,6 @@ public class BytecodePruner {
         level -= 2;
 
         // FIXME: move this to the top
-
-        // FIXME: removable?
-        load(method.getReturnType());
         Type[] argtypes = method.getArgumentTypes();
         for(int i=0; i<argtypes.length; i++) load(argtypes[i]);
         if (method.getExceptionTable() != null) {
@@ -308,34 +307,26 @@ public class BytecodePruner {
         }
     }
 
-    public void visitJavaField(Field field) throws Exception {
-        if (dest.contains(field)) return;
-        dest.add(field);
-        load(field.getType());
-    }
+    public void visitJavaField(Field field) throws Exception { if (!dest.contains(field)) dest.add(field); }
 
     public void visitJavaClass(JavaClass clazz) throws Exception {
         if (dest.contains(clazz)) return;
         dest.add(clazz);
 
         ConstantPoolGen cpg = new ConstantPoolGen(clazz.getConstantPool());
-        String name = clazz.getClassName();
         System.out.println(clazz.getClassName() + ".class");
 
         JavaClass superclass = clazz.getSuperClass();
-        JavaClass[] interfaces = clazz.getAllInterfaces();
         for(JavaClass sup = superclass; sup != null; sup = sup.getSuperClass()) {
             if (subclasses.get(sup) == null) subclasses.put(sup, new HashSet());
             ((HashSet)subclasses.get(sup)).add(clazz);
         }
+        JavaClass[] interfaces = clazz.getAllInterfaces();
         for(int i=0; i<interfaces.length; i++) {
             if (subclasses.get(interfaces[i]) == null) subclasses.put(interfaces[i], new HashSet());
             ((HashSet)subclasses.get(interfaces[i])).add(clazz);
         }
 
-        // FIXME
-        if (clazz.getClassName().startsWith("org.ibex.")) loadAllMethods(clazz.getClassName());
-
         for(JavaClass sup = superclass; sup != null; sup = sup.getSuperClass()) {
             visitJavaClass(sup);
             remarkMethods(sup, clazz, cpg);
@@ -372,8 +363,6 @@ public class BytecodePruner {
         for(int i=0; i<subclasses.length; i++) {
             JavaClass subclass = (JavaClass)subclasses[i];
             if (subclass == c) continue;
-            //for(int j=0; j<level; j++) System.out.print(" ");
-            //System.out.println("  [subclass " + subclass.getClassName() + "]");
             markMethodInSubclasses(c, m, subclass, cpg);
         }
     }