JDK-8080555 : Different bytecode between JDK8u45 and JDK8u60-ea-b12
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u60
  • Priority: P2
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: linux
  • CPU: x86
  • Submitted: 2015-05-15
  • Updated: 2017-04-20
  • Resolved: 2015-05-29
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

java version "1.8.0_60-ea"
Java(TM) SE Runtime Environment (build 1.8.0_60-ea-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b12, mixed mode)

Same happens between JDK 7u75 and JDK 7u80:

java version "1.7.0_75"
Java(TM) SE Runtime Environment (build 1.7.0_75-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.75-b04, mixed mode)

java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)


A DESCRIPTION OF THE PROBLEM :
JDK8u45 (and JDK7u75) generate:
 
    8: aload_2       
     9: ifnull        44
    12: iload_1       
    13: lookupswitch  { // 1
                   0: 32
             default: 39
        }
    32: aconst_null   
    33: astore_3      
    34: aconst_null   
    35: astore_2      
    36: goto          41
    39: aconst_null   
    40: astore_2      
    41: goto          8

while JDK8u60-ea-b12 (and JDK7u80):

     8: aload_2       
     9: ifnull        44
    12: iload_1       
    13: lookupswitch  { // 1
                   0: 32
             default: 39
        }
    32: aconst_null   
    33: astore_3      
    34: aconst_null   
    35: astore_2      
    36: goto          8
    39: aconst_null   
    40: astore_2      
    41: goto          8

This is positive change for JaCoCo coverage engine, however might be an unexpected/overlooked side-effect of change in JDK:
I bisected jdk8u-dev forest and first commit, which changes behavior is http://hg.openjdk.java.net/jdk8u/jdk8u-dev/langtools/rev/dca7f60e618d , so associated ticket is https://bugs.openjdk.java.net/browse/JDK-8064857 , which is for my understanding has nothing to do with gotos, but only about LVT.
In case of jdk7 this seems to be related to https://bugs.openjdk.java.net/browse/JDK-8065674 and so http://hg.openjdk.java.net/jdk7u/jdk7u-dev/langtools/rev/979f55cda0e2

Original issue, which was reported against JaCoCo, and analysis can be found at https://github.com/jacoco/jacoco/issues/307


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
class Example {
  void fun(int p) {
    Object c = new Object();
    while (c != null) {
      switch (p) {
        case 0:
          Object s = null;
          c  = null;
          break;
        default:
          c = null;
          break;
      }
    }
  }
}
---------- END SOURCE ----------


Comments
This change is provoked by the new code at Code.entryPoint, see [1]: public int entryPoint(State state) { int pc = curCP(); alive = true; - this.state = state.dup(); + State newState = state.dup(); + setDefined(newState.defined); + this.state = newState; IMO not doing this was a bug in javac and a lack of consistency with the existing design for defining alive variables. So this change should be there. The obtained code is both correct and better than the previous one. I'm closing this as not a bug. [1] http://hg.openjdk.java.net/jdk9/jdk9/langtools/rev/3bdbc3b8aa14
29-05-2015

Please investigate if your latest LVT patch could trigger changes in resulting bytecode and, if they are benign or not. If I remember correctly, this patch should simply bring bytecode in line with what was generated in JDK 6 - as the older LVT patch required some bytecode changes in order to generate correct LVT entries, but this one does not.
18-05-2015