6919069: client compiler needs to capture more profile information for tiered work

Mon, 13 Sep 2010 12:10:49 -0700

author
iveresov
date
Mon, 13 Sep 2010 12:10:49 -0700
changeset 2146
3a294e483abc
parent 2145
7f9553bedfd5
child 2147
d20603ee9e10

6919069: client compiler needs to capture more profile information for tiered work
Summary: Added profiling of instanceof and aastore.
Reviewed-by: kvn, jrose, never

src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp file | annotate | diff | comparison | revisions
src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/c1_LIRAssembler_x86.cpp file | annotate | diff | comparison | revisions
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp file | annotate | diff | comparison | revisions
src/share/vm/c1/c1_Canonicalizer.cpp file | annotate | diff | comparison | revisions
src/share/vm/c1/c1_GraphBuilder.cpp file | annotate | diff | comparison | revisions
src/share/vm/c1/c1_Instruction.hpp file | annotate | diff | comparison | revisions
src/share/vm/c1/c1_LIR.cpp file | annotate | diff | comparison | revisions
src/share/vm/c1/c1_LIR.hpp file | annotate | diff | comparison | revisions
src/share/vm/c1/c1_LIRAssembler.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Sat Sep 11 15:21:37 2010 -0700
     1.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp	Mon Sep 13 12:10:49 2010 -0700
     1.3 @@ -2471,8 +2471,25 @@
     1.4    }
     1.5  }
     1.6  
     1.7 -void LIR_Assembler::emit_checkcast(LIR_OpTypeCheck *op) {
     1.8 -  assert(op->code() == lir_checkcast, "Invalid operation");
     1.9 +
    1.10 +void LIR_Assembler::setup_md_access(ciMethod* method, int bci,
    1.11 +                                    ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias) {
    1.12 +  md = method->method_data();
    1.13 +  if (md == NULL) {
    1.14 +    bailout("out of memory building methodDataOop");
    1.15 +    return;
    1.16 +  }
    1.17 +  data = md->bci_to_data(bci);
    1.18 +  assert(data != NULL,       "need data for checkcast");
    1.19 +  assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
    1.20 +  if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) {
    1.21 +    // The offset is large so bias the mdo by the base of the slot so
    1.22 +    // that the ld can use simm13s to reference the slots of the data
    1.23 +    mdo_offset_bias = md->byte_offset_of_slot(data, DataLayout::header_offset());
    1.24 +  }
    1.25 +}
    1.26 +
    1.27 +void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
    1.28    // we always need a stub for the failure case.
    1.29    CodeStub* stub = op->stub();
    1.30    Register obj = op->object()->as_register();
    1.31 @@ -2494,25 +2511,10 @@
    1.32    if (op->should_profile()) {
    1.33      ciMethod* method = op->profiled_method();
    1.34      assert(method != NULL, "Should have method");
    1.35 -    int bci          = op->profiled_bci();
    1.36 -    md = method->method_data();
    1.37 -    if (md == NULL) {
    1.38 -      bailout("out of memory building methodDataOop");
    1.39 -      return;
    1.40 -    }
    1.41 -    data = md->bci_to_data(bci);
    1.42 -    assert(data != NULL,       "need data for checkcast");
    1.43 -    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for checkcast");
    1.44 -    if (!Assembler::is_simm13(md->byte_offset_of_slot(data, DataLayout::header_offset()) + data->size_in_bytes())) {
    1.45 -      // The offset is large so bias the mdo by the base of the slot so
    1.46 -      // that the ld can use simm13s to reference the slots of the data
    1.47 -      mdo_offset_bias = md->byte_offset_of_slot(data, DataLayout::header_offset());
    1.48 -    }
    1.49 -
    1.50 -    // We need two temporaries to perform this operation on SPARC,
    1.51 -    // so to keep things simple we perform a redundant test here
    1.52 -    Label profile_done;
    1.53 -    __ br_notnull(obj, false, Assembler::pn, profile_done);
    1.54 +    setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias);
    1.55 +
    1.56 +    Label not_null;
    1.57 +    __ br_notnull(obj, false, Assembler::pn, not_null);
    1.58      __ delayed()->nop();
    1.59      Register mdo      = k_RInfo;
    1.60      Register data_val = Rtmp1;
    1.61 @@ -2525,13 +2527,17 @@
    1.62      __ ldub(flags_addr, data_val);
    1.63      __ or3(data_val, BitData::null_seen_byte_constant(), data_val);
    1.64      __ stb(data_val, flags_addr);
    1.65 -    __ bind(profile_done);
    1.66 +    __ ba(false, *obj_is_null);
    1.67 +    __ delayed()->nop();
    1.68 +    __ bind(not_null);
    1.69 +  } else {
    1.70 +    __ br_null(obj, false, Assembler::pn, *obj_is_null);
    1.71 +    __ delayed()->nop();
    1.72    }
    1.73 -  Label profile_cast_failure;
    1.74 -
    1.75 -  Label done, done_null;
    1.76 -  // Where to go in case of cast failure
    1.77 -  Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
    1.78 +
    1.79 +  Label profile_cast_failure, profile_cast_success;
    1.80 +  Label *failure_target = op->should_profile() ? &profile_cast_failure : failure;
    1.81 +  Label *success_target = op->should_profile() ? &profile_cast_success : success;
    1.82  
    1.83    // patching may screw with our temporaries on sparc,
    1.84    // so let's do it before loading the class
    1.85 @@ -2541,8 +2547,6 @@
    1.86      jobject2reg_with_patching(k_RInfo, op->info_for_patch());
    1.87    }
    1.88    assert(obj != k_RInfo, "must be different");
    1.89 -  __ br_null(obj, false, Assembler::pn, done_null);
    1.90 -  __ delayed()->nop();
    1.91  
    1.92    // get object class
    1.93    // not a safepoint as obj null check happens earlier
    1.94 @@ -2559,12 +2563,12 @@
    1.95          need_slow_path = false;
    1.96        // perform the fast part of the checking logic
    1.97        __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, noreg,
    1.98 -                                       (need_slow_path ? &done : NULL),
    1.99 +                                       (need_slow_path ? success_target : NULL),
   1.100                                         failure_target, NULL,
   1.101                                         RegisterOrConstant(k->super_check_offset()));
   1.102      } else {
   1.103        // perform the fast part of the checking logic
   1.104 -      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, &done,
   1.105 +      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target,
   1.106                                         failure_target, NULL);
   1.107      }
   1.108      if (need_slow_path) {
   1.109 @@ -2575,27 +2579,24 @@
   1.110        __ cmp(G3, 0);
   1.111        __ br(Assembler::equal, false, Assembler::pn, *failure_target);
   1.112        __ delayed()->nop();
   1.113 +      // Fall through to success case
   1.114      }
   1.115    }
   1.116 -  __ bind(done);
   1.117  
   1.118    if (op->should_profile()) {
   1.119      Register mdo  = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1;
   1.120      assert_different_registers(obj, mdo, recv, tmp1);
   1.121 -
   1.122 +    __ bind(profile_cast_success);
   1.123      jobject2reg(md->constant_encoding(), mdo);
   1.124      if (mdo_offset_bias > 0) {
   1.125        __ set(mdo_offset_bias, tmp1);
   1.126        __ add(mdo, tmp1, mdo);
   1.127      }
   1.128 -    Label update_done;
   1.129      load(Address(obj, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT);
   1.130 -    type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &update_done);
   1.131 +    type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, success);
   1.132      // Jump over the failure case
   1.133 -    __ ba(false, update_done);
   1.134 +    __ ba(false, *success);
   1.135      __ delayed()->nop();
   1.136 -
   1.137 -
   1.138      // Cast failure case
   1.139      __ bind(profile_cast_failure);
   1.140      jobject2reg(md->constant_encoding(), mdo);
   1.141 @@ -2607,17 +2608,13 @@
   1.142      __ ld_ptr(data_addr, tmp1);
   1.143      __ sub(tmp1, DataLayout::counter_increment, tmp1);
   1.144      __ st_ptr(tmp1, data_addr);
   1.145 -    __ ba(false, *stub->entry());
   1.146 +    __ ba(false, *failure);
   1.147      __ delayed()->nop();
   1.148 -
   1.149 -    __ bind(update_done);
   1.150    }
   1.151 -
   1.152 -  __ bind(done_null);
   1.153 -  __ mov(obj, dst);
   1.154 +  __ ba(false, *success);
   1.155 +  __ delayed()->nop();
   1.156  }
   1.157  
   1.158 -
   1.159  void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
   1.160    LIR_Code code = op->code();
   1.161    if (code == lir_store_check) {
   1.162 @@ -2628,88 +2625,106 @@
   1.163      Register Rtmp1 = op->tmp3()->as_register();
   1.164  
   1.165      __ verify_oop(value);
   1.166 -
   1.167      CodeStub* stub = op->stub();
   1.168 -    Label done;
   1.169 -    __ br_null(value, false, Assembler::pn, done);
   1.170 -    __ delayed()->nop();
   1.171 +    // check if it needs to be profiled
   1.172 +    ciMethodData* md;
   1.173 +    ciProfileData* data;
   1.174 +    int mdo_offset_bias = 0;
   1.175 +    if (op->should_profile()) {
   1.176 +      ciMethod* method = op->profiled_method();
   1.177 +      assert(method != NULL, "Should have method");
   1.178 +      setup_md_access(method, op->profiled_bci(), md, data, mdo_offset_bias);
   1.179 +    }
   1.180 +    Label profile_cast_success, profile_cast_failure, done;
   1.181 +    Label *success_target = op->should_profile() ? &profile_cast_success : &done;
   1.182 +    Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
   1.183 +
   1.184 +    if (op->should_profile()) {
   1.185 +      Label not_null;
   1.186 +      __ br_notnull(value, false, Assembler::pn, not_null);
   1.187 +      __ delayed()->nop();
   1.188 +      Register mdo      = k_RInfo;
   1.189 +      Register data_val = Rtmp1;
   1.190 +      jobject2reg(md->constant_encoding(), mdo);
   1.191 +      if (mdo_offset_bias > 0) {
   1.192 +        __ set(mdo_offset_bias, data_val);
   1.193 +        __ add(mdo, data_val, mdo);
   1.194 +      }
   1.195 +      Address flags_addr(mdo, md->byte_offset_of_slot(data, DataLayout::flags_offset()) - mdo_offset_bias);
   1.196 +      __ ldub(flags_addr, data_val);
   1.197 +      __ or3(data_val, BitData::null_seen_byte_constant(), data_val);
   1.198 +      __ stb(data_val, flags_addr);
   1.199 +      __ ba(false, done);
   1.200 +      __ delayed()->nop();
   1.201 +      __ bind(not_null);
   1.202 +    } else {
   1.203 +      __ br_null(value, false, Assembler::pn, done);
   1.204 +      __ delayed()->nop();
   1.205 +    }
   1.206      load(array, oopDesc::klass_offset_in_bytes(), k_RInfo, T_OBJECT, op->info_for_exception());
   1.207      load(value, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL);
   1.208  
   1.209      // get instance klass
   1.210      load(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc), k_RInfo, T_OBJECT, NULL);
   1.211      // perform the fast part of the checking logic
   1.212 -    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, &done, stub->entry(), NULL);
   1.213 +    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, O7, success_target, failure_target, NULL);
   1.214  
   1.215      // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   1.216      assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup");
   1.217      __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
   1.218      __ delayed()->nop();
   1.219      __ cmp(G3, 0);
   1.220 -    __ br(Assembler::equal, false, Assembler::pn, *stub->entry());
   1.221 +    __ br(Assembler::equal, false, Assembler::pn, *failure_target);
   1.222      __ delayed()->nop();
   1.223 +    // fall through to the success case
   1.224 +
   1.225 +    if (op->should_profile()) {
   1.226 +      Register mdo  = klass_RInfo, recv = k_RInfo, tmp1 = Rtmp1;
   1.227 +      assert_different_registers(value, mdo, recv, tmp1);
   1.228 +      __ bind(profile_cast_success);
   1.229 +      jobject2reg(md->constant_encoding(), mdo);
   1.230 +      if (mdo_offset_bias > 0) {
   1.231 +        __ set(mdo_offset_bias, tmp1);
   1.232 +        __ add(mdo, tmp1, mdo);
   1.233 +      }
   1.234 +      load(Address(value, oopDesc::klass_offset_in_bytes()), recv, T_OBJECT);
   1.235 +      type_profile_helper(mdo, mdo_offset_bias, md, data, recv, tmp1, &done);
   1.236 +      __ ba(false, done);
   1.237 +      __ delayed()->nop();
   1.238 +      // Cast failure case
   1.239 +      __ bind(profile_cast_failure);
   1.240 +      jobject2reg(md->constant_encoding(), mdo);
   1.241 +      if (mdo_offset_bias > 0) {
   1.242 +        __ set(mdo_offset_bias, tmp1);
   1.243 +        __ add(mdo, tmp1, mdo);
   1.244 +      }
   1.245 +      Address data_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
   1.246 +      __ ld_ptr(data_addr, tmp1);
   1.247 +      __ sub(tmp1, DataLayout::counter_increment, tmp1);
   1.248 +      __ st_ptr(tmp1, data_addr);
   1.249 +      __ ba(false, *stub->entry());
   1.250 +      __ delayed()->nop();
   1.251 +    }
   1.252      __ bind(done);
   1.253 +  } else if (code == lir_checkcast) {
   1.254 +    Register obj = op->object()->as_register();
   1.255 +    Register dst = op->result_opr()->as_register();
   1.256 +    Label success;
   1.257 +    emit_typecheck_helper(op, &success, op->stub()->entry(), &success);
   1.258 +    __ bind(success);
   1.259 +    __ mov(obj, dst);
   1.260    } else if (code == lir_instanceof) {
   1.261      Register obj = op->object()->as_register();
   1.262 -    Register k_RInfo = op->tmp1()->as_register();
   1.263 -    Register klass_RInfo = op->tmp2()->as_register();
   1.264      Register dst = op->result_opr()->as_register();
   1.265 -    Register Rtmp1 = op->tmp3()->as_register();
   1.266 -    ciKlass* k = op->klass();
   1.267 -
   1.268 -    Label done;
   1.269 -    if (obj == k_RInfo) {
   1.270 -      k_RInfo = klass_RInfo;
   1.271 -      klass_RInfo = obj;
   1.272 -    }
   1.273 -    // patching may screw with our temporaries on sparc,
   1.274 -    // so let's do it before loading the class
   1.275 -    if (k->is_loaded()) {
   1.276 -      jobject2reg(k->constant_encoding(), k_RInfo);
   1.277 -    } else {
   1.278 -      jobject2reg_with_patching(k_RInfo, op->info_for_patch());
   1.279 -    }
   1.280 -    assert(obj != k_RInfo, "must be different");
   1.281 -    __ br_null(obj, true, Assembler::pn, done);
   1.282 -    __ delayed()->set(0, dst);
   1.283 -
   1.284 -    // get object class
   1.285 -    // not a safepoint as obj null check happens earlier
   1.286 -    load(obj, oopDesc::klass_offset_in_bytes(), klass_RInfo, T_OBJECT, NULL);
   1.287 -    if (op->fast_check()) {
   1.288 -      __ cmp(k_RInfo, klass_RInfo);
   1.289 -      __ brx(Assembler::equal, true, Assembler::pt, done);
   1.290 -      __ delayed()->set(1, dst);
   1.291 -      __ set(0, dst);
   1.292 -      __ bind(done);
   1.293 -    } else {
   1.294 -      bool need_slow_path = true;
   1.295 -      if (k->is_loaded()) {
   1.296 -        if (k->super_check_offset() != sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())
   1.297 -          need_slow_path = false;
   1.298 -        // perform the fast part of the checking logic
   1.299 -        __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, noreg,
   1.300 -                                         (need_slow_path ? &done : NULL),
   1.301 -                                         (need_slow_path ? &done : NULL), NULL,
   1.302 -                                         RegisterOrConstant(k->super_check_offset()),
   1.303 -                                         dst);
   1.304 -      } else {
   1.305 -        assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers");
   1.306 -        // perform the fast part of the checking logic
   1.307 -        __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, O7, dst,
   1.308 -                                         &done, &done, NULL,
   1.309 -                                         RegisterOrConstant(-1),
   1.310 -                                         dst);
   1.311 -      }
   1.312 -      if (need_slow_path) {
   1.313 -        // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   1.314 -        assert(klass_RInfo == G3 && k_RInfo == G1, "incorrect call setup");
   1.315 -        __ call(Runtime1::entry_for(Runtime1::slow_subtype_check_id), relocInfo::runtime_call_type);
   1.316 -        __ delayed()->nop();
   1.317 -        __ mov(G3, dst);
   1.318 -      }
   1.319 -      __ bind(done);
   1.320 -    }
   1.321 +    Label success, failure, done;
   1.322 +    emit_typecheck_helper(op, &success, &failure, &failure);
   1.323 +    __ bind(failure);
   1.324 +    __ set(0, dst);
   1.325 +    __ ba(false, done);
   1.326 +    __ delayed()->nop();
   1.327 +    __ bind(success);
   1.328 +    __ set(1, dst);
   1.329 +    __ bind(done);
   1.330    } else {
   1.331      ShouldNotReachHere();
   1.332    }
     2.1 --- a/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp	Sat Sep 11 15:21:37 2010 -0700
     2.2 +++ b/src/cpu/sparc/vm/c1_LIRAssembler_sparc.hpp	Mon Sep 13 12:10:49 2010 -0700
     2.3 @@ -75,6 +75,9 @@
     2.4    void type_profile_helper(Register mdo, int mdo_offset_bias,
     2.5                             ciMethodData *md, ciProfileData *data,
     2.6                             Register recv, Register tmp1, Label* update_done);
     2.7 +  // Setup pointers to MDO, MDO slot, also compute offset bias to access the slot.
     2.8 +  void setup_md_access(ciMethod* method, int bci,
     2.9 +                       ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias);
    2.10   public:
    2.11    void   pack64(LIR_Opr src, LIR_Opr dst);
    2.12    void unpack64(LIR_Opr src, LIR_Opr dst);
     3.1 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Sat Sep 11 15:21:37 2010 -0700
     3.2 +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp	Mon Sep 13 12:10:49 2010 -0700
     3.3 @@ -1047,7 +1047,9 @@
     3.4    LIR_Opr tmp1 = FrameMap::G1_oop_opr;
     3.5    LIR_Opr tmp2 = FrameMap::G3_oop_opr;
     3.6    LIR_Opr tmp3 = FrameMap::G4_oop_opr;
     3.7 -  __ instanceof(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3,  x->direct_compare(), patching_info);
     3.8 +  __ instanceof(out_reg, obj.result(), x->klass(), tmp1, tmp2, tmp3,
     3.9 +                x->direct_compare(), patching_info,
    3.10 +                x->profiled_method(), x->profiled_bci());
    3.11  }
    3.12  
    3.13  
     4.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Sat Sep 11 15:21:37 2010 -0700
     4.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	Mon Sep 13 12:10:49 2010 -0700
     4.3 @@ -1624,7 +1624,7 @@
     4.4      __ jccb(Assembler::notEqual, next_test);
     4.5      Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)));
     4.6      __ addptr(data_addr, DataLayout::counter_increment);
     4.7 -    __ jmpb(*update_done);
     4.8 +    __ jmp(*update_done);
     4.9      __ bind(next_test);
    4.10    }
    4.11  
    4.12 @@ -1636,13 +1636,12 @@
    4.13      __ jccb(Assembler::notEqual, next_test);
    4.14      __ movptr(recv_addr, recv);
    4.15      __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment);
    4.16 -    __ jmpb(*update_done);
    4.17 +    __ jmp(*update_done);
    4.18      __ bind(next_test);
    4.19    }
    4.20  }
    4.21  
    4.22 -void LIR_Assembler::emit_checkcast(LIR_OpTypeCheck *op) {
    4.23 -  assert(op->code() == lir_checkcast, "Invalid operation");
    4.24 +void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
    4.25    // we always need a stub for the failure case.
    4.26    CodeStub* stub = op->stub();
    4.27    Register obj = op->object()->as_register();
    4.28 @@ -1666,14 +1665,12 @@
    4.29        return;
    4.30      }
    4.31      data = md->bci_to_data(bci);
    4.32 -    assert(data != NULL,                "need data for checkcast");
    4.33 -    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for checkcast");
    4.34 +    assert(data != NULL,                "need data for type check");
    4.35 +    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
    4.36    }
    4.37 -  Label profile_cast_failure;
    4.38 -
    4.39 -  Label done, done_null;
    4.40 -  // Where to go in case of cast failure
    4.41 -  Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
    4.42 +  Label profile_cast_success, profile_cast_failure;
    4.43 +  Label *success_target = op->should_profile() ? &profile_cast_success : success;
    4.44 +  Label *failure_target = op->should_profile() ? &profile_cast_failure : failure;
    4.45  
    4.46    if (obj == k_RInfo) {
    4.47      k_RInfo = dst;
    4.48 @@ -1699,23 +1696,23 @@
    4.49  
    4.50    __ cmpptr(obj, (int32_t)NULL_WORD);
    4.51    if (op->should_profile()) {
    4.52 -    Label profile_done;
    4.53 -    __ jccb(Assembler::notEqual, profile_done);
    4.54 -    // Object is null; update methodDataOop
    4.55 +    Label not_null;
    4.56 +    __ jccb(Assembler::notEqual, not_null);
    4.57 +    // Object is null; update MDO and exit
    4.58      Register mdo  = klass_RInfo;
    4.59      __ movoop(mdo, md->constant_encoding());
    4.60      Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
    4.61      int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
    4.62      __ orl(data_addr, header_bits);
    4.63 -    __ jmp(done_null);
    4.64 -    __ bind(profile_done);
    4.65 +    __ jmp(*obj_is_null);
    4.66 +    __ bind(not_null);
    4.67    } else {
    4.68 -    __ jcc(Assembler::equal, done_null);
    4.69 +    __ jcc(Assembler::equal, *obj_is_null);
    4.70    }
    4.71    __ verify_oop(obj);
    4.72  
    4.73    if (op->fast_check()) {
    4.74 -    // get object classo
    4.75 +    // get object class
    4.76      // not a safepoint as obj null check happens earlier
    4.77      if (k->is_loaded()) {
    4.78  #ifdef _LP64
    4.79 @@ -1727,6 +1724,7 @@
    4.80        __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
    4.81      }
    4.82      __ jcc(Assembler::notEqual, *failure_target);
    4.83 +    // successful cast, fall through to profile or jump
    4.84    } else {
    4.85      // get object class
    4.86      // not a safepoint as obj null check happens earlier
    4.87 @@ -1740,16 +1738,17 @@
    4.88  #endif // _LP64
    4.89        if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) {
    4.90          __ jcc(Assembler::notEqual, *failure_target);
    4.91 +        // successful cast, fall through to profile or jump
    4.92        } else {
    4.93          // See if we get an immediate positive hit
    4.94 -        __ jcc(Assembler::equal, done);
    4.95 +        __ jcc(Assembler::equal, *success_target);
    4.96          // check for self
    4.97  #ifdef _LP64
    4.98          __ cmpptr(klass_RInfo, k_RInfo);
    4.99  #else
   4.100          __ cmpoop(klass_RInfo, k->constant_encoding());
   4.101  #endif // _LP64
   4.102 -        __ jcc(Assembler::equal, done);
   4.103 +        __ jcc(Assembler::equal, *success_target);
   4.104  
   4.105          __ push(klass_RInfo);
   4.106  #ifdef _LP64
   4.107 @@ -1763,10 +1762,11 @@
   4.108          // result is a boolean
   4.109          __ cmpl(klass_RInfo, 0);
   4.110          __ jcc(Assembler::equal, *failure_target);
   4.111 +        // successful cast, fall through to profile or jump
   4.112        }
   4.113      } else {
   4.114        // perform the fast part of the checking logic
   4.115 -      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, failure_target, NULL);
   4.116 +      __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
   4.117        // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   4.118        __ push(klass_RInfo);
   4.119        __ push(k_RInfo);
   4.120 @@ -1776,32 +1776,28 @@
   4.121        // result is a boolean
   4.122        __ cmpl(k_RInfo, 0);
   4.123        __ jcc(Assembler::equal, *failure_target);
   4.124 +      // successful cast, fall through to profile or jump
   4.125      }
   4.126    }
   4.127 -  __ bind(done);
   4.128 -
   4.129    if (op->should_profile()) {
   4.130      Register mdo  = klass_RInfo, recv = k_RInfo;
   4.131 +    __ bind(profile_cast_success);
   4.132      __ movoop(mdo, md->constant_encoding());
   4.133      __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes()));
   4.134      Label update_done;
   4.135 -    type_profile_helper(mdo, md, data, recv, &update_done);
   4.136 -    __ jmpb(update_done);
   4.137 +    type_profile_helper(mdo, md, data, recv, success);
   4.138 +    __ jmp(*success);
   4.139  
   4.140      __ bind(profile_cast_failure);
   4.141      __ movoop(mdo, md->constant_encoding());
   4.142      Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
   4.143      __ subptr(counter_addr, DataLayout::counter_increment);
   4.144 -    __ jmp(*stub->entry());
   4.145 -
   4.146 -    __ bind(update_done);
   4.147 +    __ jmp(*failure);
   4.148    }
   4.149 -  __ bind(done_null);
   4.150 -  if (dst != obj) {
   4.151 -    __ mov(dst, obj);
   4.152 -  }
   4.153 +  __ jmp(*success);
   4.154  }
   4.155  
   4.156 +
   4.157  void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
   4.158    LIR_Code code = op->code();
   4.159    if (code == lir_store_check) {
   4.160 @@ -1812,9 +1808,44 @@
   4.161      Register Rtmp1 = op->tmp3()->as_register();
   4.162  
   4.163      CodeStub* stub = op->stub();
   4.164 -    Label done;
   4.165 +
   4.166 +    // check if it needs to be profiled
   4.167 +    ciMethodData* md;
   4.168 +    ciProfileData* data;
   4.169 +
   4.170 +    if (op->should_profile()) {
   4.171 +      ciMethod* method = op->profiled_method();
   4.172 +      assert(method != NULL, "Should have method");
   4.173 +      int bci = op->profiled_bci();
   4.174 +      md = method->method_data();
   4.175 +      if (md == NULL) {
   4.176 +        bailout("out of memory building methodDataOop");
   4.177 +        return;
   4.178 +      }
   4.179 +      data = md->bci_to_data(bci);
   4.180 +      assert(data != NULL,                "need data for type check");
   4.181 +      assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
   4.182 +    }
   4.183 +    Label profile_cast_success, profile_cast_failure, done;
   4.184 +    Label *success_target = op->should_profile() ? &profile_cast_success : &done;
   4.185 +    Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
   4.186 +
   4.187      __ cmpptr(value, (int32_t)NULL_WORD);
   4.188 -    __ jcc(Assembler::equal, done);
   4.189 +    if (op->should_profile()) {
   4.190 +      Label not_null;
   4.191 +      __ jccb(Assembler::notEqual, not_null);
   4.192 +      // Object is null; update MDO and exit
   4.193 +      Register mdo  = klass_RInfo;
   4.194 +      __ movoop(mdo, md->constant_encoding());
   4.195 +      Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
   4.196 +      int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
   4.197 +      __ orl(data_addr, header_bits);
   4.198 +      __ jmp(done);
   4.199 +      __ bind(not_null);
   4.200 +    } else {
   4.201 +      __ jcc(Assembler::equal, done);
   4.202 +    }
   4.203 +
   4.204      add_debug_info_for_null_check_here(op->info_for_exception());
   4.205      __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes()));
   4.206      __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes()));
   4.207 @@ -1822,7 +1853,7 @@
   4.208      // get instance klass
   4.209      __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc)));
   4.210      // perform the fast part of the checking logic
   4.211 -    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, stub->entry(), NULL);
   4.212 +    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
   4.213      // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   4.214      __ push(klass_RInfo);
   4.215      __ push(k_RInfo);
   4.216 @@ -1831,94 +1862,51 @@
   4.217      __ pop(k_RInfo);
   4.218      // result is a boolean
   4.219      __ cmpl(k_RInfo, 0);
   4.220 -    __ jcc(Assembler::equal, *stub->entry());
   4.221 +    __ jcc(Assembler::equal, *failure_target);
   4.222 +    // fall through to the success case
   4.223 +
   4.224 +    if (op->should_profile()) {
   4.225 +      Register mdo  = klass_RInfo, recv = k_RInfo;
   4.226 +      __ bind(profile_cast_success);
   4.227 +      __ movoop(mdo, md->constant_encoding());
   4.228 +      __ movptr(recv, Address(value, oopDesc::klass_offset_in_bytes()));
   4.229 +      Label update_done;
   4.230 +      type_profile_helper(mdo, md, data, recv, &done);
   4.231 +      __ jmpb(done);
   4.232 +
   4.233 +      __ bind(profile_cast_failure);
   4.234 +      __ movoop(mdo, md->constant_encoding());
   4.235 +      Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
   4.236 +      __ subptr(counter_addr, DataLayout::counter_increment);
   4.237 +      __ jmp(*stub->entry());
   4.238 +    }
   4.239 +
   4.240      __ bind(done);
   4.241 -  } else if (code == lir_instanceof) {
   4.242 -    Register obj = op->object()->as_register();
   4.243 -    Register k_RInfo = op->tmp1()->as_register();
   4.244 -    Register klass_RInfo = op->tmp2()->as_register();
   4.245 -    Register dst = op->result_opr()->as_register();
   4.246 -    ciKlass* k = op->klass();
   4.247 -
   4.248 -    Label done;
   4.249 -    Label zero;
   4.250 -    Label one;
   4.251 -    if (obj == k_RInfo) {
   4.252 -      k_RInfo = klass_RInfo;
   4.253 -      klass_RInfo = obj;
   4.254 -    }
   4.255 -    // patching may screw with our temporaries on sparc,
   4.256 -    // so let's do it before loading the class
   4.257 -    if (!k->is_loaded()) {
   4.258 -      jobject2reg_with_patching(k_RInfo, op->info_for_patch());
   4.259 -    } else {
   4.260 -      LP64_ONLY(__ movoop(k_RInfo, k->constant_encoding()));
   4.261 -    }
   4.262 -    assert(obj != k_RInfo, "must be different");
   4.263 -
   4.264 -    __ verify_oop(obj);
   4.265 -    if (op->fast_check()) {
   4.266 -      __ cmpptr(obj, (int32_t)NULL_WORD);
   4.267 -      __ jcc(Assembler::equal, zero);
   4.268 -      // get object class
   4.269 -      // not a safepoint as obj null check happens earlier
   4.270 -      if (LP64_ONLY(false &&) k->is_loaded()) {
   4.271 -        NOT_LP64(__ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()));
   4.272 -        k_RInfo = noreg;
   4.273 +  } else
   4.274 +    if (code == lir_checkcast) {
   4.275 +      Register obj = op->object()->as_register();
   4.276 +      Register dst = op->result_opr()->as_register();
   4.277 +      Label success;
   4.278 +      emit_typecheck_helper(op, &success, op->stub()->entry(), &success);
   4.279 +      __ bind(success);
   4.280 +      if (dst != obj) {
   4.281 +        __ mov(dst, obj);
   4.282 +      }
   4.283 +    } else
   4.284 +      if (code == lir_instanceof) {
   4.285 +        Register obj = op->object()->as_register();
   4.286 +        Register dst = op->result_opr()->as_register();
   4.287 +        Label success, failure, done;
   4.288 +        emit_typecheck_helper(op, &success, &failure, &failure);
   4.289 +        __ bind(failure);
   4.290 +        __ xorptr(dst, dst);
   4.291 +        __ jmpb(done);
   4.292 +        __ bind(success);
   4.293 +        __ movptr(dst, 1);
   4.294 +        __ bind(done);
   4.295        } else {
   4.296 -        __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   4.297 -
   4.298 +        ShouldNotReachHere();
   4.299        }
   4.300 -      __ jcc(Assembler::equal, one);
   4.301 -    } else {
   4.302 -      // get object class
   4.303 -      // not a safepoint as obj null check happens earlier
   4.304 -      __ cmpptr(obj, (int32_t)NULL_WORD);
   4.305 -      __ jcc(Assembler::equal, zero);
   4.306 -      __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
   4.307 -
   4.308 -#ifndef _LP64
   4.309 -      if (k->is_loaded()) {
   4.310 -        // See if we get an immediate positive hit
   4.311 -        __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding());
   4.312 -        __ jcc(Assembler::equal, one);
   4.313 -        if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() == k->super_check_offset()) {
   4.314 -          // check for self
   4.315 -          __ cmpoop(klass_RInfo, k->constant_encoding());
   4.316 -          __ jcc(Assembler::equal, one);
   4.317 -          __ push(klass_RInfo);
   4.318 -          __ pushoop(k->constant_encoding());
   4.319 -          __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   4.320 -          __ pop(klass_RInfo);
   4.321 -          __ pop(dst);
   4.322 -          __ jmp(done);
   4.323 -        }
   4.324 -      }
   4.325 -        else // next block is unconditional if LP64:
   4.326 -#endif // LP64
   4.327 -      {
   4.328 -        assert(dst != klass_RInfo && dst != k_RInfo, "need 3 registers");
   4.329 -
   4.330 -        // perform the fast part of the checking logic
   4.331 -        __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, dst, &one, &zero, NULL);
   4.332 -        // call out-of-line instance of __ check_klass_subtype_slow_path(...):
   4.333 -        __ push(klass_RInfo);
   4.334 -        __ push(k_RInfo);
   4.335 -        __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id)));
   4.336 -        __ pop(klass_RInfo);
   4.337 -        __ pop(dst);
   4.338 -        __ jmp(done);
   4.339 -      }
   4.340 -    }
   4.341 -    __ bind(zero);
   4.342 -    __ xorptr(dst, dst);
   4.343 -    __ jmp(done);
   4.344 -    __ bind(one);
   4.345 -    __ movptr(dst, 1);
   4.346 -    __ bind(done);
   4.347 -  } else {
   4.348 -    ShouldNotReachHere();
   4.349 -  }
   4.350  
   4.351  }
   4.352  
     5.1 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Sat Sep 11 15:21:37 2010 -0700
     5.2 +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp	Mon Sep 13 12:10:49 2010 -0700
     5.3 @@ -1156,10 +1156,10 @@
     5.4      patching_info = state_for(x, x->state_before());
     5.5    }
     5.6    obj.load_item();
     5.7 -  LIR_Opr tmp = new_register(objectType);
     5.8    __ instanceof(reg, obj.result(), x->klass(),
     5.9 -                tmp, new_register(objectType), LIR_OprFact::illegalOpr,
    5.10 -                x->direct_compare(), patching_info);
    5.11 +                new_register(objectType), new_register(objectType),
    5.12 +                !x->klass()->is_loaded() ? new_register(objectType) : LIR_OprFact::illegalOpr,
    5.13 +                x->direct_compare(), patching_info, x->profiled_method(), x->profiled_bci());
    5.14  }
    5.15  
    5.16  
     6.1 --- a/src/share/vm/c1/c1_Canonicalizer.cpp	Sat Sep 11 15:21:37 2010 -0700
     6.2 +++ b/src/share/vm/c1/c1_Canonicalizer.cpp	Mon Sep 13 12:10:49 2010 -0700
     6.3 @@ -673,6 +673,8 @@
     6.4      } else if (l->as_InstanceOf() != NULL) {
     6.5        // NOTE: Code permanently disabled for now since it leaves the old InstanceOf
     6.6        //       instruction in the graph (it is pinned). Need to fix this at some point.
     6.7 +      //       It should also be left in the graph when generating a profiled method version or Goto
     6.8 +      //       has to know that it was an InstanceOf.
     6.9        return;
    6.10        // pattern: If ((obj instanceof klass) cond rc) => simplify to: IfInstanceOf or: Goto
    6.11        InstanceOf* inst = l->as_InstanceOf();
     7.1 --- a/src/share/vm/c1/c1_GraphBuilder.cpp	Sat Sep 11 15:21:37 2010 -0700
     7.2 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp	Mon Sep 13 12:10:49 2010 -0700
     7.3 @@ -967,6 +967,17 @@
     7.4    StoreIndexed* result = new StoreIndexed(array, index, length, type, value, lock_stack());
     7.5    append(result);
     7.6    _memory->store_value(value);
     7.7 +
     7.8 +  if (type == T_OBJECT && is_profiling()) {
     7.9 +    // Note that we'd collect profile data in this method if we wanted it.
    7.10 +    compilation()->set_would_profile(true);
    7.11 +
    7.12 +    if (profile_checkcasts()) {
    7.13 +      result->set_profiled_method(method());
    7.14 +      result->set_profiled_bci(bci());
    7.15 +      result->set_should_profile(true);
    7.16 +    }
    7.17 +  }
    7.18  }
    7.19  
    7.20  
    7.21 @@ -1852,6 +1863,17 @@
    7.22    InstanceOf* i = new InstanceOf(klass, apop(), state_before);
    7.23    ipush(append_split(i));
    7.24    i->set_direct_compare(direct_compare(klass));
    7.25 +
    7.26 +  if (is_profiling()) {
    7.27 +    // Note that we'd collect profile data in this method if we wanted it.
    7.28 +    compilation()->set_would_profile(true);
    7.29 +
    7.30 +    if (profile_checkcasts()) {
    7.31 +      i->set_profiled_method(method());
    7.32 +      i->set_profiled_bci(bci());
    7.33 +      i->set_should_profile(true);
    7.34 +    }
    7.35 +  }
    7.36  }
    7.37  
    7.38  
     8.1 --- a/src/share/vm/c1/c1_Instruction.hpp	Sat Sep 11 15:21:37 2010 -0700
     8.2 +++ b/src/share/vm/c1/c1_Instruction.hpp	Mon Sep 13 12:10:49 2010 -0700
     8.3 @@ -906,11 +906,13 @@
     8.4   private:
     8.5    Value       _value;
     8.6  
     8.7 +  ciMethod* _profiled_method;
     8.8 +  int       _profiled_bci;
     8.9   public:
    8.10    // creation
    8.11    StoreIndexed(Value array, Value index, Value length, BasicType elt_type, Value value, ValueStack* lock_stack)
    8.12    : AccessIndexed(array, index, length, elt_type, lock_stack)
    8.13 -  , _value(value)
    8.14 +  , _value(value), _profiled_method(NULL), _profiled_bci(0)
    8.15    {
    8.16      set_flag(NeedsWriteBarrierFlag, (as_ValueType(elt_type)->is_object()));
    8.17      set_flag(NeedsStoreCheckFlag, (as_ValueType(elt_type)->is_object()));
    8.18 @@ -923,7 +925,13 @@
    8.19    IRScope* scope() const;                        // the state's scope
    8.20    bool needs_write_barrier() const               { return check_flag(NeedsWriteBarrierFlag); }
    8.21    bool needs_store_check() const                 { return check_flag(NeedsStoreCheckFlag); }
    8.22 -
    8.23 +  // Helpers for methodDataOop profiling
    8.24 +  void set_should_profile(bool value)                { set_flag(ProfileMDOFlag, value); }
    8.25 +  void set_profiled_method(ciMethod* method)         { _profiled_method = method;   }
    8.26 +  void set_profiled_bci(int bci)                     { _profiled_bci = bci;         }
    8.27 +  bool      should_profile() const                   { return check_flag(ProfileMDOFlag); }
    8.28 +  ciMethod* profiled_method() const                  { return _profiled_method;     }
    8.29 +  int       profiled_bci() const                     { return _profiled_bci;        }
    8.30    // generic
    8.31    virtual void input_values_do(ValueVisitor* f)   { AccessIndexed::input_values_do(f); f->visit(&_value); }
    8.32  };
    8.33 @@ -1297,9 +1305,14 @@
    8.34    Value       _obj;
    8.35    ValueStack* _state_before;
    8.36  
    8.37 +  ciMethod* _profiled_method;
    8.38 +  int       _profiled_bci;
    8.39 +
    8.40   public:
    8.41    // creation
    8.42 -  TypeCheck(ciKlass* klass, Value obj, ValueType* type, ValueStack* state_before) : StateSplit(type), _klass(klass), _obj(obj), _state_before(state_before) {
    8.43 +  TypeCheck(ciKlass* klass, Value obj, ValueType* type, ValueStack* state_before)
    8.44 +  : StateSplit(type), _klass(klass), _obj(obj), _state_before(state_before),
    8.45 +    _profiled_method(NULL), _profiled_bci(0) {
    8.46      ASSERT_VALUES
    8.47      set_direct_compare(false);
    8.48    }
    8.49 @@ -1318,20 +1331,22 @@
    8.50    virtual bool can_trap() const                  { return true; }
    8.51    virtual void input_values_do(ValueVisitor* f)   { StateSplit::input_values_do(f); f->visit(&_obj); }
    8.52    virtual void other_values_do(ValueVisitor* f);
    8.53 +
    8.54 +  // Helpers for methodDataOop profiling
    8.55 +  void set_should_profile(bool value)                { set_flag(ProfileMDOFlag, value); }
    8.56 +  void set_profiled_method(ciMethod* method)         { _profiled_method = method;   }
    8.57 +  void set_profiled_bci(int bci)                     { _profiled_bci = bci;         }
    8.58 +  bool      should_profile() const                   { return check_flag(ProfileMDOFlag); }
    8.59 +  ciMethod* profiled_method() const                  { return _profiled_method;     }
    8.60 +  int       profiled_bci() const                     { return _profiled_bci;        }
    8.61  };
    8.62  
    8.63  
    8.64  LEAF(CheckCast, TypeCheck)
    8.65 - private:
    8.66 -  ciMethod* _profiled_method;
    8.67 -  int       _profiled_bci;
    8.68 -
    8.69   public:
    8.70    // creation
    8.71    CheckCast(ciKlass* klass, Value obj, ValueStack* state_before)
    8.72 -  : TypeCheck(klass, obj, objectType, state_before)
    8.73 -  , _profiled_method(NULL)
    8.74 -  , _profiled_bci(0) {}
    8.75 +  : TypeCheck(klass, obj, objectType, state_before) {}
    8.76  
    8.77    void set_incompatible_class_change_check() {
    8.78      set_flag(ThrowIncompatibleClassChangeErrorFlag, true);
    8.79 @@ -1340,17 +1355,8 @@
    8.80      return check_flag(ThrowIncompatibleClassChangeErrorFlag);
    8.81    }
    8.82  
    8.83 -  // Helpers for methodDataOop profiling
    8.84 -  void set_should_profile(bool value)                { set_flag(ProfileMDOFlag, value); }
    8.85 -  void set_profiled_method(ciMethod* method)         { _profiled_method = method;   }
    8.86 -  void set_profiled_bci(int bci)                     { _profiled_bci = bci;         }
    8.87 -  bool      should_profile() const                   { return check_flag(ProfileMDOFlag); }
    8.88 -  ciMethod* profiled_method() const                  { return _profiled_method;     }
    8.89 -  int       profiled_bci() const                     { return _profiled_bci;        }
    8.90 -
    8.91    ciType* declared_type() const;
    8.92    ciType* exact_type() const;
    8.93 -
    8.94  };
    8.95  
    8.96  
     9.1 --- a/src/share/vm/c1/c1_LIR.cpp	Sat Sep 11 15:21:37 2010 -0700
     9.2 +++ b/src/share/vm/c1/c1_LIR.cpp	Mon Sep 13 12:10:49 2010 -0700
     9.3 @@ -1019,11 +1019,7 @@
     9.4  }
     9.5  
     9.6  void LIR_OpTypeCheck::emit_code(LIR_Assembler* masm) {
     9.7 -  if (code() == lir_checkcast) {
     9.8 -    masm->emit_checkcast(this);
     9.9 -  } else {
    9.10 -    masm->emit_opTypeCheck(this);
    9.11 -  }
    9.12 +  masm->emit_opTypeCheck(this);
    9.13    if (stub()) {
    9.14      masm->emit_code_stub(stub());
    9.15    }
    9.16 @@ -1380,8 +1376,14 @@
    9.17    append(c);
    9.18  }
    9.19  
    9.20 -void LIR_List::instanceof(LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, CodeEmitInfo* info_for_patch) {
    9.21 -  append(new LIR_OpTypeCheck(lir_instanceof, result, object, klass, tmp1, tmp2, tmp3, fast_check, NULL, info_for_patch, NULL));
    9.22 +void LIR_List::instanceof(LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, CodeEmitInfo* info_for_patch, ciMethod* profiled_method, int profiled_bci) {
    9.23 +  LIR_OpTypeCheck* c = new LIR_OpTypeCheck(lir_instanceof, result, object, klass, tmp1, tmp2, tmp3, fast_check, NULL, info_for_patch, NULL);
    9.24 +  if (profiled_method != NULL) {
    9.25 +    c->set_profiled_method(profiled_method);
    9.26 +    c->set_profiled_bci(profiled_bci);
    9.27 +    c->set_should_profile(true);
    9.28 +  }
    9.29 +  append(c);
    9.30  }
    9.31  
    9.32  
    10.1 --- a/src/share/vm/c1/c1_LIR.hpp	Sat Sep 11 15:21:37 2010 -0700
    10.2 +++ b/src/share/vm/c1/c1_LIR.hpp	Mon Sep 13 12:10:49 2010 -0700
    10.3 @@ -2041,7 +2041,7 @@
    10.4  
    10.5    void fpop_raw()                                { append(new LIR_Op0(lir_fpop_raw)); }
    10.6  
    10.7 -  void instanceof(LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, CodeEmitInfo* info_for_patch);
    10.8 +  void instanceof(LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, CodeEmitInfo* info_for_patch, ciMethod* profiled_method, int profiled_bci);
    10.9    void store_check(LIR_Opr object, LIR_Opr array, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, CodeEmitInfo* info_for_exception);
   10.10  
   10.11    void checkcast (LIR_Opr result, LIR_Opr object, ciKlass* klass,
    11.1 --- a/src/share/vm/c1/c1_LIRAssembler.hpp	Sat Sep 11 15:21:37 2010 -0700
    11.2 +++ b/src/share/vm/c1/c1_LIRAssembler.hpp	Mon Sep 13 12:10:49 2010 -0700
    11.3 @@ -187,7 +187,7 @@
    11.4    void emit_alloc_obj(LIR_OpAllocObj* op);
    11.5    void emit_alloc_array(LIR_OpAllocArray* op);
    11.6    void emit_opTypeCheck(LIR_OpTypeCheck* op);
    11.7 -  void emit_checkcast(LIR_OpTypeCheck* op);
    11.8 +  void emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null);
    11.9    void emit_compare_and_swap(LIR_OpCompareAndSwap* op);
   11.10    void emit_lock(LIR_OpLock* op);
   11.11    void emit_call(LIR_OpJavaCall* op);

mercurial