1.1 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Sep 02 11:40:02 2010 -0700 1.2 +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Fri Sep 03 17:51:07 2010 -0700 1.3 @@ -1613,7 +1613,194 @@ 1.4 __ bind(*op->stub()->continuation()); 1.5 } 1.6 1.7 - 1.8 +void LIR_Assembler::type_profile_helper(Register mdo, 1.9 + ciMethodData *md, ciProfileData *data, 1.10 + Register recv, Label* update_done) { 1.11 + uint i; 1.12 + for (i = 0; i < ReceiverTypeData::row_limit(); i++) { 1.13 + Label next_test; 1.14 + // See if the receiver is receiver[n]. 1.15 + __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)))); 1.16 + __ jccb(Assembler::notEqual, next_test); 1.17 + Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))); 1.18 + __ addptr(data_addr, DataLayout::counter_increment); 1.19 + __ jmpb(*update_done); 1.20 + __ bind(next_test); 1.21 + } 1.22 + 1.23 + // Didn't find receiver; find next empty slot and fill it in 1.24 + for (i = 0; i < ReceiverTypeData::row_limit(); i++) { 1.25 + Label next_test; 1.26 + Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i))); 1.27 + __ cmpptr(recv_addr, (intptr_t)NULL_WORD); 1.28 + __ jccb(Assembler::notEqual, next_test); 1.29 + __ movptr(recv_addr, recv); 1.30 + __ movptr(Address(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i))), DataLayout::counter_increment); 1.31 + __ jmpb(*update_done); 1.32 + __ bind(next_test); 1.33 + } 1.34 +} 1.35 + 1.36 +void LIR_Assembler::emit_checkcast(LIR_OpTypeCheck *op) { 1.37 + assert(op->code() == lir_checkcast, "Invalid operation"); 1.38 + // we always need a stub for the failure case. 1.39 + CodeStub* stub = op->stub(); 1.40 + Register obj = op->object()->as_register(); 1.41 + Register k_RInfo = op->tmp1()->as_register(); 1.42 + Register klass_RInfo = op->tmp2()->as_register(); 1.43 + Register dst = op->result_opr()->as_register(); 1.44 + ciKlass* k = op->klass(); 1.45 + Register Rtmp1 = noreg; 1.46 + 1.47 + // check if it needs to be profiled 1.48 + ciMethodData* md; 1.49 + ciProfileData* data; 1.50 + 1.51 + if (op->should_profile()) { 1.52 + ciMethod* method = op->profiled_method(); 1.53 + assert(method != NULL, "Should have method"); 1.54 + int bci = op->profiled_bci(); 1.55 + md = method->method_data(); 1.56 + if (md == NULL) { 1.57 + bailout("out of memory building methodDataOop"); 1.58 + return; 1.59 + } 1.60 + data = md->bci_to_data(bci); 1.61 + assert(data != NULL, "need data for checkcast"); 1.62 + assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for checkcast"); 1.63 + } 1.64 + Label profile_cast_failure; 1.65 + 1.66 + Label done, done_null; 1.67 + // Where to go in case of cast failure 1.68 + Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry(); 1.69 + 1.70 + if (obj == k_RInfo) { 1.71 + k_RInfo = dst; 1.72 + } else if (obj == klass_RInfo) { 1.73 + klass_RInfo = dst; 1.74 + } 1.75 + if (k->is_loaded()) { 1.76 + select_different_registers(obj, dst, k_RInfo, klass_RInfo); 1.77 + } else { 1.78 + Rtmp1 = op->tmp3()->as_register(); 1.79 + select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); 1.80 + } 1.81 + 1.82 + assert_different_registers(obj, k_RInfo, klass_RInfo); 1.83 + if (!k->is_loaded()) { 1.84 + jobject2reg_with_patching(k_RInfo, op->info_for_patch()); 1.85 + } else { 1.86 +#ifdef _LP64 1.87 + __ movoop(k_RInfo, k->constant_encoding()); 1.88 +#endif // _LP64 1.89 + } 1.90 + assert(obj != k_RInfo, "must be different"); 1.91 + 1.92 + __ cmpptr(obj, (int32_t)NULL_WORD); 1.93 + if (op->should_profile()) { 1.94 + Label profile_done; 1.95 + __ jccb(Assembler::notEqual, profile_done); 1.96 + // Object is null; update methodDataOop 1.97 + Register mdo = klass_RInfo; 1.98 + __ movoop(mdo, md->constant_encoding()); 1.99 + Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); 1.100 + int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); 1.101 + __ orl(data_addr, header_bits); 1.102 + __ jmp(done_null); 1.103 + __ bind(profile_done); 1.104 + } else { 1.105 + __ jcc(Assembler::equal, done_null); 1.106 + } 1.107 + __ verify_oop(obj); 1.108 + 1.109 + if (op->fast_check()) { 1.110 + // get object classo 1.111 + // not a safepoint as obj null check happens earlier 1.112 + if (k->is_loaded()) { 1.113 +#ifdef _LP64 1.114 + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 1.115 +#else 1.116 + __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); 1.117 +#endif // _LP64 1.118 + } else { 1.119 + __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 1.120 + } 1.121 + __ jcc(Assembler::notEqual, *failure_target); 1.122 + } else { 1.123 + // get object class 1.124 + // not a safepoint as obj null check happens earlier 1.125 + __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 1.126 + if (k->is_loaded()) { 1.127 + // See if we get an immediate positive hit 1.128 +#ifdef _LP64 1.129 + __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); 1.130 +#else 1.131 + __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); 1.132 +#endif // _LP64 1.133 + if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { 1.134 + __ jcc(Assembler::notEqual, *failure_target); 1.135 + } else { 1.136 + // See if we get an immediate positive hit 1.137 + __ jcc(Assembler::equal, done); 1.138 + // check for self 1.139 +#ifdef _LP64 1.140 + __ cmpptr(klass_RInfo, k_RInfo); 1.141 +#else 1.142 + __ cmpoop(klass_RInfo, k->constant_encoding()); 1.143 +#endif // _LP64 1.144 + __ jcc(Assembler::equal, done); 1.145 + 1.146 + __ push(klass_RInfo); 1.147 +#ifdef _LP64 1.148 + __ push(k_RInfo); 1.149 +#else 1.150 + __ pushoop(k->constant_encoding()); 1.151 +#endif // _LP64 1.152 + __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); 1.153 + __ pop(klass_RInfo); 1.154 + __ pop(klass_RInfo); 1.155 + // result is a boolean 1.156 + __ cmpl(klass_RInfo, 0); 1.157 + __ jcc(Assembler::equal, *failure_target); 1.158 + } 1.159 + } else { 1.160 + // perform the fast part of the checking logic 1.161 + __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, failure_target, NULL); 1.162 + // call out-of-line instance of __ check_klass_subtype_slow_path(...): 1.163 + __ push(klass_RInfo); 1.164 + __ push(k_RInfo); 1.165 + __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); 1.166 + __ pop(klass_RInfo); 1.167 + __ pop(k_RInfo); 1.168 + // result is a boolean 1.169 + __ cmpl(k_RInfo, 0); 1.170 + __ jcc(Assembler::equal, *failure_target); 1.171 + } 1.172 + } 1.173 + __ bind(done); 1.174 + 1.175 + if (op->should_profile()) { 1.176 + Register mdo = klass_RInfo, recv = k_RInfo; 1.177 + __ movoop(mdo, md->constant_encoding()); 1.178 + __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes())); 1.179 + Label update_done; 1.180 + type_profile_helper(mdo, md, data, recv, &update_done); 1.181 + __ jmpb(update_done); 1.182 + 1.183 + __ bind(profile_cast_failure); 1.184 + __ movoop(mdo, md->constant_encoding()); 1.185 + Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())); 1.186 + __ subptr(counter_addr, DataLayout::counter_increment); 1.187 + __ jmp(*stub->entry()); 1.188 + 1.189 + __ bind(update_done); 1.190 + } 1.191 + __ bind(done_null); 1.192 + if (dst != obj) { 1.193 + __ mov(dst, obj); 1.194 + } 1.195 +} 1.196 1.197 void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) { 1.198 LIR_Code code = op->code(); 1.199 @@ -1646,140 +1833,6 @@ 1.200 __ cmpl(k_RInfo, 0); 1.201 __ jcc(Assembler::equal, *stub->entry()); 1.202 __ bind(done); 1.203 - } else if (op->code() == lir_checkcast) { 1.204 - // we always need a stub for the failure case. 1.205 - CodeStub* stub = op->stub(); 1.206 - Register obj = op->object()->as_register(); 1.207 - Register k_RInfo = op->tmp1()->as_register(); 1.208 - Register klass_RInfo = op->tmp2()->as_register(); 1.209 - Register dst = op->result_opr()->as_register(); 1.210 - ciKlass* k = op->klass(); 1.211 - Register Rtmp1 = noreg; 1.212 - 1.213 - Label done; 1.214 - if (obj == k_RInfo) { 1.215 - k_RInfo = dst; 1.216 - } else if (obj == klass_RInfo) { 1.217 - klass_RInfo = dst; 1.218 - } 1.219 - if (k->is_loaded()) { 1.220 - select_different_registers(obj, dst, k_RInfo, klass_RInfo); 1.221 - } else { 1.222 - Rtmp1 = op->tmp3()->as_register(); 1.223 - select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); 1.224 - } 1.225 - 1.226 - assert_different_registers(obj, k_RInfo, klass_RInfo); 1.227 - if (!k->is_loaded()) { 1.228 - jobject2reg_with_patching(k_RInfo, op->info_for_patch()); 1.229 - } else { 1.230 -#ifdef _LP64 1.231 - __ movoop(k_RInfo, k->constant_encoding()); 1.232 -#else 1.233 - k_RInfo = noreg; 1.234 -#endif // _LP64 1.235 - } 1.236 - assert(obj != k_RInfo, "must be different"); 1.237 - __ cmpptr(obj, (int32_t)NULL_WORD); 1.238 - if (op->profiled_method() != NULL) { 1.239 - ciMethod* method = op->profiled_method(); 1.240 - int bci = op->profiled_bci(); 1.241 - 1.242 - Label profile_done; 1.243 - __ jcc(Assembler::notEqual, profile_done); 1.244 - // Object is null; update methodDataOop 1.245 - ciMethodData* md = method->method_data(); 1.246 - if (md == NULL) { 1.247 - bailout("out of memory building methodDataOop"); 1.248 - return; 1.249 - } 1.250 - ciProfileData* data = md->bci_to_data(bci); 1.251 - assert(data != NULL, "need data for checkcast"); 1.252 - assert(data->is_BitData(), "need BitData for checkcast"); 1.253 - Register mdo = klass_RInfo; 1.254 - __ movoop(mdo, md->constant_encoding()); 1.255 - Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset())); 1.256 - int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant()); 1.257 - __ orl(data_addr, header_bits); 1.258 - __ jmp(done); 1.259 - __ bind(profile_done); 1.260 - } else { 1.261 - __ jcc(Assembler::equal, done); 1.262 - } 1.263 - __ verify_oop(obj); 1.264 - 1.265 - if (op->fast_check()) { 1.266 - // get object classo 1.267 - // not a safepoint as obj null check happens earlier 1.268 - if (k->is_loaded()) { 1.269 -#ifdef _LP64 1.270 - __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 1.271 -#else 1.272 - __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); 1.273 -#endif // _LP64 1.274 - } else { 1.275 - __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 1.276 - 1.277 - } 1.278 - __ jcc(Assembler::notEqual, *stub->entry()); 1.279 - __ bind(done); 1.280 - } else { 1.281 - // get object class 1.282 - // not a safepoint as obj null check happens earlier 1.283 - __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); 1.284 - if (k->is_loaded()) { 1.285 - // See if we get an immediate positive hit 1.286 -#ifdef _LP64 1.287 - __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); 1.288 -#else 1.289 - __ cmpoop(Address(klass_RInfo, k->super_check_offset()), k->constant_encoding()); 1.290 -#endif // _LP64 1.291 - if (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() != k->super_check_offset()) { 1.292 - __ jcc(Assembler::notEqual, *stub->entry()); 1.293 - } else { 1.294 - // See if we get an immediate positive hit 1.295 - __ jcc(Assembler::equal, done); 1.296 - // check for self 1.297 -#ifdef _LP64 1.298 - __ cmpptr(klass_RInfo, k_RInfo); 1.299 -#else 1.300 - __ cmpoop(klass_RInfo, k->constant_encoding()); 1.301 -#endif // _LP64 1.302 - __ jcc(Assembler::equal, done); 1.303 - 1.304 - __ push(klass_RInfo); 1.305 -#ifdef _LP64 1.306 - __ push(k_RInfo); 1.307 -#else 1.308 - __ pushoop(k->constant_encoding()); 1.309 -#endif // _LP64 1.310 - __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); 1.311 - __ pop(klass_RInfo); 1.312 - __ pop(klass_RInfo); 1.313 - // result is a boolean 1.314 - __ cmpl(klass_RInfo, 0); 1.315 - __ jcc(Assembler::equal, *stub->entry()); 1.316 - } 1.317 - __ bind(done); 1.318 - } else { 1.319 - // perform the fast part of the checking logic 1.320 - __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, &done, stub->entry(), NULL); 1.321 - // call out-of-line instance of __ check_klass_subtype_slow_path(...): 1.322 - __ push(klass_RInfo); 1.323 - __ push(k_RInfo); 1.324 - __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::slow_subtype_check_id))); 1.325 - __ pop(klass_RInfo); 1.326 - __ pop(k_RInfo); 1.327 - // result is a boolean 1.328 - __ cmpl(k_RInfo, 0); 1.329 - __ jcc(Assembler::equal, *stub->entry()); 1.330 - __ bind(done); 1.331 - } 1.332 - 1.333 - } 1.334 - if (dst != obj) { 1.335 - __ mov(dst, obj); 1.336 - } 1.337 } else if (code == lir_instanceof) { 1.338 Register obj = op->object()->as_register(); 1.339 Register k_RInfo = op->tmp1()->as_register(); 1.340 @@ -1922,7 +1975,6 @@ 1.341 } 1.342 } 1.343 1.344 - 1.345 void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result) { 1.346 Assembler::Condition acond, ncond; 1.347 switch (condition) { 1.348 @@ -3253,13 +3305,13 @@ 1.349 // Perform additional virtual call profiling for invokevirtual and 1.350 // invokeinterface bytecodes 1.351 if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) && 1.352 - Tier1ProfileVirtualCalls) { 1.353 + C1ProfileVirtualCalls) { 1.354 assert(op->recv()->is_single_cpu(), "recv must be allocated"); 1.355 Register recv = op->recv()->as_register(); 1.356 assert_different_registers(mdo, recv); 1.357 assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls"); 1.358 ciKlass* known_klass = op->known_holder(); 1.359 - if (Tier1OptimizeVirtualCallProfiling && known_klass != NULL) { 1.360 + if (C1OptimizeVirtualCallProfiling && known_klass != NULL) { 1.361 // We know the type that will be seen at this call site; we can 1.362 // statically update the methodDataOop rather than needing to do 1.363 // dynamic tests on the receiver type 1.364 @@ -3272,7 +3324,7 @@ 1.365 ciKlass* receiver = vc_data->receiver(i); 1.366 if (known_klass->equals(receiver)) { 1.367 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); 1.368 - __ addl(data_addr, DataLayout::counter_increment); 1.369 + __ addptr(data_addr, DataLayout::counter_increment); 1.370 return; 1.371 } 1.372 } 1.373 @@ -3288,49 +3340,26 @@ 1.374 Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); 1.375 __ movoop(recv_addr, known_klass->constant_encoding()); 1.376 Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); 1.377 - __ addl(data_addr, DataLayout::counter_increment); 1.378 + __ addptr(data_addr, DataLayout::counter_increment); 1.379 return; 1.380 } 1.381 } 1.382 } else { 1.383 __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); 1.384 Label update_done; 1.385 - uint i; 1.386 - for (i = 0; i < VirtualCallData::row_limit(); i++) { 1.387 - Label next_test; 1.388 - // See if the receiver is receiver[n]. 1.389 - __ cmpptr(recv, Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)))); 1.390 - __ jcc(Assembler::notEqual, next_test); 1.391 - Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))); 1.392 - __ addl(data_addr, DataLayout::counter_increment); 1.393 - __ jmp(update_done); 1.394 - __ bind(next_test); 1.395 - } 1.396 - 1.397 - // Didn't find receiver; find next empty slot and fill it in 1.398 - for (i = 0; i < VirtualCallData::row_limit(); i++) { 1.399 - Label next_test; 1.400 - Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i))); 1.401 - __ cmpptr(recv_addr, (int32_t)NULL_WORD); 1.402 - __ jcc(Assembler::notEqual, next_test); 1.403 - __ movptr(recv_addr, recv); 1.404 - __ movl(Address(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i))), DataLayout::counter_increment); 1.405 - __ jmp(update_done); 1.406 - __ bind(next_test); 1.407 - } 1.408 + type_profile_helper(mdo, md, data, recv, &update_done); 1.409 // Receiver did not match any saved receiver and there is no empty row for it. 1.410 // Increment total counter to indicate polymorphic case. 1.411 - __ addl(counter_addr, DataLayout::counter_increment); 1.412 + __ addptr(counter_addr, DataLayout::counter_increment); 1.413 1.414 __ bind(update_done); 1.415 } 1.416 } else { 1.417 // Static call 1.418 - __ addl(counter_addr, DataLayout::counter_increment); 1.419 + __ addptr(counter_addr, DataLayout::counter_increment); 1.420 } 1.421 } 1.422 1.423 - 1.424 void LIR_Assembler::emit_delay(LIR_OpDelay*) { 1.425 Unimplemented(); 1.426 }