X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Futil%2FBytecodePruner.java;h=f9a3b644721c252fe45a3e76f7f822bc3df08e0a;hb=c8f04834582049dce7f80507a1b2b6c6210d5c3f;hp=f5dea9dbfd74b9dbb7ccc1673defb592ef967d43;hpb=769cf53f52755d6b8c976edb561e3c21700447aa;p=org.ibex.core.git diff --git a/src/org/ibex/util/BytecodePruner.java b/src/org/ibex/util/BytecodePruner.java index f5dea9d..f9a3b64 100644 --- a/src/org/ibex/util/BytecodePruner.java +++ b/src/org/ibex/util/BytecodePruner.java @@ -7,21 +7,11 @@ 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 - -// 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; + // FIXME public static SyntheticRepository repo = null; @@ -31,14 +21,27 @@ public class BytecodePruner { public void loadAllMethods(String classname) throws Exception { visitJavaClass(repo.loadClass(classname)); - Method[] meths = repo.loadClass(classname).getMethods(); - for(int i=0; i= 3 && s[1].equals("-o")) { outdir = s[2]; start += 2; } repo = SyntheticRepository.getInstance(new ClassPath(s[0])); - BytecodePruner bcp = new BytecodePruner(); + BytecodePruner bcp = new BytecodePruner(); for(int i=start; i")) good = true; } else { - if (methods[i].getCode() != null) { + 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) { 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)); + "", 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")) - || - (!good && - !clazz.isInterface() && - !clazz.isAbstract() && - !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"); @@ -239,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()); @@ -248,8 +220,7 @@ public class BytecodePruner { // hashtable of hashsets public static Hashtable subclasses = new Hashtable(); - public String getMethodSignature(Method m) throws Exception { - ConstantPoolGen cpg = new ConstantPoolGen(m.getConstantPool()); + public String getMethodSignature(Method m, ConstantPoolGen cpg) throws Exception { return m.getName() + m.getSignature(); } @@ -259,16 +230,30 @@ public class BytecodePruner { for(int j=0; j"); + } + 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]); + for(int i=0; i")) 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]); if (methods[i].getName().equals("finalize")) visitJavaMethod(clazz, methods[i]); if (methods[i].getName().equals("clone")) visitJavaMethod(clazz, methods[i]); if (methods[i].getName().equals("toString")) visitJavaMethod(clazz, methods[i]); } - for(int i=0; i