src/share/vm/opto/parse1.cpp

Print this page

        

*** 389,398 **** --- 389,400 ---- _method = parse_method; _expected_uses = expected_uses; _depth = 1 + (caller->has_method() ? caller->depth() : 0); _wrote_final = false; _wrote_volatile = false; + _wrote_stable = false; + _wrote_fields = false; _alloc_with_final = NULL; _entry_bci = InvocationEntryBci; _tf = NULL; _block = NULL; debug_only(_block_count = -1);
*** 906,944 **** _exits.set_control(gvn().transform(region)); Node* iophi = _exits.i_o(); _exits.set_i_o(gvn().transform(iophi)); ! // On PPC64, also add MemBarRelease for constructors which write // volatile fields. As support_IRIW_for_not_multiple_copy_atomic_cpu // is set on PPC64, no sync instruction is issued after volatile ! // stores. We want to quarantee the same behaviour as on platforms // with total store order, although this is not required by the Java // memory model. So as with finals, we add a barrier here. ! if (wrote_final() PPC64_ONLY(|| (wrote_volatile() && method()->is_initializer()))) { ! // This method (which must be a constructor by the rules of Java) ! // wrote a final. The effects of all initializations must be ! // committed to memory before any code after the constructor ! // publishes the reference to the newly constructor object. ! // Rather than wait for the publication, we simply block the ! // writes here. Rather than put a barrier on only those writes ! // which are required to complete, we force all writes to complete. // // "All bets are off" unless the first publication occurs after a // normal return from the constructor. We do not attempt to detect // such unusual early publications. But no barrier is needed on // exceptional returns, since they cannot publish normally. // _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final()); #ifndef PRODUCT if (PrintOpto && (Verbose || WizardMode)) { method()->print_name(); tty->print_cr(" writes finals and needs a memory barrier"); } #endif } for (MergeMemStream mms(_exits.merged_memory()); mms.next_non_empty(); ) { // transform each slice of the original memphi: mms.set_memory(_gvn.transform(mms.memory())); } --- 908,968 ---- _exits.set_control(gvn().transform(region)); Node* iophi = _exits.i_o(); _exits.set_i_o(gvn().transform(iophi)); ! // Figure out if we need to emit the trailing barrier. The barrier is only ! // needed in the constructors, and only in three cases: ! // ! // 1. The constructor wrote a final. The effects of all initializations ! // must be committed to memory before any code after the constructor ! // publishes the reference to the newly constructed object. Rather ! // than wait for the publication, we simply block the writes here. ! // Rather than put a barrier on only those writes which are required ! // to complete, we force all writes to complete. ! // ! // 2. On PPC64, also add MemBarRelease for constructors which write // volatile fields. As support_IRIW_for_not_multiple_copy_atomic_cpu // is set on PPC64, no sync instruction is issued after volatile ! // stores. We want to guarantee the same behavior as on platforms // with total store order, although this is not required by the Java // memory model. So as with finals, we add a barrier here. ! // ! // 3. Experimental VM option is used to force the barrier if any field ! // was written out in the constructor. // // "All bets are off" unless the first publication occurs after a // normal return from the constructor. We do not attempt to detect // such unusual early publications. But no barrier is needed on // exceptional returns, since they cannot publish normally. // + if (method()->is_initializer() && + (wrote_final() || + PPC64_ONLY(wrote_volatile() ||) + (AlwaysSafeConstructors && wrote_fields()))) { _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final()); #ifndef PRODUCT if (PrintOpto && (Verbose || WizardMode)) { method()->print_name(); tty->print_cr(" writes finals and needs a memory barrier"); } #endif } + // Any method can write a @Stable field; insert memory barriers after + // 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()); + #ifndef PRODUCT + if (PrintOpto && (Verbose || WizardMode)) { + method()->print_name(); + tty->print_cr(" writes @Stable and needs a memory barrier"); + } + #endif + } + for (MergeMemStream mms(_exits.merged_memory()); mms.next_non_empty(); ) { // transform each slice of the original memphi: mms.set_memory(_gvn.transform(mms.memory())); }