src/share/vm/c1/c1_LIRGenerator.cpp

changeset 777
37f87013dfd8
parent 435
a61af66fc99e
child 797
f8199438385b
     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()) {

mercurial