< prev index next >

src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp

Print this page
rev 51327 : Make C1 write-barrier use a stub instead of dedicated instruction


  25 #include "gc/g1/satbMarkQueue.hpp"
  26 #include "gc/shenandoah/brooksPointer.hpp"
  27 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
  28 #include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
  29 #include "gc/shenandoah/shenandoahHeap.hpp"
  30 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  31 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
  32 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
  33 
  34 #ifdef ASSERT
  35 #define __ gen->lir(__FILE__, __LINE__)->
  36 #else
  37 #define __ gen->lir()->
  38 #endif
  39 
  40 void ShenandoahPreBarrierStub::emit_code(LIR_Assembler* ce) {
  41   ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
  42   bs->gen_pre_barrier_stub(ce, this);
  43 }
  44 





  45 void ShenandoahBarrierSetC1::pre_barrier(LIRAccess& access, LIR_Opr addr_opr, LIR_Opr pre_val) {
  46   LIRGenerator* gen = access.gen();
  47   CodeEmitInfo* info = access.access_emit_info();
  48   DecoratorSet decorators = access.decorators();
  49 
  50   // First we test whether marking is in progress.
  51   BasicType flag_type;
  52   bool patch = (decorators & C1_NEEDS_PATCHING) != 0;
  53   bool do_load = pre_val == LIR_OprFact::illegalOpr;
  54   if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
  55     flag_type = T_INT;
  56   } else {
  57     guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,
  58               "Assumption");
  59     // Use unsigned type T_BOOLEAN here rather than signed T_BYTE since some platforms, eg. ARM,
  60     // need to use unsigned instructions to use the large offset to load the satb_mark_queue.
  61     flag_type = T_BOOLEAN;
  62   }
  63   LIR_Opr thrd = gen->getThreadPointer();
  64   LIR_Address* mark_active_flag_addr =


 188     __ branch(lir_cond_equal, T_LONG, done->label());
 189   }
 190   LIR_Address* brooks_ptr_address = gen->generate_address(result, BrooksPointer::byte_offset(), T_ADDRESS);
 191   __ load(brooks_ptr_address, result, info ? new CodeEmitInfo(info) : NULL, lir_patch_none);
 192 
 193   __ branch_destination(done->label());
 194   return result;
 195 }
 196 
 197 LIR_Opr ShenandoahBarrierSetC1::write_barrier(LIRAccess& access, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) {
 198   if (UseShenandoahGC && ShenandoahWriteBarrier) {
 199     return write_barrier_impl(access, obj, info, need_null_check);
 200   } else {
 201     return obj;
 202   }
 203 }
 204 
 205 LIR_Opr ShenandoahBarrierSetC1::write_barrier_impl(LIRAccess& access, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) {
 206   assert(UseShenandoahGC && (ShenandoahWriteBarrier || ShenandoahStoreValEnqueueBarrier), "Should be enabled");
 207   LIRGenerator* gen = access.gen();
 208   LIR_Opr result = gen->new_register(T_OBJECT);
 209 
 210   obj = ensure_in_register(access, obj);
 211   assert(obj->is_register(), "must be a register at this point");





















 212 
 213   __ shenandoah_wb(obj, result, info ? new CodeEmitInfo(info) : NULL, need_null_check);
 214   return result;
 215 }
 216 
 217 LIR_Opr ShenandoahBarrierSetC1::ensure_in_register(LIRAccess& access, LIR_Opr obj) {
 218   if (!obj->is_register()) {
 219     LIRGenerator* gen = access.gen();
 220     LIR_Opr obj_reg = gen->new_register(T_OBJECT);
 221     if (obj->is_constant()) {
 222       __ move(obj, obj_reg);
 223     } else {
 224       __ leal(obj, obj_reg);
 225     }
 226     obj = obj_reg;
 227   }
 228   return obj;
 229 }
 230 
 231 LIR_Opr ShenandoahBarrierSetC1::storeval_barrier(LIRAccess& access, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) {
 232   LIRGenerator* gen = access.gen();
 233   if (UseShenandoahGC) {




  25 #include "gc/g1/satbMarkQueue.hpp"
  26 #include "gc/shenandoah/brooksPointer.hpp"
  27 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
  28 #include "gc/shenandoah/shenandoahConnectionMatrix.hpp"
  29 #include "gc/shenandoah/shenandoahHeap.hpp"
  30 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
  31 #include "gc/shenandoah/shenandoahThreadLocalData.hpp"
  32 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
  33 
  34 #ifdef ASSERT
  35 #define __ gen->lir(__FILE__, __LINE__)->
  36 #else
  37 #define __ gen->lir()->
  38 #endif
  39 
  40 void ShenandoahPreBarrierStub::emit_code(LIR_Assembler* ce) {
  41   ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
  42   bs->gen_pre_barrier_stub(ce, this);
  43 }
  44 
  45 void ShenandoahWriteBarrierStub::emit_code(LIR_Assembler* ce) {
  46   ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
  47   bs->gen_write_barrier_stub(ce, this);
  48 }
  49 
  50 void ShenandoahBarrierSetC1::pre_barrier(LIRAccess& access, LIR_Opr addr_opr, LIR_Opr pre_val) {
  51   LIRGenerator* gen = access.gen();
  52   CodeEmitInfo* info = access.access_emit_info();
  53   DecoratorSet decorators = access.decorators();
  54 
  55   // First we test whether marking is in progress.
  56   BasicType flag_type;
  57   bool patch = (decorators & C1_NEEDS_PATCHING) != 0;
  58   bool do_load = pre_val == LIR_OprFact::illegalOpr;
  59   if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
  60     flag_type = T_INT;
  61   } else {
  62     guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,
  63               "Assumption");
  64     // Use unsigned type T_BOOLEAN here rather than signed T_BYTE since some platforms, eg. ARM,
  65     // need to use unsigned instructions to use the large offset to load the satb_mark_queue.
  66     flag_type = T_BOOLEAN;
  67   }
  68   LIR_Opr thrd = gen->getThreadPointer();
  69   LIR_Address* mark_active_flag_addr =


 193     __ branch(lir_cond_equal, T_LONG, done->label());
 194   }
 195   LIR_Address* brooks_ptr_address = gen->generate_address(result, BrooksPointer::byte_offset(), T_ADDRESS);
 196   __ load(brooks_ptr_address, result, info ? new CodeEmitInfo(info) : NULL, lir_patch_none);
 197 
 198   __ branch_destination(done->label());
 199   return result;
 200 }
 201 
 202 LIR_Opr ShenandoahBarrierSetC1::write_barrier(LIRAccess& access, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) {
 203   if (UseShenandoahGC && ShenandoahWriteBarrier) {
 204     return write_barrier_impl(access, obj, info, need_null_check);
 205   } else {
 206     return obj;
 207   }
 208 }
 209 
 210 LIR_Opr ShenandoahBarrierSetC1::write_barrier_impl(LIRAccess& access, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) {
 211   assert(UseShenandoahGC && (ShenandoahWriteBarrier || ShenandoahStoreValEnqueueBarrier), "Should be enabled");
 212   LIRGenerator* gen = access.gen();

 213 
 214   obj = ensure_in_register(access, obj);
 215   assert(obj->is_register(), "must be a register at this point");
 216   LIR_Opr result = gen->new_register(T_OBJECT);
 217   __ move(obj, result);
 218 
 219   LIR_Opr thrd = gen->getThreadPointer();
 220   LIR_Address* active_flag_addr =
 221     new LIR_Address(thrd,
 222                     in_bytes(ShenandoahThreadLocalData::gc_state_offset()),
 223                     T_BYTE);
 224   // Read the marking-in-progress flag.
 225   LIR_Opr flag_val = gen->new_register(T_INT);
 226   __ load(active_flag_addr, flag_val);
 227   __ logical_and(flag_val,
 228                  LIR_OprFact::intConst(ShenandoahHeap::HAS_FORWARDED |
 229                                        ShenandoahHeap::EVACUATION |
 230                                        ShenandoahHeap::TRAVERSAL),
 231                  flag_val);
 232   __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
 233 
 234   CodeStub* slow = new ShenandoahWriteBarrierStub(obj, result, info ? new CodeEmitInfo(info) : NULL, need_null_check);
 235   __ branch(lir_cond_notEqual, T_INT, slow);
 236   __ branch_destination(slow->continuation());
 237 

 238   return result;
 239 }
 240 
 241 LIR_Opr ShenandoahBarrierSetC1::ensure_in_register(LIRAccess& access, LIR_Opr obj) {
 242   if (!obj->is_register()) {
 243     LIRGenerator* gen = access.gen();
 244     LIR_Opr obj_reg = gen->new_register(T_OBJECT);
 245     if (obj->is_constant()) {
 246       __ move(obj, obj_reg);
 247     } else {
 248       __ leal(obj, obj_reg);
 249     }
 250     obj = obj_reg;
 251   }
 252   return obj;
 253 }
 254 
 255 LIR_Opr ShenandoahBarrierSetC1::storeval_barrier(LIRAccess& access, LIR_Opr obj, CodeEmitInfo* info, bool need_null_check) {
 256   LIRGenerator* gen = access.gen();
 257   if (UseShenandoahGC) {


< prev index next >