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