8138956: Elide more final field's write memory barrier with escape analysis result
Summary: membar for final/stable fields eliminated if possible
Reviewed-by: roland, mdoerr, enevill, aph
Contributed-by: hui.shi@linaro.org
--- a/hotspot/src/share/vm/opto/parse.hpp Wed Oct 14 09:22:21 2015 -1000
+++ b/hotspot/src/share/vm/opto/parse.hpp Thu Oct 15 09:40:45 2015 +0200
@@ -343,6 +343,7 @@
bool _count_invocations; // update and test invocation counter
bool _method_data_update; // update method data oop
Node* _alloc_with_final; // An allocation node with final field
+ Node* _alloc_with_stable; // An allocation node with stable field
// Variables which track Java semantics during bytecode parsing:
@@ -398,6 +399,25 @@
_alloc_with_final = n;
}
+ Node* alloc_with_stable() const {
+ if (_alloc_with_stable == NodeSentinel) {
+ return NULL;
+ }
+ return _alloc_with_stable;
+ }
+
+ void set_alloc_with_stable(Node* n) {
+ if (_alloc_with_stable == NodeSentinel) {
+ // uninitialized status, initialize with current input, can be
+ // null or valid node.
+ _alloc_with_stable = n;
+ } else if (_alloc_with_stable != n) {
+ // _alloc_with_stable isn't equal to n
+ _alloc_with_stable = NULL;
+ }
+ // _alloc_with_stable is equal with n, do nothing
+ }
+
Block* block() const { return _block; }
ciBytecodeStream& iter() { return _iter; }
Bytecodes::Code bc() const { return _iter.cur_bc(); }
--- a/hotspot/src/share/vm/opto/parse1.cpp Wed Oct 14 09:22:21 2015 -1000
+++ b/hotspot/src/share/vm/opto/parse1.cpp Thu Oct 15 09:40:45 2015 +0200
@@ -397,6 +397,7 @@
_wrote_stable = false;
_wrote_fields = false;
_alloc_with_final = NULL;
+ _alloc_with_stable = NodeSentinel;
_entry_bci = InvocationEntryBci;
_tf = NULL;
_block = NULL;
@@ -970,7 +971,7 @@
// those also. If there is a predecessor allocation node, bind the
// barrier there.
if (wrote_stable()) {
- _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final());
+ _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_stable());
#ifndef PRODUCT
if (PrintOpto && (Verbose || WizardMode)) {
method()->print_name();
--- a/hotspot/src/share/vm/opto/parse3.cpp Wed Oct 14 09:22:21 2015 -1000
+++ b/hotspot/src/share/vm/opto/parse3.cpp Thu Oct 15 09:40:45 2015 +0200
@@ -313,10 +313,19 @@
// Preserve allocation ptr to create precedent edge to it in membar
// generated on exit from constructor.
- if (C->eliminate_boxing() &&
- adr_type->isa_oopptr() && adr_type->is_oopptr()->is_ptr_to_boxed_value() &&
- AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) {
- set_alloc_with_final(obj);
+ if (AllocateNode::Ideal_allocation(obj, &_gvn) != NULL) {
+ if (field->is_final()) {
+ set_alloc_with_final(obj);
+ }
+ if (field->is_stable()) {
+ set_alloc_with_stable(obj);
+ }
+ } else if (field->is_stable()) {
+ // This stable field doesn't have an allocation, set
+ // alloc_with_stable as NULL: its initial value is NodeSentinel,
+ // if it is not set to NULL here, next set_alloc_with_stable
+ // call might set none-NULL value successfully.
+ set_alloc_with_stable(NULL);
}
}
}