RFR: Elide more final field's write memory barrier with escape analysis result
Hui Shi
hui.shi at linaro.org
Mon Oct 5 13:14:45 UTC 2015
Would some one please help review and comments this change?
MemBarRelease for final field write can be removed when its allocation
doesn't escape thread, allocation node can be acquired from its
MemBarNode::Precedent input.
Currently, MemBarRelase's Precedent input is only added when
eliminate_boxing is true and its owning object is primitive Box (see
Parse::do_put_xxx and Parse::do_exits). Checking OpenJDK log, this is added
for autoboxing elimination early. Now I suggest turn on this optimization
for general object type, this can benefit RMO platform (like aarch64)
performance.
This patch is not trivial, so put it at
http://people.linaro.org/~hui.shi/membar_precedent/membar_precedent.patch
Patch removes constraints for set_alloc_with_final(obj) in do_put_xxx
(parse3.cpp). This leads to adding Precedent input for all kind object's
final field writes' MemBarRelase node. Then they have opportunities to get
optimized.
In TestString small case, String object is allocated but not escaped in
bar. Checking TestString_base.txt and TestString_fix.txt. Without this
patch, Memory barrier is not removed even object allocation is optimized
out.
http://people.linaro.org/~hui.shi/membar_precedent/TestString.java
http://people.linaro.org/~hui.shi/membar_precedent/TestString_base.txt
http://people.linaro.org/~hui.shi/membar_precedent/TestString_fix.txt
All kind object's final/stable field store's MemBarRelease node has chance
to be optimized when its allocation doesn't escape thread. It’s safe based
on following 4 pre-conditions:
1. Only MemBarRelease created for final/stable field store has
MemBarNode::Precedent input.
2. MemBarRelease nodes' MemBarNode::Precedent input is only used in
MemBarNode.Ideal, removing MemBarRelease when allocation doesn't escape.
3. MemBarRelease's MemBarNode::Precedent input is correctly set with
final/stable field's owning object allocation if exist.
4. Escape analysis result is correct.
Extra changes in patch target the 3rd pre-condition. In Parse::do_put_xxx,
alloc_with_final is set and used for both final and Stable fields write. As
final field can only be written in owning class initializer, but Stable
field can be written in any method. There might be issues when writing both
final and Stable field (could be stable field from different allocation) in
same initializer method.
1. Stable field and final field has different owning object, it trigger
assertions in set_alloc_with_final (different allocation objs).
2. If final field's allocation doesn't escape and stable field's allocation
is unknown, both MemBarRelased node will be removed as they use same final
field's allocation as Precedent input.
Above issues can be reproduced with
http://people.linaro.org/~hui.shi/membar_precedent/TestStable.java
These issue can't be reproduced with current implementation, because
alloc_with_final is only set in primitive box type initializer and no final
and stable field both written cases there. Issues become visible with my
change. So I suggest re-factor final and stable field handling here. Add an
alloc_with_stable field for stable field write's MemBarRelease Precedent
input, initialize as NodeSentinel. If stable field's allocation node is
conflict or unknown, set it as NULL.
Another small issue for MemBarRelease node created for volatile field write
on PPC64. Volatile field’s owning object might be different with final
field’s allocation. When MemBarRelease is removed because final field's
allocation doesn’t escape, still need keep MemBarRelease for volatile
write. Solution is using NULL as MemBarRelase node precedent input when
wrote volatile is true.
Regards
Shi Hui
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20151005/f966004f/attachment.html>
More information about the hotspot-compiler-dev
mailing list