How to make ProGuard remove a class method?

15

I can not get ProGuard 4.10 to cause a static method to inline . I only get this with instance methods.

For example, this short stretch:

public final class Calc {
    private int x = 0;
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int i = s.nextInt();

        Calc c = new Calc();
        int res = c.getX();
        if ((c.getX() & 1) != 0)
            res++;
        else
            res += 2;
        c.setX(res);

        System.out.println(res);
    }
}

After rendered by ProGuard it becomes (disregarding the obfuscation):

public final class Calc {
    private int x = 0;
}

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int i = s.nextInt();

        Calc c = new Calc();
        int res = c.x;
        if ((c.x & 1) != 0)
            res++;
        else
            res += 2;
        c.x = res;

        System.out.println(res);
    }
}

However, if I adapt the classes, and transform the methods into static , this section below does not change (disregarding the obfuscation):

public final class Calc {
    private static int x = 0;
    public static int getX() {
        return x;
    }
    public static void setX(int x) {
        Calc.x = x;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int i = s.nextInt();

        int res = Calc.getX();
        if ((Calc.getX() & 1) != 0)
            res++;
        else
            res += 2;
        Calc.setX(res);

        System.out.println(res);
    }
}

To fix any doubt, here's the configuration I'm using in both cases:

-dontskipnonpubliclibraryclassmembers
-optimizationpasses 9
-allowaccessmodification
-mergeinterfacesaggressively
-dontusemixedcaseclassnames
-dontpreverify
-keepclasseswithmembers public class * {
    public static void main(java.lang.String[]);
}
-keep class * extends java.sql.Driver
-keep class * extends javax.swing.plaf.ComponentUI {
    public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
}
-keepclasseswithmembers,allowshrinking class * {
    native <methods>;
}

Am I missing something? Are there any options to make ProGuard optimize and do methods% inline ?

Now these three documents (besides many others) and found nothing mentioning this case. Is this a limitation of ProGuard?

Optimizations

Usage

Examples

    
asked by anonymous 15.01.2015 / 04:17

1 answer

5

I hope to help you after so long, here is my answer:

  

Am I missing something? One option is missing to make the   ProGuard optimize and make static inline methods?

No, Proguard does inlining of methods class (or superclass) having static initializers, its static accessor methods can trigger an static initializer , may cause problems in applications outside of the compiler parse scope, for example:

The static x statement:

private static int x = 0;

Causes Calc to have an implicit static initializer :

public final class Calc {
    private static int x;
    static { // inicializador estatico implicito 
     x = 0; 
    }
   // ... continua ...
}

Suppose we have a static initializer in class or superclasses,

static { 
 setupDatabaseConfig(); 
}

I know it's not your case, but make sure that no problems occur was entered this cutoff criterion, until refine the "Escape Analysis" of inlining optimizations and can ensure that there are no collateral problems in eligible situations. Home I confess I did some testing (by example) the last version (5.2) of Proguard and not getting success in inlining. But anyway I recommend the last version (because there were refinements).


Follows the method of ProGuard , which is safeguarded when executing inlining in static methods and in unsigned subsets : Excerpt from MethodInliner.java :

 // Only inline the method if it comes from the a class with at most
    // a subset of the initialized superclasses.
    ((accessFlags & ClassConstants.ACC_STATIC) == 0 ||
     programClass.equals(targetClass)                        ||
     initializedSuperClasses(targetClass).containsAll(initializedSuperClasses(programClass))))

Filmography ps: If so I can compile a version of Proguard ignoring the exclusion criterion of static initializers inlining and you can use for specific purposes

.     
07.07.2015 / 02:31