X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Futil%2FBytecodePruner.java;h=f9a3b644721c252fe45a3e76f7f822bc3df08e0a;hb=c8f04834582049dce7f80507a1b2b6c6210d5c3f;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..f9a3b64 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; @@ -39,7 +22,8 @@ public class BytecodePruner { public void loadAllMethods(String classname) throws Exception { visitJavaClass(repo.loadClass(classname)); Method[] meths = getMethods(repo.loadClass(classname)); - 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"); @@ -285,7 +212,6 @@ public class BytecodePruner { } public void load(Type t) throws Exception { if (t == null) return; - //String sig = t.getSignature(); if (t instanceof ArrayType) load(((ArrayType)t).getElementType()); if (!(t instanceof ObjectType)) return; load(((ObjectType)t).getClassName()); @@ -308,11 +234,20 @@ public class BytecodePruner { public static int level = 0; 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; + + /* + // HACK (okay?) + // not inferrable: CNI call to abstract method + if (jc.getClassName().equals("java.util.TimeZone") && method.getName().equals("getDefaultTimeZoneId")) + loadMethod("java.util.SimpleTimeZone.useDaylightTime"); + */ + dest.add(method); level += 2; for(int i=0; i"); + } + if (instr instanceof org.apache.bcel.generic.FieldOrMethod) + load(((org.apache.bcel.generic.FieldOrMethod)instr).getClassType(cpg)); + if (instr instanceof org.apache.bcel.generic.FieldInstruction) { + load(((org.apache.bcel.generic.FieldInstruction)instr).getFieldType(cpg)); + load(((org.apache.bcel.generic.FieldInstruction)instr).getType(cpg)); + String fieldName = ((org.apache.bcel.generic.FieldInstruction)instr).getFieldName(cpg); + JavaClass jc2 = repo.loadClass(((ObjectType)((org.apache.bcel.generic.FieldInstruction)instr). + getLoadClassType(cpg)).getClassName()); + Field[] fields = jc2.getFields(); + for(int j=0; j")) visitJavaMethod(clazz, methods[i]); - // only if ctor reachable (?) if (methods[i].getName().equals("equals")) visitJavaMethod(clazz, methods[i]); if (methods[i].getName().equals("hashCode")) visitJavaMethod(clazz, methods[i]); @@ -426,9 +378,9 @@ public class BytecodePruner { Object[] subclasses = s.toArray(); for(int i=0; i