src/cpu/x86/vm/c1_LIRAssembler_x86.cpp

changeset 2146
3a294e483abc
parent 2145
7f9553bedfd5
child 2163
5511edd5d719
child 2185
a3f7f95b0165
     1.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Sat Sep 11 15:21:37 2010 -0700
     1.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Sep 13 12:10:49 2010 -0700
     1.3 @@ -1624,7 +1624,7 @@
     1.4      __ jccb(Assembler::notEqual, next_test);
     1.5      Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)));
     1.6      __ addptr(data_addr, DataLayout::counter_increment);
     1.7 -    __ jmpb(*update_done);
     1.8 +    __ jmp(*update_done);
     1.9      __ bind(next_test);
    1.10    }
    1.11  
    1.12 @@ -1636,13 +1636,12 @@
    1.13      __ jccb(Assembler::notEqual, next_test);
    1.14      __ movptr(recv_addr, recv);
    1.15      __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment);
    1.16 -    __ jmpb(*update_done);
    1.17 +    __ jmp(*update_done);
    1.18      __ bind(next_test);
    1.19    }
    1.20  }
    1.21  
    1.22 -void LIR_Assembler::emit_checkcast(LIR_OpTypeCheck *op) {
    1.23 -  assert(op->code() == lir_checkcast, "Invalid operation");
    1.24 +void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
    1.25    // we always need a stub for the failure case.
    1.26    CodeStub* stub = op->stub();
    1.27    Register obj = op->object()->as_register();
    1.28 @@ -1666,14 +1665,12 @@
    1.29        return;
    1.30      }
    1.31      data = md->bci_to_data(bci);
    1.32 -    assert(data != NULL,                "need data for checkcast");
    1.33 -    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for checkcast");
    1.34 +    assert(data != NULL,                "need data for type check");
    1.35 +    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
    1.36    }
    1.37 -  Label profile_cast_failure;
    1.38 -
    1.39 -  Label done, done_null;
    1.40 -  // Where to go in case of cast failure
    1.41 -  Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
    1.42 +  Label profile_cast_success, profile_cast_failure;
    1.43 +  Label *success_target = op->should_profile() ? &profile_cast_success : success;
    1.44 +  Label *failure_target = op->should_profile() ? &profile_cast_failure : failure;
    1.45  
    1.46    if (obj == k_RInfo) {
    1.47      k_RInfo = dst;
    1.48 @@ -1699,23 +1696,23 @@
    1.49  
    1.50    __ cmpptr(obj, (int32_t)NULL_WORD);
    1.51    if (op->should_profile()) {
    1.52 -    Label profile_done;
    1.53 -    __ jccb(Assembler::notEqual, profile_done);
    1.54 -    // Object is null; update methodDataOop
    1.55 +    Label not_null;
    1.56 +    __ jccb(Assembler::notEqual, not_null);
    1.57 +    // Object is null; update MDO and exit
    1.58      Register mdo  = klass_RInfo;
    1.59      __ movoop(mdo, md->constant_encoding());
    1.60      Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
    1.61      int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
    1.62      __ orl(data_addr, header_bits);
    1.63 -    __ jmp(done_null);
    1.64 -    __ bind(profile_done);
    1.65 +    __ jmp(*obj_is_null);
    1.66 +    __ bind(not_null);
    1.67    } else {
    1.68 -    __ jcc(Assembler::equal, done_null);
    1.69 +    __ jcc(Assembler::equal, *obj_is_null);
    1.70    }
    1.71    __ verify_oop(obj);
    1.72  
    1.73    if (op->fast_check()) {
    1.74 -    // get object classo
    1.75 +    // get object class
    1.76      // not a safepoint as obj null check happens earlier
    1.77      if (k->is_loaded()) {
    1.78  #ifdef _LP64
    1.79 @@ -1727,6 +1724,7 @@
    1.80        __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
    1.81      }
    1.82      __ jcc(Assembler::notEqual, *failure_target);
    1.83 +    // successful cast, fall through to profile or jump
    1.84    } else {
    1.85      // get object class
    1.86      // not a safepoint as obj null check happens earlier
    1.87 @@ -1740,16 +1738,17 @@
    1.88  #endif // _LP64
    1.89        if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
    1.90          __ jcc(Assembler::notEqual, *failure_target);
    1.91 +        // successful cast, fall through to profile or jump
    1.92        } else {
    1.93          // See if we get an immediate positive hit
    1.94 -        __ jcc(Assembler::equal, done);
    1.95 +        __ jcc(Assembler::equal, *success_target);
    1.96          // check for self
    1.97  #ifdef _LP64
    1.98          __ cmpptr(klass_RInfo, k_RInfo);
    1.99  #else
   1.100          __ cmpoop(klass_RInfo, k->constant_encoding());
   1.101  #endif // _LP64
   1.102 -        __ jcc(Assembler::equal, done);
   1.103 +        __ jcc(Assembler::equal, *success_target);
   1.104  
   1.105          __ push(klass_RInfo);
   1.106  #ifdef _LP64
   1.107 @@ -1763,10 +1762,11 @@
   1.108          // result is a boolean
   1.109          __ cmpl(klass_RInfo, 0);
   1.110          __ jcc(Assembler::equal, *failure_target);
   1.111 +        // successful cast, fall through to profile or jump
   1.112        }
   1.113      } else {
   1.114        // perform the fast part of the checking logic
   1.115 -      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, failure_target, NULL);
   1.116 +      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
   1.117        // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   1.118        __ push(klass_RInfo);
   1.119        __ push(k_RInfo);
   1.120 @@ -1776,32 +1776,28 @@
   1.121        // result is a boolean
   1.122        __ cmpl(k_RInfo, 0);
   1.123        __ jcc(Assembler::equal, *failure_target);
   1.124 +      // successful cast, fall through to profile or jump
   1.125      }
   1.126    }
   1.127 -  __ bind(done);
   1.128 -
   1.129    if (op->should_profile()) {
   1.130      Register mdo  = klass_RInfo, recv = k_RInfo;
   1.131 +    __ bind(profile_cast_success);
   1.132      __ movoop(mdo, md->constant_encoding());
   1.133      __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.134      Label update_done;
   1.135 -    type_profile_helper(mdo, md, data, recv, &update_done);
   1.136 -    __ jmpb(update_done);
   1.137 +    type_profile_helper(mdo, md, data, recv, success);
   1.138 +    __ jmp(*success);
   1.139  
   1.140      __ bind(profile_cast_failure);
   1.141      __ movoop(mdo, md->constant_encoding());
   1.142      Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
   1.143      __ subptr(counter_addr, DataLayout::counter_increment);
   1.144 -    __ jmp(*stub->entry());
   1.145 -
   1.146 -    __ bind(update_done);
   1.147 +    __ jmp(*failure);
   1.148    }
   1.149 -  __ bind(done_null);
   1.150 -  if (dst != obj) {
   1.151 -    __ mov(dst, obj);
   1.152 -  }
   1.153 +  __ jmp(*success);
   1.154  }
   1.155  
   1.156 +
   1.157  void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
   1.158    LIR_Code code = op->code();
   1.159    if (code == lir_store_check) {
   1.160 @@ -1812,9 +1808,44 @@
   1.161      Register Rtmp1 = op->tmp3()->as_register();
   1.162  
   1.163      CodeStub* stub = op->stub();
   1.164 -    Label done;
   1.165 +
   1.166 +    // check if it needs to be profiled
   1.167 +    ciMethodData* md;
   1.168 +    ciProfileData* data;
   1.169 +
   1.170 +    if (op->should_profile()) {
   1.171 +      ciMethod* method = op->profiled_method();
   1.172 +      assert(method != NULL, "Should have method");
   1.173 +      int bci = op->profiled_bci();
   1.174 +      md = method->method_data();
   1.175 +      if (md == NULL) {
   1.176 +        bailout("out of memory building methodDataOop");
   1.177 +        return;
   1.178 +      }
   1.179 +      data = md->bci_to_data(bci);
   1.180 +      assert(data != NULL,                "need data for type check");
   1.181 +      assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
   1.182 +    }
   1.183 +    Label profile_cast_success, profile_cast_failure, done;
   1.184 +    Label *success_target = op->should_profile() ? &profile_cast_success : &done;
   1.185 +    Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
   1.186 +
   1.187      __ cmpptr(value, (int32_t)NULL_WORD);
   1.188 -    __ jcc(Assembler::equal, done);
   1.189 +    if (op->should_profile()) {
   1.190 +      Label not_null;
   1.191 +      __ jccb(Assembler::notEqual, not_null);
   1.192 +      // Object is null; update MDO and exit
   1.193 +      Register mdo  = klass_RInfo;
   1.194 +      __ movoop(mdo, md->constant_encoding());
   1.195 +      Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
   1.196 +      int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
   1.197 +      __ orl(data_addr, header_bits);
   1.198 +      __ jmp(done);
   1.199 +      __ bind(not_null);
   1.200 +    } else {
   1.201 +      __ jcc(Assembler::equal, done);
   1.202 +    }
   1.203 +
   1.204      add_debug_info_for_null_check_here(op->info_for_exception());
   1.205      __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes()));
   1.206      __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes()));
   1.207 @@ -1822,7 +1853,7 @@
   1.208      // get instance klass
   1.209      __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
   1.210      // perform the fast part of the checking logic
   1.211 -    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, stub->entry(), NULL);
   1.212 +    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
   1.213      // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   1.214      __ push(klass_RInfo);
   1.215      __ push(k_RInfo);
   1.216 @@ -1831,94 +1862,51 @@
   1.217      __ pop(k_RInfo);
   1.218      // result is a boolean
   1.219      __ cmpl(k_RInfo, 0);
   1.220 -    __ jcc(Assembler::equal, *stub->entry());
   1.221 +    __ jcc(Assembler::equal, *failure_target);
   1.222 +    // fall through to the success case
   1.223 +
   1.224 +    if (op->should_profile()) {
   1.225 +      Register mdo  = klass_RInfo, recv = k_RInfo;
   1.226 +      __ bind(profile_cast_success);
   1.227 +      __ movoop(mdo, md->constant_encoding());
   1.228 +      __ movptr(recv, Address(value, oopDesc::klass_offset_in_bytes()));
   1.229 +      Label update_done;
   1.230 +      type_profile_helper(mdo, md, data, recv, &done);
   1.231 +      __ jmpb(done);
   1.232 +
   1.233 +      __ bind(profile_cast_failure);
   1.234 +      __ movoop(mdo, md->constant_encoding());
   1.235 +      Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
   1.236 +      __ subptr(counter_addr, DataLayout::counter_increment);
   1.237 +      __ jmp(*stub->entry());
   1.238 +    }
   1.239 +
   1.240      __ bind(done);
   1.241 -  } else if (code == lir_instanceof) {
   1.242 -    Register obj = op->object()->as_register();
   1.243 -    Register k_RInfo = op->tmp1()->as_register();
   1.244 -    Register klass_RInfo = op->tmp2()->as_register();
   1.245 -    Register dst = op->result_opr()->as_register();
   1.246 -    ciKlass* k = op->klass();
   1.247 -
   1.248 -    Label done;
   1.249 -    Label zero;
   1.250 -    Label one;
   1.251 -    if (obj == k_RInfo) {
   1.252 -      k_RInfo = klass_RInfo;
   1.253 -      klass_RInfo = obj;
   1.254 -    }
   1.255 -    // patching may screw with our temporaries on sparc,
   1.256 -    // so let's do it before loading the class
   1.257 -    if (!k->is_loaded()) {
   1.258 -      jobject2reg_with_patching(k_RInfo, op->info_for_patch());
   1.259 -    } else {
   1.260 -      LP64_ONLY(__ movoop(k_RInfo, k->constant_encoding()));
   1.261 -    }
   1.262 -    assert(obj != k_RInfo, "must be different");
   1.263 -
   1.264 -    __ verify_oop(obj);
   1.265 -    if (op->fast_check()) {
   1.266 -      __ cmpptr(obj, (int32_t)NULL_WORD);
   1.267 -      __ jcc(Assembler::equal, zero);
   1.268 -      // get object class
   1.269 -      // not a safepoint as obj null check happens earlier
   1.270 -      if (LP64_ONLY(false &&) k->is_loaded()) {
   1.271 -        NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()));
   1.272 -        k_RInfo = noreg;
   1.273 +  } else
   1.274 +    if (code == lir_checkcast) {
   1.275 +      Register obj = op->object()->as_register();
   1.276 +      Register dst = op->result_opr()->as_register();
   1.277 +      Label success;
   1.278 +      emit_typecheck_helper(op, &success, op->stub()->entry(), &success);
   1.279 +      __ bind(success);
   1.280 +      if (dst != obj) {
   1.281 +        __ mov(dst, obj);
   1.282 +      }
   1.283 +    } else
   1.284 +      if (code == lir_instanceof) {
   1.285 +        Register obj = op->object()->as_register();
   1.286 +        Register dst = op->result_opr()->as_register();
   1.287 +        Label success, failure, done;
   1.288 +        emit_typecheck_helper(op, &success, &failure, &failure);
   1.289 +        __ bind(failure);
   1.290 +        __ xorptr(dst, dst);
   1.291 +        __ jmpb(done);
   1.292 +        __ bind(success);
   1.293 +        __ movptr(dst, 1);
   1.294 +        __ bind(done);
   1.295        } else {
   1.296 -        __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.297 -
   1.298 +        ShouldNotReachHere();
   1.299        }
   1.300 -      __ jcc(Assembler::equal, one);
   1.301 -    } else {
   1.302 -      // get object class
   1.303 -      // not a safepoint as obj null check happens earlier
   1.304 -      __ cmpptr(obj, (int32_t)NULL_WORD);
   1.305 -      __ jcc(Assembler::equal, zero);
   1.306 -      __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   1.307 -
   1.308 -#ifndef _LP64
   1.309 -      if (k->is_loaded()) {
   1.310 -        // See if we get an immediate positive hit
   1.311 -        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
   1.312 -        __ jcc(Assembler::equal, one);
   1.313 -        if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() == k->super_check_offset()) {
   1.314 -          // check for self
   1.315 -          __ cmpoop(klass_RInfo, k->constant_encoding());
   1.316 -          __ jcc(Assembler::equal, one);
   1.317 -          __ push(klass_RInfo);
   1.318 -          __ pushoop(k->constant_encoding());
   1.319 -          __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   1.320 -          __ pop(klass_RInfo);
   1.321 -          __ pop(dst);
   1.322 -          __ jmp(done);
   1.323 -        }
   1.324 -      }
   1.325 -        else // next block is unconditional if LP64:
   1.326 -#endif // LP64
   1.327 -      {
   1.328 -        assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers");
   1.329 -
   1.330 -        // perform the fast part of the checking logic
   1.331 -        __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, dst, &one, &zero, NULL);
   1.332 -        // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   1.333 -        __ push(klass_RInfo);
   1.334 -        __ push(k_RInfo);
   1.335 -        __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   1.336 -        __ pop(klass_RInfo);
   1.337 -        __ pop(dst);
   1.338 -        __ jmp(done);
   1.339 -      }
   1.340 -    }
   1.341 -    __ bind(zero);
   1.342 -    __ xorptr(dst, dst);
   1.343 -    __ jmp(done);
   1.344 -    __ bind(one);
   1.345 -    __ movptr(dst, 1);
   1.346 -    __ bind(done);
   1.347 -  } else {
   1.348 -    ShouldNotReachHere();
   1.349 -  }
   1.350  
   1.351  }
   1.352  

mercurial