[9] RFR (M): 8037209: Improvements and cleanups to bytecode assembly for lambda forms

Paul Sandoz paul.sandoz at oracle.com
Wed Jul 9 10:14:24 UTC 2014


On Jul 8, 2014, at 9:09 PM, John Rose <john.r.rose at oracle.com> wrote:

> Regarding the extra cast in accessor logic that Paul picked up on:  That may be a left-over from obsolete versions of the code, or it may cover for some corner cases, or it could possibly be a re-assurance to the JIT.
> 
> Generally speaking, we lean heavily on MH types to guarantee a priori correctness of argument types.  Paul is right that the stored value type is already validated and (except for corner cases we may be neglecting) does not need re-validation via a cast.
> 
> It might be an interesting experiment to replace the cast with an assert.
> 

I did briefly look at that a few months ago, i would need to systematically revisit. My memory is hazy, I seem to recall removing casts perturbed the compilation process more than i expected.


> Sometimes corner cases bite you.  For example, an array store check is necessary, if the type is an interface, because interfaces are weakly checked all the way up to aastore or invokeinterface.
> 
> Sometimes the JIT cannot see the type assurances implicit in a MH type, and so (when choosing internal MH code shapes) we must choose between handing the JIT code that is not locally verifiable, or adding "reassurance" casts to repair the local verifiability of the code.  If the JIT thinks it sees badly-typed code, it might bail out.Note that "locality" of verifiability is a fluid concept, depending sometime on vagaries of inlining decisions.  This is the reason for some awkward looking "belt and suspenders" MH internals, such as the free use of casts in LF bytecode rendering.
> 
> Usually, redundant type verifications (including casts and signatures of incoming arguments) are eliminated, but they can cause (as noted) an extra null check.  In theory, that should fold up also, if the null value is replaced by "another" null, as (p == null ? null : identityFunction(p)).
> 

I quickly verified the fold up does as you expect. Also, if i do the following the null check goes away:

public class A {

   volatile String a = "A";
   volatile String snull = null;
   public volatile String b;

   static final MethodHandle b_setter;

   static {
       try {
           b_setter = MethodHandles.lookup().findSetter(A.class, "b", String.class);
       }
       catch (Exception e) {
           throw new Error(e);
       }
   }

   public static void main(String[] args) {
       A a = new A();
       a.testLoop();
   }

   void testLoop() {
       for (int i = 0; i < 1000000; i++) {
           testLoopOne(a);
           testLoopOne(snull);
       }
   }
   void testLoopOne(String s) {
       try {
             b_setter.invokeExact(this, s);
       } catch (Throwable t) {
           throw new Error(t);
       }
   }
}

I am probably obsessing too much over some micro/nano-benchmarks, but i am wondering if this could cause some unwanted de-opt/recompilation effects when all is good with no null values then suddenly a null triggers de-optimization.

Paul.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 841 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20140709/7cc5ca17/signature.asc>


More information about the mlvm-dev mailing list