[9] RFR (S): 8157181: Compilers accept modification of final fields outside initializer methods
Zoltán Majó
zoltan.majo at oracle.com
Thu Jun 9 14:03:20 UTC 2016
Hi,
On 06/08/2016 08:00 PM, Zoltán Majó wrote:
> [...]
> I'm currently running pre-PIT RBT to see if there are any problems
> with our testbase. Performance runs are also in progress.
Just to report on the performance/correctness results: The change does
not cause any performance regression; pre-PIT RBT completed successfully.
Thank you!
Best regards,
Zoltan
>
> Here is the updated webrev:
> http://cr.openjdk.java.net/~zmajo/8157181/webrev.06/
>
> Testing:
> - JPRT;
> - local testing with reproducer (verified that interpreter/compiled
> code behave the same way);
> - pre-PIT RBT in progress.
>
>
>>
>> And file a separate issue for JVMS-7 conformance. It looks like it
>> may have huge impact on performance and we are already very late in
>> JDK 9 development to make such changes in rush.
>
> I agree that the two issues can be treated as unrelated. But, for now,
> I'd like to keep them together as by fixing them together we cover
> both the > JAVA_7_VERSION and the <= JAVA_7_VERSION case at the same
> time.
>
> The performance runs (in progress) show that the fix has no
> performance impact (because we disable constant folding in very rare
> cases). I'll report all numbers once they become available.
>
>>
>> Zoltan, what C2 does in such case?
>
> I can reproduce the problem only with -Xcomp. With -Xcomp, there is
> not enough profiling information available for C2 to compile the
> problematic bytecode. Thus, C2 deoptimizes before execution proceeds
> to that bytecode.
>
> But C2 folds final fields as well, therefore C2-compiled methods can
> also be negatively impacted if final fields chang after they have been
> initialized. Fortunately, with the current fix we have to disable
> folding only in very rare cases.
>
> Thank you!
>
> Best regards,
>
>
> Zoltan
>
>> Tom, what Graal does in such case?
>>
>> The case is:
>>
>> https://bugs.openjdk.java.net/browse/JDK-8157181?focusedCommentId=13942824&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13942824
>>
>>
>> "While compiling bytecode @29, the C1 compiler assumes that the value
>> of the _pyx0.self field has already been set in the class initializer
>> <clinit> method (as the class is initialized). The C1 compiler also
>> assumes that the field will not change (as it is static final).
>> Therefore, the C1 compiler omits reading the field _pyx0.self and
>> passes the current value of the field ('null') to the
>> org/python/core/Py.newCode() method called at bytecode @37. (The
>> correct value would be 'this'.)"
>>
>> Thanks,
>> Vladimir
>>
>> On 6/2/16 10:51 AM, Tom Rodriguez wrote:
>>>>>> Therefore, in the current webrev, I've disabled folding of
>>>>>> accesses to
>>>>>> all non-stable fields.
>>>>> Please do not do that, it will be a huge regression in term of
>>>>> perf at least for the language runtimes i maintain
>>>>> (and i suppose for Nashorn, JRuby or Groovy), Here are the perf
>>>>> assertions i use routinely,
>>>>> static final method handle is considered as constant, final fields
>>>>> (even not static) of VM anonymous class is considered as truly final.
>>>>>
>>>>
>>>> I fully understand your concerns. And thank you for sharing your
>>>> asserts!
>>>
>>> The folding within the compiler should be handled differently since
>>> the concerns are different and removing it will likely cause
>>> invokeynamic performance to collapse. The compiler is only folding
>>> final instance fields that are part of a chain of constants, so the
>>> main concern is whether an object has been published before it’s
>>> been fully constructed or if someone is going to use reflection to
>>> modify a final field after the object has been published. The
>>> trust_final_non_static_fields logic in ciField.cpp is calling out
>>> classes which we control that shouldn’t violate those rules and that
>>> are important for performance. So I think it should be left as is.
>>> It really doesn’t relate to the issue at hand I think.
>>>
>>> Also you’ve removed folding of static final fields which would be a
>>> very bad thing to do.
>>>
>>> ciField has some caching logic for _known_to_link_with_get/set and
>>> if you are adding a ciMethod* argument you also need to cache the
>>> method that was checked last time as well.
>>>
>>> tom
>>>
>>>>
>>>> Let's see what others think about how to go about this problem. So
>>>> far the following options were explored
>>>> - bail out compilation of non-compliant methods;
>>>> - enforce JVMS conformance for all classes and keep constant
>>>> folding enabled;
>>>> - enforce JVMS conformance only for classes with _major_version
>>>> >=52 and completely disable constant folding.
>>>>
>>>> I'm not sure which option is the best. Also, there might be other
>>>> options as well.
>>>>
>>>> Thank you and best regards,
>>>>
>>>>
>>>> Zoltan
>>>>
>>>>
>>>>
>>>>>> We could relax that criteria, e.g., by disabling folding only for
>>>>>> those
>>>>>> field that were declared in a class with _major_version < 52. But it
>>>>>> would be great if you could give me some feedback before I look into
>>>>>> that. Thank you very much in advance!
>>>>>>
>>>>>> Updated webrev:
>>>>>> http://cr.openjdk.java.net/~zmajo/8157181/webrev.05/
>>>>>>
>>>>>> Testing: JPRT in progress.
>>>>>>
>>>>>> Best regards,
>>>>>>
>>>>>>
>>>>>> Zoltan
>>>>> Rémi
>>>>>
>>>>>>> Thank you and best regards,
>>>>>>>
>>>>>>>
>>>>>>> Zoltan
>>>>>>>
>>>>>>>> Best regards,
>>>>>>>> Vladimir Ivanov
>>>>>>>>
>>>>>>>>> I agree with you, alternatively we can propose a more generic
>>>>>>>>> fix (fix
>>>>>>>>> the interpreter and the compilers as well). The fix would most
>>>>>>>>> likely
>>>>>>>>> affect field resolution in LinkResolver::resolve_field()
>>>>>>>>> around here:
>>>>>>>>> http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/07a5eceac654/src/share/vm/interpreter/linkResolver.cpp#l910
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Changing resolve_field() to throw an IllegalAccessError for
>>>>>>>>> inappropriate field access will propagate the exception to the
>>>>>>>>> interpreter. Changing ciField::will_link() will most likely
>>>>>>>>> kill (some)
>>>>>>>>> compilations (if, e.g., fields are linked through
>>>>>>>>> ciField::will_link()).
>>>>>>>>>
>>>>>>>>> I'd prefer to take the second option (changing field
>>>>>>>>> resolution), but
>>>>>>>>> there might be some disadvantages related to option I might be
>>>>>>>>> overseeing.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>> Thank you!
>>>>>>>>>
>>>>>>>>> Best regards,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Zoltan
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>>> More details about the failure are here [3].
>>>>>>>>>>>
>>>>>>>>>>> With the patch applied, the program always completes as it is
>>>>>>>>>>> expected
>>>>>>>>>>> by Jython, no matter if we use -Xint, -Xcomp, or -Xmixed
>>>>>>>>>>> (because we
>>>>>>>>>>> always interpret methods non-conforming with the VM spec).
>>>>>>>>>>>
>>>>>>>>>>> Here is the updated webrev:
>>>>>>>>>>> http://cr.openjdk.java.net/~zmajo/8157181/webrev.01/
>>>>>>>>>> Bailing out the whole compilation in C2 is even less
>>>>>>>>>> appropriate. It
>>>>>>>>>> should generate an uncommon trap for such accesses instead (see
>>>>>>>>>> Parse::do_field_access).
>>>>>>>>>>
>>>>>>>>>> Best regards,
>>>>>>>>>> Vladimir Ivanov
>>>>>>>>>>
>>>>>>>>>> [1]
>>>>>>>>>> http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/file/07a5eceac654/src/share/vm/c1/c1_GraphBuilder.cpp#l1595
>>>>>>>>>>
>>>
>
More information about the hotspot-compiler-dev
mailing list