<p dir="ltr">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.</p>
<p dir="ltr">sent from my phone</p>
<div class="gmail_quote">On Oct 27, 2015 1:40 PM, "John Rose" <<a href="mailto:john.r.rose@oracle.com">john.r.rose@oracle.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">It's an old problem we have talked about before:  There is only limited type inference through field loads.  The JIT notes that the type of the heap variable is the erased Object[].  It does not attempt to attach special knowledge (T=String) to the type of 'strings' (ArrayList), because type parameter bindings are not completely reliable at runtime, due to the possibility of heap pollution (e.g., via reflective access).<br>
<br>
In some cases if the whole use case is inlined (as perhaps may happen here) then 'strings' can be scalarized and type propagation will be more accurate, since 'strings._items' would be lifted into a register.  (Type prop. through locals is not disturbed by the possibility of reflective access, heap pollution, etc.)  If you are seeing a cast then either (a) scalarization is incomplete (it can fail for even tiny reasons which is why we need un-aliasable value types), or (b) there is a bug somewhere.  The likely bet is (a).<br>
<br>
— John<br>
<br>
On Oct 27, 2015, at 10:23 AM, Vitaly Davidovich <<a href="mailto:vitalyd@gmail.com">vitalyd@gmail.com</a>> wrote:<br>
><br>
> Hi,<br>
><br>
> I (intuitively) thought that using Array.newInstance() and specifying a final class (e.g. String) would remove checkcasts in the caller.  However, it appears that the check is still generated (at least on 8u51).  Why would this be? It seems the JIT should know the true runtime type of the array, and if accesses to it are inlined, the checkcast could be removed.  Am I missing something?<br>
><br>
> e.g.<br>
><br>
> public final class ArrayList<T> {<br>
>     private final T[] _items;<br>
><br>
>     public ArrayList(Class<T> klass, int size) {<br>
>          _items = (T[])Array.newInstance(klass, size);<br>
>     }<br>
><br>
>     // rest omitted for brevity<br>
><br>
>     public T get(int index) { return _items[index]; }<br>
><br>
> }<br>
><br>
> ArrayList<String> strings = new ArrayList<>(String.class, 10);<br>
> String s = strings.get(0); // why is this checkcast not eliminated?<br>
><br>
><br>
> Thanks<br>
<br>
</blockquote></div>