src/share/vm/c1/c1_LIRGenerator.cpp

changeset 4002
09aad8452938
parent 3969
1d7922586cf6
child 4003
7a302948f5a4
     1.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp	Mon Aug 20 09:07:21 2012 -0700
     1.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Mon Aug 20 09:58:58 2012 -0700
     1.3 @@ -2176,9 +2176,9 @@
     1.4    off.load_item();
     1.5    src.load_item();
     1.6  
     1.7 -  LIR_Opr reg = rlock_result(x, x->basic_type());
     1.8 -
     1.9 -  get_Object_unsafe(reg, src.result(), off.result(), type, x->is_volatile());
    1.10 +  LIR_Opr value = rlock_result(x, x->basic_type());
    1.11 +
    1.12 +  get_Object_unsafe(value, src.result(), off.result(), type, x->is_volatile());
    1.13  
    1.14  #ifndef SERIALGC
    1.15    // We might be reading the value of the referent field of a
    1.16 @@ -2191,19 +2191,16 @@
    1.17    // if (offset == java_lang_ref_Reference::referent_offset) {
    1.18    //   if (src != NULL) {
    1.19    //     if (klass(src)->reference_type() != REF_NONE) {
    1.20 -  //       pre_barrier(..., reg, ...);
    1.21 +  //       pre_barrier(..., value, ...);
    1.22    //     }
    1.23    //   }
    1.24    // }
    1.25 -  //
    1.26 -  // The first non-constant check of either the offset or
    1.27 -  // the src operand will be done here; the remainder
    1.28 -  // will take place in the generated code stub.
    1.29  
    1.30    if (UseG1GC && type == T_OBJECT) {
    1.31 -    bool gen_code_stub = true;       // Assume we need to generate the slow code stub.
    1.32 -    bool gen_offset_check = true;       // Assume the code stub has to generate the offset guard.
    1.33 -    bool gen_source_check = true;       // Assume the code stub has to check the src object for null.
    1.34 +    bool gen_pre_barrier = true;     // Assume we need to generate pre_barrier.
    1.35 +    bool gen_offset_check = true;    // Assume we need to generate the offset guard.
    1.36 +    bool gen_source_check = true;    // Assume we need to check the src object for null.
    1.37 +    bool gen_type_check = true;      // Assume we need to check the reference_type.
    1.38  
    1.39      if (off.is_constant()) {
    1.40        jlong off_con = (off.type()->is_int() ?
    1.41 @@ -2215,7 +2212,7 @@
    1.42          // The constant offset is something other than referent_offset.
    1.43          // We can skip generating/checking the remaining guards and
    1.44          // skip generation of the code stub.
    1.45 -        gen_code_stub = false;
    1.46 +        gen_pre_barrier = false;
    1.47        } else {
    1.48          // The constant offset is the same as referent_offset -
    1.49          // we do not need to generate a runtime offset check.
    1.50 @@ -2224,11 +2221,11 @@
    1.51      }
    1.52  
    1.53      // We don't need to generate stub if the source object is an array
    1.54 -    if (gen_code_stub && src.type()->is_array()) {
    1.55 -      gen_code_stub = false;
    1.56 +    if (gen_pre_barrier && src.type()->is_array()) {
    1.57 +      gen_pre_barrier = false;
    1.58      }
    1.59  
    1.60 -    if (gen_code_stub) {
    1.61 +    if (gen_pre_barrier) {
    1.62        // We still need to continue with the checks.
    1.63        if (src.is_constant()) {
    1.64          ciObject* src_con = src.get_jobject_constant();
    1.65 @@ -2236,7 +2233,7 @@
    1.66          if (src_con->is_null_object()) {
    1.67            // The constant src object is null - We can skip
    1.68            // generating the code stub.
    1.69 -          gen_code_stub = false;
    1.70 +          gen_pre_barrier = false;
    1.71          } else {
    1.72            // Non-null constant source object. We still have to generate
    1.73            // the slow stub - but we don't need to generate the runtime
    1.74 @@ -2245,20 +2242,28 @@
    1.75          }
    1.76        }
    1.77      }
    1.78 -
    1.79 -    if (gen_code_stub) {
    1.80 -      // Temoraries.
    1.81 -      LIR_Opr src_klass = new_register(T_OBJECT);
    1.82 -
    1.83 -      // Get the thread pointer for the pre-barrier
    1.84 -      LIR_Opr thread = getThreadPointer();
    1.85 -
    1.86 -      CodeStub* stub;
    1.87 +    if (gen_pre_barrier && !PatchALot) {
    1.88 +      // Can the klass of object be statically determined to be
    1.89 +      // a sub-class of Reference?
    1.90 +      ciType* type = src.value()->declared_type();
    1.91 +      if ((type != NULL) && type->is_loaded()) {
    1.92 +        if (type->is_subtype_of(compilation()->env()->Reference_klass())) {
    1.93 +          gen_type_check = false;
    1.94 +        } else if (type->is_klass() &&
    1.95 +                   !compilation()->env()->Object_klass()->is_subtype_of(type->as_klass())) {
    1.96 +          // Not Reference and not Object klass.
    1.97 +          gen_pre_barrier = false;
    1.98 +        }
    1.99 +      }
   1.100 +    }
   1.101 +
   1.102 +    if (gen_pre_barrier) {
   1.103 +      LabelObj* Lcont = new LabelObj();
   1.104  
   1.105        // We can have generate one runtime check here. Let's start with
   1.106        // the offset check.
   1.107        if (gen_offset_check) {
   1.108 -        // if (offset == referent_offset) -> slow code stub
   1.109 +        // if (offset != referent_offset) -> continue
   1.110          // If offset is an int then we can do the comparison with the
   1.111          // referent_offset constant; otherwise we need to move
   1.112          // referent_offset into a temporary register and generate
   1.113 @@ -2273,43 +2278,36 @@
   1.114            referent_off = new_register(T_LONG);
   1.115            __ move(LIR_OprFact::longConst(java_lang_ref_Reference::referent_offset), referent_off);
   1.116          }
   1.117 -
   1.118 -        __ cmp(lir_cond_equal, off.result(), referent_off);
   1.119 -
   1.120 -        // Optionally generate "src == null" check.
   1.121 -        stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
   1.122 -                                                    src_klass, thread,
   1.123 -                                                    gen_source_check);
   1.124 -
   1.125 -        __ branch(lir_cond_equal, as_BasicType(off.type()), stub);
   1.126 -      } else {
   1.127 -        if (gen_source_check) {
   1.128 -          // offset is a const and equals referent offset
   1.129 -          // if (source != null) -> slow code stub
   1.130 -          __ cmp(lir_cond_notEqual, src.result(), LIR_OprFact::oopConst(NULL));
   1.131 -
   1.132 -          // Since we are generating the "if src == null" guard here,
   1.133 -          // there is no need to generate the "src == null" check again.
   1.134 -          stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
   1.135 -                                                    src_klass, thread,
   1.136 -                                                    false);
   1.137 -
   1.138 -          __ branch(lir_cond_notEqual, T_OBJECT, stub);
   1.139 -        } else {
   1.140 -          // We have statically determined that offset == referent_offset
   1.141 -          // && src != null so we unconditionally branch to code stub
   1.142 -          // to perform the guards and record reg in the SATB log buffer.
   1.143 -
   1.144 -          stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
   1.145 -                                                    src_klass, thread,
   1.146 -                                                    false);
   1.147 -
   1.148 -          __ branch(lir_cond_always, T_ILLEGAL, stub);
   1.149 -        }
   1.150 +        __ cmp(lir_cond_notEqual, off.result(), referent_off);
   1.151 +        __ branch(lir_cond_notEqual, as_BasicType(off.type()), Lcont->label());
   1.152        }
   1.153 -
   1.154 -      // Continuation point
   1.155 -      __ branch_destination(stub->continuation());
   1.156 +      if (gen_source_check) {
   1.157 +        // offset is a const and equals referent offset
   1.158 +        // if (source == null) -> continue
   1.159 +        __ cmp(lir_cond_equal, src.result(), LIR_OprFact::oopConst(NULL));
   1.160 +        __ branch(lir_cond_equal, T_OBJECT, Lcont->label());
   1.161 +      }
   1.162 +      LIR_Opr src_klass = new_register(T_OBJECT);
   1.163 +      if (gen_type_check) {
   1.164 +        // We have determined that offset == referent_offset && src != null.
   1.165 +        // if (src->_klass->_reference_type == REF_NONE) -> continue
   1.166 +        __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_OBJECT), src_klass);
   1.167 +        LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(instanceKlass::reference_type_offset()), T_BYTE);
   1.168 +        LIR_Opr reference_type = new_register(T_INT);
   1.169 +        __ move(reference_type_addr, reference_type);
   1.170 +        __ cmp(lir_cond_equal, reference_type, LIR_OprFact::intConst(REF_NONE));
   1.171 +        __ branch(lir_cond_equal, T_INT, Lcont->label());
   1.172 +      }
   1.173 +      {
   1.174 +        // We have determined that src->_klass->_reference_type != REF_NONE
   1.175 +        // so register the value in the referent field with the pre-barrier.
   1.176 +        pre_barrier(LIR_OprFact::illegalOpr /* addr_opr */,
   1.177 +                    value  /* pre_val */,
   1.178 +                    false  /* do_load */,
   1.179 +                    false  /* patch */,
   1.180 +                    NULL   /* info */);
   1.181 +      }
   1.182 +      __ branch_destination(Lcont->label());
   1.183      }
   1.184    }
   1.185  #endif // SERIALGC

mercurial