<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>Hi,<br>
I had the same reaction as Remi when first reading this thread. In
principle, yes, replacing invokespecial with invokevirtual can
cause bridge calls to go up and down the hierarchy and has more
potential for generating infinite loops. That said, I have not
been able to come up with a reasonable test case that would
introduce an infinite loop should javac implement the proposed
change. While 6996415 is definitively related, I believe that the
loop in that example is started by a bad descriptor ending up in
the explicit supercall (see bug evaluation) rather than by a
problem between invokevirtual vs. invokespecial.</p>
<p>I also note that ECJ already generates an invokevirtual in the
reported example. Again, I could not find any clue of a
bridge-related loop that shows up in ECJ but not in javac (but I'd
be happy to know if something like that exists),.</p>
<p>So, maybe it's a safe move after all?<br>
</p>
<p>Maurizio<br>
</p>
<p><br>
</p>
<br>
<div class="moz-cite-prefix">On 03/10/16 14:42, Remi Forax wrote:<br>
</div>
<blockquote
cite="mid:126526629.325590.1475502172744.JavaMail.zimbra@u-pem.fr"
type="cite">
<div style="font-family: arial, helvetica, sans-serif; font-size:
12pt; color: #000000">
<div>Hi Rafael,<br>
</div>
<div>it's not a binary compatible change.<br>
</div>
<div><br data-mce-bogus="1">
</div>
<div>if the compiler emits an invokevirtual instead of an
invokespecial, you can create an infinite loop between the
bridges <br data-mce-bogus="1">
</div>
<div><a class="moz-txt-link-freetext" href="https://bugs.openjdk.java.net/browse/JDK-6996415">https://bugs.openjdk.java.net/browse/JDK-6996415</a></div>
<div><br data-mce-bogus="1">
</div>
<div>Rémi<br data-mce-bogus="1">
</div>
<div><br>
</div>
<hr id="zwchr" data-marker="__DIVIDER__">
<div data-marker="__HEADERS__">
<blockquote style="border-left: 2px solid #1010FF;
margin-left: 5px; padding-left: 5px; color: #000;
font-weight: normal; font-style: normal; text-decoration:
none; font-family: Helvetica,Arial,sans-serif; font-size:
12pt;" data-mce-style="border-left: 2px solid #1010FF;
margin-left: 5px; padding-left: 5px; color: #000;
font-weight: normal; font-style: normal; text-decoration:
none; font-family: Helvetica,Arial,sans-serif; font-size:
12pt;"><b>De: </b>"Rafael Winterhalter"
<a class="moz-txt-link-rfc2396E" href="mailto:rafael.wth@gmail.com"><rafael.wth@gmail.com></a><br>
<b>À: </b><a class="moz-txt-link-abbreviated" href="mailto:compiler-dev@openjdk.java.net">compiler-dev@openjdk.java.net</a><br>
<b>Envoyé: </b>Lundi 3 Octobre 2016 12:13:29<br>
<b>Objet: </b>Why does javac use "invokespecial" for
diamond inheritance?<br>
</blockquote>
</div>
<div data-marker="__QUOTED_TEXT__">
<blockquote style="border-left: 2px solid #1010FF;
margin-left: 5px; padding-left: 5px; color: #000;
font-weight: normal; font-style: normal; text-decoration:
none; font-family: Helvetica,Arial,sans-serif; font-size:
12pt;" data-mce-style="border-left: 2px solid #1010FF;
margin-left: 5px; padding-left: 5px; color: #000;
font-weight: normal; font-style: normal; text-decoration:
none; font-family: Helvetica,Arial,sans-serif; font-size:
12pt;">
<div dir="ltr">
<div>
<div>
<div>I am wondering why javac is using an
invokespecial instruction for a bridge method in the
following case. Considering the following
refactoring starting from:<br>
<br>
</div>
class A {<br>
</div>
 public void m(String s) {<br>
</div>
   System.out.println("foo");<br>
<div>Â }<br>
<div>}<br>
<br>
</div>
<div>class B extends A { }<br>
<br>
</div>
<div>class C extends B {<br>
 public void m(String s) {<br>
   System.out.println("bar");<br>
 }<br>
}<br>
<br>
</div>
<div>I would change the implementing of B to implement
an additional interface:<br>
<br>
</div>
<div>interface I<T> {<br>
</div>
<div>Â void m(T t);<br>
</div>
<div>}<br>
</div>
<div><br>
class B extends A implements I<String> { }<br>
<br>
</div>
<div>C would live in its own module that is not
recompiled upon changing B. I do however not consider
this a problem as the change of B is binary
compatible. However, B ends up with the following
bridge method:<br>
<br>
class B extends A implements I<String> { <br>
</div>
<div>Â public bridge void m(Object o) {<br>
</div>
<div>Â Â Â Foo.special.m((String) o);<br>
</div>
<div>Â }<br>
</div>
<div>}<br>
<br>
</div>
<div>If a program does now invoke I::m on an instance of
C, "foo" is printed instead of "bar". This violates
the intended virtual dispatch for C. In my opinion,
this should not happen. Bridge methods, unless
"visibility bridges" should always use invokevirtual
as an override in C, should make it impossible to
invoke A::m directly from outside the class.<br>
<br>
</div>
<div>Did I miss something here or is this a bug?<br>
<br>
</div>
<div>Thank you for the clarification,<br>
Best regards, Rafael</div>
</div>
</div>
<br>
</blockquote>
</div>
</div>
</blockquote>
<br>
</body>
</html>