src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp

Print this page
rev 3688 : 7054512: Compress class pointers after perm gen removal
Summary: support of compress class pointers in the compilers.
Reviewed-by:


  88         // the delay slot
  89         return false;
  90       }
  91 
  92       // don't put moves involving oops into the delay slot since the VerifyOops code
  93       // will make it much larger than a single instruction.
  94       if (VerifyOops) {
  95         return false;
  96       }
  97 
  98       if (src->is_double_cpu() || dst->is_double_cpu() || op1->patch_code() != lir_patch_none ||
  99           ((src->is_double_fpu() || dst->is_double_fpu()) && op1->move_kind() != lir_move_normal)) {
 100         return false;
 101       }
 102 
 103       if (UseCompressedOops) {
 104         if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false;
 105         if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false;
 106       }
 107 





 108       if (dst->is_register()) {
 109         if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) {
 110           return !PatchALot;
 111         } else if (src->is_single_stack()) {
 112           return true;
 113         }
 114       }
 115 
 116       if (src->is_register()) {
 117         if (dst->is_address() && Assembler::is_simm13(dst->as_address_ptr()->disp())) {
 118           return !PatchALot;
 119         } else if (dst->is_single_stack()) {
 120           return true;
 121         }
 122       }
 123 
 124       if (dst->is_register() &&
 125           ((src->is_register() && src->is_single_word() && src->is_same_type(dst)) ||
 126            (src->is_constant() && LIR_Assembler::is_small_constant(op->as_Op1()->in_opr())))) {
 127         return true;


 952 #endif
 953         } else {
 954 #ifdef _LP64
 955           assert(base != to_reg->as_register_lo(), "can't handle this");
 956           assert(O7 != to_reg->as_register_lo(), "can't handle this");
 957           __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_lo());
 958           __ lduw(base, offset + lo_word_offset_in_bytes, O7); // in case O7 is base or offset, use it last
 959           __ sllx(to_reg->as_register_lo(), 32, to_reg->as_register_lo());
 960           __ or3(to_reg->as_register_lo(), O7, to_reg->as_register_lo());
 961 #else
 962           if (base == to_reg->as_register_lo()) {
 963             __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
 964             __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
 965           } else {
 966             __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
 967             __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
 968           }
 969 #endif
 970         }
 971         break;
 972       case T_METADATA:
 973       case T_ADDRESS:  __ ld_ptr(base, offset, to_reg->as_register()); break;







 974       case T_ARRAY : // fall through
 975       case T_OBJECT:
 976         {
 977           if (UseCompressedOops && !wide) {
 978             __ lduw(base, offset, to_reg->as_register());
 979             __ decode_heap_oop(to_reg->as_register());
 980           } else {
 981             __ ld_ptr(base, offset, to_reg->as_register());
 982           }
 983           break;
 984         }
 985       case T_FLOAT:  __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break;
 986       case T_DOUBLE:
 987         {
 988           FloatRegister reg = to_reg->as_double_reg();
 989           // split unaligned loads
 990           if (unaligned || PatchALot) {
 991             __ ldf(FloatRegisterImpl::S, base, offset + 4, reg->successor());
 992             __ ldf(FloatRegisterImpl::S, base, offset,     reg);
 993           } else {


2327         __ delayed()->nop();
2328         __ bind(cont);
2329       }
2330     }
2331   }
2332 
2333 #ifdef ASSERT
2334   if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
2335     // Sanity check the known type with the incoming class.  For the
2336     // primitive case the types must match exactly with src.klass and
2337     // dst.klass each exactly matching the default type.  For the
2338     // object array case, if no type check is needed then either the
2339     // dst type is exactly the expected type and the src type is a
2340     // subtype which we can't check or src is the same array as dst
2341     // but not necessarily exactly of type default_type.
2342     Label known_ok, halt;
2343     metadata2reg(op->expected_type()->constant_encoding(), tmp);
2344     if (UseCompressedKlassPointers) {
2345       // tmp holds the default type. It currently comes uncompressed after the
2346       // load of a constant, so encode it.
2347       __ encode_heap_oop(tmp);
2348       // load the raw value of the dst klass, since we will be comparing
2349       // uncompressed values directly.
2350       __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
2351       if (basic_type != T_OBJECT) {
2352         __ cmp(tmp, tmp2);
2353         __ br(Assembler::notEqual, false, Assembler::pn, halt);
2354         // load the raw value of the src klass.
2355         __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
2356         __ cmp_and_br_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok);
2357       } else {
2358         __ cmp(tmp, tmp2);
2359         __ br(Assembler::equal, false, Assembler::pn, known_ok);
2360         __ delayed()->cmp(src, dst);
2361         __ brx(Assembler::equal, false, Assembler::pn, known_ok);
2362         __ delayed()->nop();
2363       }
2364     } else {
2365       __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
2366       if (basic_type != T_OBJECT) {
2367         __ cmp(tmp, tmp2);




  88         // the delay slot
  89         return false;
  90       }
  91 
  92       // don't put moves involving oops into the delay slot since the VerifyOops code
  93       // will make it much larger than a single instruction.
  94       if (VerifyOops) {
  95         return false;
  96       }
  97 
  98       if (src->is_double_cpu() || dst->is_double_cpu() || op1->patch_code() != lir_patch_none ||
  99           ((src->is_double_fpu() || dst->is_double_fpu()) && op1->move_kind() != lir_move_normal)) {
 100         return false;
 101       }
 102 
 103       if (UseCompressedOops) {
 104         if (dst->is_address() && !dst->is_stack() && (dst->type() == T_OBJECT || dst->type() == T_ARRAY)) return false;
 105         if (src->is_address() && !src->is_stack() && (src->type() == T_OBJECT || src->type() == T_ARRAY)) return false;
 106       }
 107       
 108       if (UseCompressedKlassPointers) {
 109         if (src->is_address() && !src->is_stack() && src->type() == T_ADDRESS &&
 110             src->as_address_ptr()->disp() == oopDesc::klass_offset_in_bytes()) return false;
 111       }
 112 
 113       if (dst->is_register()) {
 114         if (src->is_address() && Assembler::is_simm13(src->as_address_ptr()->disp())) {
 115           return !PatchALot;
 116         } else if (src->is_single_stack()) {
 117           return true;
 118         }
 119       }
 120 
 121       if (src->is_register()) {
 122         if (dst->is_address() && Assembler::is_simm13(dst->as_address_ptr()->disp())) {
 123           return !PatchALot;
 124         } else if (dst->is_single_stack()) {
 125           return true;
 126         }
 127       }
 128 
 129       if (dst->is_register() &&
 130           ((src->is_register() && src->is_single_word() && src->is_same_type(dst)) ||
 131            (src->is_constant() && LIR_Assembler::is_small_constant(op->as_Op1()->in_opr())))) {
 132         return true;


 957 #endif
 958         } else {
 959 #ifdef _LP64
 960           assert(base != to_reg->as_register_lo(), "can't handle this");
 961           assert(O7 != to_reg->as_register_lo(), "can't handle this");
 962           __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_lo());
 963           __ lduw(base, offset + lo_word_offset_in_bytes, O7); // in case O7 is base or offset, use it last
 964           __ sllx(to_reg->as_register_lo(), 32, to_reg->as_register_lo());
 965           __ or3(to_reg->as_register_lo(), O7, to_reg->as_register_lo());
 966 #else
 967           if (base == to_reg->as_register_lo()) {
 968             __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
 969             __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
 970           } else {
 971             __ ld(base, offset + lo_word_offset_in_bytes, to_reg->as_register_lo());
 972             __ ld(base, offset + hi_word_offset_in_bytes, to_reg->as_register_hi());
 973           }
 974 #endif
 975         }
 976         break;
 977       case T_METADATA:  __ ld_ptr(base, offset, to_reg->as_register()); break;
 978       case T_ADDRESS:
 979         if (UseCompressedKlassPointers && offset == oopDesc::klass_offset_in_bytes()) {
 980           __ lduw(base, offset, to_reg->as_register());
 981           __ decode_klass_not_null(to_reg->as_register());
 982         } else {
 983           __ ld_ptr(base, offset, to_reg->as_register());
 984         }
 985         break;
 986       case T_ARRAY : // fall through
 987       case T_OBJECT:
 988         {
 989           if (UseCompressedOops && !wide) {
 990             __ lduw(base, offset, to_reg->as_register());
 991             __ decode_heap_oop(to_reg->as_register());
 992           } else {
 993             __ ld_ptr(base, offset, to_reg->as_register());
 994           }
 995           break;
 996         }
 997       case T_FLOAT:  __ ldf(FloatRegisterImpl::S, base, offset, to_reg->as_float_reg()); break;
 998       case T_DOUBLE:
 999         {
1000           FloatRegister reg = to_reg->as_double_reg();
1001           // split unaligned loads
1002           if (unaligned || PatchALot) {
1003             __ ldf(FloatRegisterImpl::S, base, offset + 4, reg->successor());
1004             __ ldf(FloatRegisterImpl::S, base, offset,     reg);
1005           } else {


2339         __ delayed()->nop();
2340         __ bind(cont);
2341       }
2342     }
2343   }
2344 
2345 #ifdef ASSERT
2346   if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
2347     // Sanity check the known type with the incoming class.  For the
2348     // primitive case the types must match exactly with src.klass and
2349     // dst.klass each exactly matching the default type.  For the
2350     // object array case, if no type check is needed then either the
2351     // dst type is exactly the expected type and the src type is a
2352     // subtype which we can't check or src is the same array as dst
2353     // but not necessarily exactly of type default_type.
2354     Label known_ok, halt;
2355     metadata2reg(op->expected_type()->constant_encoding(), tmp);
2356     if (UseCompressedKlassPointers) {
2357       // tmp holds the default type. It currently comes uncompressed after the
2358       // load of a constant, so encode it.
2359       __ encode_klass_not_null(tmp);
2360       // load the raw value of the dst klass, since we will be comparing
2361       // uncompressed values directly.
2362       __ lduw(dst, oopDesc::klass_offset_in_bytes(), tmp2);
2363       if (basic_type != T_OBJECT) {
2364         __ cmp(tmp, tmp2);
2365         __ br(Assembler::notEqual, false, Assembler::pn, halt);
2366         // load the raw value of the src klass.
2367         __ delayed()->lduw(src, oopDesc::klass_offset_in_bytes(), tmp2);
2368         __ cmp_and_br_short(tmp, tmp2, Assembler::equal, Assembler::pn, known_ok);
2369       } else {
2370         __ cmp(tmp, tmp2);
2371         __ br(Assembler::equal, false, Assembler::pn, known_ok);
2372         __ delayed()->cmp(src, dst);
2373         __ brx(Assembler::equal, false, Assembler::pn, known_ok);
2374         __ delayed()->nop();
2375       }
2376     } else {
2377       __ ld_ptr(dst, oopDesc::klass_offset_in_bytes(), tmp2);
2378       if (basic_type != T_OBJECT) {
2379         __ cmp(tmp, tmp2);