Graal final field treatment with respect to optimizations

Tom Rodriguez tom.rodriguez at oracle.com
Mon Apr 27 18:35:09 UTC 2015


> On Apr 27, 2015, at 11:02 AM, Vitaly Davidovich <vitalyd at gmail.com> wrote:
> 
> Thanks Gilles.
> 
> Why is there a restriction that receiver has to be constant as well? In
> addition, why does the value have to be *not* default? Specifically, an
> example I mentioned to John was akin to this:
> 
> final class Foo {
>     private final Object[] _arr = new Object[10];
> 
>     int capacity() { return _arr.length; }
> 
>     Object getFirst() { return _arr[0]; }
> }
> 
> What's the reason capacity() cannot be constant folded to 10 if the
> receiver is non-constant? Likewise with getFirst().  Is this again because
> there's no field profiling? I suspect so, but just want to double check.
> 
> Has any thought been given to doing some (basic) field profiling? Actually,
> I'm reluctant to call the above profiling since it seems like it could be
> done at parse/compile time? To me profiling sounds more like "there's a
> final field of interface type Foo, and we profile to see that at runtime we
> only have 1 real type stored there, FooImpl", or something like that.

I agree field profiling doesn’t seem like it’s the solution you’re talking about here.

Years ago I build something like this for HotSpot that did a local symbolic analysis of all field initializations for a class to detect things like your example.  At the byte code level you can identify fields which are only stored in the constructor and capture symbolic properties of those initializations.  You don’t really need to care about final either, just that the amount of code you need to analyze is restricted through the use of access controls. You can dynamically trap all stores except the ones you’ve analyzying to treat fields as effectively final. In your example the fact that _arr is exactly Object[] is more interesting than having a constant length since store checks aren’t required for Object[].

My experience was that it did some really clever things but that it largely didn’t translate into performance since you’re just shaving a tiny bits of work off something which is generally well optimized in the first place.  Type profiling and other speculative optimizations often pick up the interesting things here and maybe that’s what John was getting at with suggesting field profiling.

tom

> 
> Thanks
> 
> 
> On Mon, Apr 27, 2015 at 1:45 PM, Gilles Duboscq <gilwooden at gmail.com> wrote:
> 
>> Hi Vitaly,
>> 
>> We currently do not respect the TrustNonStaticFinalFields field.
>> We have a "@Stable-like" behaviour for non-static final fields:
>> 
>> * static final:
>>  We always constant fold
>> 
>> * final
>>  We constant fold if the receiver is constant and if the value is not
>> default (null, 0, 0.0, false...). This is not what HotSpot normally does
>> and we just enabled this to see what would happen. At some point we'll
>> probably change to only do that if TrustNonStaticFinalFields is true just
>> to respect HotSpot's wish though.
>> 
>> * @Stable final array[]
>>  We constant fold if the receiver is constant and if the value is not
>> default (null, 0, 0.0, false...) and we apply the @Stable final property
>> for the elements of the array (up to the declared field's dimension). i.e.
>> an access like array[0] would also be constant folded (this would not be
>> done for final: we would access a constant array object the the load from
>> this array would stay).
>> 
>> * Some fields are automatically promoted to @Stable
>>  The String.value field and synthetic $VALUES, ENUM$VALUES, $SwitchMap$
>> and $SWITCH_TABLE$ fields (from enums) are automatically promoted to
>> @Stable.
>> 
>> We do not do any additional profiling of fields in the runtime.
>> 
>> 
>> 
>> On Fri, Apr 24, 2015 at 3:57 PM Vitaly Davidovich <vitalyd at gmail.com>
>> wrote:
>> 
>>> Hi guys,
>>> 
>>> I recently had a thread on hotspot-compiler-dev where John Rose shed some
>>> light on what the TrustNonStaticFinalFields experimental flag implies in
>>> the C2 compiler:
>>> 
>>> http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2015-April/017739.html
>>> 
>>> Based on that exchange, I see that there are some scenarios where some
>>> optimization opportunities are missed, specifically due to missing field
>>> profiling.  That got me thinking -- how does Graal handle this, and does
>>> it
>>> do something better here? Clearly Graal has to also be mindful of final
>>> fields being changed via reflection, but are there any speculative
>>> optimizations around trusting that final fields are mostly unchanged (or
>>> plans to do that)?
>>> 
>>> Thanks
>>> 
>> 



More information about the graal-dev mailing list