Odd interaction between ArrayList$Itr and Escape Analysis

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Wed Sep 14 10:12:35 UTC 2016


> And I'm happy to upstream that patch, if the team is interested.

Sure, we are definitely interested in fixing that. Feel free to file a 
bug and send the fix out for review.

> Now, when I first discovered the problem, my first intuition was that
> it's better to "fix" it in javac. But before nest mates in the Class
> file, there isn't much that javac could do. Changing the Java libraries
> to not use private constructors in inner classes is also doable, but
> needs changing a lot of files.

I agree that javac is not the best place to fix the immediate problem: 
it requires recompilation and there are already lots of problematic 
bytecode shapes out in the wild. The JVM should optimize for that case 

> So I ended up fixing it in the VM, even though I agree fully with what
> Rémi brought up.

I'm curious how did you fix it. I haven't found a description in the 

It's possible to force class loading, but I'm worried about undesirable 
effects of class initialization. Is it enough for C2 to have the class 
loaded but not initialized to make it work?

Another approach would be to issue a null check and deoptimize (for 
bridge methods, the check collapses after inlining since the argument is 
always null) or add a nmethod dependency and throw away the code when 
the parameter class is loaded.

Best regards,
Vladimir Ivanov

> The access constructor tag thingy in javac is really a weird hack. If
> you guys ever look at the contents of ArrayList$1, it's really empty
> -- the class doesn't even declare some of the usual structures in a
> normal Class file... Hopefully we can get rid of it in javac soon.

> On Tuesday, September 13, 2016, Vitaly Davidovich <vitalyd at gmail.com
> <mailto:vitalyd at gmail.com>> wrote:
>     On Tuesday, September 13, 2016, Remi Forax <forax at univ-mlv.fr
>     <javascript:_e(%7B%7D,'cvml','forax at univ-mlv.fr');>> wrote:
>         I've always found that the empty inner classes generated by
>         javac as a kind of hack.
>         These classes should be removed in Java 10, thanks to the
>         nestmate attributes.
>         http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2016-January/000060.html
>         <http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2016-January/000060.html>
>         The other solution, is to have an empty class in the jdk which
>         is not visible from javac (the class itself can be marked as
>         synthetic),
>         so javac can use it without creating method clash.
>         and to solve the problem now, the easy solution is to add a
>         package private constructor in ArrayList.Itr,
>     I'm hoping Oracle can take Kris' (Azul) patch (or do something
>     similar).  It might catch more cases than just modifying Itr.
>         private class Itr implements Iterator<E> {
>         int cursor; // index of next element to return
>         int lastRet = -1; // index of last element returned; -1 if no such
>         int expectedModCount = modCount;
>         Itr() {
>         // avoid to generate a synthetic accessor constructor
>         }
>         }
>         regards,
>         Rémi
>         ------------------------------------------------------------------------
>             *De: *"Vitaly Davidovich" <vitalyd at gmail.com>
>             *À: *"Krystal Mok" <rednaxelafx at gmail.com>
>             *Cc: *"hotspot compiler" <hotspot-compiler-dev at openjdk.java.net>
>             *Envoyé: *Lundi 12 Septembre 2016 22:15:41
>             *Objet: *Re: Odd interaction between ArrayList$Itr and
>             Escape Analysis
>             On Mon, Sep 12, 2016 at 3:56 PM, Krystal Mok
>             <rednaxelafx at gmail.com> wrote:
>                 On Mon, Sep 12, 2016 at 12:38 PM, Vitaly Davidovich
>                 <vitalyd at gmail.com> wrote:
>                     It seems odd to me as well why inlining won't force
>                     load the missing class(es).  If we're inlining, it
>                     means the method itself or the call chain it's part
>                     of is hot - failing to inline can have negative
>                     side-effects, like this example.  I suppose there
>                     must be a good reason why it doesn't do this though?
>                 That's because we can't. The JIT compilers are running
>                 on their own threads, and they're not real "Java
>                 threads". So they are not allowed to run arbitrary Java
>                 code. But Java class loading may involve running
>                 arbitrary Java code, e.g. the ClassLoader.loadClass()
>                 upcall.
>                 Force class loading can be done on the triggering side
>                 (for the top-level method), because compilation tasks
>                 are triggered from real Java threads, and they're
>                 allowed to run arbitrary Java code.
>             I see, makes sense.  Perhaps there can be an option to turn
>             on loading of required types in the entire compilation unit,
>             after all inlining is done (and therefore make the unloaded
>             types not be barriers for inlining).  I'd personally prefer
>             that over having odd performance differences.
>                 - Kris
>             Thanks Kris.
>     --
>     Sent from my phone

More information about the hotspot-compiler-dev mailing list