@@ -412,7 +412,7 @@ Parse::Parse(JVMState* caller, ciMethod* parse_method, float expected_uses)
412412 _wrote_volatile = false ;
413413 _wrote_stable = false ;
414414 _wrote_fields = false ;
415- _alloc_with_final = nullptr ;
415+ _alloc_with_final_or_stable = nullptr ;
416416 _block = nullptr ;
417417 _first_return = true ;
418418 _replaced_nodes_for_exceptions = false ;
@@ -984,8 +984,8 @@ void Parse::do_exits() {
984984 // Figure out if we need to emit the trailing barrier. The barrier is only
985985 // needed in the constructors, and only in three cases:
986986 //
987- // 1. The constructor wrote a final. The effects of all initializations
988- // must be committed to memory before any code after the constructor
987+ // 1. The constructor wrote a final or a @Stable field. All these
988+ // initializations must be ordered before any code after the constructor
989989 // publishes the reference to the newly constructed object. Rather
990990 // than wait for the publication, we simply block the writes here.
991991 // Rather than put a barrier on only those writes which are required
@@ -1010,34 +1010,23 @@ void Parse::do_exits() {
10101010 // exceptional returns, since they cannot publish normally.
10111011 //
10121012 if (method ()->is_initializer () &&
1013- (wrote_final () ||
1013+ (wrote_final () || wrote_stable () ||
10141014 (AlwaysSafeConstructors && wrote_fields ()) ||
10151015 (support_IRIW_for_not_multiple_copy_atomic_cpu && wrote_volatile ()))) {
1016+ Node* recorded_alloc = alloc_with_final_or_stable ();
10161017 _exits.insert_mem_bar (UseStoreStoreForCtor ? Op_MemBarStoreStore : Op_MemBarRelease,
1017- alloc_with_final () );
1018+ recorded_alloc );
10181019
10191020 // If Memory barrier is created for final fields write
10201021 // and allocation node does not escape the initialize method,
10211022 // then barrier introduced by allocation node can be removed.
1022- if (DoEscapeAnalysis && alloc_with_final ( )) {
1023- AllocateNode* alloc = AllocateNode::Ideal_allocation (alloc_with_final () );
1023+ if (DoEscapeAnalysis && (recorded_alloc != nullptr )) {
1024+ AllocateNode* alloc = AllocateNode::Ideal_allocation (recorded_alloc );
10241025 alloc->compute_MemBar_redundancy (method ());
10251026 }
10261027 if (PrintOpto && (Verbose || WizardMode)) {
10271028 method ()->print_name ();
1028- tty->print_cr (" writes finals and needs a memory barrier" );
1029- }
1030- }
1031-
1032- // Any method can write a @Stable field; insert memory barriers
1033- // after those also. Can't bind predecessor allocation node (if any)
1034- // with barrier because allocation doesn't always dominate
1035- // MemBarRelease.
1036- if (wrote_stable ()) {
1037- _exits.insert_mem_bar (Op_MemBarRelease);
1038- if (PrintOpto && (Verbose || WizardMode)) {
1039- method ()->print_name ();
1040- tty->print_cr (" writes @Stable and needs a memory barrier" );
1029+ tty->print_cr (" writes finals/@Stable and needs a memory barrier" );
10411030 }
10421031 }
10431032
0 commit comments