968 }
969 if (count->is_global()) {
970 __ mov(count, L1);
971 }
972 __ mov(addr->after_save(), O0);
973 // Get the count into O1
974 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
975 __ delayed()->mov(count->after_save(), O1);
976 if (addr->is_global()) {
977 __ mov(L0, addr);
978 }
979 if (count->is_global()) {
980 __ mov(L1, count);
981 }
982 __ restore();
983 }
984 break;
985 case BarrierSet::CardTableModRef:
986 case BarrierSet::CardTableExtension:
987 case BarrierSet::ModRef:
988 break;
989 default:
990 ShouldNotReachHere();
991 }
992 }
993 //
994 // Generate post-write barrier for array.
995 //
996 // Input:
997 // addr - register containing starting address
998 // count - register containing element count
999 // tmp - scratch register
1000 //
1001 // The input registers are overwritten.
1002 //
1003 void gen_write_ref_array_post_barrier(Register addr, Register count,
1004 Register tmp) {
1005 BarrierSet* bs = Universe::heap()->barrier_set();
1006
1007 switch (bs->kind()) {
1025
1026 Label L_loop;
1027
1028 __ sll_ptr(count, LogBytesPerHeapOop, count);
1029 __ sub(count, BytesPerHeapOop, count);
1030 __ add(count, addr, count);
1031 // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
1032 __ srl_ptr(addr, CardTableModRefBS::card_shift, addr);
1033 __ srl_ptr(count, CardTableModRefBS::card_shift, count);
1034 __ sub(count, addr, count);
1035 AddressLiteral rs(ct->byte_map_base);
1036 __ set(rs, tmp);
1037 __ BIND(L_loop);
1038 __ stb(G0, tmp, addr);
1039 __ subcc(count, 1, count);
1040 __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
1041 __ delayed()->add(addr, 1, addr);
1042 }
1043 break;
1044 case BarrierSet::ModRef:
1045 break;
1046 default:
1047 ShouldNotReachHere();
1048 }
1049 }
1050
1051 //
1052 // Generate main code for disjoint arraycopy
1053 //
1054 typedef void (StubGenerator::*CopyLoopFunc)(Register from, Register to, Register count, int count_dec,
1055 Label& L_loop, bool use_prefetch, bool use_bis);
1056
1057 void disjoint_copy_core(Register from, Register to, Register count, int log2_elem_size,
1058 int iter_size, StubGenerator::CopyLoopFunc copy_loop_func) {
1059 Label L_copy;
1060
1061 assert(log2_elem_size <= 3, "the following code should be changed");
1062 int count_dec = 16>>log2_elem_size;
1063
1064 int prefetch_dist = MAX2(ArraycopySrcPrefetchDistance, ArraycopyDstPrefetchDistance);
|
968 }
969 if (count->is_global()) {
970 __ mov(count, L1);
971 }
972 __ mov(addr->after_save(), O0);
973 // Get the count into O1
974 __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
975 __ delayed()->mov(count->after_save(), O1);
976 if (addr->is_global()) {
977 __ mov(L0, addr);
978 }
979 if (count->is_global()) {
980 __ mov(L1, count);
981 }
982 __ restore();
983 }
984 break;
985 case BarrierSet::CardTableModRef:
986 case BarrierSet::CardTableExtension:
987 case BarrierSet::ModRef:
988 case BarrierSet::Epsilon:
989 break;
990 default:
991 ShouldNotReachHere();
992 }
993 }
994 //
995 // Generate post-write barrier for array.
996 //
997 // Input:
998 // addr - register containing starting address
999 // count - register containing element count
1000 // tmp - scratch register
1001 //
1002 // The input registers are overwritten.
1003 //
1004 void gen_write_ref_array_post_barrier(Register addr, Register count,
1005 Register tmp) {
1006 BarrierSet* bs = Universe::heap()->barrier_set();
1007
1008 switch (bs->kind()) {
1026
1027 Label L_loop;
1028
1029 __ sll_ptr(count, LogBytesPerHeapOop, count);
1030 __ sub(count, BytesPerHeapOop, count);
1031 __ add(count, addr, count);
1032 // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
1033 __ srl_ptr(addr, CardTableModRefBS::card_shift, addr);
1034 __ srl_ptr(count, CardTableModRefBS::card_shift, count);
1035 __ sub(count, addr, count);
1036 AddressLiteral rs(ct->byte_map_base);
1037 __ set(rs, tmp);
1038 __ BIND(L_loop);
1039 __ stb(G0, tmp, addr);
1040 __ subcc(count, 1, count);
1041 __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
1042 __ delayed()->add(addr, 1, addr);
1043 }
1044 break;
1045 case BarrierSet::ModRef:
1046 case BarrierSet::Epsilon:
1047 break;
1048 default:
1049 ShouldNotReachHere();
1050 }
1051 }
1052
1053 //
1054 // Generate main code for disjoint arraycopy
1055 //
1056 typedef void (StubGenerator::*CopyLoopFunc)(Register from, Register to, Register count, int count_dec,
1057 Label& L_loop, bool use_prefetch, bool use_bis);
1058
1059 void disjoint_copy_core(Register from, Register to, Register count, int log2_elem_size,
1060 int iter_size, StubGenerator::CopyLoopFunc copy_loop_func) {
1061 Label L_copy;
1062
1063 assert(log2_elem_size <= 3, "the following code should be changed");
1064 int count_dec = 16>>log2_elem_size;
1065
1066 int prefetch_dist = MAX2(ArraycopySrcPrefetchDistance, ArraycopyDstPrefetchDistance);
|