Using Array.newInstance still generates checkcast instructions

Vitaly Davidovich vitalyd at
Tue Oct 27 18:14:55 UTC 2015

Here's the basic example I used earlier, a bit more spelled out + assembly:

static final class ArrayList<T>
        private final T[] _items;

        ArrayList(final Class<T> klass, final int size) {
            _items = (T[]) Array.newInstance(klass, size);
            for (int i = 0; i < _items.length; ++i) {
                try {
                    _items[i] = klass.newInstance();
                } catch (InstantiationException | IllegalAccessException e)
                    throw new RuntimeException(e);

        public T get(final int index) {
            return _items[index];

private static final ArrayList<String> POOL = new ArrayList<>(String.class,

private static int get() {
        return POOL.get(0).length();

Disassembly for get():

[Verified Entry Point]
  # {method} {0x00007fcd5029f960} 'get' '()I'
  #           [sp+0x20]  (sp of caller)
  0x00007fcd7a488820: mov    %eax,-0x14000(%rsp)
  0x00007fcd7a488827: push   %rbp
  0x00007fcd7a488828: sub    $0x10,%rsp         ;*synchronization entry

  0x00007fcd7a48882c: mov    $0x64890def0,%r10  ;   {oop(`POOL`)}
  0x00007fcd7a488836: mov    0xc(%r10),%r11d    ;*getfield _items

  0x00007fcd7a48883a: mov    0xc(%r12,%r11,8),%r10d  ; implicit exception:
dispatches to 0x00007fcd7a488895
  0x00007fcd7a48883f: test   %r10d,%r10d
  0x00007fcd7a488842: jbe    0x00007fcd7a488870
  0x00007fcd7a488844: mov    0x10(%r12,%r11,8),%ebp  ;*aaload

  0x00007fcd7a488849: mov    0x8(%r12,%rbp,8),%r11d  ; implicit exception:
dispatches to 0x00007fcd7a4888a5
*  0x00007fcd7a48884e: cmp    $0xf80002da,%r11d  ;
  0x00007fcd7a488855: jne    0x00007fcd7a488885
  0x00007fcd7a488857: lea    (%r12,%rbp,8),%r10  ;*checkcast

  0x00007fcd7a48885b: mov    0xc(%r10),%r10d    ;*getfield value
                                                ; -
java.lang.String::length at 1 (line 611)

  0x00007fcd7a48885f: mov    0xc(%r12,%r10,8),%eax  ;*arraylength
                                                ; -
java.lang.String::length at 4 (line 611)
                                                ; implicit exception:
dispatches to 0x00007fcd7a4888b5
  0x00007fcd7a488864: add    $0x10,%rsp
  0x00007fcd7a488868: pop    %rbp
  0x00007fcd7a488869: test   %eax,0x5e1d791(%rip)        #
                                                ;   {poll_return}
  0x00007fcd7a48886f: retq

I even gave it a static final field (as the holder of the array) to work
with :(.

On Tue, Oct 27, 2015 at 1:56 PM, John Rose <john.r.rose at> wrote:

> On Oct 27, 2015, at 10:46 AM, Vitaly Davidovich <vitalyd at> wrote:
> The whole use case is inlined here, which is the case that bothers me.  If
> the underlying array access is inlined, couldn't its runtime type be
> checked? I don't understand the heap pollution issue in this case.  The
> field is not Object[] at JIT time.
> As a more more limited use case for Array.newInstance, see
> Arrays.copyOfRange (four argument version).
> That is supposed to copyOfRange(new String[2], …) is supposed to feed
> through the right type to the return value, and it's a bug if it doesn't.
> There's some relevant difference in your use case (even after inlining)
> and copyOfRange; I think it's the field.  Maybe our scalarization
> optimization is losing the type of the value; the rules for feeding types
> through fields (even after scalarization) are tricky.
> — John
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the hotspot-compiler-dev mailing list