# HG changeset patch # User roland # Date 1444894845 -7200 # Node ID 34e5004f5acb68112ae505d27afaa2f6535b01ef # Parent f77a432b90f6010751b54a3d7cdd08f0730c8dbd 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 diff -r f77a432b90f6 -r 34e5004f5acb hotspot/src/share/vm/opto/parse.hpp --- 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(); } diff -r f77a432b90f6 -r 34e5004f5acb hotspot/src/share/vm/opto/parse1.cpp --- 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(); diff -r f77a432b90f6 -r 34e5004f5acb hotspot/src/share/vm/opto/parse3.cpp --- 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); } } }