and to add to the history... the bug was reported with an asm version
before it started to produce nop, athrow. I think I remember also that
this was not long before the change asm did.
bye Jochen
On 21.11.18 17:27, Remi Forax wrote:
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 in
context).
Reproducing full message:
@aalmiray <https://github.com/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://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.