Tue, 18 Mar 2014 14:04:47 -0700
Merge
.hgtags | file | annotate | diff | comparison | revisions | |
make/hotspot_version | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Fri Mar 14 22:57:00 2014 -0700 1.2 +++ b/.hgtags Tue Mar 18 14:04:47 2014 -0700 1.3 @@ -446,3 +446,4 @@ 1.4 54436d3b2a915ff50a8d6b34f61d5afb45be7bb6 hs25.20-b05 1.5 d4e18f0633c662588cc0875be7759721c7d85af4 jdk8u20-b04 1.6 57eb3e69397e9d5818c5fdaef65b47d9b03f7f88 jdk8u20-b05 1.7 +804f89b6ff46728d60a69e9a338e63f362f7ac68 hs25.20-b06
2.1 --- a/make/hotspot_version Fri Mar 14 22:57:00 2014 -0700 2.2 +++ b/make/hotspot_version Tue Mar 18 14:04:47 2014 -0700 2.3 @@ -35,7 +35,7 @@ 2.4 2.5 HS_MAJOR_VER=25 2.6 HS_MINOR_VER=20 2.7 -HS_BUILD_NUMBER=05 2.8 +HS_BUILD_NUMBER=06 2.9 2.10 JDK_MAJOR_VER=1 2.11 JDK_MINOR_VER=8
3.1 --- a/src/cpu/x86/vm/macroAssembler_x86.cpp Fri Mar 14 22:57:00 2014 -0700 3.2 +++ b/src/cpu/x86/vm/macroAssembler_x86.cpp Tue Mar 18 14:04:47 2014 -0700 3.3 @@ -98,217 +98,6 @@ 3.4 return Address::make_array(adr); 3.5 } 3.6 3.7 -int MacroAssembler::biased_locking_enter(Register lock_reg, 3.8 - Register obj_reg, 3.9 - Register swap_reg, 3.10 - Register tmp_reg, 3.11 - bool swap_reg_contains_mark, 3.12 - Label& done, 3.13 - Label* slow_case, 3.14 - BiasedLockingCounters* counters) { 3.15 - assert(UseBiasedLocking, "why call this otherwise?"); 3.16 - assert(swap_reg == rax, "swap_reg must be rax, for cmpxchg"); 3.17 - assert_different_registers(lock_reg, obj_reg, swap_reg); 3.18 - 3.19 - if (PrintBiasedLockingStatistics && counters == NULL) 3.20 - counters = BiasedLocking::counters(); 3.21 - 3.22 - bool need_tmp_reg = false; 3.23 - if (tmp_reg == noreg) { 3.24 - need_tmp_reg = true; 3.25 - tmp_reg = lock_reg; 3.26 - } else { 3.27 - assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg); 3.28 - } 3.29 - assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout"); 3.30 - Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); 3.31 - Address klass_addr (obj_reg, oopDesc::klass_offset_in_bytes()); 3.32 - Address saved_mark_addr(lock_reg, 0); 3.33 - 3.34 - // Biased locking 3.35 - // See whether the lock is currently biased toward our thread and 3.36 - // whether the epoch is still valid 3.37 - // Note that the runtime guarantees sufficient alignment of JavaThread 3.38 - // pointers to allow age to be placed into low bits 3.39 - // First check to see whether biasing is even enabled for this object 3.40 - Label cas_label; 3.41 - int null_check_offset = -1; 3.42 - if (!swap_reg_contains_mark) { 3.43 - null_check_offset = offset(); 3.44 - movl(swap_reg, mark_addr); 3.45 - } 3.46 - if (need_tmp_reg) { 3.47 - push(tmp_reg); 3.48 - } 3.49 - movl(tmp_reg, swap_reg); 3.50 - andl(tmp_reg, markOopDesc::biased_lock_mask_in_place); 3.51 - cmpl(tmp_reg, markOopDesc::biased_lock_pattern); 3.52 - if (need_tmp_reg) { 3.53 - pop(tmp_reg); 3.54 - } 3.55 - jcc(Assembler::notEqual, cas_label); 3.56 - // The bias pattern is present in the object's header. Need to check 3.57 - // whether the bias owner and the epoch are both still current. 3.58 - // Note that because there is no current thread register on x86 we 3.59 - // need to store off the mark word we read out of the object to 3.60 - // avoid reloading it and needing to recheck invariants below. This 3.61 - // store is unfortunate but it makes the overall code shorter and 3.62 - // simpler. 3.63 - movl(saved_mark_addr, swap_reg); 3.64 - if (need_tmp_reg) { 3.65 - push(tmp_reg); 3.66 - } 3.67 - get_thread(tmp_reg); 3.68 - xorl(swap_reg, tmp_reg); 3.69 - if (swap_reg_contains_mark) { 3.70 - null_check_offset = offset(); 3.71 - } 3.72 - movl(tmp_reg, klass_addr); 3.73 - xorl(swap_reg, Address(tmp_reg, Klass::prototype_header_offset())); 3.74 - andl(swap_reg, ~((int) markOopDesc::age_mask_in_place)); 3.75 - if (need_tmp_reg) { 3.76 - pop(tmp_reg); 3.77 - } 3.78 - if (counters != NULL) { 3.79 - cond_inc32(Assembler::zero, 3.80 - ExternalAddress((address)counters->biased_lock_entry_count_addr())); 3.81 - } 3.82 - jcc(Assembler::equal, done); 3.83 - 3.84 - Label try_revoke_bias; 3.85 - Label try_rebias; 3.86 - 3.87 - // At this point we know that the header has the bias pattern and 3.88 - // that we are not the bias owner in the current epoch. We need to 3.89 - // figure out more details about the state of the header in order to 3.90 - // know what operations can be legally performed on the object's 3.91 - // header. 3.92 - 3.93 - // If the low three bits in the xor result aren't clear, that means 3.94 - // the prototype header is no longer biased and we have to revoke 3.95 - // the bias on this object. 3.96 - testl(swap_reg, markOopDesc::biased_lock_mask_in_place); 3.97 - jcc(Assembler::notZero, try_revoke_bias); 3.98 - 3.99 - // Biasing is still enabled for this data type. See whether the 3.100 - // epoch of the current bias is still valid, meaning that the epoch 3.101 - // bits of the mark word are equal to the epoch bits of the 3.102 - // prototype header. (Note that the prototype header's epoch bits 3.103 - // only change at a safepoint.) If not, attempt to rebias the object 3.104 - // toward the current thread. Note that we must be absolutely sure 3.105 - // that the current epoch is invalid in order to do this because 3.106 - // otherwise the manipulations it performs on the mark word are 3.107 - // illegal. 3.108 - testl(swap_reg, markOopDesc::epoch_mask_in_place); 3.109 - jcc(Assembler::notZero, try_rebias); 3.110 - 3.111 - // The epoch of the current bias is still valid but we know nothing 3.112 - // about the owner; it might be set or it might be clear. Try to 3.113 - // acquire the bias of the object using an atomic operation. If this 3.114 - // fails we will go in to the runtime to revoke the object's bias. 3.115 - // Note that we first construct the presumed unbiased header so we 3.116 - // don't accidentally blow away another thread's valid bias. 3.117 - movl(swap_reg, saved_mark_addr); 3.118 - andl(swap_reg, 3.119 - markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); 3.120 - if (need_tmp_reg) { 3.121 - push(tmp_reg); 3.122 - } 3.123 - get_thread(tmp_reg); 3.124 - orl(tmp_reg, swap_reg); 3.125 - if (os::is_MP()) { 3.126 - lock(); 3.127 - } 3.128 - cmpxchgptr(tmp_reg, Address(obj_reg, 0)); 3.129 - if (need_tmp_reg) { 3.130 - pop(tmp_reg); 3.131 - } 3.132 - // If the biasing toward our thread failed, this means that 3.133 - // another thread succeeded in biasing it toward itself and we 3.134 - // need to revoke that bias. The revocation will occur in the 3.135 - // interpreter runtime in the slow case. 3.136 - if (counters != NULL) { 3.137 - cond_inc32(Assembler::zero, 3.138 - ExternalAddress((address)counters->anonymously_biased_lock_entry_count_addr())); 3.139 - } 3.140 - if (slow_case != NULL) { 3.141 - jcc(Assembler::notZero, *slow_case); 3.142 - } 3.143 - jmp(done); 3.144 - 3.145 - bind(try_rebias); 3.146 - // At this point we know the epoch has expired, meaning that the 3.147 - // current "bias owner", if any, is actually invalid. Under these 3.148 - // circumstances _only_, we are allowed to use the current header's 3.149 - // value as the comparison value when doing the cas to acquire the 3.150 - // bias in the current epoch. In other words, we allow transfer of 3.151 - // the bias from one thread to another directly in this situation. 3.152 - // 3.153 - // FIXME: due to a lack of registers we currently blow away the age 3.154 - // bits in this situation. Should attempt to preserve them. 3.155 - if (need_tmp_reg) { 3.156 - push(tmp_reg); 3.157 - } 3.158 - get_thread(tmp_reg); 3.159 - movl(swap_reg, klass_addr); 3.160 - orl(tmp_reg, Address(swap_reg, Klass::prototype_header_offset())); 3.161 - movl(swap_reg, saved_mark_addr); 3.162 - if (os::is_MP()) { 3.163 - lock(); 3.164 - } 3.165 - cmpxchgptr(tmp_reg, Address(obj_reg, 0)); 3.166 - if (need_tmp_reg) { 3.167 - pop(tmp_reg); 3.168 - } 3.169 - // If the biasing toward our thread failed, then another thread 3.170 - // succeeded in biasing it toward itself and we need to revoke that 3.171 - // bias. The revocation will occur in the runtime in the slow case. 3.172 - if (counters != NULL) { 3.173 - cond_inc32(Assembler::zero, 3.174 - ExternalAddress((address)counters->rebiased_lock_entry_count_addr())); 3.175 - } 3.176 - if (slow_case != NULL) { 3.177 - jcc(Assembler::notZero, *slow_case); 3.178 - } 3.179 - jmp(done); 3.180 - 3.181 - bind(try_revoke_bias); 3.182 - // The prototype mark in the klass doesn't have the bias bit set any 3.183 - // more, indicating that objects of this data type are not supposed 3.184 - // to be biased any more. We are going to try to reset the mark of 3.185 - // this object to the prototype value and fall through to the 3.186 - // CAS-based locking scheme. Note that if our CAS fails, it means 3.187 - // that another thread raced us for the privilege of revoking the 3.188 - // bias of this particular object, so it's okay to continue in the 3.189 - // normal locking code. 3.190 - // 3.191 - // FIXME: due to a lack of registers we currently blow away the age 3.192 - // bits in this situation. Should attempt to preserve them. 3.193 - movl(swap_reg, saved_mark_addr); 3.194 - if (need_tmp_reg) { 3.195 - push(tmp_reg); 3.196 - } 3.197 - movl(tmp_reg, klass_addr); 3.198 - movl(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset())); 3.199 - if (os::is_MP()) { 3.200 - lock(); 3.201 - } 3.202 - cmpxchgptr(tmp_reg, Address(obj_reg, 0)); 3.203 - if (need_tmp_reg) { 3.204 - pop(tmp_reg); 3.205 - } 3.206 - // Fall through to the normal CAS-based lock, because no matter what 3.207 - // the result of the above CAS, some thread must have succeeded in 3.208 - // removing the bias bit from the object's header. 3.209 - if (counters != NULL) { 3.210 - cond_inc32(Assembler::zero, 3.211 - ExternalAddress((address)counters->revoked_lock_entry_count_addr())); 3.212 - } 3.213 - 3.214 - bind(cas_label); 3.215 - 3.216 - return null_check_offset; 3.217 -} 3.218 void MacroAssembler::call_VM_leaf_base(address entry_point, 3.219 int number_of_arguments) { 3.220 call(RuntimeAddress(entry_point)); 3.221 @@ -726,165 +515,6 @@ 3.222 return array; 3.223 } 3.224 3.225 -int MacroAssembler::biased_locking_enter(Register lock_reg, 3.226 - Register obj_reg, 3.227 - Register swap_reg, 3.228 - Register tmp_reg, 3.229 - bool swap_reg_contains_mark, 3.230 - Label& done, 3.231 - Label* slow_case, 3.232 - BiasedLockingCounters* counters) { 3.233 - assert(UseBiasedLocking, "why call this otherwise?"); 3.234 - assert(swap_reg == rax, "swap_reg must be rax for cmpxchgq"); 3.235 - assert(tmp_reg != noreg, "tmp_reg must be supplied"); 3.236 - assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg); 3.237 - assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout"); 3.238 - Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); 3.239 - Address saved_mark_addr(lock_reg, 0); 3.240 - 3.241 - if (PrintBiasedLockingStatistics && counters == NULL) 3.242 - counters = BiasedLocking::counters(); 3.243 - 3.244 - // Biased locking 3.245 - // See whether the lock is currently biased toward our thread and 3.246 - // whether the epoch is still valid 3.247 - // Note that the runtime guarantees sufficient alignment of JavaThread 3.248 - // pointers to allow age to be placed into low bits 3.249 - // First check to see whether biasing is even enabled for this object 3.250 - Label cas_label; 3.251 - int null_check_offset = -1; 3.252 - if (!swap_reg_contains_mark) { 3.253 - null_check_offset = offset(); 3.254 - movq(swap_reg, mark_addr); 3.255 - } 3.256 - movq(tmp_reg, swap_reg); 3.257 - andq(tmp_reg, markOopDesc::biased_lock_mask_in_place); 3.258 - cmpq(tmp_reg, markOopDesc::biased_lock_pattern); 3.259 - jcc(Assembler::notEqual, cas_label); 3.260 - // The bias pattern is present in the object's header. Need to check 3.261 - // whether the bias owner and the epoch are both still current. 3.262 - load_prototype_header(tmp_reg, obj_reg); 3.263 - orq(tmp_reg, r15_thread); 3.264 - xorq(tmp_reg, swap_reg); 3.265 - andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place)); 3.266 - if (counters != NULL) { 3.267 - cond_inc32(Assembler::zero, 3.268 - ExternalAddress((address) counters->anonymously_biased_lock_entry_count_addr())); 3.269 - } 3.270 - jcc(Assembler::equal, done); 3.271 - 3.272 - Label try_revoke_bias; 3.273 - Label try_rebias; 3.274 - 3.275 - // At this point we know that the header has the bias pattern and 3.276 - // that we are not the bias owner in the current epoch. We need to 3.277 - // figure out more details about the state of the header in order to 3.278 - // know what operations can be legally performed on the object's 3.279 - // header. 3.280 - 3.281 - // If the low three bits in the xor result aren't clear, that means 3.282 - // the prototype header is no longer biased and we have to revoke 3.283 - // the bias on this object. 3.284 - testq(tmp_reg, markOopDesc::biased_lock_mask_in_place); 3.285 - jcc(Assembler::notZero, try_revoke_bias); 3.286 - 3.287 - // Biasing is still enabled for this data type. See whether the 3.288 - // epoch of the current bias is still valid, meaning that the epoch 3.289 - // bits of the mark word are equal to the epoch bits of the 3.290 - // prototype header. (Note that the prototype header's epoch bits 3.291 - // only change at a safepoint.) If not, attempt to rebias the object 3.292 - // toward the current thread. Note that we must be absolutely sure 3.293 - // that the current epoch is invalid in order to do this because 3.294 - // otherwise the manipulations it performs on the mark word are 3.295 - // illegal. 3.296 - testq(tmp_reg, markOopDesc::epoch_mask_in_place); 3.297 - jcc(Assembler::notZero, try_rebias); 3.298 - 3.299 - // The epoch of the current bias is still valid but we know nothing 3.300 - // about the owner; it might be set or it might be clear. Try to 3.301 - // acquire the bias of the object using an atomic operation. If this 3.302 - // fails we will go in to the runtime to revoke the object's bias. 3.303 - // Note that we first construct the presumed unbiased header so we 3.304 - // don't accidentally blow away another thread's valid bias. 3.305 - andq(swap_reg, 3.306 - markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); 3.307 - movq(tmp_reg, swap_reg); 3.308 - orq(tmp_reg, r15_thread); 3.309 - if (os::is_MP()) { 3.310 - lock(); 3.311 - } 3.312 - cmpxchgq(tmp_reg, Address(obj_reg, 0)); 3.313 - // If the biasing toward our thread failed, this means that 3.314 - // another thread succeeded in biasing it toward itself and we 3.315 - // need to revoke that bias. The revocation will occur in the 3.316 - // interpreter runtime in the slow case. 3.317 - if (counters != NULL) { 3.318 - cond_inc32(Assembler::zero, 3.319 - ExternalAddress((address) counters->anonymously_biased_lock_entry_count_addr())); 3.320 - } 3.321 - if (slow_case != NULL) { 3.322 - jcc(Assembler::notZero, *slow_case); 3.323 - } 3.324 - jmp(done); 3.325 - 3.326 - bind(try_rebias); 3.327 - // At this point we know the epoch has expired, meaning that the 3.328 - // current "bias owner", if any, is actually invalid. Under these 3.329 - // circumstances _only_, we are allowed to use the current header's 3.330 - // value as the comparison value when doing the cas to acquire the 3.331 - // bias in the current epoch. In other words, we allow transfer of 3.332 - // the bias from one thread to another directly in this situation. 3.333 - // 3.334 - // FIXME: due to a lack of registers we currently blow away the age 3.335 - // bits in this situation. Should attempt to preserve them. 3.336 - load_prototype_header(tmp_reg, obj_reg); 3.337 - orq(tmp_reg, r15_thread); 3.338 - if (os::is_MP()) { 3.339 - lock(); 3.340 - } 3.341 - cmpxchgq(tmp_reg, Address(obj_reg, 0)); 3.342 - // If the biasing toward our thread failed, then another thread 3.343 - // succeeded in biasing it toward itself and we need to revoke that 3.344 - // bias. The revocation will occur in the runtime in the slow case. 3.345 - if (counters != NULL) { 3.346 - cond_inc32(Assembler::zero, 3.347 - ExternalAddress((address) counters->rebiased_lock_entry_count_addr())); 3.348 - } 3.349 - if (slow_case != NULL) { 3.350 - jcc(Assembler::notZero, *slow_case); 3.351 - } 3.352 - jmp(done); 3.353 - 3.354 - bind(try_revoke_bias); 3.355 - // The prototype mark in the klass doesn't have the bias bit set any 3.356 - // more, indicating that objects of this data type are not supposed 3.357 - // to be biased any more. We are going to try to reset the mark of 3.358 - // this object to the prototype value and fall through to the 3.359 - // CAS-based locking scheme. Note that if our CAS fails, it means 3.360 - // that another thread raced us for the privilege of revoking the 3.361 - // bias of this particular object, so it's okay to continue in the 3.362 - // normal locking code. 3.363 - // 3.364 - // FIXME: due to a lack of registers we currently blow away the age 3.365 - // bits in this situation. Should attempt to preserve them. 3.366 - load_prototype_header(tmp_reg, obj_reg); 3.367 - if (os::is_MP()) { 3.368 - lock(); 3.369 - } 3.370 - cmpxchgq(tmp_reg, Address(obj_reg, 0)); 3.371 - // Fall through to the normal CAS-based lock, because no matter what 3.372 - // the result of the above CAS, some thread must have succeeded in 3.373 - // removing the bias bit from the object's header. 3.374 - if (counters != NULL) { 3.375 - cond_inc32(Assembler::zero, 3.376 - ExternalAddress((address) counters->revoked_lock_entry_count_addr())); 3.377 - } 3.378 - 3.379 - bind(cas_label); 3.380 - 3.381 - return null_check_offset; 3.382 -} 3.383 - 3.384 void MacroAssembler::call_VM_leaf_base(address entry_point, int num_args) { 3.385 Label L, E; 3.386 3.387 @@ -1360,9 +990,16 @@ 3.388 3.389 void MacroAssembler::atomic_incl(AddressLiteral counter_addr) { 3.390 pushf(); 3.391 - if (os::is_MP()) 3.392 - lock(); 3.393 - incrementl(counter_addr); 3.394 + if (reachable(counter_addr)) { 3.395 + if (os::is_MP()) 3.396 + lock(); 3.397 + incrementl(as_Address(counter_addr)); 3.398 + } else { 3.399 + lea(rscratch1, counter_addr); 3.400 + if (os::is_MP()) 3.401 + lock(); 3.402 + incrementl(Address(rscratch1, 0)); 3.403 + } 3.404 popf(); 3.405 } 3.406 3.407 @@ -1393,6 +1030,234 @@ 3.408 } 3.409 } 3.410 3.411 +int MacroAssembler::biased_locking_enter(Register lock_reg, 3.412 + Register obj_reg, 3.413 + Register swap_reg, 3.414 + Register tmp_reg, 3.415 + bool swap_reg_contains_mark, 3.416 + Label& done, 3.417 + Label* slow_case, 3.418 + BiasedLockingCounters* counters) { 3.419 + assert(UseBiasedLocking, "why call this otherwise?"); 3.420 + assert(swap_reg == rax, "swap_reg must be rax for cmpxchgq"); 3.421 + LP64_ONLY( assert(tmp_reg != noreg, "tmp_reg must be supplied"); ) 3.422 + bool need_tmp_reg = false; 3.423 + if (tmp_reg == noreg) { 3.424 + need_tmp_reg = true; 3.425 + tmp_reg = lock_reg; 3.426 + assert_different_registers(lock_reg, obj_reg, swap_reg); 3.427 + } else { 3.428 + assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg); 3.429 + } 3.430 + assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout"); 3.431 + Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes()); 3.432 + Address saved_mark_addr(lock_reg, 0); 3.433 + 3.434 + if (PrintBiasedLockingStatistics && counters == NULL) { 3.435 + counters = BiasedLocking::counters(); 3.436 + } 3.437 + // Biased locking 3.438 + // See whether the lock is currently biased toward our thread and 3.439 + // whether the epoch is still valid 3.440 + // Note that the runtime guarantees sufficient alignment of JavaThread 3.441 + // pointers to allow age to be placed into low bits 3.442 + // First check to see whether biasing is even enabled for this object 3.443 + Label cas_label; 3.444 + int null_check_offset = -1; 3.445 + if (!swap_reg_contains_mark) { 3.446 + null_check_offset = offset(); 3.447 + movptr(swap_reg, mark_addr); 3.448 + } 3.449 + if (need_tmp_reg) { 3.450 + push(tmp_reg); 3.451 + } 3.452 + movptr(tmp_reg, swap_reg); 3.453 + andptr(tmp_reg, markOopDesc::biased_lock_mask_in_place); 3.454 + cmpptr(tmp_reg, markOopDesc::biased_lock_pattern); 3.455 + if (need_tmp_reg) { 3.456 + pop(tmp_reg); 3.457 + } 3.458 + jcc(Assembler::notEqual, cas_label); 3.459 + // The bias pattern is present in the object's header. Need to check 3.460 + // whether the bias owner and the epoch are both still current. 3.461 +#ifndef _LP64 3.462 + // Note that because there is no current thread register on x86_32 we 3.463 + // need to store off the mark word we read out of the object to 3.464 + // avoid reloading it and needing to recheck invariants below. This 3.465 + // store is unfortunate but it makes the overall code shorter and 3.466 + // simpler. 3.467 + movptr(saved_mark_addr, swap_reg); 3.468 +#endif 3.469 + if (need_tmp_reg) { 3.470 + push(tmp_reg); 3.471 + } 3.472 + if (swap_reg_contains_mark) { 3.473 + null_check_offset = offset(); 3.474 + } 3.475 + load_prototype_header(tmp_reg, obj_reg); 3.476 +#ifdef _LP64 3.477 + orptr(tmp_reg, r15_thread); 3.478 + xorptr(tmp_reg, swap_reg); 3.479 + Register header_reg = tmp_reg; 3.480 +#else 3.481 + xorptr(tmp_reg, swap_reg); 3.482 + get_thread(swap_reg); 3.483 + xorptr(swap_reg, tmp_reg); 3.484 + Register header_reg = swap_reg; 3.485 +#endif 3.486 + andptr(header_reg, ~((int) markOopDesc::age_mask_in_place)); 3.487 + if (need_tmp_reg) { 3.488 + pop(tmp_reg); 3.489 + } 3.490 + if (counters != NULL) { 3.491 + cond_inc32(Assembler::zero, 3.492 + ExternalAddress((address) counters->biased_lock_entry_count_addr())); 3.493 + } 3.494 + jcc(Assembler::equal, done); 3.495 + 3.496 + Label try_revoke_bias; 3.497 + Label try_rebias; 3.498 + 3.499 + // At this point we know that the header has the bias pattern and 3.500 + // that we are not the bias owner in the current epoch. We need to 3.501 + // figure out more details about the state of the header in order to 3.502 + // know what operations can be legally performed on the object's 3.503 + // header. 3.504 + 3.505 + // If the low three bits in the xor result aren't clear, that means 3.506 + // the prototype header is no longer biased and we have to revoke 3.507 + // the bias on this object. 3.508 + testptr(header_reg, markOopDesc::biased_lock_mask_in_place); 3.509 + jccb(Assembler::notZero, try_revoke_bias); 3.510 + 3.511 + // Biasing is still enabled for this data type. See whether the 3.512 + // epoch of the current bias is still valid, meaning that the epoch 3.513 + // bits of the mark word are equal to the epoch bits of the 3.514 + // prototype header. (Note that the prototype header's epoch bits 3.515 + // only change at a safepoint.) If not, attempt to rebias the object 3.516 + // toward the current thread. Note that we must be absolutely sure 3.517 + // that the current epoch is invalid in order to do this because 3.518 + // otherwise the manipulations it performs on the mark word are 3.519 + // illegal. 3.520 + testptr(header_reg, markOopDesc::epoch_mask_in_place); 3.521 + jccb(Assembler::notZero, try_rebias); 3.522 + 3.523 + // The epoch of the current bias is still valid but we know nothing 3.524 + // about the owner; it might be set or it might be clear. Try to 3.525 + // acquire the bias of the object using an atomic operation. If this 3.526 + // fails we will go in to the runtime to revoke the object's bias. 3.527 + // Note that we first construct the presumed unbiased header so we 3.528 + // don't accidentally blow away another thread's valid bias. 3.529 + NOT_LP64( movptr(swap_reg, saved_mark_addr); ) 3.530 + andptr(swap_reg, 3.531 + markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place); 3.532 + if (need_tmp_reg) { 3.533 + push(tmp_reg); 3.534 + } 3.535 +#ifdef _LP64 3.536 + movptr(tmp_reg, swap_reg); 3.537 + orptr(tmp_reg, r15_thread); 3.538 +#else 3.539 + get_thread(tmp_reg); 3.540 + orptr(tmp_reg, swap_reg); 3.541 +#endif 3.542 + if (os::is_MP()) { 3.543 + lock(); 3.544 + } 3.545 + cmpxchgptr(tmp_reg, mark_addr); // compare tmp_reg and swap_reg 3.546 + if (need_tmp_reg) { 3.547 + pop(tmp_reg); 3.548 + } 3.549 + // If the biasing toward our thread failed, this means that 3.550 + // another thread succeeded in biasing it toward itself and we 3.551 + // need to revoke that bias. The revocation will occur in the 3.552 + // interpreter runtime in the slow case. 3.553 + if (counters != NULL) { 3.554 + cond_inc32(Assembler::zero, 3.555 + ExternalAddress((address) counters->anonymously_biased_lock_entry_count_addr())); 3.556 + } 3.557 + if (slow_case != NULL) { 3.558 + jcc(Assembler::notZero, *slow_case); 3.559 + } 3.560 + jmp(done); 3.561 + 3.562 + bind(try_rebias); 3.563 + // At this point we know the epoch has expired, meaning that the 3.564 + // current "bias owner", if any, is actually invalid. Under these 3.565 + // circumstances _only_, we are allowed to use the current header's 3.566 + // value as the comparison value when doing the cas to acquire the 3.567 + // bias in the current epoch. In other words, we allow transfer of 3.568 + // the bias from one thread to another directly in this situation. 3.569 + // 3.570 + // FIXME: due to a lack of registers we currently blow away the age 3.571 + // bits in this situation. Should attempt to preserve them. 3.572 + if (need_tmp_reg) { 3.573 + push(tmp_reg); 3.574 + } 3.575 + load_prototype_header(tmp_reg, obj_reg); 3.576 +#ifdef _LP64 3.577 + orptr(tmp_reg, r15_thread); 3.578 +#else 3.579 + get_thread(swap_reg); 3.580 + orptr(tmp_reg, swap_reg); 3.581 + movptr(swap_reg, saved_mark_addr); 3.582 +#endif 3.583 + if (os::is_MP()) { 3.584 + lock(); 3.585 + } 3.586 + cmpxchgptr(tmp_reg, mark_addr); // compare tmp_reg and swap_reg 3.587 + if (need_tmp_reg) { 3.588 + pop(tmp_reg); 3.589 + } 3.590 + // If the biasing toward our thread failed, then another thread 3.591 + // succeeded in biasing it toward itself and we need to revoke that 3.592 + // bias. The revocation will occur in the runtime in the slow case. 3.593 + if (counters != NULL) { 3.594 + cond_inc32(Assembler::zero, 3.595 + ExternalAddress((address) counters->rebiased_lock_entry_count_addr())); 3.596 + } 3.597 + if (slow_case != NULL) { 3.598 + jcc(Assembler::notZero, *slow_case); 3.599 + } 3.600 + jmp(done); 3.601 + 3.602 + bind(try_revoke_bias); 3.603 + // The prototype mark in the klass doesn't have the bias bit set any 3.604 + // more, indicating that objects of this data type are not supposed 3.605 + // to be biased any more. We are going to try to reset the mark of 3.606 + // this object to the prototype value and fall through to the 3.607 + // CAS-based locking scheme. Note that if our CAS fails, it means 3.608 + // that another thread raced us for the privilege of revoking the 3.609 + // bias of this particular object, so it's okay to continue in the 3.610 + // normal locking code. 3.611 + // 3.612 + // FIXME: due to a lack of registers we currently blow away the age 3.613 + // bits in this situation. Should attempt to preserve them. 3.614 + NOT_LP64( movptr(swap_reg, saved_mark_addr); ) 3.615 + if (need_tmp_reg) { 3.616 + push(tmp_reg); 3.617 + } 3.618 + load_prototype_header(tmp_reg, obj_reg); 3.619 + if (os::is_MP()) { 3.620 + lock(); 3.621 + } 3.622 + cmpxchgptr(tmp_reg, mark_addr); // compare tmp_reg and swap_reg 3.623 + if (need_tmp_reg) { 3.624 + pop(tmp_reg); 3.625 + } 3.626 + // Fall through to the normal CAS-based lock, because no matter what 3.627 + // the result of the above CAS, some thread must have succeeded in 3.628 + // removing the bias bit from the object's header. 3.629 + if (counters != NULL) { 3.630 + cond_inc32(Assembler::zero, 3.631 + ExternalAddress((address) counters->revoked_lock_entry_count_addr())); 3.632 + } 3.633 + 3.634 + bind(cas_label); 3.635 + 3.636 + return null_check_offset; 3.637 +} 3.638 + 3.639 void MacroAssembler::biased_locking_exit(Register obj_reg, Register temp_reg, Label& done) { 3.640 assert(UseBiasedLocking, "why call this otherwise?"); 3.641 3.642 @@ -1408,6 +1273,620 @@ 3.643 jcc(Assembler::equal, done); 3.644 } 3.645 3.646 +#ifdef COMPILER2 3.647 +// Fast_Lock and Fast_Unlock used by C2 3.648 + 3.649 +// Because the transitions from emitted code to the runtime 3.650 +// monitorenter/exit helper stubs are so slow it's critical that 3.651 +// we inline both the stack-locking fast-path and the inflated fast path. 3.652 +// 3.653 +// See also: cmpFastLock and cmpFastUnlock. 3.654 +// 3.655 +// What follows is a specialized inline transliteration of the code 3.656 +// in slow_enter() and slow_exit(). If we're concerned about I$ bloat 3.657 +// another option would be to emit TrySlowEnter and TrySlowExit methods 3.658 +// at startup-time. These methods would accept arguments as 3.659 +// (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure 3.660 +// indications in the icc.ZFlag. Fast_Lock and Fast_Unlock would simply 3.661 +// marshal the arguments and emit calls to TrySlowEnter and TrySlowExit. 3.662 +// In practice, however, the # of lock sites is bounded and is usually small. 3.663 +// Besides the call overhead, TrySlowEnter and TrySlowExit might suffer 3.664 +// if the processor uses simple bimodal branch predictors keyed by EIP 3.665 +// Since the helper routines would be called from multiple synchronization 3.666 +// sites. 3.667 +// 3.668 +// An even better approach would be write "MonitorEnter()" and "MonitorExit()" 3.669 +// in java - using j.u.c and unsafe - and just bind the lock and unlock sites 3.670 +// to those specialized methods. That'd give us a mostly platform-independent 3.671 +// implementation that the JITs could optimize and inline at their pleasure. 3.672 +// Done correctly, the only time we'd need to cross to native could would be 3.673 +// to park() or unpark() threads. We'd also need a few more unsafe operators 3.674 +// to (a) prevent compiler-JIT reordering of non-volatile accesses, and 3.675 +// (b) explicit barriers or fence operations. 3.676 +// 3.677 +// TODO: 3.678 +// 3.679 +// * Arrange for C2 to pass "Self" into Fast_Lock and Fast_Unlock in one of the registers (scr). 3.680 +// This avoids manifesting the Self pointer in the Fast_Lock and Fast_Unlock terminals. 3.681 +// Given TLAB allocation, Self is usually manifested in a register, so passing it into 3.682 +// the lock operators would typically be faster than reifying Self. 3.683 +// 3.684 +// * Ideally I'd define the primitives as: 3.685 +// fast_lock (nax Obj, nax box, EAX tmp, nax scr) where box, tmp and scr are KILLED. 3.686 +// fast_unlock (nax Obj, EAX box, nax tmp) where box and tmp are KILLED 3.687 +// Unfortunately ADLC bugs prevent us from expressing the ideal form. 3.688 +// Instead, we're stuck with a rather awkward and brittle register assignments below. 3.689 +// Furthermore the register assignments are overconstrained, possibly resulting in 3.690 +// sub-optimal code near the synchronization site. 3.691 +// 3.692 +// * Eliminate the sp-proximity tests and just use "== Self" tests instead. 3.693 +// Alternately, use a better sp-proximity test. 3.694 +// 3.695 +// * Currently ObjectMonitor._Owner can hold either an sp value or a (THREAD *) value. 3.696 +// Either one is sufficient to uniquely identify a thread. 3.697 +// TODO: eliminate use of sp in _owner and use get_thread(tr) instead. 3.698 +// 3.699 +// * Intrinsify notify() and notifyAll() for the common cases where the 3.700 +// object is locked by the calling thread but the waitlist is empty. 3.701 +// avoid the expensive JNI call to JVM_Notify() and JVM_NotifyAll(). 3.702 +// 3.703 +// * use jccb and jmpb instead of jcc and jmp to improve code density. 3.704 +// But beware of excessive branch density on AMD Opterons. 3.705 +// 3.706 +// * Both Fast_Lock and Fast_Unlock set the ICC.ZF to indicate success 3.707 +// or failure of the fast-path. If the fast-path fails then we pass 3.708 +// control to the slow-path, typically in C. In Fast_Lock and 3.709 +// Fast_Unlock we often branch to DONE_LABEL, just to find that C2 3.710 +// will emit a conditional branch immediately after the node. 3.711 +// So we have branches to branches and lots of ICC.ZF games. 3.712 +// Instead, it might be better to have C2 pass a "FailureLabel" 3.713 +// into Fast_Lock and Fast_Unlock. In the case of success, control 3.714 +// will drop through the node. ICC.ZF is undefined at exit. 3.715 +// In the case of failure, the node will branch directly to the 3.716 +// FailureLabel 3.717 + 3.718 + 3.719 +// obj: object to lock 3.720 +// box: on-stack box address (displaced header location) - KILLED 3.721 +// rax,: tmp -- KILLED 3.722 +// scr: tmp -- KILLED 3.723 +void MacroAssembler::fast_lock(Register objReg, Register boxReg, Register tmpReg, Register scrReg, BiasedLockingCounters* counters) { 3.724 + // Ensure the register assignents are disjoint 3.725 + guarantee (objReg != boxReg, ""); 3.726 + guarantee (objReg != tmpReg, ""); 3.727 + guarantee (objReg != scrReg, ""); 3.728 + guarantee (boxReg != tmpReg, ""); 3.729 + guarantee (boxReg != scrReg, ""); 3.730 + guarantee (tmpReg == rax, ""); 3.731 + 3.732 + if (counters != NULL) { 3.733 + atomic_incl(ExternalAddress((address)counters->total_entry_count_addr())); 3.734 + } 3.735 + if (EmitSync & 1) { 3.736 + // set box->dhw = unused_mark (3) 3.737 + // Force all sync thru slow-path: slow_enter() and slow_exit() 3.738 + movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())); 3.739 + cmpptr (rsp, (int32_t)NULL_WORD); 3.740 + } else 3.741 + if (EmitSync & 2) { 3.742 + Label DONE_LABEL ; 3.743 + if (UseBiasedLocking) { 3.744 + // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 3.745 + biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, counters); 3.746 + } 3.747 + 3.748 + movptr(tmpReg, Address(objReg, 0)); // fetch markword 3.749 + orptr (tmpReg, 0x1); 3.750 + movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS 3.751 + if (os::is_MP()) { 3.752 + lock(); 3.753 + } 3.754 + cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3.755 + jccb(Assembler::equal, DONE_LABEL); 3.756 + // Recursive locking 3.757 + subptr(tmpReg, rsp); 3.758 + andptr(tmpReg, (int32_t) (NOT_LP64(0xFFFFF003) LP64_ONLY(7 - os::vm_page_size())) ); 3.759 + movptr(Address(boxReg, 0), tmpReg); 3.760 + bind(DONE_LABEL); 3.761 + } else { 3.762 + // Possible cases that we'll encounter in fast_lock 3.763 + // ------------------------------------------------ 3.764 + // * Inflated 3.765 + // -- unlocked 3.766 + // -- Locked 3.767 + // = by self 3.768 + // = by other 3.769 + // * biased 3.770 + // -- by Self 3.771 + // -- by other 3.772 + // * neutral 3.773 + // * stack-locked 3.774 + // -- by self 3.775 + // = sp-proximity test hits 3.776 + // = sp-proximity test generates false-negative 3.777 + // -- by other 3.778 + // 3.779 + 3.780 + Label IsInflated, DONE_LABEL; 3.781 + 3.782 + // it's stack-locked, biased or neutral 3.783 + // TODO: optimize away redundant LDs of obj->mark and improve the markword triage 3.784 + // order to reduce the number of conditional branches in the most common cases. 3.785 + // Beware -- there's a subtle invariant that fetch of the markword 3.786 + // at [FETCH], below, will never observe a biased encoding (*101b). 3.787 + // If this invariant is not held we risk exclusion (safety) failure. 3.788 + if (UseBiasedLocking && !UseOptoBiasInlining) { 3.789 + biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, counters); 3.790 + } 3.791 + 3.792 + movptr(tmpReg, Address(objReg, 0)); // [FETCH] 3.793 + testl (tmpReg, markOopDesc::monitor_value); // inflated vs stack-locked|neutral|biased 3.794 + jccb (Assembler::notZero, IsInflated); 3.795 + 3.796 + // Attempt stack-locking ... 3.797 + orptr (tmpReg, 0x1); 3.798 + movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS 3.799 + if (os::is_MP()) { 3.800 + lock(); 3.801 + } 3.802 + cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3.803 + if (counters != NULL) { 3.804 + cond_inc32(Assembler::equal, 3.805 + ExternalAddress((address)counters->fast_path_entry_count_addr())); 3.806 + } 3.807 + jccb(Assembler::equal, DONE_LABEL); 3.808 + 3.809 + // Recursive locking 3.810 + subptr(tmpReg, rsp); 3.811 + andptr(tmpReg, (int32_t) (NOT_LP64(0xFFFFF003) LP64_ONLY(7 - os::vm_page_size())) ); 3.812 + movptr(Address(boxReg, 0), tmpReg); 3.813 + if (counters != NULL) { 3.814 + cond_inc32(Assembler::equal, 3.815 + ExternalAddress((address)counters->fast_path_entry_count_addr())); 3.816 + } 3.817 + jmpb(DONE_LABEL); 3.818 + 3.819 + bind(IsInflated); 3.820 +#ifndef _LP64 3.821 + // The object is inflated. 3.822 + // 3.823 + // TODO-FIXME: eliminate the ugly use of manifest constants: 3.824 + // Use markOopDesc::monitor_value instead of "2". 3.825 + // use markOop::unused_mark() instead of "3". 3.826 + // The tmpReg value is an objectMonitor reference ORed with 3.827 + // markOopDesc::monitor_value (2). We can either convert tmpReg to an 3.828 + // objectmonitor pointer by masking off the "2" bit or we can just 3.829 + // use tmpReg as an objectmonitor pointer but bias the objectmonitor 3.830 + // field offsets with "-2" to compensate for and annul the low-order tag bit. 3.831 + // 3.832 + // I use the latter as it avoids AGI stalls. 3.833 + // As such, we write "mov r, [tmpReg+OFFSETOF(Owner)-2]" 3.834 + // instead of "mov r, [tmpReg+OFFSETOF(Owner)]". 3.835 + // 3.836 + #define OFFSET_SKEWED(f) ((ObjectMonitor::f ## _offset_in_bytes())-2) 3.837 + 3.838 + // boxReg refers to the on-stack BasicLock in the current frame. 3.839 + // We'd like to write: 3.840 + // set box->_displaced_header = markOop::unused_mark(). Any non-0 value suffices. 3.841 + // This is convenient but results a ST-before-CAS penalty. The following CAS suffers 3.842 + // additional latency as we have another ST in the store buffer that must drain. 3.843 + 3.844 + if (EmitSync & 8192) { 3.845 + movptr(Address(boxReg, 0), 3); // results in ST-before-CAS penalty 3.846 + get_thread (scrReg); 3.847 + movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 3.848 + movptr(tmpReg, NULL_WORD); // consider: xor vs mov 3.849 + if (os::is_MP()) { 3.850 + lock(); 3.851 + } 3.852 + cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.853 + } else 3.854 + if ((EmitSync & 128) == 0) { // avoid ST-before-CAS 3.855 + movptr(scrReg, boxReg); 3.856 + movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 3.857 + 3.858 + // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 3.859 + if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3.860 + // prefetchw [eax + Offset(_owner)-2] 3.861 + prefetchw(Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.862 + } 3.863 + 3.864 + if ((EmitSync & 64) == 0) { 3.865 + // Optimistic form: consider XORL tmpReg,tmpReg 3.866 + movptr(tmpReg, NULL_WORD); 3.867 + } else { 3.868 + // Can suffer RTS->RTO upgrades on shared or cold $ lines 3.869 + // Test-And-CAS instead of CAS 3.870 + movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); // rax, = m->_owner 3.871 + testptr(tmpReg, tmpReg); // Locked ? 3.872 + jccb (Assembler::notZero, DONE_LABEL); 3.873 + } 3.874 + 3.875 + // Appears unlocked - try to swing _owner from null to non-null. 3.876 + // Ideally, I'd manifest "Self" with get_thread and then attempt 3.877 + // to CAS the register containing Self into m->Owner. 3.878 + // But we don't have enough registers, so instead we can either try to CAS 3.879 + // rsp or the address of the box (in scr) into &m->owner. If the CAS succeeds 3.880 + // we later store "Self" into m->Owner. Transiently storing a stack address 3.881 + // (rsp or the address of the box) into m->owner is harmless. 3.882 + // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. 3.883 + if (os::is_MP()) { 3.884 + lock(); 3.885 + } 3.886 + cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.887 + movptr(Address(scrReg, 0), 3); // box->_displaced_header = 3 3.888 + jccb (Assembler::notZero, DONE_LABEL); 3.889 + get_thread (scrReg); // beware: clobbers ICCs 3.890 + movptr(Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg); 3.891 + xorptr(boxReg, boxReg); // set icc.ZFlag = 1 to indicate success 3.892 + 3.893 + // If the CAS fails we can either retry or pass control to the slow-path. 3.894 + // We use the latter tactic. 3.895 + // Pass the CAS result in the icc.ZFlag into DONE_LABEL 3.896 + // If the CAS was successful ... 3.897 + // Self has acquired the lock 3.898 + // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. 3.899 + // Intentional fall-through into DONE_LABEL ... 3.900 + } else { 3.901 + movptr(Address(boxReg, 0), intptr_t(markOopDesc::unused_mark())); // results in ST-before-CAS penalty 3.902 + movptr(boxReg, tmpReg); 3.903 + 3.904 + // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 3.905 + if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3.906 + // prefetchw [eax + Offset(_owner)-2] 3.907 + prefetchw(Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.908 + } 3.909 + 3.910 + if ((EmitSync & 64) == 0) { 3.911 + // Optimistic form 3.912 + xorptr (tmpReg, tmpReg); 3.913 + } else { 3.914 + // Can suffer RTS->RTO upgrades on shared or cold $ lines 3.915 + movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); // rax, = m->_owner 3.916 + testptr(tmpReg, tmpReg); // Locked ? 3.917 + jccb (Assembler::notZero, DONE_LABEL); 3.918 + } 3.919 + 3.920 + // Appears unlocked - try to swing _owner from null to non-null. 3.921 + // Use either "Self" (in scr) or rsp as thread identity in _owner. 3.922 + // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. 3.923 + get_thread (scrReg); 3.924 + if (os::is_MP()) { 3.925 + lock(); 3.926 + } 3.927 + cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.928 + 3.929 + // If the CAS fails we can either retry or pass control to the slow-path. 3.930 + // We use the latter tactic. 3.931 + // Pass the CAS result in the icc.ZFlag into DONE_LABEL 3.932 + // If the CAS was successful ... 3.933 + // Self has acquired the lock 3.934 + // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. 3.935 + // Intentional fall-through into DONE_LABEL ... 3.936 + } 3.937 +#else // _LP64 3.938 + // It's inflated 3.939 + 3.940 + // TODO: someday avoid the ST-before-CAS penalty by 3.941 + // relocating (deferring) the following ST. 3.942 + // We should also think about trying a CAS without having 3.943 + // fetched _owner. If the CAS is successful we may 3.944 + // avoid an RTO->RTS upgrade on the $line. 3.945 + 3.946 + // Without cast to int32_t a movptr will destroy r10 which is typically obj 3.947 + movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())); 3.948 + 3.949 + mov (boxReg, tmpReg); 3.950 + movptr (tmpReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.951 + testptr(tmpReg, tmpReg); 3.952 + jccb (Assembler::notZero, DONE_LABEL); 3.953 + 3.954 + // It's inflated and appears unlocked 3.955 + if (os::is_MP()) { 3.956 + lock(); 3.957 + } 3.958 + cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.959 + // Intentional fall-through into DONE_LABEL ... 3.960 + 3.961 +#endif 3.962 + 3.963 + // DONE_LABEL is a hot target - we'd really like to place it at the 3.964 + // start of cache line by padding with NOPs. 3.965 + // See the AMD and Intel software optimization manuals for the 3.966 + // most efficient "long" NOP encodings. 3.967 + // Unfortunately none of our alignment mechanisms suffice. 3.968 + bind(DONE_LABEL); 3.969 + 3.970 + // At DONE_LABEL the icc ZFlag is set as follows ... 3.971 + // Fast_Unlock uses the same protocol. 3.972 + // ZFlag == 1 -> Success 3.973 + // ZFlag == 0 -> Failure - force control through the slow-path 3.974 + } 3.975 +} 3.976 + 3.977 +// obj: object to unlock 3.978 +// box: box address (displaced header location), killed. Must be EAX. 3.979 +// tmp: killed, cannot be obj nor box. 3.980 +// 3.981 +// Some commentary on balanced locking: 3.982 +// 3.983 +// Fast_Lock and Fast_Unlock are emitted only for provably balanced lock sites. 3.984 +// Methods that don't have provably balanced locking are forced to run in the 3.985 +// interpreter - such methods won't be compiled to use fast_lock and fast_unlock. 3.986 +// The interpreter provides two properties: 3.987 +// I1: At return-time the interpreter automatically and quietly unlocks any 3.988 +// objects acquired the current activation (frame). Recall that the 3.989 +// interpreter maintains an on-stack list of locks currently held by 3.990 +// a frame. 3.991 +// I2: If a method attempts to unlock an object that is not held by the 3.992 +// the frame the interpreter throws IMSX. 3.993 +// 3.994 +// Lets say A(), which has provably balanced locking, acquires O and then calls B(). 3.995 +// B() doesn't have provably balanced locking so it runs in the interpreter. 3.996 +// Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O 3.997 +// is still locked by A(). 3.998 +// 3.999 +// The only other source of unbalanced locking would be JNI. The "Java Native Interface: 3.1000 +// Programmer's Guide and Specification" claims that an object locked by jni_monitorenter 3.1001 +// should not be unlocked by "normal" java-level locking and vice-versa. The specification 3.1002 +// doesn't specify what will occur if a program engages in such mixed-mode locking, however. 3.1003 + 3.1004 +void MacroAssembler::fast_unlock(Register objReg, Register boxReg, Register tmpReg) { 3.1005 + guarantee (objReg != boxReg, ""); 3.1006 + guarantee (objReg != tmpReg, ""); 3.1007 + guarantee (boxReg != tmpReg, ""); 3.1008 + guarantee (boxReg == rax, ""); 3.1009 + 3.1010 + if (EmitSync & 4) { 3.1011 + // Disable - inhibit all inlining. Force control through the slow-path 3.1012 + cmpptr (rsp, 0); 3.1013 + } else 3.1014 + if (EmitSync & 8) { 3.1015 + Label DONE_LABEL; 3.1016 + if (UseBiasedLocking) { 3.1017 + biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3.1018 + } 3.1019 + // Classic stack-locking code ... 3.1020 + // Check whether the displaced header is 0 3.1021 + //(=> recursive unlock) 3.1022 + movptr(tmpReg, Address(boxReg, 0)); 3.1023 + testptr(tmpReg, tmpReg); 3.1024 + jccb(Assembler::zero, DONE_LABEL); 3.1025 + // If not recursive lock, reset the header to displaced header 3.1026 + if (os::is_MP()) { 3.1027 + lock(); 3.1028 + } 3.1029 + cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3.1030 + bind(DONE_LABEL); 3.1031 + } else { 3.1032 + Label DONE_LABEL, Stacked, CheckSucc; 3.1033 + 3.1034 + // Critically, the biased locking test must have precedence over 3.1035 + // and appear before the (box->dhw == 0) recursive stack-lock test. 3.1036 + if (UseBiasedLocking && !UseOptoBiasInlining) { 3.1037 + biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3.1038 + } 3.1039 + 3.1040 + cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD); // Examine the displaced header 3.1041 + movptr(tmpReg, Address(objReg, 0)); // Examine the object's markword 3.1042 + jccb (Assembler::zero, DONE_LABEL); // 0 indicates recursive stack-lock 3.1043 + 3.1044 + testptr(tmpReg, 0x02); // Inflated? 3.1045 + jccb (Assembler::zero, Stacked); 3.1046 + 3.1047 + // It's inflated. 3.1048 + // Despite our balanced locking property we still check that m->_owner == Self 3.1049 + // as java routines or native JNI code called by this thread might 3.1050 + // have released the lock. 3.1051 + // Refer to the comments in synchronizer.cpp for how we might encode extra 3.1052 + // state in _succ so we can avoid fetching EntryList|cxq. 3.1053 + // 3.1054 + // I'd like to add more cases in fast_lock() and fast_unlock() -- 3.1055 + // such as recursive enter and exit -- but we have to be wary of 3.1056 + // I$ bloat, T$ effects and BP$ effects. 3.1057 + // 3.1058 + // If there's no contention try a 1-0 exit. That is, exit without 3.1059 + // a costly MEMBAR or CAS. See synchronizer.cpp for details on how 3.1060 + // we detect and recover from the race that the 1-0 exit admits. 3.1061 + // 3.1062 + // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier 3.1063 + // before it STs null into _owner, releasing the lock. Updates 3.1064 + // to data protected by the critical section must be visible before 3.1065 + // we drop the lock (and thus before any other thread could acquire 3.1066 + // the lock and observe the fields protected by the lock). 3.1067 + // IA32's memory-model is SPO, so STs are ordered with respect to 3.1068 + // each other and there's no need for an explicit barrier (fence). 3.1069 + // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html. 3.1070 +#ifndef _LP64 3.1071 + get_thread (boxReg); 3.1072 + if ((EmitSync & 4096) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3.1073 + // prefetchw [ebx + Offset(_owner)-2] 3.1074 + prefetchw(Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.1075 + } 3.1076 + 3.1077 + // Note that we could employ various encoding schemes to reduce 3.1078 + // the number of loads below (currently 4) to just 2 or 3. 3.1079 + // Refer to the comments in synchronizer.cpp. 3.1080 + // In practice the chain of fetches doesn't seem to impact performance, however. 3.1081 + if ((EmitSync & 65536) == 0 && (EmitSync & 256)) { 3.1082 + // Attempt to reduce branch density - AMD's branch predictor. 3.1083 + xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.1084 + orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)); 3.1085 + orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)); 3.1086 + orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)); 3.1087 + jccb (Assembler::notZero, DONE_LABEL); 3.1088 + movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD); 3.1089 + jmpb (DONE_LABEL); 3.1090 + } else { 3.1091 + xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.1092 + orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)); 3.1093 + jccb (Assembler::notZero, DONE_LABEL); 3.1094 + movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)); 3.1095 + orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)); 3.1096 + jccb (Assembler::notZero, CheckSucc); 3.1097 + movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD); 3.1098 + jmpb (DONE_LABEL); 3.1099 + } 3.1100 + 3.1101 + // The Following code fragment (EmitSync & 65536) improves the performance of 3.1102 + // contended applications and contended synchronization microbenchmarks. 3.1103 + // Unfortunately the emission of the code - even though not executed - causes regressions 3.1104 + // in scimark and jetstream, evidently because of $ effects. Replacing the code 3.1105 + // with an equal number of never-executed NOPs results in the same regression. 3.1106 + // We leave it off by default. 3.1107 + 3.1108 + if ((EmitSync & 65536) != 0) { 3.1109 + Label LSuccess, LGoSlowPath ; 3.1110 + 3.1111 + bind (CheckSucc); 3.1112 + 3.1113 + // Optional pre-test ... it's safe to elide this 3.1114 + if ((EmitSync & 16) == 0) { 3.1115 + cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD); 3.1116 + jccb (Assembler::zero, LGoSlowPath); 3.1117 + } 3.1118 + 3.1119 + // We have a classic Dekker-style idiom: 3.1120 + // ST m->_owner = 0 ; MEMBAR; LD m->_succ 3.1121 + // There are a number of ways to implement the barrier: 3.1122 + // (1) lock:andl &m->_owner, 0 3.1123 + // is fast, but mask doesn't currently support the "ANDL M,IMM32" form. 3.1124 + // LOCK: ANDL [ebx+Offset(_Owner)-2], 0 3.1125 + // Encodes as 81 31 OFF32 IMM32 or 83 63 OFF8 IMM8 3.1126 + // (2) If supported, an explicit MFENCE is appealing. 3.1127 + // In older IA32 processors MFENCE is slower than lock:add or xchg 3.1128 + // particularly if the write-buffer is full as might be the case if 3.1129 + // if stores closely precede the fence or fence-equivalent instruction. 3.1130 + // In more modern implementations MFENCE appears faster, however. 3.1131 + // (3) In lieu of an explicit fence, use lock:addl to the top-of-stack 3.1132 + // The $lines underlying the top-of-stack should be in M-state. 3.1133 + // The locked add instruction is serializing, of course. 3.1134 + // (4) Use xchg, which is serializing 3.1135 + // mov boxReg, 0; xchgl boxReg, [tmpReg + Offset(_owner)-2] also works 3.1136 + // (5) ST m->_owner = 0 and then execute lock:orl &m->_succ, 0. 3.1137 + // The integer condition codes will tell us if succ was 0. 3.1138 + // Since _succ and _owner should reside in the same $line and 3.1139 + // we just stored into _owner, it's likely that the $line 3.1140 + // remains in M-state for the lock:orl. 3.1141 + // 3.1142 + // We currently use (3), although it's likely that switching to (2) 3.1143 + // is correct for the future. 3.1144 + 3.1145 + movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD); 3.1146 + if (os::is_MP()) { 3.1147 + if (VM_Version::supports_sse2() && 1 == FenceInstruction) { 3.1148 + mfence(); 3.1149 + } else { 3.1150 + lock (); addptr(Address(rsp, 0), 0); 3.1151 + } 3.1152 + } 3.1153 + // Ratify _succ remains non-null 3.1154 + cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0); 3.1155 + jccb (Assembler::notZero, LSuccess); 3.1156 + 3.1157 + xorptr(boxReg, boxReg); // box is really EAX 3.1158 + if (os::is_MP()) { lock(); } 3.1159 + cmpxchgptr(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.1160 + jccb (Assembler::notEqual, LSuccess); 3.1161 + // Since we're low on registers we installed rsp as a placeholding in _owner. 3.1162 + // Now install Self over rsp. This is safe as we're transitioning from 3.1163 + // non-null to non=null 3.1164 + get_thread (boxReg); 3.1165 + movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg); 3.1166 + // Intentional fall-through into LGoSlowPath ... 3.1167 + 3.1168 + bind (LGoSlowPath); 3.1169 + orptr(boxReg, 1); // set ICC.ZF=0 to indicate failure 3.1170 + jmpb (DONE_LABEL); 3.1171 + 3.1172 + bind (LSuccess); 3.1173 + xorptr(boxReg, boxReg); // set ICC.ZF=1 to indicate success 3.1174 + jmpb (DONE_LABEL); 3.1175 + } 3.1176 + 3.1177 + bind (Stacked); 3.1178 + // It's not inflated and it's not recursively stack-locked and it's not biased. 3.1179 + // It must be stack-locked. 3.1180 + // Try to reset the header to displaced header. 3.1181 + // The "box" value on the stack is stable, so we can reload 3.1182 + // and be assured we observe the same value as above. 3.1183 + movptr(tmpReg, Address(boxReg, 0)); 3.1184 + if (os::is_MP()) { 3.1185 + lock(); 3.1186 + } 3.1187 + cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3.1188 + // Intention fall-thru into DONE_LABEL 3.1189 + 3.1190 + // DONE_LABEL is a hot target - we'd really like to place it at the 3.1191 + // start of cache line by padding with NOPs. 3.1192 + // See the AMD and Intel software optimization manuals for the 3.1193 + // most efficient "long" NOP encodings. 3.1194 + // Unfortunately none of our alignment mechanisms suffice. 3.1195 + if ((EmitSync & 65536) == 0) { 3.1196 + bind (CheckSucc); 3.1197 + } 3.1198 +#else // _LP64 3.1199 + // It's inflated 3.1200 + movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.1201 + xorptr(boxReg, r15_thread); 3.1202 + orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)); 3.1203 + jccb (Assembler::notZero, DONE_LABEL); 3.1204 + movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)); 3.1205 + orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)); 3.1206 + jccb (Assembler::notZero, CheckSucc); 3.1207 + movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD); 3.1208 + jmpb (DONE_LABEL); 3.1209 + 3.1210 + if ((EmitSync & 65536) == 0) { 3.1211 + Label LSuccess, LGoSlowPath ; 3.1212 + bind (CheckSucc); 3.1213 + cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD); 3.1214 + jccb (Assembler::zero, LGoSlowPath); 3.1215 + 3.1216 + // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 3.1217 + // the explicit ST;MEMBAR combination, but masm doesn't currently support 3.1218 + // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 3.1219 + // are all faster when the write buffer is populated. 3.1220 + movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD); 3.1221 + if (os::is_MP()) { 3.1222 + lock (); addl (Address(rsp, 0), 0); 3.1223 + } 3.1224 + cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD); 3.1225 + jccb (Assembler::notZero, LSuccess); 3.1226 + 3.1227 + movptr (boxReg, (int32_t)NULL_WORD); // box is really EAX 3.1228 + if (os::is_MP()) { lock(); } 3.1229 + cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3.1230 + jccb (Assembler::notEqual, LSuccess); 3.1231 + // Intentional fall-through into slow-path 3.1232 + 3.1233 + bind (LGoSlowPath); 3.1234 + orl (boxReg, 1); // set ICC.ZF=0 to indicate failure 3.1235 + jmpb (DONE_LABEL); 3.1236 + 3.1237 + bind (LSuccess); 3.1238 + testl (boxReg, 0); // set ICC.ZF=1 to indicate success 3.1239 + jmpb (DONE_LABEL); 3.1240 + } 3.1241 + 3.1242 + bind (Stacked); 3.1243 + movptr(tmpReg, Address (boxReg, 0)); // re-fetch 3.1244 + if (os::is_MP()) { lock(); } 3.1245 + cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3.1246 + 3.1247 + if (EmitSync & 65536) { 3.1248 + bind (CheckSucc); 3.1249 + } 3.1250 +#endif 3.1251 + bind(DONE_LABEL); 3.1252 + // Avoid branch to branch on AMD processors 3.1253 + if (EmitSync & 32768) { 3.1254 + nop(); 3.1255 + } 3.1256 + } 3.1257 +} 3.1258 +#endif // COMPILER2 3.1259 + 3.1260 void MacroAssembler::c2bool(Register x) { 3.1261 // implements x == 0 ? 0 : 1 3.1262 // note: must only look at least-significant byte of x
4.1 --- a/src/cpu/x86/vm/macroAssembler_x86.hpp Fri Mar 14 22:57:00 2014 -0700 4.2 +++ b/src/cpu/x86/vm/macroAssembler_x86.hpp Tue Mar 18 14:04:47 2014 -0700 4.3 @@ -651,7 +651,12 @@ 4.4 Label& done, Label* slow_case = NULL, 4.5 BiasedLockingCounters* counters = NULL); 4.6 void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done); 4.7 - 4.8 +#ifdef COMPILER2 4.9 + // Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file. 4.10 + // See full desription in macroAssembler_x86.cpp. 4.11 + void fast_lock(Register obj, Register box, Register tmp, Register scr, BiasedLockingCounters* counters); 4.12 + void fast_unlock(Register obj, Register box, Register tmp); 4.13 +#endif 4.14 4.15 Condition negate_condition(Condition cond); 4.16
5.1 --- a/src/cpu/x86/vm/x86_32.ad Fri Mar 14 22:57:00 2014 -0700 5.2 +++ b/src/cpu/x86/vm/x86_32.ad Tue Mar 18 14:04:47 2014 -0700 5.3 @@ -2910,542 +2910,6 @@ 5.4 emit_d8 (cbuf,0 ); 5.5 %} 5.6 5.7 - 5.8 - // Because the transitions from emitted code to the runtime 5.9 - // monitorenter/exit helper stubs are so slow it's critical that 5.10 - // we inline both the stack-locking fast-path and the inflated fast path. 5.11 - // 5.12 - // See also: cmpFastLock and cmpFastUnlock. 5.13 - // 5.14 - // What follows is a specialized inline transliteration of the code 5.15 - // in slow_enter() and slow_exit(). If we're concerned about I$ bloat 5.16 - // another option would be to emit TrySlowEnter and TrySlowExit methods 5.17 - // at startup-time. These methods would accept arguments as 5.18 - // (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure 5.19 - // indications in the icc.ZFlag. Fast_Lock and Fast_Unlock would simply 5.20 - // marshal the arguments and emit calls to TrySlowEnter and TrySlowExit. 5.21 - // In practice, however, the # of lock sites is bounded and is usually small. 5.22 - // Besides the call overhead, TrySlowEnter and TrySlowExit might suffer 5.23 - // if the processor uses simple bimodal branch predictors keyed by EIP 5.24 - // Since the helper routines would be called from multiple synchronization 5.25 - // sites. 5.26 - // 5.27 - // An even better approach would be write "MonitorEnter()" and "MonitorExit()" 5.28 - // in java - using j.u.c and unsafe - and just bind the lock and unlock sites 5.29 - // to those specialized methods. That'd give us a mostly platform-independent 5.30 - // implementation that the JITs could optimize and inline at their pleasure. 5.31 - // Done correctly, the only time we'd need to cross to native could would be 5.32 - // to park() or unpark() threads. We'd also need a few more unsafe operators 5.33 - // to (a) prevent compiler-JIT reordering of non-volatile accesses, and 5.34 - // (b) explicit barriers or fence operations. 5.35 - // 5.36 - // TODO: 5.37 - // 5.38 - // * Arrange for C2 to pass "Self" into Fast_Lock and Fast_Unlock in one of the registers (scr). 5.39 - // This avoids manifesting the Self pointer in the Fast_Lock and Fast_Unlock terminals. 5.40 - // Given TLAB allocation, Self is usually manifested in a register, so passing it into 5.41 - // the lock operators would typically be faster than reifying Self. 5.42 - // 5.43 - // * Ideally I'd define the primitives as: 5.44 - // fast_lock (nax Obj, nax box, EAX tmp, nax scr) where box, tmp and scr are KILLED. 5.45 - // fast_unlock (nax Obj, EAX box, nax tmp) where box and tmp are KILLED 5.46 - // Unfortunately ADLC bugs prevent us from expressing the ideal form. 5.47 - // Instead, we're stuck with a rather awkward and brittle register assignments below. 5.48 - // Furthermore the register assignments are overconstrained, possibly resulting in 5.49 - // sub-optimal code near the synchronization site. 5.50 - // 5.51 - // * Eliminate the sp-proximity tests and just use "== Self" tests instead. 5.52 - // Alternately, use a better sp-proximity test. 5.53 - // 5.54 - // * Currently ObjectMonitor._Owner can hold either an sp value or a (THREAD *) value. 5.55 - // Either one is sufficient to uniquely identify a thread. 5.56 - // TODO: eliminate use of sp in _owner and use get_thread(tr) instead. 5.57 - // 5.58 - // * Intrinsify notify() and notifyAll() for the common cases where the 5.59 - // object is locked by the calling thread but the waitlist is empty. 5.60 - // avoid the expensive JNI call to JVM_Notify() and JVM_NotifyAll(). 5.61 - // 5.62 - // * use jccb and jmpb instead of jcc and jmp to improve code density. 5.63 - // But beware of excessive branch density on AMD Opterons. 5.64 - // 5.65 - // * Both Fast_Lock and Fast_Unlock set the ICC.ZF to indicate success 5.66 - // or failure of the fast-path. If the fast-path fails then we pass 5.67 - // control to the slow-path, typically in C. In Fast_Lock and 5.68 - // Fast_Unlock we often branch to DONE_LABEL, just to find that C2 5.69 - // will emit a conditional branch immediately after the node. 5.70 - // So we have branches to branches and lots of ICC.ZF games. 5.71 - // Instead, it might be better to have C2 pass a "FailureLabel" 5.72 - // into Fast_Lock and Fast_Unlock. In the case of success, control 5.73 - // will drop through the node. ICC.ZF is undefined at exit. 5.74 - // In the case of failure, the node will branch directly to the 5.75 - // FailureLabel 5.76 - 5.77 - 5.78 - // obj: object to lock 5.79 - // box: on-stack box address (displaced header location) - KILLED 5.80 - // rax,: tmp -- KILLED 5.81 - // scr: tmp -- KILLED 5.82 - enc_class Fast_Lock( eRegP obj, eRegP box, eAXRegI tmp, eRegP scr ) %{ 5.83 - 5.84 - Register objReg = as_Register($obj$$reg); 5.85 - Register boxReg = as_Register($box$$reg); 5.86 - Register tmpReg = as_Register($tmp$$reg); 5.87 - Register scrReg = as_Register($scr$$reg); 5.88 - 5.89 - // Ensure the register assignents are disjoint 5.90 - guarantee (objReg != boxReg, "") ; 5.91 - guarantee (objReg != tmpReg, "") ; 5.92 - guarantee (objReg != scrReg, "") ; 5.93 - guarantee (boxReg != tmpReg, "") ; 5.94 - guarantee (boxReg != scrReg, "") ; 5.95 - guarantee (tmpReg == as_Register(EAX_enc), "") ; 5.96 - 5.97 - MacroAssembler masm(&cbuf); 5.98 - 5.99 - if (_counters != NULL) { 5.100 - masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 5.101 - } 5.102 - if (EmitSync & 1) { 5.103 - // set box->dhw = unused_mark (3) 5.104 - // Force all sync thru slow-path: slow_enter() and slow_exit() 5.105 - masm.movptr (Address(boxReg, 0), int32_t(markOopDesc::unused_mark())) ; 5.106 - masm.cmpptr (rsp, (int32_t)0) ; 5.107 - } else 5.108 - if (EmitSync & 2) { 5.109 - Label DONE_LABEL ; 5.110 - if (UseBiasedLocking) { 5.111 - // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 5.112 - masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 5.113 - } 5.114 - 5.115 - masm.movptr(tmpReg, Address(objReg, 0)) ; // fetch markword 5.116 - masm.orptr (tmpReg, 0x1); 5.117 - masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS 5.118 - if (os::is_MP()) { masm.lock(); } 5.119 - masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 5.120 - masm.jcc(Assembler::equal, DONE_LABEL); 5.121 - // Recursive locking 5.122 - masm.subptr(tmpReg, rsp); 5.123 - masm.andptr(tmpReg, (int32_t) 0xFFFFF003 ); 5.124 - masm.movptr(Address(boxReg, 0), tmpReg); 5.125 - masm.bind(DONE_LABEL) ; 5.126 - } else { 5.127 - // Possible cases that we'll encounter in fast_lock 5.128 - // ------------------------------------------------ 5.129 - // * Inflated 5.130 - // -- unlocked 5.131 - // -- Locked 5.132 - // = by self 5.133 - // = by other 5.134 - // * biased 5.135 - // -- by Self 5.136 - // -- by other 5.137 - // * neutral 5.138 - // * stack-locked 5.139 - // -- by self 5.140 - // = sp-proximity test hits 5.141 - // = sp-proximity test generates false-negative 5.142 - // -- by other 5.143 - // 5.144 - 5.145 - Label IsInflated, DONE_LABEL, PopDone ; 5.146 - 5.147 - // TODO: optimize away redundant LDs of obj->mark and improve the markword triage 5.148 - // order to reduce the number of conditional branches in the most common cases. 5.149 - // Beware -- there's a subtle invariant that fetch of the markword 5.150 - // at [FETCH], below, will never observe a biased encoding (*101b). 5.151 - // If this invariant is not held we risk exclusion (safety) failure. 5.152 - if (UseBiasedLocking && !UseOptoBiasInlining) { 5.153 - masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 5.154 - } 5.155 - 5.156 - masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 5.157 - masm.testptr(tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) 5.158 - masm.jccb (Assembler::notZero, IsInflated) ; 5.159 - 5.160 - // Attempt stack-locking ... 5.161 - masm.orptr (tmpReg, 0x1); 5.162 - masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS 5.163 - if (os::is_MP()) { masm.lock(); } 5.164 - masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 5.165 - if (_counters != NULL) { 5.166 - masm.cond_inc32(Assembler::equal, 5.167 - ExternalAddress((address)_counters->fast_path_entry_count_addr())); 5.168 - } 5.169 - masm.jccb (Assembler::equal, DONE_LABEL); 5.170 - 5.171 - // Recursive locking 5.172 - masm.subptr(tmpReg, rsp); 5.173 - masm.andptr(tmpReg, 0xFFFFF003 ); 5.174 - masm.movptr(Address(boxReg, 0), tmpReg); 5.175 - if (_counters != NULL) { 5.176 - masm.cond_inc32(Assembler::equal, 5.177 - ExternalAddress((address)_counters->fast_path_entry_count_addr())); 5.178 - } 5.179 - masm.jmp (DONE_LABEL) ; 5.180 - 5.181 - masm.bind (IsInflated) ; 5.182 - 5.183 - // The object is inflated. 5.184 - // 5.185 - // TODO-FIXME: eliminate the ugly use of manifest constants: 5.186 - // Use markOopDesc::monitor_value instead of "2". 5.187 - // use markOop::unused_mark() instead of "3". 5.188 - // The tmpReg value is an objectMonitor reference ORed with 5.189 - // markOopDesc::monitor_value (2). We can either convert tmpReg to an 5.190 - // objectmonitor pointer by masking off the "2" bit or we can just 5.191 - // use tmpReg as an objectmonitor pointer but bias the objectmonitor 5.192 - // field offsets with "-2" to compensate for and annul the low-order tag bit. 5.193 - // 5.194 - // I use the latter as it avoids AGI stalls. 5.195 - // As such, we write "mov r, [tmpReg+OFFSETOF(Owner)-2]" 5.196 - // instead of "mov r, [tmpReg+OFFSETOF(Owner)]". 5.197 - // 5.198 - #define OFFSET_SKEWED(f) ((ObjectMonitor::f ## _offset_in_bytes())-2) 5.199 - 5.200 - // boxReg refers to the on-stack BasicLock in the current frame. 5.201 - // We'd like to write: 5.202 - // set box->_displaced_header = markOop::unused_mark(). Any non-0 value suffices. 5.203 - // This is convenient but results a ST-before-CAS penalty. The following CAS suffers 5.204 - // additional latency as we have another ST in the store buffer that must drain. 5.205 - 5.206 - if (EmitSync & 8192) { 5.207 - masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty 5.208 - masm.get_thread (scrReg) ; 5.209 - masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 5.210 - masm.movptr(tmpReg, NULL_WORD); // consider: xor vs mov 5.211 - if (os::is_MP()) { masm.lock(); } 5.212 - masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 5.213 - } else 5.214 - if ((EmitSync & 128) == 0) { // avoid ST-before-CAS 5.215 - masm.movptr(scrReg, boxReg) ; 5.216 - masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 5.217 - 5.218 - // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 5.219 - if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 5.220 - // prefetchw [eax + Offset(_owner)-2] 5.221 - masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); 5.222 - } 5.223 - 5.224 - if ((EmitSync & 64) == 0) { 5.225 - // Optimistic form: consider XORL tmpReg,tmpReg 5.226 - masm.movptr(tmpReg, NULL_WORD) ; 5.227 - } else { 5.228 - // Can suffer RTS->RTO upgrades on shared or cold $ lines 5.229 - // Test-And-CAS instead of CAS 5.230 - masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner 5.231 - masm.testptr(tmpReg, tmpReg) ; // Locked ? 5.232 - masm.jccb (Assembler::notZero, DONE_LABEL) ; 5.233 - } 5.234 - 5.235 - // Appears unlocked - try to swing _owner from null to non-null. 5.236 - // Ideally, I'd manifest "Self" with get_thread and then attempt 5.237 - // to CAS the register containing Self into m->Owner. 5.238 - // But we don't have enough registers, so instead we can either try to CAS 5.239 - // rsp or the address of the box (in scr) into &m->owner. If the CAS succeeds 5.240 - // we later store "Self" into m->Owner. Transiently storing a stack address 5.241 - // (rsp or the address of the box) into m->owner is harmless. 5.242 - // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. 5.243 - if (os::is_MP()) { masm.lock(); } 5.244 - masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 5.245 - masm.movptr(Address(scrReg, 0), 3) ; // box->_displaced_header = 3 5.246 - masm.jccb (Assembler::notZero, DONE_LABEL) ; 5.247 - masm.get_thread (scrReg) ; // beware: clobbers ICCs 5.248 - masm.movptr(Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg) ; 5.249 - masm.xorptr(boxReg, boxReg) ; // set icc.ZFlag = 1 to indicate success 5.250 - 5.251 - // If the CAS fails we can either retry or pass control to the slow-path. 5.252 - // We use the latter tactic. 5.253 - // Pass the CAS result in the icc.ZFlag into DONE_LABEL 5.254 - // If the CAS was successful ... 5.255 - // Self has acquired the lock 5.256 - // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. 5.257 - // Intentional fall-through into DONE_LABEL ... 5.258 - } else { 5.259 - masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty 5.260 - masm.movptr(boxReg, tmpReg) ; 5.261 - 5.262 - // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 5.263 - if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 5.264 - // prefetchw [eax + Offset(_owner)-2] 5.265 - masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); 5.266 - } 5.267 - 5.268 - if ((EmitSync & 64) == 0) { 5.269 - // Optimistic form 5.270 - masm.xorptr (tmpReg, tmpReg) ; 5.271 - } else { 5.272 - // Can suffer RTS->RTO upgrades on shared or cold $ lines 5.273 - masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner 5.274 - masm.testptr(tmpReg, tmpReg) ; // Locked ? 5.275 - masm.jccb (Assembler::notZero, DONE_LABEL) ; 5.276 - } 5.277 - 5.278 - // Appears unlocked - try to swing _owner from null to non-null. 5.279 - // Use either "Self" (in scr) or rsp as thread identity in _owner. 5.280 - // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. 5.281 - masm.get_thread (scrReg) ; 5.282 - if (os::is_MP()) { masm.lock(); } 5.283 - masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 5.284 - 5.285 - // If the CAS fails we can either retry or pass control to the slow-path. 5.286 - // We use the latter tactic. 5.287 - // Pass the CAS result in the icc.ZFlag into DONE_LABEL 5.288 - // If the CAS was successful ... 5.289 - // Self has acquired the lock 5.290 - // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. 5.291 - // Intentional fall-through into DONE_LABEL ... 5.292 - } 5.293 - 5.294 - // DONE_LABEL is a hot target - we'd really like to place it at the 5.295 - // start of cache line by padding with NOPs. 5.296 - // See the AMD and Intel software optimization manuals for the 5.297 - // most efficient "long" NOP encodings. 5.298 - // Unfortunately none of our alignment mechanisms suffice. 5.299 - masm.bind(DONE_LABEL); 5.300 - 5.301 - // Avoid branch-to-branch on AMD processors 5.302 - // This appears to be superstition. 5.303 - if (EmitSync & 32) masm.nop() ; 5.304 - 5.305 - 5.306 - // At DONE_LABEL the icc ZFlag is set as follows ... 5.307 - // Fast_Unlock uses the same protocol. 5.308 - // ZFlag == 1 -> Success 5.309 - // ZFlag == 0 -> Failure - force control through the slow-path 5.310 - } 5.311 - %} 5.312 - 5.313 - // obj: object to unlock 5.314 - // box: box address (displaced header location), killed. Must be EAX. 5.315 - // rbx,: killed tmp; cannot be obj nor box. 5.316 - // 5.317 - // Some commentary on balanced locking: 5.318 - // 5.319 - // Fast_Lock and Fast_Unlock are emitted only for provably balanced lock sites. 5.320 - // Methods that don't have provably balanced locking are forced to run in the 5.321 - // interpreter - such methods won't be compiled to use fast_lock and fast_unlock. 5.322 - // The interpreter provides two properties: 5.323 - // I1: At return-time the interpreter automatically and quietly unlocks any 5.324 - // objects acquired the current activation (frame). Recall that the 5.325 - // interpreter maintains an on-stack list of locks currently held by 5.326 - // a frame. 5.327 - // I2: If a method attempts to unlock an object that is not held by the 5.328 - // the frame the interpreter throws IMSX. 5.329 - // 5.330 - // Lets say A(), which has provably balanced locking, acquires O and then calls B(). 5.331 - // B() doesn't have provably balanced locking so it runs in the interpreter. 5.332 - // Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O 5.333 - // is still locked by A(). 5.334 - // 5.335 - // The only other source of unbalanced locking would be JNI. The "Java Native Interface: 5.336 - // Programmer's Guide and Specification" claims that an object locked by jni_monitorenter 5.337 - // should not be unlocked by "normal" java-level locking and vice-versa. The specification 5.338 - // doesn't specify what will occur if a program engages in such mixed-mode locking, however. 5.339 - 5.340 - enc_class Fast_Unlock( nabxRegP obj, eAXRegP box, eRegP tmp) %{ 5.341 - 5.342 - Register objReg = as_Register($obj$$reg); 5.343 - Register boxReg = as_Register($box$$reg); 5.344 - Register tmpReg = as_Register($tmp$$reg); 5.345 - 5.346 - guarantee (objReg != boxReg, "") ; 5.347 - guarantee (objReg != tmpReg, "") ; 5.348 - guarantee (boxReg != tmpReg, "") ; 5.349 - guarantee (boxReg == as_Register(EAX_enc), "") ; 5.350 - MacroAssembler masm(&cbuf); 5.351 - 5.352 - if (EmitSync & 4) { 5.353 - // Disable - inhibit all inlining. Force control through the slow-path 5.354 - masm.cmpptr (rsp, 0) ; 5.355 - } else 5.356 - if (EmitSync & 8) { 5.357 - Label DONE_LABEL ; 5.358 - if (UseBiasedLocking) { 5.359 - masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 5.360 - } 5.361 - // classic stack-locking code ... 5.362 - masm.movptr(tmpReg, Address(boxReg, 0)) ; 5.363 - masm.testptr(tmpReg, tmpReg) ; 5.364 - masm.jcc (Assembler::zero, DONE_LABEL) ; 5.365 - if (os::is_MP()) { masm.lock(); } 5.366 - masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box 5.367 - masm.bind(DONE_LABEL); 5.368 - } else { 5.369 - Label DONE_LABEL, Stacked, CheckSucc, Inflated ; 5.370 - 5.371 - // Critically, the biased locking test must have precedence over 5.372 - // and appear before the (box->dhw == 0) recursive stack-lock test. 5.373 - if (UseBiasedLocking && !UseOptoBiasInlining) { 5.374 - masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 5.375 - } 5.376 - 5.377 - masm.cmpptr(Address(boxReg, 0), 0) ; // Examine the displaced header 5.378 - masm.movptr(tmpReg, Address(objReg, 0)) ; // Examine the object's markword 5.379 - masm.jccb (Assembler::zero, DONE_LABEL) ; // 0 indicates recursive stack-lock 5.380 - 5.381 - masm.testptr(tmpReg, 0x02) ; // Inflated? 5.382 - masm.jccb (Assembler::zero, Stacked) ; 5.383 - 5.384 - masm.bind (Inflated) ; 5.385 - // It's inflated. 5.386 - // Despite our balanced locking property we still check that m->_owner == Self 5.387 - // as java routines or native JNI code called by this thread might 5.388 - // have released the lock. 5.389 - // Refer to the comments in synchronizer.cpp for how we might encode extra 5.390 - // state in _succ so we can avoid fetching EntryList|cxq. 5.391 - // 5.392 - // I'd like to add more cases in fast_lock() and fast_unlock() -- 5.393 - // such as recursive enter and exit -- but we have to be wary of 5.394 - // I$ bloat, T$ effects and BP$ effects. 5.395 - // 5.396 - // If there's no contention try a 1-0 exit. That is, exit without 5.397 - // a costly MEMBAR or CAS. See synchronizer.cpp for details on how 5.398 - // we detect and recover from the race that the 1-0 exit admits. 5.399 - // 5.400 - // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier 5.401 - // before it STs null into _owner, releasing the lock. Updates 5.402 - // to data protected by the critical section must be visible before 5.403 - // we drop the lock (and thus before any other thread could acquire 5.404 - // the lock and observe the fields protected by the lock). 5.405 - // IA32's memory-model is SPO, so STs are ordered with respect to 5.406 - // each other and there's no need for an explicit barrier (fence). 5.407 - // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html. 5.408 - 5.409 - masm.get_thread (boxReg) ; 5.410 - if ((EmitSync & 4096) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 5.411 - // prefetchw [ebx + Offset(_owner)-2] 5.412 - masm.prefetchw(Address(rbx, ObjectMonitor::owner_offset_in_bytes()-2)); 5.413 - } 5.414 - 5.415 - // Note that we could employ various encoding schemes to reduce 5.416 - // the number of loads below (currently 4) to just 2 or 3. 5.417 - // Refer to the comments in synchronizer.cpp. 5.418 - // In practice the chain of fetches doesn't seem to impact performance, however. 5.419 - if ((EmitSync & 65536) == 0 && (EmitSync & 256)) { 5.420 - // Attempt to reduce branch density - AMD's branch predictor. 5.421 - masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 5.422 - masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 5.423 - masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 5.424 - masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 5.425 - masm.jccb (Assembler::notZero, DONE_LABEL) ; 5.426 - masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 5.427 - masm.jmpb (DONE_LABEL) ; 5.428 - } else { 5.429 - masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 5.430 - masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 5.431 - masm.jccb (Assembler::notZero, DONE_LABEL) ; 5.432 - masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 5.433 - masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 5.434 - masm.jccb (Assembler::notZero, CheckSucc) ; 5.435 - masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 5.436 - masm.jmpb (DONE_LABEL) ; 5.437 - } 5.438 - 5.439 - // The Following code fragment (EmitSync & 65536) improves the performance of 5.440 - // contended applications and contended synchronization microbenchmarks. 5.441 - // Unfortunately the emission of the code - even though not executed - causes regressions 5.442 - // in scimark and jetstream, evidently because of $ effects. Replacing the code 5.443 - // with an equal number of never-executed NOPs results in the same regression. 5.444 - // We leave it off by default. 5.445 - 5.446 - if ((EmitSync & 65536) != 0) { 5.447 - Label LSuccess, LGoSlowPath ; 5.448 - 5.449 - masm.bind (CheckSucc) ; 5.450 - 5.451 - // Optional pre-test ... it's safe to elide this 5.452 - if ((EmitSync & 16) == 0) { 5.453 - masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; 5.454 - masm.jccb (Assembler::zero, LGoSlowPath) ; 5.455 - } 5.456 - 5.457 - // We have a classic Dekker-style idiom: 5.458 - // ST m->_owner = 0 ; MEMBAR; LD m->_succ 5.459 - // There are a number of ways to implement the barrier: 5.460 - // (1) lock:andl &m->_owner, 0 5.461 - // is fast, but mask doesn't currently support the "ANDL M,IMM32" form. 5.462 - // LOCK: ANDL [ebx+Offset(_Owner)-2], 0 5.463 - // Encodes as 81 31 OFF32 IMM32 or 83 63 OFF8 IMM8 5.464 - // (2) If supported, an explicit MFENCE is appealing. 5.465 - // In older IA32 processors MFENCE is slower than lock:add or xchg 5.466 - // particularly if the write-buffer is full as might be the case if 5.467 - // if stores closely precede the fence or fence-equivalent instruction. 5.468 - // In more modern implementations MFENCE appears faster, however. 5.469 - // (3) In lieu of an explicit fence, use lock:addl to the top-of-stack 5.470 - // The $lines underlying the top-of-stack should be in M-state. 5.471 - // The locked add instruction is serializing, of course. 5.472 - // (4) Use xchg, which is serializing 5.473 - // mov boxReg, 0; xchgl boxReg, [tmpReg + Offset(_owner)-2] also works 5.474 - // (5) ST m->_owner = 0 and then execute lock:orl &m->_succ, 0. 5.475 - // The integer condition codes will tell us if succ was 0. 5.476 - // Since _succ and _owner should reside in the same $line and 5.477 - // we just stored into _owner, it's likely that the $line 5.478 - // remains in M-state for the lock:orl. 5.479 - // 5.480 - // We currently use (3), although it's likely that switching to (2) 5.481 - // is correct for the future. 5.482 - 5.483 - masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 5.484 - if (os::is_MP()) { 5.485 - if (VM_Version::supports_sse2() && 1 == FenceInstruction) { 5.486 - masm.mfence(); 5.487 - } else { 5.488 - masm.lock () ; masm.addptr(Address(rsp, 0), 0) ; 5.489 - } 5.490 - } 5.491 - // Ratify _succ remains non-null 5.492 - masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; 5.493 - masm.jccb (Assembler::notZero, LSuccess) ; 5.494 - 5.495 - masm.xorptr(boxReg, boxReg) ; // box is really EAX 5.496 - if (os::is_MP()) { masm.lock(); } 5.497 - masm.cmpxchgptr(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 5.498 - masm.jccb (Assembler::notEqual, LSuccess) ; 5.499 - // Since we're low on registers we installed rsp as a placeholding in _owner. 5.500 - // Now install Self over rsp. This is safe as we're transitioning from 5.501 - // non-null to non=null 5.502 - masm.get_thread (boxReg) ; 5.503 - masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg) ; 5.504 - // Intentional fall-through into LGoSlowPath ... 5.505 - 5.506 - masm.bind (LGoSlowPath) ; 5.507 - masm.orptr(boxReg, 1) ; // set ICC.ZF=0 to indicate failure 5.508 - masm.jmpb (DONE_LABEL) ; 5.509 - 5.510 - masm.bind (LSuccess) ; 5.511 - masm.xorptr(boxReg, boxReg) ; // set ICC.ZF=1 to indicate success 5.512 - masm.jmpb (DONE_LABEL) ; 5.513 - } 5.514 - 5.515 - masm.bind (Stacked) ; 5.516 - // It's not inflated and it's not recursively stack-locked and it's not biased. 5.517 - // It must be stack-locked. 5.518 - // Try to reset the header to displaced header. 5.519 - // The "box" value on the stack is stable, so we can reload 5.520 - // and be assured we observe the same value as above. 5.521 - masm.movptr(tmpReg, Address(boxReg, 0)) ; 5.522 - if (os::is_MP()) { masm.lock(); } 5.523 - masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box 5.524 - // Intention fall-thru into DONE_LABEL 5.525 - 5.526 - 5.527 - // DONE_LABEL is a hot target - we'd really like to place it at the 5.528 - // start of cache line by padding with NOPs. 5.529 - // See the AMD and Intel software optimization manuals for the 5.530 - // most efficient "long" NOP encodings. 5.531 - // Unfortunately none of our alignment mechanisms suffice. 5.532 - if ((EmitSync & 65536) == 0) { 5.533 - masm.bind (CheckSucc) ; 5.534 - } 5.535 - masm.bind(DONE_LABEL); 5.536 - 5.537 - // Avoid branch to branch on AMD processors 5.538 - if (EmitSync & 32768) { masm.nop() ; } 5.539 - } 5.540 - %} 5.541 - 5.542 - 5.543 enc_class enc_pop_rdx() %{ 5.544 emit_opcode(cbuf,0x5A); 5.545 %} 5.546 @@ -13147,23 +12611,26 @@ 5.547 5.548 // inlined locking and unlocking 5.549 5.550 - 5.551 -instruct cmpFastLock( eFlagsReg cr, eRegP object, eBXRegP box, eAXRegI tmp, eRegP scr) %{ 5.552 - match( Set cr (FastLock object box) ); 5.553 - effect( TEMP tmp, TEMP scr, USE_KILL box ); 5.554 +instruct cmpFastLock(eFlagsReg cr, eRegP object, eBXRegP box, eAXRegI tmp, eRegP scr) %{ 5.555 + match(Set cr (FastLock object box)); 5.556 + effect(TEMP tmp, TEMP scr, USE_KILL box); 5.557 ins_cost(300); 5.558 format %{ "FASTLOCK $object,$box\t! kills $box,$tmp,$scr" %} 5.559 - ins_encode( Fast_Lock(object,box,tmp,scr) ); 5.560 - ins_pipe( pipe_slow ); 5.561 -%} 5.562 - 5.563 -instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{ 5.564 - match( Set cr (FastUnlock object box) ); 5.565 - effect( TEMP tmp, USE_KILL box ); 5.566 + ins_encode %{ 5.567 + __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register, _counters); 5.568 + %} 5.569 + ins_pipe(pipe_slow); 5.570 +%} 5.571 + 5.572 +instruct cmpFastUnlock(eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{ 5.573 + match(Set cr (FastUnlock object box)); 5.574 + effect(TEMP tmp, USE_KILL box); 5.575 ins_cost(300); 5.576 format %{ "FASTUNLOCK $object,$box\t! kills $box,$tmp" %} 5.577 - ins_encode( Fast_Unlock(object,box,tmp) ); 5.578 - ins_pipe( pipe_slow ); 5.579 + ins_encode %{ 5.580 + __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 5.581 + %} 5.582 + ins_pipe(pipe_slow); 5.583 %} 5.584 5.585
6.1 --- a/src/cpu/x86/vm/x86_64.ad Fri Mar 14 22:57:00 2014 -0700 6.2 +++ b/src/cpu/x86/vm/x86_64.ad Tue Mar 18 14:04:47 2014 -0700 6.3 @@ -2591,231 +2591,6 @@ 6.4 %} 6.5 6.6 6.7 - // obj: object to lock 6.8 - // box: box address (header location) -- killed 6.9 - // tmp: rax -- killed 6.10 - // scr: rbx -- killed 6.11 - // 6.12 - // What follows is a direct transliteration of fast_lock() and fast_unlock() 6.13 - // from i486.ad. See that file for comments. 6.14 - // TODO: where possible switch from movq (r, 0) to movl(r,0) and 6.15 - // use the shorter encoding. (Movl clears the high-order 32-bits). 6.16 - 6.17 - 6.18 - enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 6.19 - %{ 6.20 - Register objReg = as_Register((int)$obj$$reg); 6.21 - Register boxReg = as_Register((int)$box$$reg); 6.22 - Register tmpReg = as_Register($tmp$$reg); 6.23 - Register scrReg = as_Register($scr$$reg); 6.24 - MacroAssembler masm(&cbuf); 6.25 - 6.26 - // Verify uniqueness of register assignments -- necessary but not sufficient 6.27 - assert (objReg != boxReg && objReg != tmpReg && 6.28 - objReg != scrReg && tmpReg != scrReg, "invariant") ; 6.29 - 6.30 - if (_counters != NULL) { 6.31 - masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 6.32 - } 6.33 - if (EmitSync & 1) { 6.34 - // Without cast to int32_t a movptr will destroy r10 which is typically obj 6.35 - masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 6.36 - masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 6.37 - } else 6.38 - if (EmitSync & 2) { 6.39 - Label DONE_LABEL; 6.40 - if (UseBiasedLocking) { 6.41 - // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 6.42 - masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 6.43 - } 6.44 - // QQQ was movl... 6.45 - masm.movptr(tmpReg, 0x1); 6.46 - masm.orptr(tmpReg, Address(objReg, 0)); 6.47 - masm.movptr(Address(boxReg, 0), tmpReg); 6.48 - if (os::is_MP()) { 6.49 - masm.lock(); 6.50 - } 6.51 - masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 6.52 - masm.jcc(Assembler::equal, DONE_LABEL); 6.53 - 6.54 - // Recursive locking 6.55 - masm.subptr(tmpReg, rsp); 6.56 - masm.andptr(tmpReg, 7 - os::vm_page_size()); 6.57 - masm.movptr(Address(boxReg, 0), tmpReg); 6.58 - 6.59 - masm.bind(DONE_LABEL); 6.60 - masm.nop(); // avoid branch to branch 6.61 - } else { 6.62 - Label DONE_LABEL, IsInflated, Egress; 6.63 - 6.64 - masm.movptr(tmpReg, Address(objReg, 0)) ; 6.65 - masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 6.66 - masm.jcc (Assembler::notZero, IsInflated) ; 6.67 - 6.68 - // it's stack-locked, biased or neutral 6.69 - // TODO: optimize markword triage order to reduce the number of 6.70 - // conditional branches in the most common cases. 6.71 - // Beware -- there's a subtle invariant that fetch of the markword 6.72 - // at [FETCH], below, will never observe a biased encoding (*101b). 6.73 - // If this invariant is not held we'll suffer exclusion (safety) failure. 6.74 - 6.75 - if (UseBiasedLocking && !UseOptoBiasInlining) { 6.76 - masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 6.77 - masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 6.78 - } 6.79 - 6.80 - // was q will it destroy high? 6.81 - masm.orl (tmpReg, 1) ; 6.82 - masm.movptr(Address(boxReg, 0), tmpReg) ; 6.83 - if (os::is_MP()) { masm.lock(); } 6.84 - masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 6.85 - if (_counters != NULL) { 6.86 - masm.cond_inc32(Assembler::equal, 6.87 - ExternalAddress((address) _counters->fast_path_entry_count_addr())); 6.88 - } 6.89 - masm.jcc (Assembler::equal, DONE_LABEL); 6.90 - 6.91 - // Recursive locking 6.92 - masm.subptr(tmpReg, rsp); 6.93 - masm.andptr(tmpReg, 7 - os::vm_page_size()); 6.94 - masm.movptr(Address(boxReg, 0), tmpReg); 6.95 - if (_counters != NULL) { 6.96 - masm.cond_inc32(Assembler::equal, 6.97 - ExternalAddress((address) _counters->fast_path_entry_count_addr())); 6.98 - } 6.99 - masm.jmp (DONE_LABEL) ; 6.100 - 6.101 - masm.bind (IsInflated) ; 6.102 - // It's inflated 6.103 - 6.104 - // TODO: someday avoid the ST-before-CAS penalty by 6.105 - // relocating (deferring) the following ST. 6.106 - // We should also think about trying a CAS without having 6.107 - // fetched _owner. If the CAS is successful we may 6.108 - // avoid an RTO->RTS upgrade on the $line. 6.109 - // Without cast to int32_t a movptr will destroy r10 which is typically obj 6.110 - masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 6.111 - 6.112 - masm.mov (boxReg, tmpReg) ; 6.113 - masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 6.114 - masm.testptr(tmpReg, tmpReg) ; 6.115 - masm.jcc (Assembler::notZero, DONE_LABEL) ; 6.116 - 6.117 - // It's inflated and appears unlocked 6.118 - if (os::is_MP()) { masm.lock(); } 6.119 - masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 6.120 - // Intentional fall-through into DONE_LABEL ... 6.121 - 6.122 - masm.bind (DONE_LABEL) ; 6.123 - masm.nop () ; // avoid jmp to jmp 6.124 - } 6.125 - %} 6.126 - 6.127 - // obj: object to unlock 6.128 - // box: box address (displaced header location), killed 6.129 - // RBX: killed tmp; cannot be obj nor box 6.130 - enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 6.131 - %{ 6.132 - 6.133 - Register objReg = as_Register($obj$$reg); 6.134 - Register boxReg = as_Register($box$$reg); 6.135 - Register tmpReg = as_Register($tmp$$reg); 6.136 - MacroAssembler masm(&cbuf); 6.137 - 6.138 - if (EmitSync & 4) { 6.139 - masm.cmpptr(rsp, 0) ; 6.140 - } else 6.141 - if (EmitSync & 8) { 6.142 - Label DONE_LABEL; 6.143 - if (UseBiasedLocking) { 6.144 - masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 6.145 - } 6.146 - 6.147 - // Check whether the displaced header is 0 6.148 - //(=> recursive unlock) 6.149 - masm.movptr(tmpReg, Address(boxReg, 0)); 6.150 - masm.testptr(tmpReg, tmpReg); 6.151 - masm.jcc(Assembler::zero, DONE_LABEL); 6.152 - 6.153 - // If not recursive lock, reset the header to displaced header 6.154 - if (os::is_MP()) { 6.155 - masm.lock(); 6.156 - } 6.157 - masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 6.158 - masm.bind(DONE_LABEL); 6.159 - masm.nop(); // avoid branch to branch 6.160 - } else { 6.161 - Label DONE_LABEL, Stacked, CheckSucc ; 6.162 - 6.163 - if (UseBiasedLocking && !UseOptoBiasInlining) { 6.164 - masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 6.165 - } 6.166 - 6.167 - masm.movptr(tmpReg, Address(objReg, 0)) ; 6.168 - masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 6.169 - masm.jcc (Assembler::zero, DONE_LABEL) ; 6.170 - masm.testl (tmpReg, 0x02) ; 6.171 - masm.jcc (Assembler::zero, Stacked) ; 6.172 - 6.173 - // It's inflated 6.174 - masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 6.175 - masm.xorptr(boxReg, r15_thread) ; 6.176 - masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 6.177 - masm.jcc (Assembler::notZero, DONE_LABEL) ; 6.178 - masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 6.179 - masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 6.180 - masm.jcc (Assembler::notZero, CheckSucc) ; 6.181 - masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 6.182 - masm.jmp (DONE_LABEL) ; 6.183 - 6.184 - if ((EmitSync & 65536) == 0) { 6.185 - Label LSuccess, LGoSlowPath ; 6.186 - masm.bind (CheckSucc) ; 6.187 - masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 6.188 - masm.jcc (Assembler::zero, LGoSlowPath) ; 6.189 - 6.190 - // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 6.191 - // the explicit ST;MEMBAR combination, but masm doesn't currently support 6.192 - // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 6.193 - // are all faster when the write buffer is populated. 6.194 - masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 6.195 - if (os::is_MP()) { 6.196 - masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 6.197 - } 6.198 - masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 6.199 - masm.jcc (Assembler::notZero, LSuccess) ; 6.200 - 6.201 - masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 6.202 - if (os::is_MP()) { masm.lock(); } 6.203 - masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 6.204 - masm.jcc (Assembler::notEqual, LSuccess) ; 6.205 - // Intentional fall-through into slow-path 6.206 - 6.207 - masm.bind (LGoSlowPath) ; 6.208 - masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 6.209 - masm.jmp (DONE_LABEL) ; 6.210 - 6.211 - masm.bind (LSuccess) ; 6.212 - masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 6.213 - masm.jmp (DONE_LABEL) ; 6.214 - } 6.215 - 6.216 - masm.bind (Stacked) ; 6.217 - masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 6.218 - if (os::is_MP()) { masm.lock(); } 6.219 - masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 6.220 - 6.221 - if (EmitSync & 65536) { 6.222 - masm.bind (CheckSucc) ; 6.223 - } 6.224 - masm.bind(DONE_LABEL); 6.225 - if (EmitSync & 32768) { 6.226 - masm.nop(); // avoid branch to branch 6.227 - } 6.228 - } 6.229 - %} 6.230 - 6.231 - 6.232 enc_class enc_rethrow() 6.233 %{ 6.234 cbuf.set_insts_mark(); 6.235 @@ -11443,27 +11218,25 @@ 6.236 // ============================================================================ 6.237 // inlined locking and unlocking 6.238 6.239 -instruct cmpFastLock(rFlagsReg cr, 6.240 - rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) 6.241 -%{ 6.242 +instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 6.243 match(Set cr (FastLock object box)); 6.244 effect(TEMP tmp, TEMP scr, USE_KILL box); 6.245 - 6.246 ins_cost(300); 6.247 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 6.248 - ins_encode(Fast_Lock(object, box, tmp, scr)); 6.249 + ins_encode %{ 6.250 + __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register, _counters); 6.251 + %} 6.252 ins_pipe(pipe_slow); 6.253 %} 6.254 6.255 -instruct cmpFastUnlock(rFlagsReg cr, 6.256 - rRegP object, rax_RegP box, rRegP tmp) 6.257 -%{ 6.258 +instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 6.259 match(Set cr (FastUnlock object box)); 6.260 effect(TEMP tmp, USE_KILL box); 6.261 - 6.262 ins_cost(300); 6.263 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 6.264 - ins_encode(Fast_Unlock(object, box, tmp)); 6.265 + ins_encode %{ 6.266 + __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 6.267 + %} 6.268 ins_pipe(pipe_slow); 6.269 %} 6.270
7.1 --- a/src/os/bsd/vm/os_bsd.cpp Fri Mar 14 22:57:00 2014 -0700 7.2 +++ b/src/os/bsd/vm/os_bsd.cpp Tue Mar 18 14:04:47 2014 -0700 7.3 @@ -2636,9 +2636,21 @@ 7.4 } 7.5 } 7.6 7.7 -int os::naked_sleep() { 7.8 - // %% make the sleep time an integer flag. for now use 1 millisec. 7.9 - return os::sleep(Thread::current(), 1, false); 7.10 +void os::naked_short_sleep(jlong ms) { 7.11 + struct timespec req; 7.12 + 7.13 + assert(ms < 1000, "Un-interruptable sleep, short time use only"); 7.14 + req.tv_sec = 0; 7.15 + if (ms > 0) { 7.16 + req.tv_nsec = (ms % 1000) * 1000000; 7.17 + } 7.18 + else { 7.19 + req.tv_nsec = 1; 7.20 + } 7.21 + 7.22 + nanosleep(&req, NULL); 7.23 + 7.24 + return; 7.25 } 7.26 7.27 // Sleep forever; naked call to OS-specific sleep; use with CAUTION
8.1 --- a/src/os/linux/vm/os_linux.cpp Fri Mar 14 22:57:00 2014 -0700 8.2 +++ b/src/os/linux/vm/os_linux.cpp Tue Mar 18 14:04:47 2014 -0700 8.3 @@ -3871,9 +3871,33 @@ 8.4 } 8.5 } 8.6 8.7 -int os::naked_sleep() { 8.8 - // %% make the sleep time an integer flag. for now use 1 millisec. 8.9 - return os::sleep(Thread::current(), 1, false); 8.10 +// 8.11 +// Short sleep, direct OS call. 8.12 +// 8.13 +// Note: certain versions of Linux CFS scheduler (since 2.6.23) do not guarantee 8.14 +// sched_yield(2) will actually give up the CPU: 8.15 +// 8.16 +// * Alone on this pariticular CPU, keeps running. 8.17 +// * Before the introduction of "skip_buddy" with "compat_yield" disabled 8.18 +// (pre 2.6.39). 8.19 +// 8.20 +// So calling this with 0 is an alternative. 8.21 +// 8.22 +void os::naked_short_sleep(jlong ms) { 8.23 + struct timespec req; 8.24 + 8.25 + assert(ms < 1000, "Un-interruptable sleep, short time use only"); 8.26 + req.tv_sec = 0; 8.27 + if (ms > 0) { 8.28 + req.tv_nsec = (ms % 1000) * 1000000; 8.29 + } 8.30 + else { 8.31 + req.tv_nsec = 1; 8.32 + } 8.33 + 8.34 + nanosleep(&req, NULL); 8.35 + 8.36 + return; 8.37 } 8.38 8.39 // Sleep forever; naked call to OS-specific sleep; use with CAUTION
9.1 --- a/src/os/solaris/vm/os_solaris.cpp Fri Mar 14 22:57:00 2014 -0700 9.2 +++ b/src/os/solaris/vm/os_solaris.cpp Tue Mar 18 14:04:47 2014 -0700 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -2232,8 +2232,8 @@ 9.11 st->cr(); 9.12 status = true; 9.13 } 9.14 - ::close(fd); 9.15 } 9.16 + ::close(fd); 9.17 } 9.18 return status; 9.19 } 9.20 @@ -2257,13 +2257,18 @@ 9.21 "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG", 9.22 "ILL_COPROC", "ILL_BADSTK" }; 9.23 9.24 +const size_t ill_names_length = (sizeof(ill_names)/sizeof(char *)); 9.25 + 9.26 const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV", 9.27 "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES", 9.28 "FPE_FLTINV", "FPE_FLTSUB" }; 9.29 +const size_t fpe_names_length = (sizeof(fpe_names)/sizeof(char *)); 9.30 9.31 const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" }; 9.32 +const size_t segv_names_length = (sizeof(segv_names)/sizeof(char *)); 9.33 9.34 const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" }; 9.35 +const size_t bus_names_length = (sizeof(bus_names)/sizeof(char *)); 9.36 9.37 void os::print_siginfo(outputStream* st, void* siginfo) { 9.38 st->print("siginfo:"); 9.39 @@ -2282,19 +2287,23 @@ 9.40 assert(c > 0, "unexpected si_code"); 9.41 switch (si->si_signo) { 9.42 case SIGILL: 9.43 - st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]); 9.44 + st->print(", si_code=%d (%s)", c, 9.45 + c >= ill_names_length ? "" : ill_names[c]); 9.46 st->print(", si_addr=" PTR_FORMAT, si->si_addr); 9.47 break; 9.48 case SIGFPE: 9.49 - st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]); 9.50 + st->print(", si_code=%d (%s)", c, 9.51 + c >= fpe_names_length ? "" : fpe_names[c]); 9.52 st->print(", si_addr=" PTR_FORMAT, si->si_addr); 9.53 break; 9.54 case SIGSEGV: 9.55 - st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]); 9.56 + st->print(", si_code=%d (%s)", c, 9.57 + c >= segv_names_length ? "" : segv_names[c]); 9.58 st->print(", si_addr=" PTR_FORMAT, si->si_addr); 9.59 break; 9.60 case SIGBUS: 9.61 - st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]); 9.62 + st->print(", si_code=%d (%s)", c, 9.63 + c >= bus_names_length ? "" : bus_names[c]); 9.64 st->print(", si_addr=" PTR_FORMAT, si->si_addr); 9.65 break; 9.66 default: 9.67 @@ -3011,7 +3020,7 @@ 9.68 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { 9.69 const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE }; 9.70 const size_t types = sizeof(info_types) / sizeof(info_types[0]); 9.71 - uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT]; 9.72 + uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT + 1]; 9.73 uint_t validity[MAX_MEMINFO_CNT]; 9.74 9.75 size_t page_size = MAX2((size_t)os::vm_page_size(), page_expected->size); 9.76 @@ -3050,7 +3059,7 @@ 9.77 } 9.78 } 9.79 9.80 - if (i != addrs_count) { 9.81 + if (i < addrs_count) { 9.82 if ((validity[i] & 2) != 0) { 9.83 page_found->lgrp_id = outdata[types * i]; 9.84 } else { 9.85 @@ -3540,9 +3549,14 @@ 9.86 return os_sleep(millis, interruptible); 9.87 } 9.88 9.89 -int os::naked_sleep() { 9.90 - // %% make the sleep time an integer flag. for now use 1 millisec. 9.91 - return os_sleep(1, false); 9.92 +void os::naked_short_sleep(jlong ms) { 9.93 + assert(ms < 1000, "Un-interruptable sleep, short time use only"); 9.94 + 9.95 + // usleep is deprecated and removed from POSIX, in favour of nanosleep, but 9.96 + // Solaris requires -lrt for this. 9.97 + usleep((ms * 1000)); 9.98 + 9.99 + return; 9.100 } 9.101 9.102 // Sleep forever; naked call to OS-specific sleep; use with CAUTION
10.1 --- a/src/os/solaris/vm/perfMemory_solaris.cpp Fri Mar 14 22:57:00 2014 -0700 10.2 +++ b/src/os/solaris/vm/perfMemory_solaris.cpp Tue Mar 18 14:04:47 2014 -0700 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -431,10 +431,12 @@ 10.11 10.12 RESTARTABLE(::read(fd, addr, remaining), result); 10.13 if (result == OS_ERR) { 10.14 + ::close(fd); 10.15 THROW_MSG_0(vmSymbols::java_io_IOException(), "Read error"); 10.16 + } else { 10.17 + remaining-=result; 10.18 + addr+=result; 10.19 } 10.20 - remaining-=result; 10.21 - addr+=result; 10.22 } 10.23 10.24 ::close(fd); 10.25 @@ -906,8 +908,16 @@ 10.26 FREE_C_HEAP_ARRAY(char, filename, mtInternal); 10.27 10.28 // open the shared memory file for the give vmid 10.29 - fd = open_sharedmem_file(rfilename, file_flags, CHECK); 10.30 - assert(fd != OS_ERR, "unexpected value"); 10.31 + fd = open_sharedmem_file(rfilename, file_flags, THREAD); 10.32 + 10.33 + if (fd == OS_ERR) { 10.34 + return; 10.35 + } 10.36 + 10.37 + if (HAS_PENDING_EXCEPTION) { 10.38 + ::close(fd); 10.39 + return; 10.40 + } 10.41 10.42 if (*sizep == 0) { 10.43 size = sharedmem_filesize(fd, CHECK);
11.1 --- a/src/os/windows/vm/os_windows.cpp Fri Mar 14 22:57:00 2014 -0700 11.2 +++ b/src/os/windows/vm/os_windows.cpp Tue Mar 18 14:04:47 2014 -0700 11.3 @@ -3496,6 +3496,16 @@ 11.4 return result; 11.5 } 11.6 11.7 +// 11.8 +// Short sleep, direct OS call. 11.9 +// 11.10 +// ms = 0, means allow others (if any) to run. 11.11 +// 11.12 +void os::naked_short_sleep(jlong ms) { 11.13 + assert(ms < 1000, "Un-interruptable sleep, short time use only"); 11.14 + Sleep(ms); 11.15 +} 11.16 + 11.17 // Sleep forever; naked call to OS-specific sleep; use with CAUTION 11.18 void os::infinite_sleep() { 11.19 while (true) { // sleep forever ... 11.20 @@ -3623,13 +3633,14 @@ 11.21 "possibility of dangling Thread pointer"); 11.22 11.23 OSThread* osthread = thread->osthread(); 11.24 - bool interrupted = osthread->interrupted(); 11.25 // There is no synchronization between the setting of the interrupt 11.26 // and it being cleared here. It is critical - see 6535709 - that 11.27 // we only clear the interrupt state, and reset the interrupt event, 11.28 // if we are going to report that we were indeed interrupted - else 11.29 // an interrupt can be "lost", leading to spurious wakeups or lost wakeups 11.30 - // depending on the timing 11.31 + // depending on the timing. By checking thread interrupt event to see 11.32 + // if the thread gets real interrupt thus prevent spurious wakeup. 11.33 + bool interrupted = osthread->interrupted() && (WaitForSingleObject(osthread->interrupt_event(), 0) == WAIT_OBJECT_0); 11.34 if (interrupted && clear_interrupted) { 11.35 osthread->set_interrupted(false); 11.36 ResetEvent(osthread->interrupt_event());
12.1 --- a/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Fri Mar 14 22:57:00 2014 -0700 12.2 +++ b/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp Tue Mar 18 14:04:47 2014 -0700 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -475,9 +475,11 @@ 12.11 // here if the underlying file has been truncated. 12.12 // Do not crash the VM in such a case. 12.13 CodeBlob* cb = CodeCache::find_blob_unsafe(pc); 12.14 - nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; 12.15 - if (nm != NULL && nm->has_unsafe_access()) { 12.16 - stub = StubRoutines::handler_for_unsafe_access(); 12.17 + if (cb != NULL) { 12.18 + nmethod* nm = cb->is_nmethod() ? (nmethod*)cb : NULL; 12.19 + if (nm != NULL && nm->has_unsafe_access()) { 12.20 + stub = StubRoutines::handler_for_unsafe_access(); 12.21 + } 12.22 } 12.23 } 12.24 else 12.25 @@ -724,6 +726,7 @@ 12.26 err.report_and_die(); 12.27 12.28 ShouldNotReachHere(); 12.29 + return false; 12.30 } 12.31 12.32 void os::print_context(outputStream *st, void *context) {
13.1 --- a/src/share/vm/classfile/altHashing.cpp Fri Mar 14 22:57:00 2014 -0700 13.2 +++ b/src/share/vm/classfile/altHashing.cpp Tue Mar 18 14:04:47 2014 -0700 13.3 @@ -1,5 +1,5 @@ 13.4 /* 13.5 - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 13.6 + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 * 13.9 * This code is free software; you can redistribute it and/or modify it 13.10 @@ -39,18 +39,18 @@ 13.11 } 13.12 13.13 // Seed value used for each alternative hash calculated. 13.14 -jint AltHashing::compute_seed() { 13.15 +juint AltHashing::compute_seed() { 13.16 jlong nanos = os::javaTimeNanos(); 13.17 jlong now = os::javaTimeMillis(); 13.18 - jint SEED_MATERIAL[8] = { 13.19 - (jint) object_hash(SystemDictionary::String_klass()), 13.20 - (jint) object_hash(SystemDictionary::System_klass()), 13.21 - (jint) os::random(), // current thread isn't a java thread 13.22 - (jint) (((julong)nanos) >> 32), 13.23 - (jint) nanos, 13.24 - (jint) (((julong)now) >> 32), 13.25 - (jint) now, 13.26 - (jint) (os::javaTimeNanos() >> 2) 13.27 + int SEED_MATERIAL[8] = { 13.28 + (int) object_hash(SystemDictionary::String_klass()), 13.29 + (int) object_hash(SystemDictionary::System_klass()), 13.30 + (int) os::random(), // current thread isn't a java thread 13.31 + (int) (((julong)nanos) >> 32), 13.32 + (int) nanos, 13.33 + (int) (((julong)now) >> 32), 13.34 + (int) now, 13.35 + (int) (os::javaTimeNanos() >> 2) 13.36 }; 13.37 13.38 return murmur3_32(SEED_MATERIAL, 8); 13.39 @@ -58,14 +58,14 @@ 13.40 13.41 13.42 // Murmur3 hashing for Symbol 13.43 -jint AltHashing::murmur3_32(jint seed, const jbyte* data, int len) { 13.44 - jint h1 = seed; 13.45 +juint AltHashing::murmur3_32(juint seed, const jbyte* data, int len) { 13.46 + juint h1 = seed; 13.47 int count = len; 13.48 int offset = 0; 13.49 13.50 // body 13.51 while (count >= 4) { 13.52 - jint k1 = (data[offset] & 0x0FF) 13.53 + juint k1 = (data[offset] & 0x0FF) 13.54 | (data[offset + 1] & 0x0FF) << 8 13.55 | (data[offset + 2] & 0x0FF) << 16 13.56 | data[offset + 3] << 24; 13.57 @@ -85,7 +85,7 @@ 13.58 // tail 13.59 13.60 if (count > 0) { 13.61 - jint k1 = 0; 13.62 + juint k1 = 0; 13.63 13.64 switch (count) { 13.65 case 3: 13.66 @@ -109,18 +109,18 @@ 13.67 h1 ^= len; 13.68 13.69 // finalization mix force all bits of a hash block to avalanche 13.70 - h1 ^= ((unsigned int)h1) >> 16; 13.71 + h1 ^= h1 >> 16; 13.72 h1 *= 0x85ebca6b; 13.73 - h1 ^= ((unsigned int)h1) >> 13; 13.74 + h1 ^= h1 >> 13; 13.75 h1 *= 0xc2b2ae35; 13.76 - h1 ^= ((unsigned int)h1) >> 16; 13.77 + h1 ^= h1 >> 16; 13.78 13.79 return h1; 13.80 } 13.81 13.82 // Murmur3 hashing for Strings 13.83 -jint AltHashing::murmur3_32(jint seed, const jchar* data, int len) { 13.84 - jint h1 = seed; 13.85 +juint AltHashing::murmur3_32(juint seed, const jchar* data, int len) { 13.86 + juint h1 = seed; 13.87 13.88 int off = 0; 13.89 int count = len; 13.90 @@ -129,7 +129,7 @@ 13.91 while (count >= 2) { 13.92 jchar d1 = data[off++] & 0xFFFF; 13.93 jchar d2 = data[off++]; 13.94 - jint k1 = (d1 | d2 << 16); 13.95 + juint k1 = (d1 | d2 << 16); 13.96 13.97 count -= 2; 13.98 13.99 @@ -145,7 +145,7 @@ 13.100 // tail 13.101 13.102 if (count > 0) { 13.103 - int k1 = data[off]; 13.104 + juint k1 = (juint)data[off]; 13.105 13.106 k1 *= 0xcc9e2d51; 13.107 k1 = Integer_rotateLeft(k1, 15); 13.108 @@ -157,25 +157,25 @@ 13.109 h1 ^= len * 2; // (Character.SIZE / Byte.SIZE); 13.110 13.111 // finalization mix force all bits of a hash block to avalanche 13.112 - h1 ^= ((unsigned int)h1) >> 16; 13.113 + h1 ^= h1 >> 16; 13.114 h1 *= 0x85ebca6b; 13.115 - h1 ^= ((unsigned int)h1) >> 13; 13.116 + h1 ^= h1 >> 13; 13.117 h1 *= 0xc2b2ae35; 13.118 - h1 ^= ((unsigned int)h1) >> 16; 13.119 + h1 ^= h1 >> 16; 13.120 13.121 return h1; 13.122 } 13.123 13.124 // Hash used for the seed. 13.125 -jint AltHashing::murmur3_32(jint seed, const int* data, int len) { 13.126 - jint h1 = seed; 13.127 +juint AltHashing::murmur3_32(juint seed, const int* data, int len) { 13.128 + juint h1 = seed; 13.129 13.130 int off = 0; 13.131 int end = len; 13.132 13.133 // body 13.134 while (off < end) { 13.135 - jint k1 = data[off++]; 13.136 + juint k1 = (juint)data[off++]; 13.137 13.138 k1 *= 0xcc9e2d51; 13.139 k1 = Integer_rotateLeft(k1, 15); 13.140 @@ -193,26 +193,26 @@ 13.141 h1 ^= len * 4; // (Integer.SIZE / Byte.SIZE); 13.142 13.143 // finalization mix force all bits of a hash block to avalanche 13.144 - h1 ^= ((juint)h1) >> 16; 13.145 + h1 ^= h1 >> 16; 13.146 h1 *= 0x85ebca6b; 13.147 - h1 ^= ((juint)h1) >> 13; 13.148 + h1 ^= h1 >> 13; 13.149 h1 *= 0xc2b2ae35; 13.150 - h1 ^= ((juint)h1) >> 16; 13.151 + h1 ^= h1 >> 16; 13.152 13.153 return h1; 13.154 } 13.155 13.156 -jint AltHashing::murmur3_32(const int* data, int len) { 13.157 +juint AltHashing::murmur3_32(const int* data, int len) { 13.158 return murmur3_32(0, data, len); 13.159 } 13.160 13.161 #ifndef PRODUCT 13.162 // Overloaded versions for internal test. 13.163 -jint AltHashing::murmur3_32(const jbyte* data, int len) { 13.164 +juint AltHashing::murmur3_32(const jbyte* data, int len) { 13.165 return murmur3_32(0, data, len); 13.166 } 13.167 13.168 -jint AltHashing::murmur3_32(const jchar* data, int len) { 13.169 +juint AltHashing::murmur3_32(const jchar* data, int len) { 13.170 return murmur3_32(0, data, len); 13.171 } 13.172 13.173 @@ -251,11 +251,11 @@ 13.174 13.175 // Hash subranges {}, {0}, {0,1}, {0,1,2}, ..., {0,...,255} 13.176 for (int i = 0; i < 256; i++) { 13.177 - jint hash = murmur3_32(256 - i, vector, i); 13.178 + juint hash = murmur3_32(256 - i, vector, i); 13.179 hashes[i * 4] = (jbyte) hash; 13.180 - hashes[i * 4 + 1] = (jbyte) (((juint)hash) >> 8); 13.181 - hashes[i * 4 + 2] = (jbyte) (((juint)hash) >> 16); 13.182 - hashes[i * 4 + 3] = (jbyte) (((juint)hash) >> 24); 13.183 + hashes[i * 4 + 1] = (jbyte)(hash >> 8); 13.184 + hashes[i * 4 + 2] = (jbyte)(hash >> 16); 13.185 + hashes[i * 4 + 3] = (jbyte)(hash >> 24); 13.186 } 13.187 13.188 // hash to get const result. 13.189 @@ -269,7 +269,7 @@ 13.190 } 13.191 13.192 void AltHashing::testEquivalentHashes() { 13.193 - jint jbytes, jchars, ints; 13.194 + juint jbytes, jchars, ints; 13.195 13.196 // printf("testEquivalentHashes\n"); 13.197
14.1 --- a/src/share/vm/classfile/altHashing.hpp Fri Mar 14 22:57:00 2014 -0700 14.2 +++ b/src/share/vm/classfile/altHashing.hpp Tue Mar 18 14:04:47 2014 -0700 14.3 @@ -1,5 +1,5 @@ 14.4 /* 14.5 - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 14.6 + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 14.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.8 * 14.9 * This code is free software; you can redistribute it and/or modify it 14.10 @@ -39,24 +39,24 @@ 14.11 class AltHashing : AllStatic { 14.12 14.13 // utility function copied from java/lang/Integer 14.14 - static jint Integer_rotateLeft(jint i, int distance) { 14.15 - return (i << distance) | (((juint)i) >> (32-distance)); 14.16 + static juint Integer_rotateLeft(juint i, int distance) { 14.17 + return (i << distance) | (i >> (32-distance)); 14.18 } 14.19 - static jint murmur3_32(const int* data, int len); 14.20 - static jint murmur3_32(jint seed, const int* data, int len); 14.21 + static juint murmur3_32(const int* data, int len); 14.22 + static juint murmur3_32(juint seed, const int* data, int len); 14.23 14.24 #ifndef PRODUCT 14.25 // Hashing functions used for internal testing 14.26 - static jint murmur3_32(const jbyte* data, int len); 14.27 - static jint murmur3_32(const jchar* data, int len); 14.28 + static juint murmur3_32(const jbyte* data, int len); 14.29 + static juint murmur3_32(const jchar* data, int len); 14.30 static void testMurmur3_32_ByteArray(); 14.31 static void testEquivalentHashes(); 14.32 #endif // PRODUCT 14.33 14.34 public: 14.35 - static jint compute_seed(); 14.36 - static jint murmur3_32(jint seed, const jbyte* data, int len); 14.37 - static jint murmur3_32(jint seed, const jchar* data, int len); 14.38 + static juint compute_seed(); 14.39 + static juint murmur3_32(juint seed, const jbyte* data, int len); 14.40 + static juint murmur3_32(juint seed, const jchar* data, int len); 14.41 NOT_PRODUCT(static void test_alt_hash();) 14.42 }; 14.43 #endif // SHARE_VM_CLASSFILE_ALTHASHING_HPP
15.1 --- a/src/share/vm/oops/instanceKlass.hpp Fri Mar 14 22:57:00 2014 -0700 15.2 +++ b/src/share/vm/oops/instanceKlass.hpp Tue Mar 18 14:04:47 2014 -0700 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -554,6 +554,7 @@ 15.11 if (hk == NULL) { 15.12 return NULL; 15.13 } else { 15.14 + assert(*hk != NULL, "host klass should always be set if the address is not null"); 15.15 return *hk; 15.16 } 15.17 }
16.1 --- a/src/share/vm/oops/metadata.hpp Fri Mar 14 22:57:00 2014 -0700 16.2 +++ b/src/share/vm/oops/metadata.hpp Tue Mar 18 14:04:47 2014 -0700 16.3 @@ -1,5 +1,5 @@ 16.4 /* 16.5 - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 16.6 + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 16.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.8 * 16.9 * This code is free software; you can redistribute it and/or modify it 16.10 @@ -40,7 +40,7 @@ 16.11 int identity_hash() { return (int)(uintptr_t)this; } 16.12 16.13 // Rehashing support for tables containing pointers to this 16.14 - unsigned int new_hash(jint seed) { ShouldNotReachHere(); return 0; } 16.15 + unsigned int new_hash(juint seed) { ShouldNotReachHere(); return 0; } 16.16 16.17 virtual bool is_klass() const volatile { return false; } 16.18 virtual bool is_method() const volatile { return false; }
17.1 --- a/src/share/vm/oops/oop.cpp Fri Mar 14 22:57:00 2014 -0700 17.2 +++ b/src/share/vm/oops/oop.cpp Tue Mar 18 14:04:47 2014 -0700 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -102,7 +102,7 @@ 17.11 } 17.12 17.13 // When String table needs to rehash 17.14 -unsigned int oopDesc::new_hash(jint seed) { 17.15 +unsigned int oopDesc::new_hash(juint seed) { 17.16 EXCEPTION_MARK; 17.17 ResourceMark rm; 17.18 int length;
18.1 --- a/src/share/vm/oops/oop.hpp Fri Mar 14 22:57:00 2014 -0700 18.2 +++ b/src/share/vm/oops/oop.hpp Tue Mar 18 14:04:47 2014 -0700 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 * 18.9 * This code is free software; you can redistribute it and/or modify it 18.10 @@ -362,7 +362,7 @@ 18.11 intptr_t slow_identity_hash(); 18.12 18.13 // Alternate hashing code if string table is rehashed 18.14 - unsigned int new_hash(jint seed); 18.15 + unsigned int new_hash(juint seed); 18.16 18.17 // marks are forwarded to stack when object is locked 18.18 bool has_displaced_mark() const;
19.1 --- a/src/share/vm/oops/symbol.cpp Fri Mar 14 22:57:00 2014 -0700 19.2 +++ b/src/share/vm/oops/symbol.cpp Tue Mar 18 14:04:47 2014 -0700 19.3 @@ -1,5 +1,5 @@ 19.4 /* 19.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 19.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 19.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.8 * 19.9 * This code is free software; you can redistribute it and/or modify it 19.10 @@ -207,7 +207,7 @@ 19.11 } 19.12 19.13 // Alternate hashing for unbalanced symbol tables. 19.14 -unsigned int Symbol::new_hash(jint seed) { 19.15 +unsigned int Symbol::new_hash(juint seed) { 19.16 ResourceMark rm; 19.17 // Use alternate hashing algorithm on this symbol. 19.18 return AltHashing::murmur3_32(seed, (const jbyte*)as_C_string(), utf8_length());
20.1 --- a/src/share/vm/oops/symbol.hpp Fri Mar 14 22:57:00 2014 -0700 20.2 +++ b/src/share/vm/oops/symbol.hpp Tue Mar 18 14:04:47 2014 -0700 20.3 @@ -1,5 +1,5 @@ 20.4 /* 20.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 20.6 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 20.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.8 * 20.9 * This code is free software; you can redistribute it and/or modify it 20.10 @@ -154,7 +154,7 @@ 20.11 int identity_hash() { return _identity_hash; } 20.12 20.13 // For symbol table alternate hashing 20.14 - unsigned int new_hash(jint seed); 20.15 + unsigned int new_hash(juint seed); 20.16 20.17 // Reference counting. See comments above this class for when to use. 20.18 int refcount() const { return _refcount; }
21.1 --- a/src/share/vm/opto/graphKit.cpp Fri Mar 14 22:57:00 2014 -0700 21.2 +++ b/src/share/vm/opto/graphKit.cpp Tue Mar 18 14:04:47 2014 -0700 21.3 @@ -2994,22 +2994,28 @@ 21.4 } 21.5 21.6 Node* cast_obj = NULL; 21.7 - const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr(); 21.8 - // We may not have profiling here or it may not help us. If we have 21.9 - // a speculative type use it to perform an exact cast. 21.10 - ciKlass* spec_obj_type = obj_type->speculative_type(); 21.11 - if (spec_obj_type != NULL || 21.12 - (data != NULL && 21.13 - // Counter has never been decremented (due to cast failure). 21.14 - // ...This is a reasonable thing to expect. It is true of 21.15 - // all casts inserted by javac to implement generic types. 21.16 - data->as_CounterData()->count() >= 0)) { 21.17 - cast_obj = maybe_cast_profiled_receiver(not_null_obj, tk->klass(), spec_obj_type, safe_for_replace); 21.18 - if (cast_obj != NULL) { 21.19 - if (failure_control != NULL) // failure is now impossible 21.20 - (*failure_control) = top(); 21.21 - // adjust the type of the phi to the exact klass: 21.22 - phi->raise_bottom_type(_gvn.type(cast_obj)->meet_speculative(TypePtr::NULL_PTR)); 21.23 + if (tk->klass_is_exact()) { 21.24 + // The following optimization tries to statically cast the speculative type of the object 21.25 + // (for example obtained during profiling) to the type of the superklass and then do a 21.26 + // dynamic check that the type of the object is what we expect. To work correctly 21.27 + // for checkcast and aastore the type of superklass should be exact. 21.28 + const TypeOopPtr* obj_type = _gvn.type(obj)->is_oopptr(); 21.29 + // We may not have profiling here or it may not help us. If we have 21.30 + // a speculative type use it to perform an exact cast. 21.31 + ciKlass* spec_obj_type = obj_type->speculative_type(); 21.32 + if (spec_obj_type != NULL || 21.33 + (data != NULL && 21.34 + // Counter has never been decremented (due to cast failure). 21.35 + // ...This is a reasonable thing to expect. It is true of 21.36 + // all casts inserted by javac to implement generic types. 21.37 + data->as_CounterData()->count() >= 0)) { 21.38 + cast_obj = maybe_cast_profiled_receiver(not_null_obj, tk->klass(), spec_obj_type, safe_for_replace); 21.39 + if (cast_obj != NULL) { 21.40 + if (failure_control != NULL) // failure is now impossible 21.41 + (*failure_control) = top(); 21.42 + // adjust the type of the phi to the exact klass: 21.43 + phi->raise_bottom_type(_gvn.type(cast_obj)->meet_speculative(TypePtr::NULL_PTR)); 21.44 + } 21.45 } 21.46 } 21.47
22.1 --- a/src/share/vm/opto/library_call.cpp Fri Mar 14 22:57:00 2014 -0700 22.2 +++ b/src/share/vm/opto/library_call.cpp Tue Mar 18 14:04:47 2014 -0700 22.3 @@ -3237,7 +3237,8 @@ 22.4 // private native boolean java.lang.Thread.isInterrupted(boolean ClearInterrupted); 22.5 bool LibraryCallKit::inline_native_isInterrupted() { 22.6 // Add a fast path to t.isInterrupted(clear_int): 22.7 - // (t == Thread.current() && (!TLS._osthread._interrupted || !clear_int)) 22.8 + // (t == Thread.current() && 22.9 + // (!TLS._osthread._interrupted || WINDOWS_ONLY(false) NOT_WINDOWS(!clear_int))) 22.10 // ? TLS._osthread._interrupted : /*slow path:*/ t.isInterrupted(clear_int) 22.11 // So, in the common case that the interrupt bit is false, 22.12 // we avoid making a call into the VM. Even if the interrupt bit 22.13 @@ -3294,6 +3295,7 @@ 22.14 // drop through to next case 22.15 set_control( _gvn.transform(new (C) IfTrueNode(iff_bit))); 22.16 22.17 +#ifndef TARGET_OS_FAMILY_windows 22.18 // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path. 22.19 Node* clr_arg = argument(1); 22.20 Node* cmp_arg = _gvn.transform(new (C) CmpINode(clr_arg, intcon(0))); 22.21 @@ -3307,6 +3309,10 @@ 22.22 22.23 // drop through to next case 22.24 set_control( _gvn.transform(new (C) IfTrueNode(iff_arg))); 22.25 +#else 22.26 + // To return true on Windows you must read the _interrupted field 22.27 + // and check the the event state i.e. take the slow path. 22.28 +#endif // TARGET_OS_FAMILY_windows 22.29 22.30 // (d) Otherwise, go to the slow path. 22.31 slow_region->add_req(control());
23.1 --- a/src/share/vm/prims/jni.cpp Fri Mar 14 22:57:00 2014 -0700 23.2 +++ b/src/share/vm/prims/jni.cpp Tue Mar 18 14:04:47 2014 -0700 23.3 @@ -4450,8 +4450,23 @@ 23.4 23.5 // Get needed field and method IDs 23.6 directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V"); 23.7 + if (env->ExceptionCheck()) { 23.8 + env->ExceptionClear(); 23.9 + directBufferSupportInitializeFailed = 1; 23.10 + return false; 23.11 + } 23.12 directBufferAddressField = env->GetFieldID(bufferClass, "address", "J"); 23.13 + if (env->ExceptionCheck()) { 23.14 + env->ExceptionClear(); 23.15 + directBufferSupportInitializeFailed = 1; 23.16 + return false; 23.17 + } 23.18 bufferCapacityField = env->GetFieldID(bufferClass, "capacity", "I"); 23.19 + if (env->ExceptionCheck()) { 23.20 + env->ExceptionClear(); 23.21 + directBufferSupportInitializeFailed = 1; 23.22 + return false; 23.23 + } 23.24 23.25 if ((directByteBufferConstructor == NULL) || 23.26 (directBufferAddressField == NULL) ||
24.1 --- a/src/share/vm/prims/unsafe.cpp Fri Mar 14 22:57:00 2014 -0700 24.2 +++ b/src/share/vm/prims/unsafe.cpp Tue Mar 18 14:04:47 2014 -0700 24.3 @@ -858,6 +858,11 @@ 24.4 strcpy(buf, "java/lang/"); 24.5 strcat(buf, ename); 24.6 jclass cls = env->FindClass(buf); 24.7 + if (env->ExceptionCheck()) { 24.8 + env->ExceptionClear(); 24.9 + tty->print_cr("Unsafe: cannot throw %s because FindClass has failed", buf); 24.10 + return; 24.11 + } 24.12 char* msg = NULL; 24.13 env->ThrowNew(cls, msg); 24.14 }
25.1 --- a/src/share/vm/prims/whitebox.cpp Fri Mar 14 22:57:00 2014 -0700 25.2 +++ b/src/share/vm/prims/whitebox.cpp Tue Mar 18 14:04:47 2014 -0700 25.3 @@ -316,9 +316,10 @@ 25.4 25.5 WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) 25.6 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.7 + int result = 0; 25.8 + CHECK_JNI_EXCEPTION_(env, result); 25.9 MutexLockerEx mu(Compile_lock); 25.10 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.11 - int result = 0; 25.12 nmethod* code; 25.13 if (is_osr) { 25.14 int bci = InvocationEntryBci; 25.15 @@ -344,6 +345,7 @@ 25.16 25.17 WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) 25.18 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.19 + CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 25.20 MutexLockerEx mu(Compile_lock); 25.21 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.22 nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code(); 25.23 @@ -355,6 +357,7 @@ 25.24 25.25 WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr)) 25.26 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.27 + CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 25.28 MutexLockerEx mu(Compile_lock); 25.29 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.30 if (is_osr) { 25.31 @@ -366,6 +369,7 @@ 25.32 25.33 WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method)) 25.34 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.35 + CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 25.36 MutexLockerEx mu(Compile_lock); 25.37 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.38 return mh->queued_for_compilation(); 25.39 @@ -373,6 +377,7 @@ 25.40 25.41 WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) 25.42 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.43 + CHECK_JNI_EXCEPTION_(env, CompLevel_none); 25.44 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.45 nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code(); 25.46 return (code != NULL ? code->comp_level() : CompLevel_none); 25.47 @@ -380,6 +385,7 @@ 25.48 25.49 WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr)) 25.50 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.51 + CHECK_JNI_EXCEPTION(env); 25.52 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.53 if (is_osr) { 25.54 mh->set_not_osr_compilable(comp_level, true /* report */, "WhiteBox"); 25.55 @@ -390,6 +396,7 @@ 25.56 25.57 WB_ENTRY(jint, WB_GetMethodEntryBci(JNIEnv* env, jobject o, jobject method)) 25.58 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.59 + CHECK_JNI_EXCEPTION_(env, InvocationEntryBci); 25.60 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.61 nmethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false); 25.62 return (code != NULL && code->is_osr_method() ? code->osr_entry_bci() : InvocationEntryBci); 25.63 @@ -397,6 +404,7 @@ 25.64 25.65 WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) 25.66 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.67 + CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 25.68 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.69 bool result = mh->dont_inline(); 25.70 mh->set_dont_inline(value == JNI_TRUE); 25.71 @@ -414,6 +422,7 @@ 25.72 25.73 WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) 25.74 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.75 + CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 25.76 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.77 bool result = mh->force_inline(); 25.78 mh->set_force_inline(value == JNI_TRUE); 25.79 @@ -422,6 +431,7 @@ 25.80 25.81 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci)) 25.82 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.83 + CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 25.84 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.85 nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD); 25.86 MutexLockerEx mu(Compile_lock); 25.87 @@ -430,6 +440,7 @@ 25.88 25.89 WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method)) 25.90 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 25.91 + CHECK_JNI_EXCEPTION(env); 25.92 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 25.93 MutexLockerEx mu(Compile_lock); 25.94 MethodData* mdo = mh->method_data(); 25.95 @@ -616,14 +627,18 @@ 25.96 bool result = true; 25.97 // one by one registration natives for exception catching 25.98 jclass exceptionKlass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string()); 25.99 + CHECK_JNI_EXCEPTION(env); 25.100 for (int i = 0, n = sizeof(methods) / sizeof(methods[0]); i < n; ++i) { 25.101 if (env->RegisterNatives(wbclass, methods + i, 1) != 0) { 25.102 result = false; 25.103 - if (env->ExceptionCheck() && env->IsInstanceOf(env->ExceptionOccurred(), exceptionKlass)) { 25.104 - // j.l.NoSuchMethodError is thrown when a method can't be found or a method is not native 25.105 - // ignoring the exception 25.106 - tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s", methods[i].name, methods[i].signature); 25.107 + jthrowable throwable_obj = env->ExceptionOccurred(); 25.108 + if (throwable_obj != NULL) { 25.109 env->ExceptionClear(); 25.110 + if (env->IsInstanceOf(throwable_obj, exceptionKlass)) { 25.111 + // j.l.NoSuchMethodError is thrown when a method can't be found or a method is not native 25.112 + // ignoring the exception 25.113 + tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s", methods[i].name, methods[i].signature); 25.114 + } 25.115 } else { 25.116 // register is failed w/o exception or w/ unexpected exception 25.117 tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered", methods[i].name, methods[i].signature);
26.1 --- a/src/share/vm/prims/whitebox.hpp Fri Mar 14 22:57:00 2014 -0700 26.2 +++ b/src/share/vm/prims/whitebox.hpp Tue Mar 18 14:04:47 2014 -0700 26.3 @@ -36,6 +36,24 @@ 26.4 #define WB_END JNI_END 26.5 #define WB_METHOD_DECLARE(result_type) extern "C" result_type JNICALL 26.6 26.7 +#define CHECK_JNI_EXCEPTION_(env, value) \ 26.8 + do { \ 26.9 + JavaThread* THREAD = JavaThread::thread_from_jni_environment(env); \ 26.10 + if (HAS_PENDING_EXCEPTION) { \ 26.11 + CLEAR_PENDING_EXCEPTION; \ 26.12 + return(value); \ 26.13 + } \ 26.14 + } while (0) 26.15 + 26.16 +#define CHECK_JNI_EXCEPTION(env) \ 26.17 + do { \ 26.18 + JavaThread* THREAD = JavaThread::thread_from_jni_environment(env); \ 26.19 + if (HAS_PENDING_EXCEPTION) { \ 26.20 + CLEAR_PENDING_EXCEPTION; \ 26.21 + return; \ 26.22 + } \ 26.23 + } while (0) 26.24 + 26.25 class WhiteBox : public AllStatic { 26.26 private: 26.27 static bool _used;
27.1 --- a/src/share/vm/runtime/os.hpp Fri Mar 14 22:57:00 2014 -0700 27.2 +++ b/src/share/vm/runtime/os.hpp Tue Mar 18 14:04:47 2014 -0700 27.3 @@ -430,7 +430,10 @@ 27.4 static intx current_thread_id(); 27.5 static int current_process_id(); 27.6 static int sleep(Thread* thread, jlong ms, bool interruptable); 27.7 - static int naked_sleep(); 27.8 + // Short standalone OS sleep suitable for slow path spin loop. 27.9 + // Ignores Thread.interrupt() (so keep it short). 27.10 + // ms = 0, will sleep for the least amount of time allowed by the OS. 27.11 + static void naked_short_sleep(jlong ms); 27.12 static void infinite_sleep(); // never returns, use with CAUTION 27.13 static void yield(); // Yields to all threads with same priority 27.14 enum YieldResult {
28.1 --- a/src/share/vm/runtime/park.cpp Fri Mar 14 22:57:00 2014 -0700 28.2 +++ b/src/share/vm/runtime/park.cpp Tue Mar 18 14:04:47 2014 -0700 28.3 @@ -59,58 +59,22 @@ 28.4 28.5 // Start by trying to recycle an existing but unassociated 28.6 // ParkEvent from the global free list. 28.7 - for (;;) { 28.8 - ev = FreeList ; 28.9 - if (ev == NULL) break ; 28.10 - // 1: Detach - sequester or privatize the list 28.11 - // Tantamount to ev = Swap (&FreeList, NULL) 28.12 - if (Atomic::cmpxchg_ptr (NULL, &FreeList, ev) != ev) { 28.13 - continue ; 28.14 + // Using a spin lock since we are part of the mutex impl. 28.15 + // 8028280: using concurrent free list without memory management can leak 28.16 + // pretty badly it turns out. 28.17 + Thread::SpinAcquire(&ListLock, "ParkEventFreeListAllocate"); 28.18 + { 28.19 + ev = FreeList; 28.20 + if (ev != NULL) { 28.21 + FreeList = ev->FreeNext; 28.22 } 28.23 - 28.24 - // We've detached the list. The list in-hand is now 28.25 - // local to this thread. This thread can operate on the 28.26 - // list without risk of interference from other threads. 28.27 - // 2: Extract -- pop the 1st element from the list. 28.28 - ParkEvent * List = ev->FreeNext ; 28.29 - if (List == NULL) break ; 28.30 - for (;;) { 28.31 - // 3: Try to reattach the residual list 28.32 - guarantee (List != NULL, "invariant") ; 28.33 - ParkEvent * Arv = (ParkEvent *) Atomic::cmpxchg_ptr (List, &FreeList, NULL) ; 28.34 - if (Arv == NULL) break ; 28.35 - 28.36 - // New nodes arrived. Try to detach the recent arrivals. 28.37 - if (Atomic::cmpxchg_ptr (NULL, &FreeList, Arv) != Arv) { 28.38 - continue ; 28.39 - } 28.40 - guarantee (Arv != NULL, "invariant") ; 28.41 - // 4: Merge Arv into List 28.42 - ParkEvent * Tail = List ; 28.43 - while (Tail->FreeNext != NULL) Tail = Tail->FreeNext ; 28.44 - Tail->FreeNext = Arv ; 28.45 - } 28.46 - break ; 28.47 } 28.48 + Thread::SpinRelease(&ListLock); 28.49 28.50 if (ev != NULL) { 28.51 guarantee (ev->AssociatedWith == NULL, "invariant") ; 28.52 } else { 28.53 // Do this the hard way -- materialize a new ParkEvent. 28.54 - // In rare cases an allocating thread might detach a long list -- 28.55 - // installing null into FreeList -- and then stall or be obstructed. 28.56 - // A 2nd thread calling Allocate() would see FreeList == null. 28.57 - // The list held privately by the 1st thread is unavailable to the 2nd thread. 28.58 - // In that case the 2nd thread would have to materialize a new ParkEvent, 28.59 - // even though free ParkEvents existed in the system. In this case we end up 28.60 - // with more ParkEvents in circulation than we need, but the race is 28.61 - // rare and the outcome is benign. Ideally, the # of extant ParkEvents 28.62 - // is equal to the maximum # of threads that existed at any one time. 28.63 - // Because of the race mentioned above, segments of the freelist 28.64 - // can be transiently inaccessible. At worst we may end up with the 28.65 - // # of ParkEvents in circulation slightly above the ideal. 28.66 - // Note that if we didn't have the TSM/immortal constraint, then 28.67 - // when reattaching, above, we could trim the list. 28.68 ev = new ParkEvent () ; 28.69 guarantee ((intptr_t(ev) & 0xFF) == 0, "invariant") ; 28.70 } 28.71 @@ -124,13 +88,14 @@ 28.72 if (ev == NULL) return ; 28.73 guarantee (ev->FreeNext == NULL , "invariant") ; 28.74 ev->AssociatedWith = NULL ; 28.75 - for (;;) { 28.76 - // Push ev onto FreeList 28.77 - // The mechanism is "half" lock-free. 28.78 - ParkEvent * List = FreeList ; 28.79 - ev->FreeNext = List ; 28.80 - if (Atomic::cmpxchg_ptr (ev, &FreeList, List) == List) break ; 28.81 + // Note that if we didn't have the TSM/immortal constraint, then 28.82 + // when reattaching we could trim the list. 28.83 + Thread::SpinAcquire(&ListLock, "ParkEventFreeListRelease"); 28.84 + { 28.85 + ev->FreeNext = FreeList; 28.86 + FreeList = ev; 28.87 } 28.88 + Thread::SpinRelease(&ListLock); 28.89 } 28.90 28.91 // Override operator new and delete so we can ensure that the 28.92 @@ -164,56 +129,21 @@ 28.93 28.94 // Start by trying to recycle an existing but unassociated 28.95 // Parker from the global free list. 28.96 - for (;;) { 28.97 - p = FreeList ; 28.98 - if (p == NULL) break ; 28.99 - // 1: Detach 28.100 - // Tantamount to p = Swap (&FreeList, NULL) 28.101 - if (Atomic::cmpxchg_ptr (NULL, &FreeList, p) != p) { 28.102 - continue ; 28.103 + // 8028280: using concurrent free list without memory management can leak 28.104 + // pretty badly it turns out. 28.105 + Thread::SpinAcquire(&ListLock, "ParkerFreeListAllocate"); 28.106 + { 28.107 + p = FreeList; 28.108 + if (p != NULL) { 28.109 + FreeList = p->FreeNext; 28.110 } 28.111 - 28.112 - // We've detached the list. The list in-hand is now 28.113 - // local to this thread. This thread can operate on the 28.114 - // list without risk of interference from other threads. 28.115 - // 2: Extract -- pop the 1st element from the list. 28.116 - Parker * List = p->FreeNext ; 28.117 - if (List == NULL) break ; 28.118 - for (;;) { 28.119 - // 3: Try to reattach the residual list 28.120 - guarantee (List != NULL, "invariant") ; 28.121 - Parker * Arv = (Parker *) Atomic::cmpxchg_ptr (List, &FreeList, NULL) ; 28.122 - if (Arv == NULL) break ; 28.123 - 28.124 - // New nodes arrived. Try to detach the recent arrivals. 28.125 - if (Atomic::cmpxchg_ptr (NULL, &FreeList, Arv) != Arv) { 28.126 - continue ; 28.127 - } 28.128 - guarantee (Arv != NULL, "invariant") ; 28.129 - // 4: Merge Arv into List 28.130 - Parker * Tail = List ; 28.131 - while (Tail->FreeNext != NULL) Tail = Tail->FreeNext ; 28.132 - Tail->FreeNext = Arv ; 28.133 - } 28.134 - break ; 28.135 } 28.136 + Thread::SpinRelease(&ListLock); 28.137 28.138 if (p != NULL) { 28.139 guarantee (p->AssociatedWith == NULL, "invariant") ; 28.140 } else { 28.141 // Do this the hard way -- materialize a new Parker.. 28.142 - // In rare cases an allocating thread might detach 28.143 - // a long list -- installing null into FreeList --and 28.144 - // then stall. Another thread calling Allocate() would see 28.145 - // FreeList == null and then invoke the ctor. In this case we 28.146 - // end up with more Parkers in circulation than we need, but 28.147 - // the race is rare and the outcome is benign. 28.148 - // Ideally, the # of extant Parkers is equal to the 28.149 - // maximum # of threads that existed at any one time. 28.150 - // Because of the race mentioned above, segments of the 28.151 - // freelist can be transiently inaccessible. At worst 28.152 - // we may end up with the # of Parkers in circulation 28.153 - // slightly above the ideal. 28.154 p = new Parker() ; 28.155 } 28.156 p->AssociatedWith = t ; // Associate p with t 28.157 @@ -227,11 +157,12 @@ 28.158 guarantee (p->AssociatedWith != NULL, "invariant") ; 28.159 guarantee (p->FreeNext == NULL , "invariant") ; 28.160 p->AssociatedWith = NULL ; 28.161 - for (;;) { 28.162 - // Push p onto FreeList 28.163 - Parker * List = FreeList ; 28.164 - p->FreeNext = List ; 28.165 - if (Atomic::cmpxchg_ptr (p, &FreeList, List) == List) break ; 28.166 + 28.167 + Thread::SpinAcquire(&ListLock, "ParkerFreeListRelease"); 28.168 + { 28.169 + p->FreeNext = FreeList; 28.170 + FreeList = p; 28.171 } 28.172 + Thread::SpinRelease(&ListLock); 28.173 } 28.174
29.1 --- a/src/share/vm/runtime/thread.cpp Fri Mar 14 22:57:00 2014 -0700 29.2 +++ b/src/share/vm/runtime/thread.cpp Tue Mar 18 14:04:47 2014 -0700 29.3 @@ -4446,9 +4446,7 @@ 29.4 ++ctr ; 29.5 if ((ctr & 0xFFF) == 0 || !os::is_MP()) { 29.6 if (Yields > 5) { 29.7 - // Consider using a simple NakedSleep() instead. 29.8 - // Then SpinAcquire could be called by non-JVM threads 29.9 - Thread::current()->_ParkEvent->park(1) ; 29.10 + os::naked_short_sleep(1); 29.11 } else { 29.12 os::NakedYield() ; 29.13 ++Yields ;
30.1 --- a/src/share/vm/utilities/hashtable.cpp Fri Mar 14 22:57:00 2014 -0700 30.2 +++ b/src/share/vm/utilities/hashtable.cpp Tue Mar 18 14:04:47 2014 -0700 30.3 @@ -1,5 +1,5 @@ 30.4 /* 30.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 30.6 + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 30.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 30.8 * 30.9 * This code is free software; you can redistribute it and/or modify it 30.10 @@ -93,7 +93,7 @@ 30.11 return false; 30.12 } 30.13 30.14 -template <class T, MEMFLAGS F> jint Hashtable<T, F>::_seed = 0; 30.15 +template <class T, MEMFLAGS F> juint Hashtable<T, F>::_seed = 0; 30.16 30.17 // Create a new table and using alternate hash code, populate the new table 30.18 // with the existing elements. This can be used to change the hash code
31.1 --- a/src/share/vm/utilities/hashtable.hpp Fri Mar 14 22:57:00 2014 -0700 31.2 +++ b/src/share/vm/utilities/hashtable.hpp Tue Mar 18 14:04:47 2014 -0700 31.3 @@ -1,5 +1,5 @@ 31.4 /* 31.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 31.6 + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. 31.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.8 * 31.9 * This code is free software; you can redistribute it and/or modify it 31.10 @@ -280,7 +280,7 @@ 31.11 // Function to move these elements into the new table. 31.12 void move_to(Hashtable<T, F>* new_table); 31.13 static bool use_alternate_hashcode() { return _seed != 0; } 31.14 - static jint seed() { return _seed; } 31.15 + static juint seed() { return _seed; } 31.16 31.17 static int literal_size(Symbol *symbol); 31.18 static int literal_size(oop oop); 31.19 @@ -296,7 +296,7 @@ 31.20 void dump_table(outputStream* st, const char *table_name); 31.21 31.22 private: 31.23 - static jint _seed; 31.24 + static juint _seed; 31.25 }; 31.26 31.27
32.1 --- a/src/share/vm/utilities/vmError.cpp Fri Mar 14 22:57:00 2014 -0700 32.2 +++ b/src/share/vm/utilities/vmError.cpp Tue Mar 18 14:04:47 2014 -0700 32.3 @@ -592,13 +592,24 @@ 32.4 st->cr(); 32.5 // Compiled code may use EBP register on x86 so it looks like 32.6 // non-walkable C frame. Use frame.sender() for java frames. 32.7 - if (_thread && _thread->is_Java_thread() && fr.is_java_frame()) { 32.8 - RegisterMap map((JavaThread*)_thread, false); // No update 32.9 - fr = fr.sender(&map); 32.10 - continue; 32.11 + if (_thread && _thread->is_Java_thread()) { 32.12 + // Catch very first native frame by using stack address. 32.13 + // For JavaThread stack_base and stack_size should be set. 32.14 + if (!_thread->on_local_stack((address)(fr.sender_sp() + 1))) { 32.15 + break; 32.16 + } 32.17 + if (fr.is_java_frame()) { 32.18 + RegisterMap map((JavaThread*)_thread, false); // No update 32.19 + fr = fr.sender(&map); 32.20 + } else { 32.21 + fr = os::get_sender_for_C_frame(&fr); 32.22 + } 32.23 + } else { 32.24 + // is_first_C_frame() does only simple checks for frame pointer, 32.25 + // it will pass if java compiled code has a pointer in EBP. 32.26 + if (os::is_first_C_frame(&fr)) break; 32.27 + fr = os::get_sender_for_C_frame(&fr); 32.28 } 32.29 - if (os::is_first_C_frame(&fr)) break; 32.30 - fr = os::get_sender_for_C_frame(&fr); 32.31 } 32.32 32.33 if (count > StackPrintLimit) {
33.1 --- a/test/TEST.groups Fri Mar 14 22:57:00 2014 -0700 33.2 +++ b/test/TEST.groups Tue Mar 18 14:04:47 2014 -0700 33.3 @@ -131,7 +131,9 @@ 33.4 gc/arguments/TestG1HeapRegionSize.java \ 33.5 gc/metaspace/TestMetaspaceMemoryPool.java \ 33.6 runtime/InternalApi/ThreadCpuTimesDeadlock.java \ 33.7 - serviceability/threads/TestFalseDeadLock.java 33.8 + serviceability/threads/TestFalseDeadLock.java \ 33.9 + compiler/tiered/NonTieredLevelsTest.java \ 33.10 + compiler/tiered/TieredLevelsTest.java 33.11 33.12 # Compact 2 adds full VM tests 33.13 compact2 = \
34.1 --- a/test/compiler/ciReplay/TestVM.sh Fri Mar 14 22:57:00 2014 -0700 34.2 +++ b/test/compiler/ciReplay/TestVM.sh Tue Mar 18 14:04:47 2014 -0700 34.3 @@ -78,8 +78,8 @@ 34.4 positive_test `expr $stop_level + 50` "TIERED LEVEL $stop_level :: REPLAY" \ 34.5 "-XX:TieredStopAtLevel=$stop_level" 34.6 stop_level=`expr $stop_level + 1` 34.7 + cleanup 34.8 done 34.9 - cleanup 34.10 fi 34.11 34.12 echo TEST PASSED
35.1 --- a/test/compiler/ciReplay/common.sh Fri Mar 14 22:57:00 2014 -0700 35.2 +++ b/test/compiler/ciReplay/common.sh Tue Mar 18 14:04:47 2014 -0700 35.3 @@ -99,14 +99,13 @@ 35.4 # $2 - non-tiered comp_level 35.5 nontiered_tests() { 35.6 level=`grep "^compile " $replay_data | awk '{print $6}'` 35.7 - # is level available in non-tiere 35.8 + # is level available in non-tiered 35.9 if [ "$level" -eq $2 ] 35.10 then 35.11 positive_test $1 "NON-TIERED :: AVAILABLE COMP_LEVEL" \ 35.12 -XX:-TieredCompilation 35.13 else 35.14 negative_test `expr $1 + 1` "NON-TIERED :: UNAVAILABLE COMP_LEVEL" \ 35.15 - negative_test `expr $1 + 1` "NON-TIERED :: UNAVAILABLE COMP_LEVEL" \ 35.16 -XX:-TieredCompilation 35.17 fi 35.18 }
36.1 --- a/test/compiler/tiered/NonTieredLevelsTest.java Fri Mar 14 22:57:00 2014 -0700 36.2 +++ b/test/compiler/tiered/NonTieredLevelsTest.java Tue Mar 18 14:04:47 2014 -0700 36.3 @@ -1,5 +1,5 @@ 36.4 /* 36.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 36.6 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 36.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.8 * 36.9 * This code is free software; you can redistribute it and/or modify it 36.10 @@ -70,6 +70,9 @@ 36.11 36.12 @Override 36.13 protected void test() throws Exception { 36.14 + if (skipXcompOSR()) { 36.15 + return; 36.16 + } 36.17 checkNotCompiled(); 36.18 compile(); 36.19 checkCompiled();
37.1 --- a/test/compiler/tiered/TieredLevelsTest.java Fri Mar 14 22:57:00 2014 -0700 37.2 +++ b/test/compiler/tiered/TieredLevelsTest.java Tue Mar 18 14:04:47 2014 -0700 37.3 @@ -1,5 +1,5 @@ 37.4 /* 37.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 37.6 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 37.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 37.8 * 37.9 * This code is free software; you can redistribute it and/or modify it 37.10 @@ -51,6 +51,9 @@ 37.11 37.12 @Override 37.13 protected void test() throws Exception { 37.14 + if (skipXcompOSR()) { 37.15 + return; 37.16 + } 37.17 checkNotCompiled(); 37.18 compile(); 37.19 checkCompiled();
38.1 --- a/test/compiler/whitebox/CompilerWhiteBoxTest.java Fri Mar 14 22:57:00 2014 -0700 38.2 +++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java Tue Mar 18 14:04:47 2014 -0700 38.3 @@ -1,5 +1,5 @@ 38.4 /* 38.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 38.6 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 38.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 38.8 * 38.9 * This code is free software; you can redistribute it and/or modify it 38.10 @@ -380,6 +380,20 @@ 38.11 /** flag for OSR test case */ 38.12 boolean isOsr(); 38.13 } 38.14 + 38.15 + /** 38.16 + * @return {@code true} if the current test case is OSR and the mode is 38.17 + * Xcomp, otherwise {@code false} 38.18 + */ 38.19 + protected boolean skipXcompOSR() { 38.20 + boolean result = testCase.isOsr() 38.21 + && CompilerWhiteBoxTest.MODE.startsWith("compiled "); 38.22 + if (result && IS_VERBOSE) { 38.23 + System.err.printf("Warning: %s is not applicable in %s%n", 38.24 + testCase.name(), CompilerWhiteBoxTest.MODE); 38.25 + } 38.26 + return result; 38.27 + } 38.28 } 38.29 38.30 enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
39.1 --- a/test/compiler/whitebox/DeoptimizeAllTest.java Fri Mar 14 22:57:00 2014 -0700 39.2 +++ b/test/compiler/whitebox/DeoptimizeAllTest.java Tue Mar 18 14:04:47 2014 -0700 39.3 @@ -1,5 +1,5 @@ 39.4 /* 39.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 39.6 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 39.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 39.8 * 39.9 * This code is free software; you can redistribute it and/or modify it 39.10 @@ -51,11 +51,8 @@ 39.11 */ 39.12 @Override 39.13 protected void test() throws Exception { 39.14 - if (testCase.isOsr() && CompilerWhiteBoxTest.MODE.startsWith( 39.15 - "compiled ")) { 39.16 - System.err.printf("Warning: %s is not applicable in %s%n", 39.17 - testCase.name(), CompilerWhiteBoxTest.MODE); 39.18 - return; 39.19 + if (skipXcompOSR()) { 39.20 + return; 39.21 } 39.22 compile(); 39.23 checkCompiled();
40.1 --- a/test/compiler/whitebox/DeoptimizeMethodTest.java Fri Mar 14 22:57:00 2014 -0700 40.2 +++ b/test/compiler/whitebox/DeoptimizeMethodTest.java Tue Mar 18 14:04:47 2014 -0700 40.3 @@ -1,5 +1,5 @@ 40.4 /* 40.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 40.6 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 40.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 40.8 * 40.9 * This code is free software; you can redistribute it and/or modify it 40.10 @@ -51,11 +51,8 @@ 40.11 */ 40.12 @Override 40.13 protected void test() throws Exception { 40.14 - if (testCase.isOsr() && CompilerWhiteBoxTest.MODE.startsWith( 40.15 - "compiled ")) { 40.16 - System.err.printf("Warning: %s is not applicable in %s%n", 40.17 - testCase.name(), CompilerWhiteBoxTest.MODE); 40.18 - return; 40.19 + if (skipXcompOSR()) { 40.20 + return; 40.21 } 40.22 compile(); 40.23 checkCompiled();
41.1 --- a/test/compiler/whitebox/IsMethodCompilableTest.java Fri Mar 14 22:57:00 2014 -0700 41.2 +++ b/test/compiler/whitebox/IsMethodCompilableTest.java Tue Mar 18 14:04:47 2014 -0700 41.3 @@ -1,5 +1,5 @@ 41.4 /* 41.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 41.6 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 41.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 41.8 * 41.9 * This code is free software; you can redistribute it and/or modify it 41.10 @@ -66,10 +66,7 @@ 41.11 */ 41.12 @Override 41.13 protected void test() throws Exception { 41.14 - if (testCase.isOsr() && CompilerWhiteBoxTest.MODE.startsWith( 41.15 - "compiled ")) { 41.16 - System.err.printf("Warning: %s is not applicable in %s%n", 41.17 - testCase.name(), CompilerWhiteBoxTest.MODE); 41.18 + if (skipXcompOSR()) { 41.19 return; 41.20 } 41.21 if (!isCompilable()) {
42.1 --- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java Fri Mar 14 22:57:00 2014 -0700 42.2 +++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java Tue Mar 18 14:04:47 2014 -0700 42.3 @@ -1,5 +1,5 @@ 42.4 /* 42.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 42.6 + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 42.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 42.8 * 42.9 * This code is free software; you can redistribute it and/or modify it 42.10 @@ -53,11 +53,8 @@ 42.11 */ 42.12 @Override 42.13 protected void test() throws Exception { 42.14 - if (testCase.isOsr() && CompilerWhiteBoxTest.MODE.startsWith( 42.15 - "compiled ")) { 42.16 - System.err.printf("Warning: %s is not applicable in %s%n", 42.17 - testCase.name(), CompilerWhiteBoxTest.MODE); 42.18 - return; 42.19 + if (skipXcompOSR()) { 42.20 + return; 42.21 } 42.22 checkNotCompiled(); 42.23 if (!isCompilable()) {