1.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Aug 11 12:08:11 2011 -0700 1.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Tue Aug 16 04:14:05 2011 -0700 1.3 @@ -202,45 +202,74 @@ 1.4 } 1.5 1.6 1.7 -void TemplateTable::patch_bytecode(Bytecodes::Code bytecode, Register bc, 1.8 - Register scratch, 1.9 - bool load_bc_into_scratch/*=true*/) { 1.10 - 1.11 - if (!RewriteBytecodes) return; 1.12 - // the pair bytecodes have already done the load. 1.13 - if (load_bc_into_scratch) { 1.14 - __ movl(bc, bytecode); 1.15 +void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg, 1.16 + Register temp_reg, bool load_bc_into_bc_reg/*=true*/, 1.17 + int byte_no) { 1.18 + if (!RewriteBytecodes) return; 1.19 + Label L_patch_done; 1.20 + 1.21 + switch (bc) { 1.22 + case Bytecodes::_fast_aputfield: 1.23 + case Bytecodes::_fast_bputfield: 1.24 + case Bytecodes::_fast_cputfield: 1.25 + case Bytecodes::_fast_dputfield: 1.26 + case Bytecodes::_fast_fputfield: 1.27 + case Bytecodes::_fast_iputfield: 1.28 + case Bytecodes::_fast_lputfield: 1.29 + case Bytecodes::_fast_sputfield: 1.30 + { 1.31 + // We skip bytecode quickening for putfield instructions when 1.32 + // the put_code written to the constant pool cache is zero. 1.33 + // This is required so that every execution of this instruction 1.34 + // calls out to InterpreterRuntime::resolve_get_put to do 1.35 + // additional, required work. 1.36 + assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); 1.37 + assert(load_bc_into_bc_reg, "we use bc_reg as temp"); 1.38 + __ get_cache_and_index_and_bytecode_at_bcp(bc_reg, temp_reg, temp_reg, byte_no, 1); 1.39 + __ movl(bc_reg, bc); 1.40 + __ cmpl(temp_reg, (int) 0); 1.41 + __ jcc(Assembler::zero, L_patch_done); // don't patch 1.42 + } 1.43 + break; 1.44 + default: 1.45 + assert(byte_no == -1, "sanity"); 1.46 + // the pair bytecodes have already done the load. 1.47 + if (load_bc_into_bc_reg) { 1.48 + __ movl(bc_reg, bc); 1.49 + } 1.50 } 1.51 - Label patch_done; 1.52 + 1.53 if (JvmtiExport::can_post_breakpoint()) { 1.54 - Label fast_patch; 1.55 + Label L_fast_patch; 1.56 // if a breakpoint is present we can't rewrite the stream directly 1.57 - __ movzbl(scratch, at_bcp(0)); 1.58 - __ cmpl(scratch, Bytecodes::_breakpoint); 1.59 - __ jcc(Assembler::notEqual, fast_patch); 1.60 - __ get_method(scratch); 1.61 + __ movzbl(temp_reg, at_bcp(0)); 1.62 + __ cmpl(temp_reg, Bytecodes::_breakpoint); 1.63 + __ jcc(Assembler::notEqual, L_fast_patch); 1.64 + __ get_method(temp_reg); 1.65 // Let breakpoint table handling rewrite to quicker bytecode 1.66 - __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), scratch, rsi, bc); 1.67 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at), temp_reg, rsi, bc_reg); 1.68 #ifndef ASSERT 1.69 - __ jmpb(patch_done); 1.70 + __ jmpb(L_patch_done); 1.71 #else 1.72 - __ jmp(patch_done); 1.73 + __ jmp(L_patch_done); 1.74 #endif 1.75 - __ bind(fast_patch); 1.76 + __ bind(L_fast_patch); 1.77 } 1.78 + 1.79 #ifdef ASSERT 1.80 - Label okay; 1.81 - __ load_unsigned_byte(scratch, at_bcp(0)); 1.82 - __ cmpl(scratch, (int)Bytecodes::java_code(bytecode)); 1.83 - __ jccb(Assembler::equal, okay); 1.84 - __ cmpl(scratch, bc); 1.85 - __ jcc(Assembler::equal, okay); 1.86 + Label L_okay; 1.87 + __ load_unsigned_byte(temp_reg, at_bcp(0)); 1.88 + __ cmpl(temp_reg, (int)Bytecodes::java_code(bc)); 1.89 + __ jccb(Assembler::equal, L_okay); 1.90 + __ cmpl(temp_reg, bc_reg); 1.91 + __ jcc(Assembler::equal, L_okay); 1.92 __ stop("patching the wrong bytecode"); 1.93 - __ bind(okay); 1.94 + __ bind(L_okay); 1.95 #endif 1.96 + 1.97 // patch bytecode 1.98 - __ movb(at_bcp(0), bc); 1.99 - __ bind(patch_done); 1.100 + __ movb(at_bcp(0), bc_reg); 1.101 + __ bind(L_patch_done); 1.102 } 1.103 1.104 //---------------------------------------------------------------------------------------------------- 1.105 @@ -2060,24 +2089,20 @@ 1.106 assert_different_registers(result, Rcache, index, temp); 1.107 1.108 Label resolved; 1.109 - __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); 1.110 if (byte_no == f1_oop) { 1.111 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) 1.112 // This kind of CP cache entry does not need to match the flags byte, because 1.113 // there is a 1-1 relation between bytecode type and CP entry type. 1.114 assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD) 1.115 + __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size); 1.116 __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset())); 1.117 __ testptr(result, result); 1.118 __ jcc(Assembler::notEqual, resolved); 1.119 } else { 1.120 assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range"); 1.121 assert(result == noreg, ""); //else change code for setting result 1.122 - const int shift_count = (1 + byte_no)*BitsPerByte; 1.123 - __ movl(temp, Address(Rcache, index, Address::times_4, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset())); 1.124 - __ shrl(temp, shift_count); 1.125 - // have we resolved this bytecode? 1.126 - __ andl(temp, 0xFF); 1.127 - __ cmpl(temp, (int)bytecode()); 1.128 + __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size); 1.129 + __ cmpl(temp, (int) bytecode()); // have we resolved this bytecode? 1.130 __ jcc(Assembler::equal, resolved); 1.131 } 1.132 1.133 @@ -2453,138 +2478,153 @@ 1.134 1.135 __ shrl(flags, ConstantPoolCacheEntry::tosBits); 1.136 assert(btos == 0, "change code, btos != 0"); 1.137 - // btos 1.138 __ andl(flags, 0x0f); 1.139 __ jcc(Assembler::notZero, notByte); 1.140 1.141 - __ pop(btos); 1.142 - if (!is_static) pop_and_check_object(obj); 1.143 - __ movb(lo, rax ); 1.144 - if (!is_static) { 1.145 - patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx); 1.146 + // btos 1.147 + { 1.148 + __ pop(btos); 1.149 + if (!is_static) pop_and_check_object(obj); 1.150 + __ movb(lo, rax); 1.151 + if (!is_static) { 1.152 + patch_bytecode(Bytecodes::_fast_bputfield, rcx, rbx, true, byte_no); 1.153 + } 1.154 + __ jmp(Done); 1.155 } 1.156 - __ jmp(Done); 1.157 1.158 __ bind(notByte); 1.159 + __ cmpl(flags, itos); 1.160 + __ jcc(Assembler::notEqual, notInt); 1.161 + 1.162 // itos 1.163 - __ cmpl(flags, itos ); 1.164 - __ jcc(Assembler::notEqual, notInt); 1.165 - 1.166 - __ pop(itos); 1.167 - if (!is_static) pop_and_check_object(obj); 1.168 - 1.169 - __ movl(lo, rax ); 1.170 - if (!is_static) { 1.171 - patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx); 1.172 + { 1.173 + __ pop(itos); 1.174 + if (!is_static) pop_and_check_object(obj); 1.175 + __ movl(lo, rax); 1.176 + if (!is_static) { 1.177 + patch_bytecode(Bytecodes::_fast_iputfield, rcx, rbx, true, byte_no); 1.178 + } 1.179 + __ jmp(Done); 1.180 } 1.181 - __ jmp(Done); 1.182 1.183 __ bind(notInt); 1.184 + __ cmpl(flags, atos); 1.185 + __ jcc(Assembler::notEqual, notObj); 1.186 + 1.187 // atos 1.188 - __ cmpl(flags, atos ); 1.189 - __ jcc(Assembler::notEqual, notObj); 1.190 - 1.191 - __ pop(atos); 1.192 - if (!is_static) pop_and_check_object(obj); 1.193 - 1.194 - do_oop_store(_masm, lo, rax, _bs->kind(), false); 1.195 - 1.196 - if (!is_static) { 1.197 - patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx); 1.198 + { 1.199 + __ pop(atos); 1.200 + if (!is_static) pop_and_check_object(obj); 1.201 + do_oop_store(_masm, lo, rax, _bs->kind(), false); 1.202 + if (!is_static) { 1.203 + patch_bytecode(Bytecodes::_fast_aputfield, rcx, rbx, true, byte_no); 1.204 + } 1.205 + __ jmp(Done); 1.206 } 1.207 1.208 - __ jmp(Done); 1.209 - 1.210 __ bind(notObj); 1.211 + __ cmpl(flags, ctos); 1.212 + __ jcc(Assembler::notEqual, notChar); 1.213 + 1.214 // ctos 1.215 - __ cmpl(flags, ctos ); 1.216 - __ jcc(Assembler::notEqual, notChar); 1.217 - 1.218 - __ pop(ctos); 1.219 - if (!is_static) pop_and_check_object(obj); 1.220 - __ movw(lo, rax ); 1.221 - if (!is_static) { 1.222 - patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx); 1.223 + { 1.224 + __ pop(ctos); 1.225 + if (!is_static) pop_and_check_object(obj); 1.226 + __ movw(lo, rax); 1.227 + if (!is_static) { 1.228 + patch_bytecode(Bytecodes::_fast_cputfield, rcx, rbx, true, byte_no); 1.229 + } 1.230 + __ jmp(Done); 1.231 } 1.232 - __ jmp(Done); 1.233 1.234 __ bind(notChar); 1.235 + __ cmpl(flags, stos); 1.236 + __ jcc(Assembler::notEqual, notShort); 1.237 + 1.238 // stos 1.239 - __ cmpl(flags, stos ); 1.240 - __ jcc(Assembler::notEqual, notShort); 1.241 - 1.242 - __ pop(stos); 1.243 - if (!is_static) pop_and_check_object(obj); 1.244 - __ movw(lo, rax ); 1.245 - if (!is_static) { 1.246 - patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx); 1.247 + { 1.248 + __ pop(stos); 1.249 + if (!is_static) pop_and_check_object(obj); 1.250 + __ movw(lo, rax); 1.251 + if (!is_static) { 1.252 + patch_bytecode(Bytecodes::_fast_sputfield, rcx, rbx, true, byte_no); 1.253 + } 1.254 + __ jmp(Done); 1.255 } 1.256 - __ jmp(Done); 1.257 1.258 __ bind(notShort); 1.259 + __ cmpl(flags, ltos); 1.260 + __ jcc(Assembler::notEqual, notLong); 1.261 + 1.262 // ltos 1.263 - __ cmpl(flags, ltos ); 1.264 - __ jcc(Assembler::notEqual, notLong); 1.265 - 1.266 - Label notVolatileLong; 1.267 - __ testl(rdx, rdx); 1.268 - __ jcc(Assembler::zero, notVolatileLong); 1.269 - 1.270 - __ pop(ltos); // overwrites rdx, do this after testing volatile. 1.271 - if (!is_static) pop_and_check_object(obj); 1.272 - 1.273 - // Replace with real volatile test 1.274 - __ push(rdx); 1.275 - __ push(rax); // Must update atomically with FIST 1.276 - __ fild_d(Address(rsp,0)); // So load into FPU register 1.277 - __ fistp_d(lo); // and put into memory atomically 1.278 - __ addptr(rsp, 2*wordSize); 1.279 - // volatile_barrier(); 1.280 - volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | 1.281 - Assembler::StoreStore)); 1.282 - // Don't rewrite volatile version 1.283 - __ jmp(notVolatile); 1.284 - 1.285 - __ bind(notVolatileLong); 1.286 - 1.287 - __ pop(ltos); // overwrites rdx 1.288 - if (!is_static) pop_and_check_object(obj); 1.289 - NOT_LP64(__ movptr(hi, rdx)); 1.290 - __ movptr(lo, rax); 1.291 - if (!is_static) { 1.292 - patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx); 1.293 + { 1.294 + Label notVolatileLong; 1.295 + __ testl(rdx, rdx); 1.296 + __ jcc(Assembler::zero, notVolatileLong); 1.297 + 1.298 + __ pop(ltos); // overwrites rdx, do this after testing volatile. 1.299 + if (!is_static) pop_and_check_object(obj); 1.300 + 1.301 + // Replace with real volatile test 1.302 + __ push(rdx); 1.303 + __ push(rax); // Must update atomically with FIST 1.304 + __ fild_d(Address(rsp,0)); // So load into FPU register 1.305 + __ fistp_d(lo); // and put into memory atomically 1.306 + __ addptr(rsp, 2*wordSize); 1.307 + // volatile_barrier(); 1.308 + volatile_barrier(Assembler::Membar_mask_bits(Assembler::StoreLoad | 1.309 + Assembler::StoreStore)); 1.310 + // Don't rewrite volatile version 1.311 + __ jmp(notVolatile); 1.312 + 1.313 + __ bind(notVolatileLong); 1.314 + 1.315 + __ pop(ltos); // overwrites rdx 1.316 + if (!is_static) pop_and_check_object(obj); 1.317 + NOT_LP64(__ movptr(hi, rdx)); 1.318 + __ movptr(lo, rax); 1.319 + if (!is_static) { 1.320 + patch_bytecode(Bytecodes::_fast_lputfield, rcx, rbx, true, byte_no); 1.321 + } 1.322 + __ jmp(notVolatile); 1.323 } 1.324 - __ jmp(notVolatile); 1.325 1.326 __ bind(notLong); 1.327 + __ cmpl(flags, ftos); 1.328 + __ jcc(Assembler::notEqual, notFloat); 1.329 + 1.330 // ftos 1.331 - __ cmpl(flags, ftos ); 1.332 - __ jcc(Assembler::notEqual, notFloat); 1.333 - 1.334 - __ pop(ftos); 1.335 - if (!is_static) pop_and_check_object(obj); 1.336 - __ fstp_s(lo); 1.337 - if (!is_static) { 1.338 - patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx); 1.339 + { 1.340 + __ pop(ftos); 1.341 + if (!is_static) pop_and_check_object(obj); 1.342 + __ fstp_s(lo); 1.343 + if (!is_static) { 1.344 + patch_bytecode(Bytecodes::_fast_fputfield, rcx, rbx, true, byte_no); 1.345 + } 1.346 + __ jmp(Done); 1.347 } 1.348 - __ jmp(Done); 1.349 1.350 __ bind(notFloat); 1.351 +#ifdef ASSERT 1.352 + __ cmpl(flags, dtos); 1.353 + __ jcc(Assembler::notEqual, notDouble); 1.354 +#endif 1.355 + 1.356 // dtos 1.357 - __ cmpl(flags, dtos ); 1.358 - __ jcc(Assembler::notEqual, notDouble); 1.359 - 1.360 - __ pop(dtos); 1.361 - if (!is_static) pop_and_check_object(obj); 1.362 - __ fstp_d(lo); 1.363 - if (!is_static) { 1.364 - patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx); 1.365 + { 1.366 + __ pop(dtos); 1.367 + if (!is_static) pop_and_check_object(obj); 1.368 + __ fstp_d(lo); 1.369 + if (!is_static) { 1.370 + patch_bytecode(Bytecodes::_fast_dputfield, rcx, rbx, true, byte_no); 1.371 + } 1.372 + __ jmp(Done); 1.373 } 1.374 - __ jmp(Done); 1.375 - 1.376 + 1.377 +#ifdef ASSERT 1.378 __ bind(notDouble); 1.379 - 1.380 __ stop("Bad state"); 1.381 +#endif 1.382 1.383 __ bind(Done); 1.384