The history from the ASM point of view, 
starting with Java 6, the VM starts to use a new bytecode verifier which is 
linear in time and not exponential like the previous one but it requires to 
annotate with a StackMap attribute the bytecode with the state of the local 
types and the stack types more or less at the start of each basic block. 
with Java 7, if you want to generate Java 7 bytecode (to access to 
invokedynamic by example), you have to use the new bytecode verifier, so you 
have no choice but to add those StackMap attributes. 

ASM since Java 6 allows users to ask to generate the StackMap attributes by 
running a point fix algorithm (the exponential one) when you generate the 
bytecode so the VM can verify the bytecode linearly. 
The problem if that in order to compute the StackMap information, we need to 
information that comes from the "parameter" of the basic block, but if the code 
is never called, we do not have this information. 
A previous release of ASM (again a long time ago) was failing in that case, a 
lot of people ask us to find a way to generate something (you can not remove 
it) when there is a dead code given that it will be never called anyway. That's 
why ASM generates the infamous nop ... athrow sequence. 

So you have several ways to fix the issue, 
- ask Evgeny (in CC) that jacoco should recognize the nop ... athrow sequence 
and do not report it. 
- fix the groovy compiler to not generate dead code 

regards, 
Rémi 

> De: "Jochen Theodorou" <blackd...@gmx.org>
> À: "dev" <dev@groovy.apache.org>
> Envoyé: Mercredi 21 Novembre 2018 15:02:49
> Objet: Aw: Groovy 2.5.4 generates dead code

> Hi Andres,
> there was at some point in the past (I think it was related to Java8) a 
> problem
> with us doing entries into the exception table (I think it was that table).
> There was no fix to this on any simple or middle level. The entry was made 
> like
> that because of how the data is processed in AsmClassGenerator. That is why we
> added an additional instruction at the end, which then gets compiled by asm as
> nop; athrow; even though we do something else here. I vagually remember it had
> to do with us using asm to create a label for marking a range, then not having
> any instructions anymore and then marking the end of the range, followed by no
> further instructions... take it with care, this was 3 or 4 years ago or so -
> and I do not remember any JIRA issue for this right now either, but I think 
> the
> riginal issue mentioned VerificationErrors.
> It is possible that this original issue no longer exists.
> bye Jochen
> Gesendet: Mittwoch, 21. November 2018 um 11:19 Uhr
> Von: "Andres Almiray" <aalmi...@gmail.com>
> An: dev@groovy.apache.org
> Betreff: Groovy 2.5.4 generates dead code
> Hello everyone,
> Evgeny Mandrikov (from JaCoCo) sent me a message regarding dead code produced 
> by
> Groovy 2.5.4 (see [
> https://github.com/jacoco/jacoco/pull/733#issuecomment-440030323 |
> https://github.com/jacoco/jacoco/pull/733#issuecomment-440030323 ] in 
> context).
> Reproducing full message:

> [ https://github.com/aalmiray | @aalmiray ] while playing further with 
> Groovy, I
> noticed that groovyc 2.5.4 generates dead bytecode for the following
> Example.groovy
> Closure closure = { println ( " Hello, " ) println ( " World! " )
> }
> closure()

> here is corresponding part from javap -v -p Example\$_run_closure1 output
> public java.lang.Object doCall(java.lang.Object);
>     descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
>     flags: ACC_PUBLIC
>     Code:
>       stack=3, locals=3, args_size=2
>         0: invokestatic  #22                 // Method
>          $getCallSiteArray:()[Lorg/codehaus/groovy/runtime/callsite/CallSite;
>          3: astore_2
>          4: aload_2
>          5: ldc           #32                 // int 0
>          7: aaload
>          8: aload_0
>          9: ldc           #34                 // String Hello,
>        11: invokeinterface #40,  3           // InterfaceMethod
>         
> org/codehaus/groovy/runtime/callsite/CallSite.callCurrent:(Lgroovy/lang/GroovyObject;Ljava/lang/Object;)Ljava/lang/Object;
>         16: pop
>         17: aload_2
>         18: ldc           #41                 // int 1
>         20: aaload
>         21: aload_0
>         22: ldc           #43                 // String World!
>        24: invokeinterface #40,  3           // InterfaceMethod
>         
> org/codehaus/groovy/runtime/callsite/CallSite.callCurrent:(Lgroovy/lang/GroovyObject;Ljava/lang/Object;)Ljava/lang/Object;
>         29: areturn
>         30: nop
>         31: athrow
>       StackMapTable: number_of_entries = 1
>         frame_type = 255 /* full_frame */
>           offset_delta = 30
>           locals = []
>           stack = [ class java/lang/Throwable ]
>       LineNumberTable:
>         line 2: 4
>         line 3: 17
>       LocalVariableTable:
>         Start  Length  Slot  Name   Signature
>             0      30     0  this   LExample$_run_closure1;
>             0      30     1    it   Ljava/lang/Object;

> instructions at offsets 30 and 31 are not reachable, therefore line 3 that
> starts at instruction with offset 17 will always be marked as uncovered.
> Any ideas on what may be causing this behavior?
> Cheers,
> Andres
> -------------------------------------------
> Java Champion; Groovy Enthusiast
> JCP EC Associate Seat
> [ http://andresalmiray.com/ | http://andresalmiray.com ]
> [ http://www.linkedin.com/in/aalmiray | http://www.linkedin.com/in/aalmiray ]
> --
> What goes up, must come down. Ask any system administrator.
> There are 10 types of people in the world: Those who understand binary, and
> those who don't.
> To understand recursion, we must first understand recursion.

Reply via email to