Using Array.newInstance still generates checkcast instructions
Vitaly Davidovich
vitalyd at gmail.com
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,
10);
private static int get() {
return POOL.get(0).length();
}
Disassembly for get():
[Verified Entry Point]
[Constants]
# {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 ;
{metadata('java/lang/String')}*
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) #
0x00007fcd802a6000
; {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 oracle.com> wrote:
> On Oct 27, 2015, at 10:46 AM, Vitaly Davidovich <vitalyd at gmail.com> 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: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20151027/864c862a/attachment-0001.html>
More information about the hotspot-compiler-dev
mailing list