src/cpu/x86/vm/c1_LIRAssembler_x86.cpp

changeset 2344
ac637b7220d1
parent 2314
f95d63e2154a
child 2349
5ddfcf4b079e
     1.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Nov 23 13:22:55 2010 -0800
     1.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Tue Nov 30 23:23:40 2010 -0800
     1.3 @@ -343,8 +343,8 @@
     1.4    Register receiver = FrameMap::receiver_opr->as_register();
     1.5    Register ic_klass = IC_Klass;
     1.6    const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
     1.7 -
     1.8 -  if (!VerifyOops) {
     1.9 +  const bool do_post_padding = VerifyOops || UseCompressedOops;
    1.10 +  if (!do_post_padding) {
    1.11      // insert some nops so that the verified entry point is aligned on CodeEntryAlignment
    1.12      while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) {
    1.13        __ nop();
    1.14 @@ -352,8 +352,8 @@
    1.15    }
    1.16    int offset = __ offset();
    1.17    __ inline_cache_check(receiver, IC_Klass);
    1.18 -  assert(__ offset() % CodeEntryAlignment == 0 || VerifyOops, "alignment must be correct");
    1.19 -  if (VerifyOops) {
    1.20 +  assert(__ offset() % CodeEntryAlignment == 0 || do_post_padding, "alignment must be correct");
    1.21 +  if (do_post_padding) {
    1.22      // force alignment after the cache check.
    1.23      // It's been verified to be aligned if !VerifyOops
    1.24      __ align(CodeEntryAlignment);
    1.25 @@ -559,16 +559,16 @@
    1.26    __ movptr (rax, arg1->as_register());
    1.27  
    1.28    // Get addresses of first characters from both Strings
    1.29 -  __ movptr (rsi, Address(rax, java_lang_String::value_offset_in_bytes()));
    1.30 -  __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
    1.31 -  __ lea    (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
    1.32 +  __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes()));
    1.33 +  __ movptr       (rcx, Address(rax, java_lang_String::offset_offset_in_bytes()));
    1.34 +  __ lea          (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
    1.35  
    1.36  
    1.37    // rbx, may be NULL
    1.38    add_debug_info_for_null_check_here(info);
    1.39 -  __ movptr (rdi, Address(rbx, java_lang_String::value_offset_in_bytes()));
    1.40 -  __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
    1.41 -  __ lea    (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
    1.42 +  __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes()));
    1.43 +  __ movptr       (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes()));
    1.44 +  __ lea          (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
    1.45  
    1.46    // compute minimum length (in rax) and difference of lengths (on top of stack)
    1.47    if (VM_Version::supports_cmov()) {
    1.48 @@ -696,10 +696,15 @@
    1.49    LIR_Const* c = src->as_constant_ptr();
    1.50  
    1.51    switch (c->type()) {
    1.52 -    case T_INT:
    1.53 +    case T_INT: {
    1.54 +      assert(patch_code == lir_patch_none, "no patching handled here");
    1.55 +      __ movl(dest->as_register(), c->as_jint());
    1.56 +      break;
    1.57 +    }
    1.58 +
    1.59      case T_ADDRESS: {
    1.60        assert(patch_code == lir_patch_none, "no patching handled here");
    1.61 -      __ movl(dest->as_register(), c->as_jint());
    1.62 +      __ movptr(dest->as_register(), c->as_jint());
    1.63        break;
    1.64      }
    1.65  
    1.66 @@ -780,8 +785,11 @@
    1.67    switch (c->type()) {
    1.68      case T_INT:  // fall through
    1.69      case T_FLOAT:
    1.70 +      __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
    1.71 +      break;
    1.72 +
    1.73      case T_ADDRESS:
    1.74 -      __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
    1.75 +      __ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits());
    1.76        break;
    1.77  
    1.78      case T_OBJECT:
    1.79 @@ -806,7 +814,7 @@
    1.80    }
    1.81  }
    1.82  
    1.83 -void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) {
    1.84 +void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
    1.85    assert(src->is_constant(), "should not call otherwise");
    1.86    assert(dest->is_address(), "should not call otherwise");
    1.87    LIR_Const* c = src->as_constant_ptr();
    1.88 @@ -816,14 +824,21 @@
    1.89    switch (type) {
    1.90      case T_INT:    // fall through
    1.91      case T_FLOAT:
    1.92 +      __ movl(as_Address(addr), c->as_jint_bits());
    1.93 +      break;
    1.94 +
    1.95      case T_ADDRESS:
    1.96 -      __ movl(as_Address(addr), c->as_jint_bits());
    1.97 +      __ movptr(as_Address(addr), c->as_jint_bits());
    1.98        break;
    1.99  
   1.100      case T_OBJECT:  // fall through
   1.101      case T_ARRAY:
   1.102        if (c->as_jobject() == NULL) {
   1.103 -        __ movptr(as_Address(addr), NULL_WORD);
   1.104 +        if (UseCompressedOops && !wide) {
   1.105 +          __ movl(as_Address(addr), (int32_t)NULL_WORD);
   1.106 +        } else {
   1.107 +          __ movptr(as_Address(addr), NULL_WORD);
   1.108 +        }
   1.109        } else {
   1.110          if (is_literal_address(addr)) {
   1.111            ShouldNotReachHere();
   1.112 @@ -831,8 +846,14 @@
   1.113          } else {
   1.114  #ifdef _LP64
   1.115            __ movoop(rscratch1, c->as_jobject());
   1.116 -          null_check_here = code_offset();
   1.117 -          __ movptr(as_Address_lo(addr), rscratch1);
   1.118 +          if (UseCompressedOops && !wide) {
   1.119 +            __ encode_heap_oop(rscratch1);
   1.120 +            null_check_here = code_offset();
   1.121 +            __ movl(as_Address_lo(addr), rscratch1);
   1.122 +          } else {
   1.123 +            null_check_here = code_offset();
   1.124 +            __ movptr(as_Address_lo(addr), rscratch1);
   1.125 +          }
   1.126  #else
   1.127            __ movoop(as_Address(addr), c->as_jobject());
   1.128  #endif
   1.129 @@ -1009,22 +1030,28 @@
   1.130  }
   1.131  
   1.132  
   1.133 -void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool /* unaligned */) {
   1.134 +void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) {
   1.135    LIR_Address* to_addr = dest->as_address_ptr();
   1.136    PatchingStub* patch = NULL;
   1.137 +  Register compressed_src = rscratch1;
   1.138  
   1.139    if (type == T_ARRAY || type == T_OBJECT) {
   1.140      __ verify_oop(src->as_register());
   1.141 +#ifdef _LP64
   1.142 +    if (UseCompressedOops && !wide) {
   1.143 +      __ movptr(compressed_src, src->as_register());
   1.144 +      __ encode_heap_oop(compressed_src);
   1.145 +    }
   1.146 +#endif
   1.147    }
   1.148 +
   1.149    if (patch_code != lir_patch_none) {
   1.150      patch = new PatchingStub(_masm, PatchingStub::access_field_id);
   1.151      Address toa = as_Address(to_addr);
   1.152      assert(toa.disp() != 0, "must have");
   1.153    }
   1.154 -  if (info != NULL) {
   1.155 -    add_debug_info_for_null_check_here(info);
   1.156 -  }
   1.157 -
   1.158 +
   1.159 +  int null_check_here = code_offset();
   1.160    switch (type) {
   1.161      case T_FLOAT: {
   1.162        if (src->is_single_xmm()) {
   1.163 @@ -1050,13 +1077,17 @@
   1.164        break;
   1.165      }
   1.166  
   1.167 -    case T_ADDRESS: // fall through
   1.168      case T_ARRAY:   // fall through
   1.169      case T_OBJECT:  // fall through
   1.170 -#ifdef _LP64
   1.171 +      if (UseCompressedOops && !wide) {
   1.172 +        __ movl(as_Address(to_addr), compressed_src);
   1.173 +      } else {
   1.174 +        __ movptr(as_Address(to_addr), src->as_register());
   1.175 +      }
   1.176 +      break;
   1.177 +    case T_ADDRESS:
   1.178        __ movptr(as_Address(to_addr), src->as_register());
   1.179        break;
   1.180 -#endif // _LP64
   1.181      case T_INT:
   1.182        __ movl(as_Address(to_addr), src->as_register());
   1.183        break;
   1.184 @@ -1113,6 +1144,9 @@
   1.185      default:
   1.186        ShouldNotReachHere();
   1.187    }
   1.188 +  if (info != NULL) {
   1.189 +    add_debug_info_for_null_check(null_check_here, info);
   1.190 +  }
   1.191  
   1.192    if (patch_code != lir_patch_none) {
   1.193      patching_epilog(patch, patch_code, to_addr->base()->as_register(), info);
   1.194 @@ -1196,7 +1230,7 @@
   1.195  }
   1.196  
   1.197  
   1.198 -void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool /* unaligned */) {
   1.199 +void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool /* unaligned */) {
   1.200    assert(src->is_address(), "should not call otherwise");
   1.201    assert(dest->is_register(), "should not call otherwise");
   1.202  
   1.203 @@ -1250,13 +1284,18 @@
   1.204        break;
   1.205      }
   1.206  
   1.207 -    case T_ADDRESS: // fall through
   1.208      case T_OBJECT:  // fall through
   1.209      case T_ARRAY:   // fall through
   1.210 -#ifdef _LP64
   1.211 +      if (UseCompressedOops && !wide) {
   1.212 +        __ movl(dest->as_register(), from_addr);
   1.213 +      } else {
   1.214 +        __ movptr(dest->as_register(), from_addr);
   1.215 +      }
   1.216 +      break;
   1.217 +
   1.218 +    case T_ADDRESS:
   1.219        __ movptr(dest->as_register(), from_addr);
   1.220        break;
   1.221 -#endif // _L64
   1.222      case T_INT:
   1.223        __ movl(dest->as_register(), from_addr);
   1.224        break;
   1.225 @@ -1351,6 +1390,11 @@
   1.226    }
   1.227  
   1.228    if (type == T_ARRAY || type == T_OBJECT) {
   1.229 +#ifdef _LP64
   1.230 +    if (UseCompressedOops && !wide) {
   1.231 +      __ decode_heap_oop(dest->as_register());
   1.232 +    }
   1.233 +#endif
   1.234      __ verify_oop(dest->as_register());
   1.235    }
   1.236  }
   1.237 @@ -1690,7 +1734,7 @@
   1.238    } else if (obj == klass_RInfo) {
   1.239      klass_RInfo = dst;
   1.240    }
   1.241 -  if (k->is_loaded()) {
   1.242 +  if (k->is_loaded() && !UseCompressedOops) {
   1.243      select_different_registers(obj, dst, k_RInfo, klass_RInfo);
   1.244    } else {
   1.245      Rtmp1 = op->tmp3()->as_register();
   1.246 @@ -1727,21 +1771,26 @@
   1.247    if (op->fast_check()) {
   1.248      // get object class
   1.249      // not a safepoint as obj null check happens earlier
   1.250 -    if (k->is_loaded()) {
   1.251  #ifdef _LP64
   1.252 -      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.253 -#else
   1.254 -      __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
   1.255 -#endif // _LP64
   1.256 +    if (UseCompressedOops) {
   1.257 +      __ load_klass(Rtmp1, obj);
   1.258 +      __ cmpptr(k_RInfo, Rtmp1);
   1.259      } else {
   1.260        __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.261      }
   1.262 +#else
   1.263 +    if (k->is_loaded()) {
   1.264 +      __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding());
   1.265 +    } else {
   1.266 +      __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.267 +    }
   1.268 +#endif
   1.269      __ jcc(Assembler::notEqual, *failure_target);
   1.270      // successful cast, fall through to profile or jump
   1.271    } else {
   1.272      // get object class
   1.273      // not a safepoint as obj null check happens earlier
   1.274 -    __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.275 +    __ load_klass(klass_RInfo, obj);
   1.276      if (k->is_loaded()) {
   1.277        // See if we get an immediate positive hit
   1.278  #ifdef _LP64
   1.279 @@ -1796,7 +1845,7 @@
   1.280      Register mdo  = klass_RInfo, recv = k_RInfo;
   1.281      __ bind(profile_cast_success);
   1.282      __ movoop(mdo, md->constant_encoding());
   1.283 -    __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.284 +    __ load_klass(recv, obj);
   1.285      Label update_done;
   1.286      type_profile_helper(mdo, md, data, recv, success);
   1.287      __ jmp(*success);
   1.288 @@ -1860,10 +1909,10 @@
   1.289      }
   1.290  
   1.291      add_debug_info_for_null_check_here(op->info_for_exception());
   1.292 -    __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes()));
   1.293 -    __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes()));
   1.294 -
   1.295 -    // get instance klass
   1.296 +    __ load_klass(k_RInfo, array);
   1.297 +    __ load_klass(klass_RInfo, value);
   1.298 +
   1.299 +    // get instance klass (it's already uncompressed)
   1.300      __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
   1.301      // perform the fast part of the checking logic
   1.302      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
   1.303 @@ -1882,7 +1931,7 @@
   1.304        Register mdo  = klass_RInfo, recv = k_RInfo;
   1.305        __ bind(profile_cast_success);
   1.306        __ movoop(mdo, md->constant_encoding());
   1.307 -      __ movptr(recv, Address(value, oopDesc::klass_offset_in_bytes()));
   1.308 +      __ load_klass(recv, value);
   1.309        Label update_done;
   1.310        type_profile_helper(mdo, md, data, recv, &done);
   1.311        __ jmpb(done);
   1.312 @@ -1946,12 +1995,32 @@
   1.313      assert(cmpval != newval, "cmp and new values must be in different registers");
   1.314      assert(cmpval != addr, "cmp and addr must be in different registers");
   1.315      assert(newval != addr, "new value and addr must be in different registers");
   1.316 -    if (os::is_MP()) {
   1.317 -      __ lock();
   1.318 -    }
   1.319 +
   1.320      if ( op->code() == lir_cas_obj) {
   1.321 -      __ cmpxchgptr(newval, Address(addr, 0));
   1.322 -    } else if (op->code() == lir_cas_int) {
   1.323 +#ifdef _LP64
   1.324 +      if (UseCompressedOops) {
   1.325 +        __ mov(rscratch1, cmpval);
   1.326 +        __ encode_heap_oop(cmpval);
   1.327 +        __ mov(rscratch2, newval);
   1.328 +        __ encode_heap_oop(rscratch2);
   1.329 +        if (os::is_MP()) {
   1.330 +          __ lock();
   1.331 +        }
   1.332 +        __ cmpxchgl(rscratch2, Address(addr, 0));
   1.333 +        __ mov(cmpval, rscratch1);
   1.334 +      } else
   1.335 +#endif
   1.336 +      {
   1.337 +        if (os::is_MP()) {
   1.338 +          __ lock();
   1.339 +        }
   1.340 +        __ cmpxchgptr(newval, Address(addr, 0));
   1.341 +      }
   1.342 +    } else {
   1.343 +      assert(op->code() == lir_cas_int, "lir_cas_int expected");
   1.344 +      if (os::is_MP()) {
   1.345 +        __ lock();
   1.346 +      }
   1.347        __ cmpxchgl(newval, Address(addr, 0));
   1.348      }
   1.349  #ifdef _LP64
   1.350 @@ -3193,8 +3262,13 @@
   1.351    }
   1.352  
   1.353    if (flags & LIR_OpArrayCopy::type_check) {
   1.354 -    __ movptr(tmp, src_klass_addr);
   1.355 -    __ cmpptr(tmp, dst_klass_addr);
   1.356 +    if (UseCompressedOops) {
   1.357 +      __ movl(tmp, src_klass_addr);
   1.358 +      __ cmpl(tmp, dst_klass_addr);
   1.359 +    } else {
   1.360 +      __ movptr(tmp, src_klass_addr);
   1.361 +      __ cmpptr(tmp, dst_klass_addr);
   1.362 +    }
   1.363      __ jcc(Assembler::notEqual, *stub->entry());
   1.364    }
   1.365  
   1.366 @@ -3209,13 +3283,23 @@
   1.367      // but not necessarily exactly of type default_type.
   1.368      Label known_ok, halt;
   1.369      __ movoop(tmp, default_type->constant_encoding());
   1.370 +#ifdef _LP64
   1.371 +    if (UseCompressedOops) {
   1.372 +      __ encode_heap_oop(tmp);
   1.373 +    }
   1.374 +#endif
   1.375 +
   1.376      if (basic_type != T_OBJECT) {
   1.377 -      __ cmpptr(tmp, dst_klass_addr);
   1.378 +
   1.379 +      if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr);
   1.380 +      else                   __ cmpptr(tmp, dst_klass_addr);
   1.381        __ jcc(Assembler::notEqual, halt);
   1.382 -      __ cmpptr(tmp, src_klass_addr);
   1.383 +      if (UseCompressedOops) __ cmpl(tmp, src_klass_addr);
   1.384 +      else                   __ cmpptr(tmp, src_klass_addr);
   1.385        __ jcc(Assembler::equal, known_ok);
   1.386      } else {
   1.387 -      __ cmpptr(tmp, dst_klass_addr);
   1.388 +      if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr);
   1.389 +      else                   __ cmpptr(tmp, dst_klass_addr);
   1.390        __ jcc(Assembler::equal, known_ok);
   1.391        __ cmpptr(src, dst);
   1.392        __ jcc(Assembler::equal, known_ok);
   1.393 @@ -3344,7 +3428,7 @@
   1.394          }
   1.395        }
   1.396      } else {
   1.397 -      __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes()));
   1.398 +      __ load_klass(recv, recv);
   1.399        Label update_done;
   1.400        type_profile_helper(mdo, md, data, recv, &update_done);
   1.401        // Receiver did not match any saved receiver and there is no empty row for it.

mercurial