comparison src/share/vm/opto/parse1.cpp @ 14663:3edd4a71588b

8031818: Experimental VM flag for enforcing safe object construction Summary: -XX:+AlwaysSafeConstructors to unconditionally emit the trailing constructor barrier. Reviewed-by: kvn, roland
author shade
date Mon, 03 Mar 2014 15:31:27 +0400
parents 45467c53f178
children 92aa6797d639
comparison
equal deleted inserted replaced
14662:3c3953fb3f2a 14663:3edd4a71588b
389 _method = parse_method; 389 _method = parse_method;
390 _expected_uses = expected_uses; 390 _expected_uses = expected_uses;
391 _depth = 1 + (caller->has_method() ? caller->depth() : 0); 391 _depth = 1 + (caller->has_method() ? caller->depth() : 0);
392 _wrote_final = false; 392 _wrote_final = false;
393 _wrote_volatile = false; 393 _wrote_volatile = false;
394 _wrote_stable = false;
395 _wrote_fields = false;
394 _alloc_with_final = NULL; 396 _alloc_with_final = NULL;
395 _entry_bci = InvocationEntryBci; 397 _entry_bci = InvocationEntryBci;
396 _tf = NULL; 398 _tf = NULL;
397 _block = NULL; 399 _block = NULL;
398 debug_only(_block_count = -1); 400 debug_only(_block_count = -1);
906 _exits.set_control(gvn().transform(region)); 908 _exits.set_control(gvn().transform(region));
907 909
908 Node* iophi = _exits.i_o(); 910 Node* iophi = _exits.i_o();
909 _exits.set_i_o(gvn().transform(iophi)); 911 _exits.set_i_o(gvn().transform(iophi));
910 912
911 // On PPC64, also add MemBarRelease for constructors which write 913 // Figure out if we need to emit the trailing barrier. The barrier is only
912 // volatile fields. As support_IRIW_for_not_multiple_copy_atomic_cpu 914 // needed in the constructors, and only in three cases:
913 // is set on PPC64, no sync instruction is issued after volatile 915 //
914 // stores. We want to quarantee the same behaviour as on platforms 916 // 1. The constructor wrote a final. The effects of all initializations
915 // with total store order, although this is not required by the Java 917 // must be committed to memory before any code after the constructor
916 // memory model. So as with finals, we add a barrier here. 918 // publishes the reference to the newly constructed object. Rather
917 if (wrote_final() PPC64_ONLY(|| (wrote_volatile() && method()->is_initializer()))) { 919 // than wait for the publication, we simply block the writes here.
918 // This method (which must be a constructor by the rules of Java) 920 // Rather than put a barrier on only those writes which are required
919 // wrote a final. The effects of all initializations must be 921 // to complete, we force all writes to complete.
920 // committed to memory before any code after the constructor 922 //
921 // publishes the reference to the newly constructor object. 923 // 2. On PPC64, also add MemBarRelease for constructors which write
922 // Rather than wait for the publication, we simply block the 924 // volatile fields. As support_IRIW_for_not_multiple_copy_atomic_cpu
923 // writes here. Rather than put a barrier on only those writes 925 // is set on PPC64, no sync instruction is issued after volatile
924 // which are required to complete, we force all writes to complete. 926 // stores. We want to guarantee the same behavior as on platforms
925 // 927 // with total store order, although this is not required by the Java
926 // "All bets are off" unless the first publication occurs after a 928 // memory model. So as with finals, we add a barrier here.
927 // normal return from the constructor. We do not attempt to detect 929 //
928 // such unusual early publications. But no barrier is needed on 930 // 3. Experimental VM option is used to force the barrier if any field
929 // exceptional returns, since they cannot publish normally. 931 // was written out in the constructor.
930 // 932 //
933 // "All bets are off" unless the first publication occurs after a
934 // normal return from the constructor. We do not attempt to detect
935 // such unusual early publications. But no barrier is needed on
936 // exceptional returns, since they cannot publish normally.
937 //
938 if (method()->is_initializer() &&
939 (wrote_final() ||
940 PPC64_ONLY(wrote_volatile() ||)
941 (AlwaysSafeConstructors && wrote_fields()))) {
931 _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final()); 942 _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final());
932 #ifndef PRODUCT 943 #ifndef PRODUCT
933 if (PrintOpto && (Verbose || WizardMode)) { 944 if (PrintOpto && (Verbose || WizardMode)) {
934 method()->print_name(); 945 method()->print_name();
935 tty->print_cr(" writes finals and needs a memory barrier"); 946 tty->print_cr(" writes finals and needs a memory barrier");
947 }
948 #endif
949 }
950
951 // Any method can write a @Stable field; insert memory barriers after
952 // those also. If there is a predecessor allocation node, bind the
953 // barrier there.
954 if (wrote_stable()) {
955 _exits.insert_mem_bar(Op_MemBarRelease, alloc_with_final());
956 #ifndef PRODUCT
957 if (PrintOpto && (Verbose || WizardMode)) {
958 method()->print_name();
959 tty->print_cr(" writes @Stable and needs a memory barrier");
936 } 960 }
937 #endif 961 #endif
938 } 962 }
939 963
940 for (MergeMemStream mms(_exits.merged_memory()); mms.next_non_empty(); ) { 964 for (MergeMemStream mms(_exits.merged_memory()); mms.next_non_empty(); ) {