summaryrefslogtreecommitdiff
path: root/src/proguard/optimize/peephole/MethodInliner.java
diff options
context:
space:
mode:
authorYing Wang <wangying@google.com>2012-02-27 18:34:24 -0800
committerYing Wang <wangying@google.com>2012-02-27 18:34:24 -0800
commit9f606f95f03a75961498803e24bee6799a7c0885 (patch)
treea45f4d74feda9b76277a0c9ced55ad15d82248a1 /src/proguard/optimize/peephole/MethodInliner.java
parentcfead78069f3dc32998dc118ee08cab3867acea2 (diff)
downloadproguard-9f606f95f03a75961498803e24bee6799a7c0885.tar.gz
This reverts commit cfead78069f3dc32998dc118ee08cab3867acea2. Bug: 6079915
Diffstat (limited to 'src/proguard/optimize/peephole/MethodInliner.java')
-rw-r--r--src/proguard/optimize/peephole/MethodInliner.java120
1 files changed, 45 insertions, 75 deletions
diff --git a/src/proguard/optimize/peephole/MethodInliner.java b/src/proguard/optimize/peephole/MethodInliner.java
index 8857202..55f9ccb 100644
--- a/src/proguard/optimize/peephole/MethodInliner.java
+++ b/src/proguard/optimize/peephole/MethodInliner.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -29,10 +29,10 @@ import proguard.classfile.editor.*;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.*;
-import proguard.classfile.visitor.*;
+import proguard.classfile.visitor.MemberVisitor;
import proguard.optimize.info.*;
-import java.util.*;
+import java.util.Stack;
/**
* This AttributeVisitor inlines short methods or methods that are only invoked
@@ -48,7 +48,7 @@ implements AttributeVisitor,
MemberVisitor
{
private static final int MAXIMUM_INLINED_CODE_LENGTH = Integer.parseInt(System.getProperty("maximum.inlined.code.length", "8"));
- private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "7000"));
+ private static final int MAXIMUM_RESULTING_CODE_LENGTH_JSE = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "8000"));
private static final int MAXIMUM_RESULTING_CODE_LENGTH_JME = Integer.parseInt(System.getProperty("maximum.resulting.code.length", "2000"));
private static final int MAXIMUM_CODE_EXPANSION = 2;
private static final int MAXIMUM_EXTRA_CODE_LENGTH = 128;
@@ -138,42 +138,6 @@ implements AttributeVisitor,
public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
{
- // TODO: Remove this when the method inliner has stabilized.
- // Catch any unexpected exceptions from the actual visiting method.
- try
- {
- // Process the code.
- visitCodeAttribute0(clazz, method, codeAttribute);
- }
- catch (RuntimeException ex)
- {
- System.err.println("Unexpected error while inlining method:");
- System.err.println(" Target class = ["+targetClass.getName()+"]");
- System.err.println(" Target method = ["+targetMethod.getName(targetClass)+targetMethod.getDescriptor(targetClass)+"]");
- if (inlining)
- {
- System.err.println(" Inlined class = ["+clazz.getName()+"]");
- System.err.println(" Inlined method = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");
- }
- System.err.println(" Exception = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");
- System.err.println("Not inlining this method");
-
- if (DEBUG)
- {
- targetMethod.accept(targetClass, new ClassPrinter());
- if (inlining)
- {
- method.accept(clazz, new ClassPrinter());
- }
-
- throw ex;
- }
- }
- }
-
-
- public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute)
- {
if (!inlining)
{
// codeAttributeComposer.DEBUG = DEBUG =
@@ -341,12 +305,12 @@ implements AttributeVisitor,
// Copy the instructions.
codeAttribute.instructionsAccept(clazz, method, this);
- // Append a label just after the code.
- codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
-
// Copy the exceptions.
codeAttribute.exceptionsAccept(clazz, method, exceptionInfoAdder);
+ // Append a label just after the code.
+ codeAttributeComposer.appendLabel(codeAttribute.u4codeLength);
+
codeAttributeComposer.endCodeFragment();
}
@@ -493,42 +457,42 @@ implements AttributeVisitor,
if (// Only inline the method if it is private, static, or final.
(accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE |
ClassConstants.INTERNAL_ACC_STATIC |
- ClassConstants.INTERNAL_ACC_FINAL)) != 0 &&
+ ClassConstants.INTERNAL_ACC_FINAL)) != 0 &&
// Only inline the method if it is not synchronized, etc.
(accessFlags & (ClassConstants.INTERNAL_ACC_SYNCHRONIZED |
ClassConstants.INTERNAL_ACC_NATIVE |
ClassConstants.INTERNAL_ACC_INTERFACE |
- ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
+ ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
// Don't inline an <init> method, except in an <init> method in the
// same class.
// (!programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ||
// (programClass.equals(targetClass) &&
// targetMethod.getName(targetClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT))) &&
- !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) &&
+ !programMethod.getName(programClass).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) &&
// Don't inline a method into itself.
(!programMethod.equals(targetMethod) ||
- !programClass.equals(targetClass)) &&
+ !programClass.equals(targetClass)) &&
// Only inline the method if it isn't recursing.
- !inliningMethods.contains(programMethod) &&
+ !inliningMethods.contains(programMethod) &&
// Only inline the method if its target class has at least the
// same version number as the source class, in order to avoid
// introducing incompatible constructs.
- targetClass.u4version >= programClass.u4version &&
+ targetClass.u4version >= programClass.u4version &&
// Only inline the method if it doesn't invoke a super method, or if
// it is in the same class.
(!SuperInvocationMarker.invokesSuperMethods(programMethod) ||
- programClass.equals(targetClass)) &&
+ programClass.equals(targetClass)) &&
// Only inline the method if it doesn't branch backward while there
// are uninitialized objects.
(!BackwardBranchMarker.branchesBackward(programMethod) ||
- uninitializedObjectCount == 0) &&
+ uninitializedObjectCount == 0) &&
// Only inline if the code access of the inlined method allows it.
(allowAccessModification ||
@@ -537,24 +501,47 @@ implements AttributeVisitor,
(!AccessMethodMarker.accessesPackageCode(programMethod) ||
ClassUtil.internalPackageName(programClass.getName()).equals(
- ClassUtil.internalPackageName(targetClass.getName()))))) &&
+ ClassUtil.internalPackageName(targetClass.getName()))))) &&
// (!AccessMethodMarker.accessesProtectedCode(programMethod) ||
// targetClass.extends_(programClass) ||
// targetClass.implements_(programClass)) ||
(!AccessMethodMarker.accessesProtectedCode(programMethod) ||
- programClass.equals(targetClass)) &&
+ programClass.equals(targetClass)) &&
// Only inline the method if it doesn't catch exceptions, or if it
// is invoked with an empty stack.
(!CatchExceptionMarker.catchesExceptions(programMethod) ||
- emptyInvokingStack) &&
+ emptyInvokingStack) &&
- // Only inline the method if it comes from the a class with at most
- // a subset of the initialized superclasses.
+ // Only inline the method if it comes from the same class or from
+ // a class with a static initializer.
(programClass.equals(targetClass) ||
- initializedSuperClasses(targetClass).containsAll(initializedSuperClasses(programClass))))
- { boolean oldInlining = inlining;
+ programClass.findMethod(ClassConstants.INTERNAL_METHOD_NAME_CLINIT,
+ ClassConstants.INTERNAL_METHOD_TYPE_CLINIT) == null))
+ {
+// System.out.print("MethodInliner: inlining ");
+// programMethod.accept(programClass, new SimpleClassPrinter(true));
+// System.out.print(" in ");
+// targetMethod.accept(targetClass, new SimpleClassPrinter(true));
+//
+// System.out.println(" Private: "+
+// (!AccessMethodMarker.accessesPrivateCode(programMethod) ||
+// programClass.equals(targetClass)));
+//
+// System.out.println(" Package: "+
+// (!AccessMethodMarker.accessesPackageCode(programMethod) ||
+// ClassUtil.internalPackageName(programClass.getName()).equals(
+// ClassUtil.internalPackageName(targetClass.getName()))));
+//
+// System.out.println(" Protected: "+
+// ((!AccessMethodMarker.accessesProtectedCode(programMethod) ||
+// targetClass.extends_(programClass) ||
+// targetClass.implements_(programClass)) ||
+// ClassUtil.internalPackageName(programClass.getName()).equals(
+// ClassUtil.internalPackageName(targetClass.getName()))));
+
+ boolean oldInlining = inlining;
inlining = true;
inliningMethods.push(programMethod);
@@ -577,21 +564,4 @@ implements AttributeVisitor,
uninitializedObjectCount--;
}
}
-
-
- /**
- * Returns the set of superclasses and interfaces that are initialized.
- */
- private Set initializedSuperClasses(Clazz clazz)
- {
- Set set = new HashSet();
-
- // Visit all superclasses and interfaces, collecting the ones that have
- // static initializers.
- clazz.hierarchyAccept(true, true, true, false,
- new StaticInitializerContainingClassFilter(
- new ClassCollector(set)));
-
- return set;
- }
}