--- old/src/share/vm/opto/parse.hpp 2015-10-06 05:07:28.326298023 -0700 +++ new/src/share/vm/opto/parse.hpp 2015-10-06 05:07:28.134298016 -0700 @@ -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) { + // uninitialized status, initialized with current input, can be null or valid node. + if (_alloc_with_stable == NodeSentinel) { + _alloc_with_stable = n; + } + // _alloc_with_stable is isn't equal with n + else if (_alloc_with_stable != 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(); } --- old/src/share/vm/opto/parse1.cpp 2015-10-06 05:07:28.978298046 -0700 +++ new/src/share/vm/opto/parse1.cpp 2015-10-06 05:07:28.870298042 -0700 @@ -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; @@ -957,7 +958,16 @@ (wrote_final() || PPC64_ONLY(wrote_volatile() ||) (AlwaysSafeConstructors && wrote_fields()))) { - _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final()); + // For PPC64 worte volatile, if using allocation node as Precedent input + // in MemBarRelease node and allocation is not escaped, MemBarRelease will + // be removed. As written volatile field is not definitly allocation + // instance's field (different with final), can't safely remove MemBar + // when allocation is not escape. + Node *allocate = alloc_with_final(); + if (PPC64_ONLY(wrote_volatile()) NOT_PPC(false)) { + allocate = NULL; + } + _exits.insert_mem_bar(Op_MemBarRelease, allocate); #ifndef PRODUCT if (PrintOpto && (Verbose || WizardMode)) { method()->print_name(); @@ -970,7 +980,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(); --- old/src/share/vm/opto/parse3.cpp 2015-10-06 05:07:29.418298062 -0700 +++ new/src/share/vm/opto/parse3.cpp 2015-10-06 05:07:29.310298058 -0700 @@ -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()) { + // stable field doesn't have allocation, set alloc_with_stable as NULL + // because its initialize vlaue is NodeSentinel. If not set NULL, + // next set_alloc_with_stable call might set none-NULL value successfully. + set_alloc_with_stable(NULL); } } }