comparison src/cpu/x86/vm/stubGenerator_x86_32.cpp @ 2324:0ac769a57c64

6627983: G1: Bad oop deference during marking Summary: Bulk zeroing reduction didn't work with G1, because arraycopy would call pre-barriers on uninitialized oops. The solution is to have version of arraycopy stubs that don't have pre-barriers. Also refactored arraycopy stubs generation on SPARC to be more readable and reduced the number of stubs necessary in some cases. Reviewed-by: jrose, kvn, never
author iveresov
date Tue, 01 Mar 2011 14:56:48 -0800
parents 1b4e6a5d98e0
children 38fa55e5e792
comparison
equal deleted inserted replaced
2323:bc6b27fb3568 2324:0ac769a57c64
727 // Generate pre-barrier for array stores 727 // Generate pre-barrier for array stores
728 // 728 //
729 // Input: 729 // Input:
730 // start - starting address 730 // start - starting address
731 // count - element count 731 // count - element count
732 void gen_write_ref_array_pre_barrier(Register start, Register count) { 732 void gen_write_ref_array_pre_barrier(Register start, Register count, bool uninitialized_target) {
733 assert_different_registers(start, count); 733 assert_different_registers(start, count);
734 BarrierSet* bs = Universe::heap()->barrier_set(); 734 BarrierSet* bs = Universe::heap()->barrier_set();
735 switch (bs->kind()) { 735 switch (bs->kind()) {
736 case BarrierSet::G1SATBCT: 736 case BarrierSet::G1SATBCT:
737 case BarrierSet::G1SATBCTLogging: 737 case BarrierSet::G1SATBCTLogging:
738 { 738 // With G1, don't generate the call if we statically know that the target in uninitialized
739 __ pusha(); // push registers 739 if (!uninitialized_target) {
740 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 740 __ pusha(); // push registers
741 start, count); 741 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre),
742 __ popa(); 742 start, count);
743 } 743 __ popa();
744 }
744 break; 745 break;
745 case BarrierSet::CardTableModRef: 746 case BarrierSet::CardTableModRef:
746 case BarrierSet::CardTableExtension: 747 case BarrierSet::CardTableExtension:
747 case BarrierSet::ModRef: 748 case BarrierSet::ModRef:
748 break; 749 break;
917 __ emms(); 918 __ emms();
918 } 919 }
919 920
920 address generate_disjoint_copy(BasicType t, bool aligned, 921 address generate_disjoint_copy(BasicType t, bool aligned,
921 Address::ScaleFactor sf, 922 Address::ScaleFactor sf,
922 address* entry, const char *name) { 923 address* entry, const char *name,
924 bool dest_uninitialized = false) {
923 __ align(CodeEntryAlignment); 925 __ align(CodeEntryAlignment);
924 StubCodeMark mark(this, "StubRoutines", name); 926 StubCodeMark mark(this, "StubRoutines", name);
925 address start = __ pc(); 927 address start = __ pc();
926 928
927 Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte; 929 Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
948 } 950 }
949 951
950 if (t == T_OBJECT) { 952 if (t == T_OBJECT) {
951 __ testl(count, count); 953 __ testl(count, count);
952 __ jcc(Assembler::zero, L_0_count); 954 __ jcc(Assembler::zero, L_0_count);
953 gen_write_ref_array_pre_barrier(to, count); 955 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
954 __ mov(saved_to, to); // save 'to' 956 __ mov(saved_to, to); // save 'to'
955 } 957 }
956 958
957 __ subptr(to, from); // to --> to_from 959 __ subptr(to, from); // to --> to_from
958 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element 960 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
1082 } 1084 }
1083 1085
1084 address generate_conjoint_copy(BasicType t, bool aligned, 1086 address generate_conjoint_copy(BasicType t, bool aligned,
1085 Address::ScaleFactor sf, 1087 Address::ScaleFactor sf,
1086 address nooverlap_target, 1088 address nooverlap_target,
1087 address* entry, const char *name) { 1089 address* entry, const char *name,
1090 bool dest_uninitialized = false) {
1088 __ align(CodeEntryAlignment); 1091 __ align(CodeEntryAlignment);
1089 StubCodeMark mark(this, "StubRoutines", name); 1092 StubCodeMark mark(this, "StubRoutines", name);
1090 address start = __ pc(); 1093 address start = __ pc();
1091 1094
1092 Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte; 1095 Label L_0_count, L_exit, L_skip_align1, L_skip_align2, L_copy_byte;
1126 __ jump_cc(Assembler::aboveEqual, nooverlap); 1129 __ jump_cc(Assembler::aboveEqual, nooverlap);
1127 1130
1128 if (t == T_OBJECT) { 1131 if (t == T_OBJECT) {
1129 __ testl(count, count); 1132 __ testl(count, count);
1130 __ jcc(Assembler::zero, L_0_count); 1133 __ jcc(Assembler::zero, L_0_count);
1131 gen_write_ref_array_pre_barrier(dst, count); 1134 gen_write_ref_array_pre_barrier(dst, count, dest_uninitialized);
1132 } 1135 }
1133 1136
1134 // copy from high to low 1137 // copy from high to low
1135 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element 1138 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element
1136 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp 1139 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp
1413 // 1416 //
1414 // Output: 1417 // Output:
1415 // rax, == 0 - success 1418 // rax, == 0 - success
1416 // rax, == -1^K - failure, where K is partial transfer count 1419 // rax, == -1^K - failure, where K is partial transfer count
1417 // 1420 //
1418 address generate_checkcast_copy(const char *name, address* entry) { 1421 address generate_checkcast_copy(const char *name, address* entry, bool dest_uninitialized = false) {
1419 __ align(CodeEntryAlignment); 1422 __ align(CodeEntryAlignment);
1420 StubCodeMark mark(this, "StubRoutines", name); 1423 StubCodeMark mark(this, "StubRoutines", name);
1421 address start = __ pc(); 1424 address start = __ pc();
1422 1425
1423 Label L_load_element, L_store_element, L_do_card_marks, L_done; 1426 Label L_load_element, L_store_element, L_do_card_marks, L_done;
1474 Address from_element_addr(end_from, count, Address::times_ptr, 0); 1477 Address from_element_addr(end_from, count, Address::times_ptr, 0);
1475 Address to_element_addr(end_to, count, Address::times_ptr, 0); 1478 Address to_element_addr(end_to, count, Address::times_ptr, 0);
1476 Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes()); 1479 Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes());
1477 1480
1478 // Copy from low to high addresses, indexed from the end of each array. 1481 // Copy from low to high addresses, indexed from the end of each array.
1479 gen_write_ref_array_pre_barrier(to, count); 1482 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
1480 __ lea(end_from, end_from_addr); 1483 __ lea(end_from, end_from_addr);
1481 __ lea(end_to, end_to_addr); 1484 __ lea(end_to, end_to_addr);
1482 assert(length == count, ""); // else fix next line: 1485 assert(length == count, ""); // else fix next line:
1483 __ negptr(count); // negate and test the length 1486 __ negptr(count); // negate and test the length
1484 __ jccb(Assembler::notZero, L_load_element); 1487 __ jccb(Assembler::notZero, L_load_element);
2037 "oop_disjoint_arraycopy"); 2040 "oop_disjoint_arraycopy");
2038 StubRoutines::_oop_arraycopy = 2041 StubRoutines::_oop_arraycopy =
2039 generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry, 2042 generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry,
2040 &entry_oop_arraycopy, "oop_arraycopy"); 2043 &entry_oop_arraycopy, "oop_arraycopy");
2041 2044
2045 StubRoutines::_oop_disjoint_arraycopy_uninit =
2046 generate_disjoint_copy(T_OBJECT, true, Address::times_ptr, &entry,
2047 "oop_disjoint_arraycopy_uninit",
2048 /*dest_uninitialized*/true);
2049 StubRoutines::_oop_arraycopy_uninit =
2050 generate_conjoint_copy(T_OBJECT, true, Address::times_ptr, entry,
2051 NULL, "oop_arraycopy_uninit",
2052 /*dest_uninitialized*/true);
2053
2042 StubRoutines::_jlong_disjoint_arraycopy = 2054 StubRoutines::_jlong_disjoint_arraycopy =
2043 generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy"); 2055 generate_disjoint_long_copy(&entry, "jlong_disjoint_arraycopy");
2044 StubRoutines::_jlong_arraycopy = 2056 StubRoutines::_jlong_arraycopy =
2045 generate_conjoint_long_copy(entry, &entry_jlong_arraycopy, 2057 generate_conjoint_long_copy(entry, &entry_jlong_arraycopy,
2046 "jlong_arraycopy"); 2058 "jlong_arraycopy");
2050 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill"); 2062 StubRoutines::_jint_fill = generate_fill(T_INT, false, "jint_fill");
2051 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill"); 2063 StubRoutines::_arrayof_jbyte_fill = generate_fill(T_BYTE, true, "arrayof_jbyte_fill");
2052 StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill"); 2064 StubRoutines::_arrayof_jshort_fill = generate_fill(T_SHORT, true, "arrayof_jshort_fill");
2053 StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill"); 2065 StubRoutines::_arrayof_jint_fill = generate_fill(T_INT, true, "arrayof_jint_fill");
2054 2066
2055 StubRoutines::_arrayof_jint_disjoint_arraycopy = 2067 StubRoutines::_arrayof_jint_disjoint_arraycopy = StubRoutines::_jint_disjoint_arraycopy;
2056 StubRoutines::_jint_disjoint_arraycopy; 2068 StubRoutines::_arrayof_oop_disjoint_arraycopy = StubRoutines::_oop_disjoint_arraycopy;
2057 StubRoutines::_arrayof_oop_disjoint_arraycopy = 2069 StubRoutines::_arrayof_oop_disjoint_arraycopy_uninit = StubRoutines::_oop_disjoint_arraycopy_uninit;
2058 StubRoutines::_oop_disjoint_arraycopy; 2070 StubRoutines::_arrayof_jlong_disjoint_arraycopy = StubRoutines::_jlong_disjoint_arraycopy;
2059 StubRoutines::_arrayof_jlong_disjoint_arraycopy = 2071
2060 StubRoutines::_jlong_disjoint_arraycopy; 2072 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy;
2061 2073 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy;
2062 StubRoutines::_arrayof_jint_arraycopy = StubRoutines::_jint_arraycopy; 2074 StubRoutines::_arrayof_oop_arraycopy_uninit = StubRoutines::_oop_arraycopy_uninit;
2063 StubRoutines::_arrayof_oop_arraycopy = StubRoutines::_oop_arraycopy; 2075 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
2064 StubRoutines::_arrayof_jlong_arraycopy = StubRoutines::_jlong_arraycopy;
2065 2076
2066 StubRoutines::_checkcast_arraycopy = 2077 StubRoutines::_checkcast_arraycopy =
2067 generate_checkcast_copy("checkcast_arraycopy", 2078 generate_checkcast_copy("checkcast_arraycopy", &entry_checkcast_arraycopy);
2068 &entry_checkcast_arraycopy); 2079 StubRoutines::_checkcast_arraycopy_uninit =
2080 generate_checkcast_copy("checkcast_arraycopy_uninit", NULL, /*dest_uninitialized*/true);
2069 2081
2070 StubRoutines::_unsafe_arraycopy = 2082 StubRoutines::_unsafe_arraycopy =
2071 generate_unsafe_copy("unsafe_arraycopy", 2083 generate_unsafe_copy("unsafe_arraycopy",
2072 entry_jbyte_arraycopy, 2084 entry_jbyte_arraycopy,
2073 entry_jshort_arraycopy, 2085 entry_jshort_arraycopy,