Using Array.newInstance still generates checkcast instructions
Aleksey Shipilev
aleksey.shipilev at oracle.com
Tue Oct 27 18:00:38 UTC 2015
The field is Object[] both in bytecode and "at JIT time".
And you cannot do otherwise since pessimistically somebody can store,
say, Integer instead of String there, thus polluting the heap. As John
says, you can only propagate the type information if, among other
things, the instance is guaranteed to avoid heap pollution. Compiler
cannot change field types, it can only carry a limited set of
constraints about the types...
AFAIR, once instance escapes, all bets are off. But even if
(hypothetically) dataflow analysis could have said the array has no
suspicious writes before your access right after the construction, I am
not very sure Array.newInstance is transparent for compiler at all.
Mostly because it delegates to a native method and apparently has no
vmSymbols entries that might indicate any special compiler treatment.
Thanks,
-Aleksey
On 10/27/2015 08:46 PM, Vitaly Davidovich 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.
>
> sent from my phone
>
> On Oct 27, 2015 1:40 PM, "John Rose" <john.r.rose at oracle.com
> <mailto:john.r.rose at oracle.com>> wrote:
>
> 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).
>
> 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).
>
> — John
>
> On Oct 27, 2015, at 10:23 AM, Vitaly Davidovich <vitalyd at gmail.com
> <mailto:vitalyd at gmail.com>> wrote:
> >
> > Hi,
> >
> > 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?
> >
> > e.g.
> >
> > public final class ArrayList<T> {
> > private final T[] _items;
> >
> > public ArrayList(Class<T> klass, int size) {
> > _items = (T[])Array.newInstance(klass, size);
> > }
> >
> > // rest omitted for brevity
> >
> > public T get(int index) { return _items[index]; }
> >
> > }
> >
> > ArrayList<String> strings = new ArrayList<>(String.class, 10);
> > String s = strings.get(0); // why is this checkcast not eliminated?
> >
> >
> > Thanks
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20151027/1669bcce/signature.asc>
More information about the hotspot-compiler-dev
mailing list