src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp
changeset 58219 bc0648405d67
parent 57716 bfcdcd00e4fb
child 58679 9c3209ff7550
child 58693 3f35a9efd7de
equal deleted inserted replaced
58218:0d7877278adf 58219:bc0648405d67
   103 
   103 
   104   __ branch(lir_cond_notEqual, T_INT, slow);
   104   __ branch(lir_cond_notEqual, T_INT, slow);
   105   __ branch_destination(slow->continuation());
   105   __ branch_destination(slow->continuation());
   106 }
   106 }
   107 
   107 
   108 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj) {
   108 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr) {
   109   if (ShenandoahLoadRefBarrier) {
   109   if (ShenandoahLoadRefBarrier) {
   110     return load_reference_barrier_impl(gen, obj);
   110     return load_reference_barrier_impl(gen, obj, addr);
   111   } else {
   111   } else {
   112     return obj;
   112     return obj;
   113   }
   113   }
   114 }
   114 }
   115 
   115 
   116 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj) {
   116 LIR_Opr ShenandoahBarrierSetC1::load_reference_barrier_impl(LIRGenerator* gen, LIR_Opr obj, LIR_Opr addr) {
   117   assert(ShenandoahLoadRefBarrier, "Should be enabled");
   117   assert(ShenandoahLoadRefBarrier, "Should be enabled");
   118 
   118 
   119   obj = ensure_in_register(gen, obj);
   119   obj = ensure_in_register(gen, obj);
   120   assert(obj->is_register(), "must be a register at this point");
   120   assert(obj->is_register(), "must be a register at this point");
       
   121   addr = ensure_in_register(gen, addr);
       
   122   assert(addr->is_register(), "must be a register at this point");
   121   LIR_Opr result = gen->result_register_for(obj->value_type());
   123   LIR_Opr result = gen->result_register_for(obj->value_type());
   122   __ move(obj, result);
   124   __ move(obj, result);
   123   LIR_Opr tmp1 = gen->new_register(T_OBJECT);
   125   LIR_Opr tmp1 = gen->new_register(T_OBJECT);
   124   LIR_Opr tmp2 = gen->new_register(T_OBJECT);
   126   LIR_Opr tmp2 = gen->new_register(T_OBJECT);
   125 
   127 
   144     __ logical_and(flag_val, mask_reg, masked_flag);
   146     __ logical_and(flag_val, mask_reg, masked_flag);
   145     flag_val = masked_flag;
   147     flag_val = masked_flag;
   146   }
   148   }
   147   __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
   149   __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
   148 
   150 
   149   CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, result, tmp1, tmp2);
   151   CodeStub* slow = new ShenandoahLoadReferenceBarrierStub(obj, addr, result, tmp1, tmp2);
   150   __ branch(lir_cond_notEqual, T_INT, slow);
   152   __ branch(lir_cond_notEqual, T_INT, slow);
   151   __ branch_destination(slow->continuation());
   153   __ branch_destination(slow->continuation());
   152 
   154 
   153   return result;
   155   return result;
   154 }
   156 }
   155 
   157 
   156 LIR_Opr ShenandoahBarrierSetC1::ensure_in_register(LIRGenerator* gen, LIR_Opr obj) {
   158 LIR_Opr ShenandoahBarrierSetC1::ensure_in_register(LIRGenerator* gen, LIR_Opr obj) {
   157   if (!obj->is_register()) {
   159   if (!obj->is_register()) {
   158     LIR_Opr obj_reg = gen->new_register(T_OBJECT);
   160     LIR_Opr obj_reg;
   159     if (obj->is_constant()) {
   161     if (obj->is_constant()) {
       
   162       obj_reg = gen->new_register(T_OBJECT);
   160       __ move(obj, obj_reg);
   163       __ move(obj, obj_reg);
   161     } else {
   164     } else {
       
   165 #ifdef AARCH64
       
   166       // AArch64 expects double-size register.
       
   167       obj_reg = gen->new_pointer_register();
       
   168 #else
       
   169       // x86 expects single-size register.
       
   170       obj_reg = gen->new_register(T_OBJECT);
       
   171 #endif
   162       __ leal(obj, obj_reg);
   172       __ leal(obj, obj_reg);
   163     }
   173     }
   164     obj = obj_reg;
   174     obj = obj_reg;
   165   }
   175   }
   166   return obj;
   176   return obj;
   180       pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr /* pre_val */);
   190       pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), access.resolved_addr(), LIR_OprFact::illegalOpr /* pre_val */);
   181     }
   191     }
   182     value = storeval_barrier(access.gen(), value, access.access_emit_info(), access.decorators());
   192     value = storeval_barrier(access.gen(), value, access.access_emit_info(), access.decorators());
   183   }
   193   }
   184   BarrierSetC1::store_at_resolved(access, value);
   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);
   185 }
   203 }
   186 
   204 
   187 void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
   205 void ShenandoahBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
   188   if (!access.is_oop()) {
   206   if (!access.is_oop()) {
   189     BarrierSetC1::load_at_resolved(access, result);
   207     BarrierSetC1::load_at_resolved(access, result);
   208   }
   226   }
   209 
   227 
   210   if (ShenandoahLoadRefBarrier) {
   228   if (ShenandoahLoadRefBarrier) {
   211     LIR_Opr tmp = gen->new_register(T_OBJECT);
   229     LIR_Opr tmp = gen->new_register(T_OBJECT);
   212     BarrierSetC1::load_at_resolved(access, tmp);
   230     BarrierSetC1::load_at_resolved(access, tmp);
   213     tmp = load_reference_barrier(access.gen(), tmp);
   231     tmp = load_reference_barrier(access.gen(), tmp, access.resolved_addr());
   214     __ move(tmp, result);
   232     __ move(tmp, result);
   215   } else {
   233   } else {
   216     BarrierSetC1::load_at_resolved(access, result);
   234     BarrierSetC1::load_at_resolved(access, result);
   217   }
   235   }
   218 
   236