Using Array.newInstance still generates checkcast instructions

Aleksey Shipilev aleksey.shipilev at oracle.com
Tue Oct 27 18:12:57 UTC 2015


Ah no, my bad. C2 actually intrinsifies j.l.r.Array::newArray.

I would think storing that array instance into Object[] field trips any
subsequent analysis. If I were you, I'd do more differential tests:
pulling the "string" from the near-allocated newArray, the same with
load/store through String[], the same with load/store through Object[], etc.

-Aleksey

On 10/27/2015 09:00 PM, Aleksey Shipilev wrote:
> 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/76141f76/signature.asc>


More information about the hotspot-compiler-dev mailing list