Mercurial > hg > truffle
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(); ) { |