1.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Wed Jun 04 13:51:09 2008 -0700 1.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu Jun 05 15:57:56 2008 -0700 1.3 @@ -285,16 +285,7 @@ 1.4 1.5 1.6 void LIRGenerator::init() { 1.7 - BarrierSet* bs = Universe::heap()->barrier_set(); 1.8 - assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); 1.9 - CardTableModRefBS* ct = (CardTableModRefBS*)bs; 1.10 - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); 1.11 - 1.12 -#ifdef _LP64 1.13 - _card_table_base = new LIR_Const((jlong)ct->byte_map_base); 1.14 -#else 1.15 - _card_table_base = new LIR_Const((jint)ct->byte_map_base); 1.16 -#endif 1.17 + _bs = Universe::heap()->barrier_set(); 1.18 } 1.19 1.20 1.21 @@ -1239,8 +1230,37 @@ 1.22 1.23 // Various barriers 1.24 1.25 +void LIRGenerator::pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info) { 1.26 + // Do the pre-write barrier, if any. 1.27 + switch (_bs->kind()) { 1.28 +#ifndef SERIALGC 1.29 + case BarrierSet::G1SATBCT: 1.30 + case BarrierSet::G1SATBCTLogging: 1.31 + G1SATBCardTableModRef_pre_barrier(addr_opr, patch, info); 1.32 + break; 1.33 +#endif // SERIALGC 1.34 + case BarrierSet::CardTableModRef: 1.35 + case BarrierSet::CardTableExtension: 1.36 + // No pre barriers 1.37 + break; 1.38 + case BarrierSet::ModRef: 1.39 + case BarrierSet::Other: 1.40 + // No pre barriers 1.41 + break; 1.42 + default : 1.43 + ShouldNotReachHere(); 1.44 + 1.45 + } 1.46 +} 1.47 + 1.48 void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { 1.49 - switch (Universe::heap()->barrier_set()->kind()) { 1.50 + switch (_bs->kind()) { 1.51 +#ifndef SERIALGC 1.52 + case BarrierSet::G1SATBCT: 1.53 + case BarrierSet::G1SATBCTLogging: 1.54 + G1SATBCardTableModRef_post_barrier(addr, new_val); 1.55 + break; 1.56 +#endif // SERIALGC 1.57 case BarrierSet::CardTableModRef: 1.58 case BarrierSet::CardTableExtension: 1.59 CardTableModRef_post_barrier(addr, new_val); 1.60 @@ -1254,11 +1274,120 @@ 1.61 } 1.62 } 1.63 1.64 +//////////////////////////////////////////////////////////////////////// 1.65 +#ifndef SERIALGC 1.66 + 1.67 +void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info) { 1.68 + if (G1DisablePreBarrier) return; 1.69 + 1.70 + // First we test whether marking is in progress. 1.71 + BasicType flag_type; 1.72 + if (in_bytes(PtrQueue::byte_width_of_active()) == 4) { 1.73 + flag_type = T_INT; 1.74 + } else { 1.75 + guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1, 1.76 + "Assumption"); 1.77 + flag_type = T_BYTE; 1.78 + } 1.79 + LIR_Opr thrd = getThreadPointer(); 1.80 + LIR_Address* mark_active_flag_addr = 1.81 + new LIR_Address(thrd, 1.82 + in_bytes(JavaThread::satb_mark_queue_offset() + 1.83 + PtrQueue::byte_offset_of_active()), 1.84 + flag_type); 1.85 + // Read the marking-in-progress flag. 1.86 + LIR_Opr flag_val = new_register(T_INT); 1.87 + __ load(mark_active_flag_addr, flag_val); 1.88 + 1.89 + LabelObj* start_store = new LabelObj(); 1.90 + 1.91 + LIR_PatchCode pre_val_patch_code = 1.92 + patch ? lir_patch_normal : lir_patch_none; 1.93 + 1.94 + LIR_Opr pre_val = new_register(T_OBJECT); 1.95 + 1.96 + __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0)); 1.97 + if (!addr_opr->is_address()) { 1.98 + assert(addr_opr->is_register(), "must be"); 1.99 + addr_opr = LIR_OprFact::address(new LIR_Address(addr_opr, 0, T_OBJECT)); 1.100 + } 1.101 + CodeStub* slow = new G1PreBarrierStub(addr_opr, pre_val, pre_val_patch_code, 1.102 + info); 1.103 + __ branch(lir_cond_notEqual, T_INT, slow); 1.104 + __ branch_destination(slow->continuation()); 1.105 +} 1.106 + 1.107 +void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { 1.108 + if (G1DisablePostBarrier) return; 1.109 + 1.110 + // If the "new_val" is a constant NULL, no barrier is necessary. 1.111 + if (new_val->is_constant() && 1.112 + new_val->as_constant_ptr()->as_jobject() == NULL) return; 1.113 + 1.114 + if (!new_val->is_register()) { 1.115 + LIR_Opr new_val_reg = new_pointer_register(); 1.116 + if (new_val->is_constant()) { 1.117 + __ move(new_val, new_val_reg); 1.118 + } else { 1.119 + __ leal(new_val, new_val_reg); 1.120 + } 1.121 + new_val = new_val_reg; 1.122 + } 1.123 + assert(new_val->is_register(), "must be a register at this point"); 1.124 + 1.125 + if (addr->is_address()) { 1.126 + LIR_Address* address = addr->as_address_ptr(); 1.127 + LIR_Opr ptr = new_pointer_register(); 1.128 + if (!address->index()->is_valid() && address->disp() == 0) { 1.129 + __ move(address->base(), ptr); 1.130 + } else { 1.131 + assert(address->disp() != max_jint, "lea doesn't support patched addresses!"); 1.132 + __ leal(addr, ptr); 1.133 + } 1.134 + addr = ptr; 1.135 + } 1.136 + assert(addr->is_register(), "must be a register at this point"); 1.137 + 1.138 + LIR_Opr xor_res = new_pointer_register(); 1.139 + LIR_Opr xor_shift_res = new_pointer_register(); 1.140 + 1.141 + if (TwoOperandLIRForm ) { 1.142 + __ move(addr, xor_res); 1.143 + __ logical_xor(xor_res, new_val, xor_res); 1.144 + __ move(xor_res, xor_shift_res); 1.145 + __ unsigned_shift_right(xor_shift_res, 1.146 + LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes), 1.147 + xor_shift_res, 1.148 + LIR_OprDesc::illegalOpr()); 1.149 + } else { 1.150 + __ logical_xor(addr, new_val, xor_res); 1.151 + __ unsigned_shift_right(xor_res, 1.152 + LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes), 1.153 + xor_shift_res, 1.154 + LIR_OprDesc::illegalOpr()); 1.155 + } 1.156 + 1.157 + if (!new_val->is_register()) { 1.158 + LIR_Opr new_val_reg = new_pointer_register(); 1.159 + __ leal(new_val, new_val_reg); 1.160 + new_val = new_val_reg; 1.161 + } 1.162 + assert(new_val->is_register(), "must be a register at this point"); 1.163 + 1.164 + __ cmp(lir_cond_notEqual, xor_shift_res, LIR_OprFact::intptrConst(NULL_WORD)); 1.165 + 1.166 + CodeStub* slow = new G1PostBarrierStub(addr, new_val); 1.167 + __ branch(lir_cond_notEqual, T_INT, slow); 1.168 + __ branch_destination(slow->continuation()); 1.169 +} 1.170 + 1.171 +#endif // SERIALGC 1.172 +//////////////////////////////////////////////////////////////////////// 1.173 + 1.174 void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { 1.175 1.176 - BarrierSet* bs = Universe::heap()->barrier_set(); 1.177 - assert(sizeof(*((CardTableModRefBS*)bs)->byte_map_base) == sizeof(jbyte), "adjust this code"); 1.178 - LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)bs)->byte_map_base); 1.179 + assert(sizeof(*((CardTableModRefBS*)_bs)->byte_map_base) == sizeof(jbyte), "adjust this code"); 1.180 + LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)_bs)->byte_map_base); 1.181 if (addr->is_address()) { 1.182 LIR_Address* address = addr->as_address_ptr(); 1.183 LIR_Opr ptr = new_register(T_OBJECT); 1.184 @@ -1388,6 +1517,13 @@ 1.185 __ membar_release(); 1.186 } 1.187 1.188 + if (is_oop) { 1.189 + // Do the pre-write barrier, if any. 1.190 + pre_barrier(LIR_OprFact::address(address), 1.191 + needs_patching, 1.192 + (info ? new CodeEmitInfo(info) : NULL)); 1.193 + } 1.194 + 1.195 if (is_volatile) { 1.196 assert(!needs_patching && x->is_loaded(), 1.197 "how do we know it's volatile if it's not loaded"); 1.198 @@ -1398,7 +1534,12 @@ 1.199 } 1.200 1.201 if (is_oop) { 1.202 +#ifdef PRECISE_CARDMARK 1.203 + // Precise cardmarks don't work 1.204 + post_barrier(LIR_OprFact::address(address), value.result()); 1.205 +#else 1.206 post_barrier(object.result(), value.result()); 1.207 +#endif // PRECISE_CARDMARK 1.208 } 1.209 1.210 if (is_volatile && os::is_MP()) {