< prev index next >

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

Print this page
rev 56771 : 8233339: Shenandoah: Centralize load barrier decisions into ShenandoahBarrierSet


 186 
 187 void ShenandoahBarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) {
 188   if (access.is_oop()) {
 189     if (ShenandoahSATBBarrier) {
 190       pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr /* pre_val */);
 191     }
 192     value = storeval_barrier(access.gen(), value, access.access_emit_info(), access.decorators());
 193   }
 194   BarrierSetC1::store_at_resolved(access, value);
 195 }
 196 
 197 LIR_Opr ShenandoahBarrierSetC1::resolve_address(LIRAccess& access, bool resolve_in_register) {
 198   // We must resolve in register when patching. This is to avoid
 199   // having a patch area in the load barrier stub, since the call
 200   // into the runtime to patch will not have the proper oop map.
 201   const bool patch_before_barrier = access.is_oop() && (access.decorators() & C1_NEEDS_PATCHING) != 0;
 202   return BarrierSetC1::resolve_address(access, resolve_in_register || patch_before_barrier);
 203 }
 204 
 205 void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
 206   if (!access.is_oop()) {






 207     BarrierSetC1::load_at_resolved(access, result);
 208     return;
 209   }
 210 
 211   LIRGenerator* gen = access.gen();
 212 
 213   DecoratorSet decorators = access.decorators();
 214   bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
 215 
 216   if ((decorators & IN_NATIVE) != 0 && !is_traversal_mode) {
 217     assert(access.is_oop(), "IN_NATIVE access only for oop values");
 218     BarrierSetC1::load_at_resolved(access, result);
 219     LIR_OprList* args = new LIR_OprList();
 220     LIR_Opr addr = access.resolved_addr();
 221     addr = ensure_in_register(gen, addr);
 222     args->append(result);
 223     args->append(addr);
 224     BasicTypeList signature;
 225     signature.append(T_OBJECT);
 226     signature.append(T_ADDRESS);
 227     LIR_Opr call_result = gen->call_runtime(&signature, args,
 228                                             CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native),
 229                                             objectType, NULL);
 230     __ move(call_result, result);
 231   } else {
 232     if (ShenandoahLoadRefBarrier) {
 233       LIR_Opr tmp = gen->new_register(T_OBJECT);
 234       BarrierSetC1::load_at_resolved(access, tmp);
 235       tmp = load_reference_barrier(access.gen(), tmp, access.resolved_addr());
 236       __ move(tmp, result);
 237     } else {
 238       BarrierSetC1::load_at_resolved(access, result);
 239     }
 240   }
 241 
 242   if (ShenandoahKeepAliveBarrier) {
 243     bool is_weak = (decorators & ON_WEAK_OOP_REF) != 0;
 244     bool is_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
 245     bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
 246     bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode;
 247 
 248     if ((is_weak || is_phantom || is_anonymous) && keep_alive) {
 249       // Register the value in the referent field with the pre-barrier
 250       LabelObj *Lcont_anonymous;
 251       if (is_anonymous) {
 252         Lcont_anonymous = new LabelObj();
 253         generate_referent_check(access, Lcont_anonymous);
 254       }
 255       pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr /* addr_opr */,
 256                   result /* pre_val */);
 257       if (is_anonymous) {
 258         __ branch_destination(Lcont_anonymous->label());
 259       }
 260     }
 261   }
 262 }
 263 
 264 class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
 265   virtual OopMapSet* generate_code(StubAssembler* sasm) {
 266     ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
 267     bs->generate_c1_pre_barrier_runtime_stub(sasm);
 268     return NULL;
 269   }
 270 };
 271 
 272 class C1ShenandoahLoadReferenceBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
 273   virtual OopMapSet* generate_code(StubAssembler* sasm) {
 274     ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
 275     bs->generate_c1_load_reference_barrier_runtime_stub(sasm);
 276     return NULL;
 277   }
 278 };
 279 


 186 
 187 void ShenandoahBarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) {
 188   if (access.is_oop()) {
 189     if (ShenandoahSATBBarrier) {
 190       pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr /* pre_val */);
 191     }
 192     value = storeval_barrier(access.gen(), value, access.access_emit_info(), access.decorators());
 193   }
 194   BarrierSetC1::store_at_resolved(access, value);
 195 }
 196 
 197 LIR_Opr ShenandoahBarrierSetC1::resolve_address(LIRAccess& access, bool resolve_in_register) {
 198   // We must resolve in register when patching. This is to avoid
 199   // having a patch area in the load barrier stub, since the call
 200   // into the runtime to patch will not have the proper oop map.
 201   const bool patch_before_barrier = access.is_oop() && (access.decorators() & C1_NEEDS_PATCHING) != 0;
 202   return BarrierSetC1::resolve_address(access, resolve_in_register || patch_before_barrier);
 203 }
 204 
 205 void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
 206   DecoratorSet decorators = access.decorators();
 207   assert((decorators & AS_RAW) == 0, "Unexpected decorator");
 208   assert((decorators & AS_NO_KEEPALIVE) == 0, "Unexpected decorator");
 209   BasicType type = access.type();
 210   bool need_load_reference_barrier = ShenandoahBarrierSet::need_load_reference_barrier(decorators, type);
 211 
 212   if (!need_load_reference_barrier) {
 213     BarrierSetC1::load_at_resolved(access, result);
 214     return;
 215   }
 216 
 217   LIRGenerator* gen = access.gen();
 218 
 219   if (ShenandoahBarrierSet::use_native_load_reference_barrier(decorators, type)) {




 220     BarrierSetC1::load_at_resolved(access, result);
 221     LIR_OprList* args = new LIR_OprList();
 222     LIR_Opr addr = access.resolved_addr();
 223     addr = ensure_in_register(gen, addr);
 224     args->append(result);
 225     args->append(addr);
 226     BasicTypeList signature;
 227     signature.append(T_OBJECT);
 228     signature.append(T_ADDRESS);
 229     LIR_Opr call_result = gen->call_runtime(&signature, args,
 230                                             CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native),
 231                                             objectType, NULL);
 232     __ move(call_result, result);
 233   } else {

 234       LIR_Opr tmp = gen->new_register(T_OBJECT);
 235       BarrierSetC1::load_at_resolved(access, tmp);
 236       tmp = load_reference_barrier(access.gen(), tmp, access.resolved_addr());
 237       __ move(tmp, result);



 238   }
 239 
 240   if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {


 241     bool is_anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;

 242 

 243     // Register the value in the referent field with the pre-barrier
 244     LabelObj *Lcont_anonymous;
 245     if (is_anonymous) {
 246       Lcont_anonymous = new LabelObj();
 247       generate_referent_check(access, Lcont_anonymous);
 248     }
 249     pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr /* addr_opr */,
 250                 result /* pre_val */);
 251     if (is_anonymous) {
 252       __ branch_destination(Lcont_anonymous->label());

 253     }
 254   }
 255 }
 256 
 257 class C1ShenandoahPreBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
 258   virtual OopMapSet* generate_code(StubAssembler* sasm) {
 259     ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
 260     bs->generate_c1_pre_barrier_runtime_stub(sasm);
 261     return NULL;
 262   }
 263 };
 264 
 265 class C1ShenandoahLoadReferenceBarrierCodeGenClosure : public StubAssemblerCodeGenClosure {
 266   virtual OopMapSet* generate_code(StubAssembler* sasm) {
 267     ShenandoahBarrierSetAssembler* bs = (ShenandoahBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler();
 268     bs->generate_c1_load_reference_barrier_runtime_stub(sasm);
 269     return NULL;
 270   }
 271 };
 272 
< prev index next >