NOP instruction at program counter of ArrayAllocationSite

Issue #107 resolved
florian_kuebler created an issue

Within the JDK there are some ArrayAllocationSites whose program counter points to a NOP instruction.

Comments (10)

  1. florian_kuebler reporter

    To clarify this: The NOP instruction is in the TAC code. E.g. for the method updateCachedDatas in sun.management.snmp.jvminstr.JvmThreadInstanceTableMetaImpl$JvmThreadInstanceTableCache I get an ArrayAllocationSite with pc = 15. In the bytecode the instruction on pc 15 is a ANEWARRAY instruction, but in the TAC code there is a NOP at pc 15. Reffering to pc 14 there is an Assignment with an ArrayLength expression. Maybe there is an off-by-one? In the Bytecode at pc 14, there is also the ArrayLength.

  2. Michael Eichberg repo owner

    I can reproduce the problem and the problem seems to be related to the immediately preceding array length...

  3. Michael Eichberg repo owner

    The TAC code is correct - the NewArray instruction is dead and therefore removed from the Code. (And the TAC code also does not contain any instruction with the PC 15.)

  4. florian_kuebler reporter
    • changed status to open
    java.lang.RuntimeException: This analysis can't handle entity: ArrayAllocationSite(sun.management.snmp.jvminstr.JvmThreadInstanceTableMetaImpl$JvmThreadInstanceTableCache{ protected sun.management.snmp.util.SnmpCachedData updateCachedDatas(java.lang.Object){ pc=15 } }) for Nop(pc=15)
        at org.opalj.fpcf.analyses.SimpleEscapeAnalysis.determineEscape(SimpleEscapeAnalysis.scala:319)
        at org.opalj.fpcf.analyses.SimpleEscapeAnalysis$$anonfun$start$1.apply(SimpleEscapeAnalysis.scala:347)
        at org.opalj.fpcf.analyses.SimpleEscapeAnalysis$$anonfun$start$1.apply(SimpleEscapeAnalysis.scala:347)
        at org.opalj.fpcf.PropertyStore$$anonfun$org$opalj$fpcf$PropertyStore$$scheduleComputation$1.apply$mcV$sp(PropertyStore.scala:1663)
        at org.opalj.fpcf.PropertyStore$$anon$7.run(PropertyStore.scala:1700)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:748)
    [error][analysis progress] an analysis failed
    [error][analysis progress] class java.lang.RuntimeException: This analysis can't handle entity: ArrayAllocationSite(sun.management.snmp.jvminstr.JvmThreadInstanceTableMetaImpl$JvmThreadInstanceTableCache{ protected sun.management.snmp.util.SnmpCachedData updateCachedDatas(java.lang.Object){ pc=15 } }) for Nop(pc=15)
    [error][analysis progress]  org.opalj.fpcf.analyses.SimpleEscapeAnalysis.determineEscape(SimpleEscapeAnalysis.scala:319)
    [error][analysis progress]  org.opalj.fpcf.analyses.SimpleEscapeAnalysis$$anonfun$start$1.apply(SimpleEscapeAnalysis.scala:347)
    [error][analysis progress]  org.opalj.fpcf.analyses.SimpleEscapeAnalysis$$anonfun$start$1.apply(SimpleEscapeAnalysis.scala:347)
    [error][analysis progress]  org.opalj.fpcf.PropertyStore$$anonfun$org$opalj$fpcf$PropertyStore$$scheduleComputation$1.apply$mcV$sp(PropertyStore.scala:1663)
    [error][analysis progress]  org.opalj.fpcf.PropertyStore$$anon$7.run(PropertyStore.scala:1700)
    [error][analysis progress]  java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    [error][analysis progress]  java.util.concurrent.FutureTask.run(FutureTask.java:266)
    [error][analysis progress]  java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    [error][analysis progress]  java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    [error][analysis progress]  java.lang.Thread.run(Thread.java:748)
    java.lang.RuntimeException: This analysis can't handle entity: ArrayAllocationSite(com.sun.jndi.dns.DnsClient{ private byte[] doUdpQuery(com.sun.jndi.dns.Packet,java.net.InetAddress,int,int,int){ pc=117 } }) for Nop(pc=117)
        at org.opalj.fpcf.analyses.SimpleEscapeAnalysis.determineEscape(SimpleEscapeAnalysis.scala:319)
        at org.opalj.fpcf.analyses.SimpleEscapeAnalysis$$anonfun$start$1.apply(SimpleEscapeAnalysis.scala:347)
        at org.opalj.fpcf.analyses.SimpleEscapeAnalysis$$anonfun$start$1.apply(SimpleEscapeAnalysis.scala:347)
        at org.opalj.fpcf.PropertyStore$$anonfun$org$opalj$fpcf$PropertyStore$$scheduleComputation$1.apply$mcV$sp(PropertyStore.scala:1663)
        at org.opalj.fpcf.PropertyStore$$anon$7.run(PropertyStore.scala:1700)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:748)
    [error][analysis progress] an analysis failed
    [error][analysis progress] class java.lang.RuntimeException: This analysis can't handle entity: ArrayAllocationSite(com.sun.jndi.dns.DnsClient{ private byte[] doUdpQuery(com.sun.jndi.dns.Packet,java.net.InetAddress,int,int,int){ pc=117 } }) for Nop(pc=117)
    [error][analysis progress]  org.opalj.fpcf.analyses.SimpleEscapeAnalysis.determineEscape(SimpleEscapeAnalysis.scala:319)
    [error][analysis progress]  org.opalj.fpcf.analyses.SimpleEscapeAnalysis$$anonfun$start$1.apply(SimpleEscapeAnalysis.scala:347)
    [error][analysis progress]  org.opalj.fpcf.analyses.SimpleEscapeAnalysis$$anonfun$start$1.apply(SimpleEscapeAnalysis.scala:347)
    [error][analysis progress]  org.opalj.fpcf.PropertyStore$$anonfun$org$opalj$fpcf$PropertyStore$$scheduleComputation$1.apply$mcV$sp(PropertyStore.scala:1663)
    [error][analysis progress]  org.opalj.fpcf.PropertyStore$$anon$7.run(PropertyStore.scala:1700)
    [error][analysis progress]  java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    [error][analysis progress]  java.util.concurrent.FutureTask.run(FutureTask.java:266)
    [error][analysis progress]  java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    [error][analysis progress]  java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    [error][analysis progress]  java.lang.Thread.run(Thread.java:748)
    
  5. Michael Eichberg repo owner

    I'm completely puzzled.... I can't reproduce the problem. The TAC code for one of the mentioned methods looks like:

    sun.management.snmp.util.SnmpCachedData updateCachedDatas(java.lang.Object){
          /* PARAMETERS:
             param0: useSites={} (origin=-1)
             param1: useSites={} (origin=-2)
          */
        0:/*pc=0:*/ lv0 = sun.management.snmp.jvminstr.JvmThreadingImpl.getThreadMXBean()
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 0 →
        1:/*pc=3:*/ lv1 = {lv0}/*java.lang.management.ThreadMXBean*/.getAllThreadIds()
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 1 →
        2:/*pc=9:*/ lv2 = java.lang.System.currentTimeMillis()
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 2 →
        3:/*pc=14:*/ /*expression value is ignored:*/{lv1}.length
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 3 →
        4:/*pc=20:*/ lv4 = new TreeMap
        5:/*pc=24:*/ lv5 = sun.management.snmp.util.SnmpCachedData.oidComparator
        6:/*pc=27:*/ {lv4}/*(non-virtual) java.util.TreeMap*/.<init>({lv5})
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 6 →
        7:/*pc=32:*/ lv7 = 0
    
          // 26, 7 →
        8:/*pc=38:*/ lv8 = {lv1}.length
        9:/*pc=39:*/ if({lv7, lv19} >= {lv8}) goto 27
    
          // 9 →
       10:/*pc=42:*/ lva = sun.management.snmp.jvminstr.JvmThreadInstanceTableMetaImpl.log
       11:/*pc=45:*/ lvb = ""
       12:/*pc=47:*/ lvc = new StringBuilder
       13:/*pc=51:*/ {lvc}/*(non-virtual) java.lang.StringBuilder*/.<init>()
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 13 →
       14:/*pc=54:*/ lve = "Making index for thread id ["
       15:/*pc=56:*/ lvf = {lvc}/*java.lang.StringBuilder*/.append({lve})
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 15 →
       16:/*pc=62:*/ lv10 = {lv1}[{lv7, lv19}]
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 16 →
       17:/*pc=63:*/ lv11 = {lvf}/*java.lang.StringBuilder*/.append({lv10})
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 17 →
       18:/*pc=66:*/ lv12 = "]"
       19:/*pc=68:*/ lv13 = {lv11}/*java.lang.StringBuilder*/.append({lv12})
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 19 →
       20:/*pc=71:*/ lv14 = {lv13}/*java.lang.StringBuilder*/.toString()
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 20 →
       21:/*pc=74:*/ {lva}/*sun.management.snmp.util.MibLogger*/.debug({lvb}, {lv14})
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 21 →
       22:/*pc=80:*/ lv16 = {lv1}[{lv7, lv19}]
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 22 →
       23:/*pc=81:*/ lv17 = sun.management.snmp.jvminstr.JvmThreadInstanceTableMetaImpl.makeOid({lv16})
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 23 →
       24:/*pc=92:*/ /*expression value is ignored:*/{lv4}/*java.util.TreeMap*/.put({lv17}, {lv17})
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 24 →
       25:/*pc=96:*/ lv19 = {lv7, lv19} + 1
       26:/*pc=99:*/ goto 8
    
          // 9 →
       27:/*pc=102:*/ lv1b = new SnmpCachedData
       28:/*pc=109:*/ {lv1b}/*(non-virtual) sun.management.snmp.util.SnmpCachedData*/.<init>({lv2}, {lv4})
          // ⚡️ <uncaught exception ⇒ abnormal return>
    
          // 28 →
       29:/*pc=112:*/ return {lv1b}
    }
    

    And does not contain a single statement with the PC 15... can you paste the code which you use to correlate the AllocationSites with the TAC Statement over here?

  6. florian_kuebler reporter

    Okay I got a something. When running TAC with that method and class I got the TAC code without the NOP(pc=15).

    In my code I used the PrimitiveTACAIDomain, so running TAC with the following command will reproduce the error: -source PATH/TO/rt.jar -method updateCachedDatas -domain org.opalj.ai.domain.l0.PrimitiveTACAIDomain -class sun.management.snmp.jvminstr.JvmThreadInstanceTableMetaImpl$JvmThreadInstanceTableCache

    [info] sun.management.snmp.util.SnmpCachedData updateCachedDatas(java.lang.Object){
    [info]       /* PARAMETERS:
    [info]          param0: useSites={} (origin=-1)
    [info]          param1: useSites={} (origin=-2)
    [info]       */
    [info]     0:/*pc=0:*/ lv0 = sun.management.snmp.jvminstr.JvmThreadingImpl.getThreadMXBean()
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 0 →
    [info]     1:/*pc=3:*/ lv1 = {lv0}/*java.lang.management.ThreadMXBean*/.getAllThreadIds()
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 1 →
    [info]     2:/*pc=9:*/ lv2 = java.lang.System.currentTimeMillis()
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 2 →
    [info]     3:/*pc=14:*/ /*expression value is ignored:*/{lv1}.length
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 3 →
    [info]     4:/*pc=15:*/ ;
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 4 →
    [info]     5:/*pc=20:*/ lv5 = new TreeMap
    [info]     6:/*pc=24:*/ lv6 = sun.management.snmp.util.SnmpCachedData.oidComparator
    [info]     7:/*pc=27:*/ {lv5}/*(non-virtual) java.util.TreeMap*/.<init>({lv6})
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 7 →
    [info]     8:/*pc=32:*/ lv8 = 0
    [info] 
    [info]       // 8, 27 →
    [info]     9:/*pc=38:*/ lv9 = {lv1}.length
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 9 →
    [info]    10:/*pc=39:*/ if({lv8, lv1a} >= {lv9}) goto 28
    [info] 
    [info]       // 10 →
    [info]    11:/*pc=42:*/ lvb = sun.management.snmp.jvminstr.JvmThreadInstanceTableMetaImpl.log
    [info]    12:/*pc=45:*/ lvc = ""
    [info]    13:/*pc=47:*/ lvd = new StringBuilder
    [info]    14:/*pc=51:*/ {lvd}/*(non-virtual) java.lang.StringBuilder*/.<init>()
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 14 →
    [info]    15:/*pc=54:*/ lvf = "Making index for thread id ["
    [info]    16:/*pc=56:*/ lv10 = {lvd}/*java.lang.StringBuilder*/.append({lvf})
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 16 →
    [info]    17:/*pc=62:*/ lv11 = {lv1}[{lv8, lv1a}]
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 17 →
    [info]    18:/*pc=63:*/ lv12 = {lv10}/*java.lang.StringBuilder*/.append({lv11})
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 18 →
    [info]    19:/*pc=66:*/ lv13 = "]"
    [info]    20:/*pc=68:*/ lv14 = {lv12}/*java.lang.StringBuilder*/.append({lv13})
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 20 →
    [info]    21:/*pc=71:*/ lv15 = {lv14}/*java.lang.StringBuilder*/.toString()
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 21 →
    [info]    22:/*pc=74:*/ {lvb}/*sun.management.snmp.util.MibLogger*/.debug({lvc}, {lv15})
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 22 →
    [info]    23:/*pc=80:*/ lv17 = {lv1}[{lv8, lv1a}]
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 23 →
    [info]    24:/*pc=81:*/ lv18 = sun.management.snmp.jvminstr.JvmThreadInstanceTableMetaImpl.makeOid({lv17})
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 24 →
    [info]    25:/*pc=92:*/ /*expression value is ignored:*/{lv5}/*java.util.TreeMap*/.put({lv18}, {lv18})
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 25 →
    [info]    26:/*pc=96:*/ lv1a = {lv8, lv1a} + 1
    [info]    27:/*pc=99:*/ goto 9
    [info] 
    [info]       // 10 →
    [info]    28:/*pc=102:*/ lv1c = new SnmpCachedData
    [info]    29:/*pc=109:*/ {lv1c}/*(non-virtual) sun.management.snmp.util.SnmpCachedData*/.<init>({lv2}, {lv5})
    [info]       // ⚡️ <uncaught exception ⇒ abnormal return>
    [info] 
    [info]       // 29 →
    [info]    30:/*pc=112:*/ return {lv1c}
    [info] }
    
  7. Michael Eichberg repo owner

    Merge branch 'develop' of https://bitbucket.org/delors/opal into develop

    • 'develop' of https://bitbucket.org/delors/opal: fixed issue #107 Fixed TAC removed legacy call graph code sorted imports killed old/unused code fixed the generation of proxy classes if a NewInvokeSpecialMethodHandle is used added assertion to catch inconsistencies when proxy classes are generated refined documentation fixed comment added a type test method (for convenience purposes only)

    → <<cset b4546ba06ee0>>

  8. Log in to comment