< prev index next >

src/share/vm/c1/c1_LIRGenerator.cpp

Print this page




2205   if (log2_scale != 0) {
2206     // temporary fix (platform dependent code without shift on Intel would be better)
2207     // TODO: ARM also allows embedded shift in the address
2208     __ shift_left(index_op, log2_scale, index_op);
2209   }
2210 
2211   LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
2212 #endif // !GENERATE_ADDRESS_IS_PREFERRED
2213   __ move(value.result(), addr);
2214 }
2215 
2216 
2217 void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
2218   BasicType type = x->basic_type();
2219   LIRItem src(x->object(), this);
2220   LIRItem off(x->offset(), this);
2221 
2222   off.load_item();
2223   src.load_item();
2224 

2225   LIR_Opr value = rlock_result(x, x->basic_type());
2226 
2227   get_Object_unsafe(value, src.result(), off.result(), type, x->is_volatile());
2228 
2229 #if INCLUDE_ALL_GCS
2230   // We might be reading the value of the referent field of a
2231   // Reference object in order to attach it back to the live
2232   // object graph. If G1 is enabled then we need to record
2233   // the value that is being returned in an SATB log buffer.
2234   //
2235   // We need to generate code similar to the following...
2236   //
2237   // if (offset == java_lang_ref_Reference::referent_offset) {
2238   //   if (src != NULL) {
2239   //     if (klass(src)->reference_type() != REF_NONE) {
2240   //       pre_barrier(..., value, ...);
2241   //     }
2242   //   }
2243   // }
2244 
2245   if (UseG1GC && type == T_OBJECT) {
2246     bool gen_pre_barrier = true;     // Assume we need to generate pre_barrier.
2247     bool gen_offset_check = true;    // Assume we need to generate the offset guard.
2248     bool gen_source_check = true;    // Assume we need to check the src object for null.
2249     bool gen_type_check = true;      // Assume we need to check the reference_type.
2250 
2251     if (off.is_constant()) {
2252       jlong off_con = (off.type()->is_int() ?
2253                         (jlong) off.get_jint_constant() :
2254                         off.get_jlong_constant());
2255 
2256 
2257       if (off_con != (jlong) java_lang_ref_Reference::referent_offset) {
2258         // The constant offset is something other than referent_offset.
2259         // We can skip generating/checking the remaining guards and
2260         // skip generation of the code stub.
2261         gen_pre_barrier = false;
2262       } else {
2263         // The constant offset is the same as referent_offset -
2264         // we do not need to generate a runtime offset check.
2265         gen_offset_check = false;
2266       }
2267     }
2268 
2269     // We don't need to generate stub if the source object is an array
2270     if (gen_pre_barrier && src.type()->is_array()) {
2271       gen_pre_barrier = false;


2308       LabelObj* Lcont = new LabelObj();
2309 
2310       // We can have generate one runtime check here. Let's start with
2311       // the offset check.
2312       if (gen_offset_check) {
2313         // if (offset != referent_offset) -> continue
2314         // If offset is an int then we can do the comparison with the
2315         // referent_offset constant; otherwise we need to move
2316         // referent_offset into a temporary register and generate
2317         // a reg-reg compare.
2318 
2319         LIR_Opr referent_off;
2320 
2321         if (off.type()->is_int()) {
2322           referent_off = LIR_OprFact::intConst(java_lang_ref_Reference::referent_offset);
2323         } else {
2324           assert(off.type()->is_long(), "what else?");
2325           referent_off = new_register(T_LONG);
2326           __ move(LIR_OprFact::longConst(java_lang_ref_Reference::referent_offset), referent_off);
2327         }
2328         __ cmp(lir_cond_notEqual, off.result(), referent_off);
2329         __ branch(lir_cond_notEqual, as_BasicType(off.type()), Lcont->label());
2330       }
2331       if (gen_source_check) {
2332         // offset is a const and equals referent offset
2333         // if (source == null) -> continue
2334         __ cmp(lir_cond_equal, src.result(), LIR_OprFact::oopConst(NULL));
2335         __ branch(lir_cond_equal, T_OBJECT, Lcont->label());
2336       }
2337       LIR_Opr src_klass = new_register(T_OBJECT);
2338       if (gen_type_check) {
2339         // We have determined that offset == referent_offset && src != null.
2340         // if (src->_klass->_reference_type == REF_NONE) -> continue
2341         __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass);
2342         LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(InstanceKlass::reference_type_offset()), T_BYTE);
2343         LIR_Opr reference_type = new_register(T_INT);
2344         __ move(reference_type_addr, reference_type);
2345         __ cmp(lir_cond_equal, reference_type, LIR_OprFact::intConst(REF_NONE));
2346         __ branch(lir_cond_equal, T_INT, Lcont->label());
2347       }
2348       {


2359   }
2360 #endif // INCLUDE_ALL_GCS
2361 
2362   if (x->is_volatile() && os::is_MP()) __ membar_acquire();
2363 }
2364 
2365 
2366 void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) {
2367   BasicType type = x->basic_type();
2368   LIRItem src(x->object(), this);
2369   LIRItem off(x->offset(), this);
2370   LIRItem data(x->value(), this);
2371 
2372   src.load_item();
2373   if (type == T_BOOLEAN || type == T_BYTE) {
2374     data.load_byte_item();
2375   } else {
2376     data.load_item();
2377   }
2378   off.load_item();
2379 
2380   set_no_result(x);
2381 
2382   if (x->is_volatile() && os::is_MP()) __ membar_release();
2383   put_Object_unsafe(src.result(), off.result(), data.result(), type, x->is_volatile());
2384   if (x->is_volatile() && os::is_MP()) __ membar();
2385 }
2386 
2387 
2388 void LIRGenerator::do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux) {
2389   int lng = x->length();
2390 
2391   for (int i = 0; i < lng; i++) {
2392     SwitchRange* one_range = x->at(i);
2393     int low_key = one_range->low_key();
2394     int high_key = one_range->high_key();
2395     BlockBegin* dest = one_range->sux();
2396     if (low_key == high_key) {
2397       __ cmp(lir_cond_equal, value, low_key);
2398       __ branch(lir_cond_equal, T_INT, dest);
2399     } else if (high_key - low_key == 1) {
2400       __ cmp(lir_cond_equal, value, low_key);
2401       __ branch(lir_cond_equal, T_INT, dest);
2402       __ cmp(lir_cond_equal, value, high_key);
2403       __ branch(lir_cond_equal, T_INT, dest);




2205   if (log2_scale != 0) {
2206     // temporary fix (platform dependent code without shift on Intel would be better)
2207     // TODO: ARM also allows embedded shift in the address
2208     __ shift_left(index_op, log2_scale, index_op);
2209   }
2210 
2211   LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
2212 #endif // !GENERATE_ADDRESS_IS_PREFERRED
2213   __ move(value.result(), addr);
2214 }
2215 
2216 
2217 void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
2218   BasicType type = x->basic_type();
2219   LIRItem src(x->object(), this);
2220   LIRItem off(x->offset(), this);
2221 
2222   off.load_item();
2223   src.load_item();
2224 
2225   LIR_Opr offset = unpack_offset(src.result(), off.result());
2226   LIR_Opr value = rlock_result(x, x->basic_type());
2227 
2228   get_Object_unsafe(value, src.result(), offset, type, x->is_volatile());
2229 
2230 #if INCLUDE_ALL_GCS
2231   // We might be reading the value of the referent field of a
2232   // Reference object in order to attach it back to the live
2233   // object graph. If G1 is enabled then we need to record
2234   // the value that is being returned in an SATB log buffer.
2235   //
2236   // We need to generate code similar to the following...
2237   //
2238   // if (offset == java_lang_ref_Reference::referent_offset) {
2239   //   if (src != NULL) {
2240   //     if (klass(src)->reference_type() != REF_NONE) {
2241   //       pre_barrier(..., value, ...);
2242   //     }
2243   //   }
2244   // }
2245 
2246   if (UseG1GC && type == T_OBJECT) {
2247     bool gen_pre_barrier = true;     // Assume we need to generate pre_barrier.
2248     bool gen_offset_check = true;    // Assume we need to generate the offset guard.
2249     bool gen_source_check = true;    // Assume we need to check the src object for null.
2250     bool gen_type_check = true;      // Assume we need to check the reference_type.
2251 
2252     if (false /*off.is_constant()*/) {
2253       jlong off_con = (off.type()->is_int() ?
2254                         (jlong) off.get_jint_constant() :
2255                         off.get_jlong_constant());
2256 
2257 
2258       if (off_con != (jlong) java_lang_ref_Reference::referent_offset) {
2259         // The constant offset is something other than referent_offset.
2260         // We can skip generating/checking the remaining guards and
2261         // skip generation of the code stub.
2262         gen_pre_barrier = false;
2263       } else {
2264         // The constant offset is the same as referent_offset -
2265         // we do not need to generate a runtime offset check.
2266         gen_offset_check = false;
2267       }
2268     }
2269 
2270     // We don't need to generate stub if the source object is an array
2271     if (gen_pre_barrier && src.type()->is_array()) {
2272       gen_pre_barrier = false;


2309       LabelObj* Lcont = new LabelObj();
2310 
2311       // We can have generate one runtime check here. Let's start with
2312       // the offset check.
2313       if (gen_offset_check) {
2314         // if (offset != referent_offset) -> continue
2315         // If offset is an int then we can do the comparison with the
2316         // referent_offset constant; otherwise we need to move
2317         // referent_offset into a temporary register and generate
2318         // a reg-reg compare.
2319 
2320         LIR_Opr referent_off;
2321 
2322         if (off.type()->is_int()) {
2323           referent_off = LIR_OprFact::intConst(java_lang_ref_Reference::referent_offset);
2324         } else {
2325           assert(off.type()->is_long(), "what else?");
2326           referent_off = new_register(T_LONG);
2327           __ move(LIR_OprFact::longConst(java_lang_ref_Reference::referent_offset), referent_off);
2328         }
2329         __ cmp(lir_cond_notEqual, offset, referent_off);
2330         __ branch(lir_cond_notEqual, as_BasicType(off.type()), Lcont->label());
2331       }
2332       if (gen_source_check) {
2333         // offset is a const and equals referent offset
2334         // if (source == null) -> continue
2335         __ cmp(lir_cond_equal, src.result(), LIR_OprFact::oopConst(NULL));
2336         __ branch(lir_cond_equal, T_OBJECT, Lcont->label());
2337       }
2338       LIR_Opr src_klass = new_register(T_OBJECT);
2339       if (gen_type_check) {
2340         // We have determined that offset == referent_offset && src != null.
2341         // if (src->_klass->_reference_type == REF_NONE) -> continue
2342         __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass);
2343         LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(InstanceKlass::reference_type_offset()), T_BYTE);
2344         LIR_Opr reference_type = new_register(T_INT);
2345         __ move(reference_type_addr, reference_type);
2346         __ cmp(lir_cond_equal, reference_type, LIR_OprFact::intConst(REF_NONE));
2347         __ branch(lir_cond_equal, T_INT, Lcont->label());
2348       }
2349       {


2360   }
2361 #endif // INCLUDE_ALL_GCS
2362 
2363   if (x->is_volatile() && os::is_MP()) __ membar_acquire();
2364 }
2365 
2366 
2367 void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) {
2368   BasicType type = x->basic_type();
2369   LIRItem src(x->object(), this);
2370   LIRItem off(x->offset(), this);
2371   LIRItem data(x->value(), this);
2372 
2373   src.load_item();
2374   if (type == T_BOOLEAN || type == T_BYTE) {
2375     data.load_byte_item();
2376   } else {
2377     data.load_item();
2378   }
2379   off.load_item();
2380   LIR_Opr offset = unpack_offset(src.result(), off.result());
2381   set_no_result(x);
2382 
2383   if (x->is_volatile() && os::is_MP()) __ membar_release();
2384   put_Object_unsafe(src.result(), offset, data.result(), type, x->is_volatile());
2385   if (x->is_volatile() && os::is_MP()) __ membar();
2386 }
2387 
2388 
2389 void LIRGenerator::do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux) {
2390   int lng = x->length();
2391 
2392   for (int i = 0; i < lng; i++) {
2393     SwitchRange* one_range = x->at(i);
2394     int low_key = one_range->low_key();
2395     int high_key = one_range->high_key();
2396     BlockBegin* dest = one_range->sux();
2397     if (low_key == high_key) {
2398       __ cmp(lir_cond_equal, value, low_key);
2399       __ branch(lir_cond_equal, T_INT, dest);
2400     } else if (high_key - low_key == 1) {
2401       __ cmp(lir_cond_equal, value, low_key);
2402       __ branch(lir_cond_equal, T_INT, dest);
2403       __ cmp(lir_cond_equal, value, high_key);
2404       __ branch(lir_cond_equal, T_INT, dest);


< prev index next >