X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Futil%2FBytecodePruner.java;h=519fa137a500fb217c3608a66271c8ffe382b13f;hb=4c907d5df93e04fceff7dcd3f6ab42f02347fe65;hp=fffa1d69937a251ca54c6e6092983433cde7216d;hpb=82605cd4a7e0cb90f4835eeaea23802b1935dcad;p=org.ibex.core.git diff --git a/src/org/ibex/util/BytecodePruner.java b/src/org/ibex/util/BytecodePruner.java index fffa1d6..519fa13 100644 --- a/src/org/ibex/util/BytecodePruner.java +++ b/src/org/ibex/util/BytecodePruner.java @@ -7,24 +7,7 @@ import org.apache.bcel.generic.*; import org.apache.bcel.classfile.*; import org.apache.bcel.util.*; -// Reachability rules: - -// - a constructor is reachable iff it is called -// - a static method is reachable iff it is called -// - a nonstatic method is reachable -// - a static field is reachable iff it is referenced -// - a nonstatic field is reachable iff it is referenced -// - is reachable iff any methods, static methods, fields, or constructors are reachable - -// - if a method is reachable, all the methods it overrides are reachable - -// try eliminating instance methods/fields if no ctor is reachable... -// distinguish between overloaded forms of a given method -// slim down the set of loadAllMethod() classes -// field pruning? - -// FIXME: nonstatic method invocation or field access implies that object will be constructed (ie hint) - +// Field pruning public class BytecodePruner { public static final boolean deleteMethods = false; @@ -97,52 +80,28 @@ public class BytecodePruner { bcp.loadAllMethods("java.util.Hashtable$HashIterator"); bcp.loadMethod("java.util.SimpleTimeZone.useDaylightTime"); - /* - bcp.loadAllMethods("java.lang.Throwable"); - bcp.loadAllMethods("java.io.PrintStream"); - bcp.loadAllMethods("java.util.PropertyPermission"); - bcp.loadAllMethods("java.security.cert.Certificate"); - bcp.loadAllMethods("java.security.cert.CertificateEncodingException"); - bcp.loadMethod("java.util.TimeZone.getAvailableIDs"); - bcp.loadMethod("java.util.TimeZone.getDefaultTimeZoneId"); - bcp.loadAllMethods("gnu.gcj.runtime.StringBuffer"); - bcp.loadAllMethods("gnu.gcj.runtime.VMClassLoader"); - bcp.visitJavaClass(repo.loadClass("gnu.gcj.runtime.JNIWeakRef")); - */ - /* - bcp.visitJavaClass(repo.loadClass("gnu.gcj.protocol.http.Handler")); - bcp.visitJavaClass(repo.loadClass("gnu.gcj.protocol.file.Handler")); - bcp.visitJavaClass(repo.loadClass("gnu.gcj.protocol.jar.Handler")); - bcp.visitJavaClass(repo.loadClass("gnu.gcj.protocol.core.Handler")); - */ bcp.visitJavaClass(repo.loadClass("gnu.gcj.runtime.FinalizerThread")); bcp.visitJavaClass(repo.loadClass("gnu.gcj.runtime.FirstThread")); - // SecurityManager hacks to avoid java.security? - // URL and all descendents? Probably impossible. - // ObjectInput/ObjectOutput? Serialization? - - // often called from native subclasses.... - bcp.loadAllMethods("org.ibex.Surface"); - bcp.loadAllMethods("org.ibex.Template$TemplateHelper$1"); - bcp.loadAllMethods("org.ibex.Surface$DoubleBufferedSurface"); - bcp.loadAllMethods("org.ibex.Surface$3"); - bcp.loadAllMethods("org.ibex.Surface$2"); - bcp.loadAllMethods("org.ibex.Picture"); - bcp.loadAllMethods("org.ibex.PixelBuffer"); - bcp.loadAllMethods("org.ibex.Platform"); - bcp.loadAllMethods("org.ibex.Scheduler"); - bcp.loadAllMethods("org.ibex.plat.X11"); - bcp.loadAllMethods("org.ibex.plat.X11$X11Picture"); - bcp.loadAllMethods("org.ibex.plat.X11$X11PixelBuffer"); - bcp.loadAllMethods("org.ibex.plat.X11$X11Surface"); - bcp.loadAllMethods("org.ibex.XMLRPC"); - + bcp.loadMethod("java.lang.Thread.run"); // we call start(), but the VM calls run()... + bcp.loadMethod("java.lang.ref.Reference.enqueue"); // the GC calls this directly + bcp.loadAllMethods("gnu.gcj.runtime.StringBuffer"); // the compiler emits calls directly to this class + + bcp.loadAllMethods("gnu.gcj.protocol.http.Handler"); + bcp.loadAllMethods("gnu.gcj.protocol.file.Handler"); + bcp.loadAllMethods("gnu.gcj.protocol.core.Handler"); + bcp.loadAllMethods("gnu.gcj.protocol.jar.Handler"); + bcp.loadAllMethods("gnu.gcj.convert.Input_UTF8"); // retrieved via reflection + bcp.loadAllMethods("gnu.gcj.convert.Output_UTF8"); // retrieved via reflection + bcp.loadAllMethods("gnu.gcj.convert.Input_8859_1"); // retrieved via reflection + bcp.loadAllMethods("gnu.gcj.convert.Output_8859_1"); // retrieved via reflection + bcp.loadAllMethods("gnu.gcj.convert.Input_ASCII"); // retrieved via reflection + bcp.loadAllMethods("gnu.gcj.convert.Output_ASCII"); // retrieved via reflection + bcp.loadAllMethods("java.util.Date"); bcp.loadAllMethods("java.text.DateFormat"); bcp.loadAllMethods("java.text.NumberFormat"); - Method[] meths = getMethods(repo.loadClass("org.ibex.plat.Linux")); for(int i=0; i")) good = true; } else { 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()); - if (!deleteMethods) { - MethodGen mg = new MethodGen(methods[i], clazz.getClassName(), newcpg); - mg.removeExceptions(); - InstructionList il = new InstructionList(); - mg.setInstructionList(il); - - InstructionHandle ih_0 = il.append(factory.createNew("java.lang.UnsatisfiedLinkError")); - il.append(InstructionConstants.DUP); - il.append(factory.createInvoke("java.lang.UnsatisfiedLinkError", - "", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); - il.append(InstructionConstants.ATHROW); - - mg.setMaxStack(); - mg.setMaxLocals(); - mg.removeExceptions(); - mg.removeLocalVariables(); - mg.removeExceptionHandlers(); - mg.removeLineNumbers(); - - cg.replaceMethod(methods[i], mg.getMethod()); - il.dispose(); - } else { - cg.removeMethod(methods[i]); - } + if (deleteMethods) { cg.removeMethod(methods[i]); continue; } + MethodGen mg = new MethodGen(methods[i], clazz.getClassName(), newcpg); + mg.removeExceptions(); + InstructionList il = new InstructionList(); + mg.setInstructionList(il); + InstructionHandle ih_0 = il.append(factory.createNew("java.lang.UnsatisfiedLinkError")); + il.append(InstructionConstants.DUP); + il.append(factory.createInvoke("java.lang.UnsatisfiedLinkError", + "", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); + il.append(InstructionConstants.ATHROW); + mg.setMaxStack(); + mg.setMaxLocals(); + mg.removeExceptions(); + mg.removeLocalVariables(); + mg.removeExceptionHandlers(); + mg.removeLineNumbers(); + cg.replaceMethod(methods[i], mg.getMethod()); + il.dispose(); } } - if ((clazz.getClassName().startsWith("gnu.java.locale.LocaleInformation") && - !clazz.getClassName().endsWith("LocaleInformation_en") && - !clazz.getClassName().endsWith("LocaleInformation") && - !clazz.getClassName().endsWith("LocaleInformation_en_US")) - || - ((clazz.getClassName().startsWith("gnu.gcj.convert.Input_") || - clazz.getClassName().startsWith("gnu.gcj.convert.Output_")) && - !(clazz.getClassName().endsWith("ASCII") || - clazz.getClassName().endsWith("UTF8") || - clazz.getClassName().endsWith("iconv") || - clazz.getClassName().endsWith("8859_1"))) - || - (!good && - !clazz.isInterface() && - !clazz.isAbstract() && - !clazz.getClassName().startsWith("java.io.") && - !clazz.getClassName().startsWith("java.lang.") && - !clazz.getClassName().startsWith("gnu.") && - !clazz.getClassName().endsWith("Error") && - !clazz.getClassName().endsWith("Exception") && - !clazz.getClassName().endsWith("Permission"))) { - - //System.out.println("DROPPING " + clazz.getClassName()); - //return; } + new File(outdir + "/" + new File(clazz.getClassName().replace('.', '/')).getParent()).mkdirs(); System.out.println("dumping " + clazz.getClassName()); cg.getJavaClass().dump(outdir + "/" + clazz.getClassName().replace('.', '/') + ".class"); @@ -309,10 +233,13 @@ public class BytecodePruner { public void visitJavaMethod(JavaClass jc, Method method) throws Exception { visitJavaClass(jc); if (jc.getClassName().equals("java.util.Date") && method.getName().equals("readObject")) return; - //if (jc.getClassName().equals("java.net.URLClassLoader")) return; if (jc.getClassName().indexOf("SharedLib") != -1) return; if (jc.getClassName().indexOf("Datagram") != -1) return; if (dest.contains(method)) return; + + // gcj bug; gcj can't compile this method from a .class file input + //if (jc.getClassName().equals("java.lang.System") && method.getName().equals("runFinalizersOnExit")) return; + dest.add(method); level += 2; for(int i=0; i