equal
deleted
inserted
replaced
318 if (mark == (markOop) lock) { |
318 if (mark == (markOop) lock) { |
319 // If the object is stack-locked by the current thread, try to |
319 // If the object is stack-locked by the current thread, try to |
320 // swing the displaced header from the BasicLock back to the mark. |
320 // swing the displaced header from the BasicLock back to the mark. |
321 assert(dhw->is_neutral(), "invariant"); |
321 assert(dhw->is_neutral(), "invariant"); |
322 if (object->cas_set_mark(dhw, mark) == mark) { |
322 if (object->cas_set_mark(dhw, mark) == mark) { |
323 TEVENT(fast_exit: release stack-lock); |
|
324 return; |
323 return; |
325 } |
324 } |
326 } |
325 } |
327 |
326 |
328 // We have to take the slow-path of possible inflation and then exit. |
327 // We have to take the slow-path of possible inflation and then exit. |
343 if (mark->is_neutral()) { |
342 if (mark->is_neutral()) { |
344 // Anticipate successful CAS -- the ST of the displaced mark must |
343 // Anticipate successful CAS -- the ST of the displaced mark must |
345 // be visible <= the ST performed by the CAS. |
344 // be visible <= the ST performed by the CAS. |
346 lock->set_displaced_header(mark); |
345 lock->set_displaced_header(mark); |
347 if (mark == obj()->cas_set_mark((markOop) lock, mark)) { |
346 if (mark == obj()->cas_set_mark((markOop) lock, mark)) { |
348 TEVENT(slow_enter: release stacklock); |
|
349 return; |
347 return; |
350 } |
348 } |
351 // Fall through to inflate() ... |
349 // Fall through to inflate() ... |
352 } else if (mark->has_locker() && |
350 } else if (mark->has_locker() && |
353 THREAD->is_lock_owned((address)mark->locker())) { |
351 THREAD->is_lock_owned((address)mark->locker())) { |
386 // 3) when notified on lock2, unlock lock2 |
384 // 3) when notified on lock2, unlock lock2 |
387 // 4) reenter lock1 with original recursion count |
385 // 4) reenter lock1 with original recursion count |
388 // 5) lock lock2 |
386 // 5) lock lock2 |
389 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() |
387 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() |
390 intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) { |
388 intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) { |
391 TEVENT(complete_exit); |
|
392 if (UseBiasedLocking) { |
389 if (UseBiasedLocking) { |
393 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
390 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
394 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
391 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
395 } |
392 } |
396 |
393 |
401 return monitor->complete_exit(THREAD); |
398 return monitor->complete_exit(THREAD); |
402 } |
399 } |
403 |
400 |
404 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() |
401 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() |
405 void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) { |
402 void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) { |
406 TEVENT(reenter); |
|
407 if (UseBiasedLocking) { |
403 if (UseBiasedLocking) { |
408 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
404 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
409 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
405 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
410 } |
406 } |
411 |
407 |
418 // ----------------------------------------------------------------------------- |
414 // ----------------------------------------------------------------------------- |
419 // JNI locks on java objects |
415 // JNI locks on java objects |
420 // NOTE: must use heavy weight monitor to handle jni monitor enter |
416 // NOTE: must use heavy weight monitor to handle jni monitor enter |
421 void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) { |
417 void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) { |
422 // the current locking is from JNI instead of Java code |
418 // the current locking is from JNI instead of Java code |
423 TEVENT(jni_enter); |
|
424 if (UseBiasedLocking) { |
419 if (UseBiasedLocking) { |
425 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
420 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
426 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
421 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
427 } |
422 } |
428 THREAD->set_current_pending_monitor_is_from_java(false); |
423 THREAD->set_current_pending_monitor_is_from_java(false); |
430 THREAD->set_current_pending_monitor_is_from_java(true); |
425 THREAD->set_current_pending_monitor_is_from_java(true); |
431 } |
426 } |
432 |
427 |
433 // NOTE: must use heavy weight monitor to handle jni monitor exit |
428 // NOTE: must use heavy weight monitor to handle jni monitor exit |
434 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) { |
429 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) { |
435 TEVENT(jni_exit); |
|
436 if (UseBiasedLocking) { |
430 if (UseBiasedLocking) { |
437 Handle h_obj(THREAD, obj); |
431 Handle h_obj(THREAD, obj); |
438 BiasedLocking::revoke_and_rebias(h_obj, false, THREAD); |
432 BiasedLocking::revoke_and_rebias(h_obj, false, THREAD); |
439 obj = h_obj(); |
433 obj = h_obj(); |
440 } |
434 } |
458 _thread = thread; |
452 _thread = thread; |
459 debug_only(if (StrictSafepointChecks) _thread->check_for_valid_safepoint_state(false);) |
453 debug_only(if (StrictSafepointChecks) _thread->check_for_valid_safepoint_state(false);) |
460 _obj = obj; |
454 _obj = obj; |
461 |
455 |
462 if (_dolock) { |
456 if (_dolock) { |
463 TEVENT(ObjectLocker); |
|
464 |
|
465 ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread); |
457 ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread); |
466 } |
458 } |
467 } |
459 } |
468 |
460 |
469 ObjectLocker::~ObjectLocker() { |
461 ObjectLocker::~ObjectLocker() { |
480 if (UseBiasedLocking) { |
472 if (UseBiasedLocking) { |
481 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
473 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
482 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
474 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
483 } |
475 } |
484 if (millis < 0) { |
476 if (millis < 0) { |
485 TEVENT(wait - throw IAX); |
|
486 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); |
477 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); |
487 } |
478 } |
488 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, |
479 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, |
489 obj(), |
480 obj(), |
490 inflate_cause_wait); |
481 inflate_cause_wait); |
503 if (UseBiasedLocking) { |
494 if (UseBiasedLocking) { |
504 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
495 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
505 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
496 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
506 } |
497 } |
507 if (millis < 0) { |
498 if (millis < 0) { |
508 TEVENT(wait - throw IAX); |
|
509 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); |
499 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); |
510 } |
500 } |
511 ObjectSynchronizer::inflate(THREAD, |
501 ObjectSynchronizer::inflate(THREAD, |
512 obj(), |
502 obj(), |
513 inflate_cause_wait)->wait(millis, false, THREAD); |
503 inflate_cause_wait)->wait(millis, false, THREAD); |
606 |
596 |
607 ++its; |
597 ++its; |
608 if (its > 10000 || !os::is_MP()) { |
598 if (its > 10000 || !os::is_MP()) { |
609 if (its & 1) { |
599 if (its & 1) { |
610 os::naked_yield(); |
600 os::naked_yield(); |
611 TEVENT(Inflate: INFLATING - yield); |
|
612 } else { |
601 } else { |
613 // Note that the following code attenuates the livelock problem but is not |
602 // Note that the following code attenuates the livelock problem but is not |
614 // a complete remedy. A more complete solution would require that the inflating |
603 // a complete remedy. A more complete solution would require that the inflating |
615 // thread hold the associated inflation lock. The following code simply restricts |
604 // thread hold the associated inflation lock. The following code simply restricts |
616 // the number of spinners to at most one. We'll have N-2 threads blocked |
605 // the number of spinners to at most one. We'll have N-2 threads blocked |
639 } else { |
628 } else { |
640 os::naked_yield(); |
629 os::naked_yield(); |
641 } |
630 } |
642 } |
631 } |
643 Thread::muxRelease(gInflationLocks + ix); |
632 Thread::muxRelease(gInflationLocks + ix); |
644 TEVENT(Inflate: INFLATING - yield/park); |
|
645 } |
633 } |
646 } else { |
634 } else { |
647 SpinPause(); // SMP-polite spinning |
635 SpinPause(); // SMP-polite spinning |
648 } |
636 } |
649 } |
637 } |
701 } |
689 } |
702 |
690 |
703 value &= markOopDesc::hash_mask; |
691 value &= markOopDesc::hash_mask; |
704 if (value == 0) value = 0xBAD; |
692 if (value == 0) value = 0xBAD; |
705 assert(value != markOopDesc::no_hash, "invariant"); |
693 assert(value != markOopDesc::no_hash, "invariant"); |
706 TEVENT(hashCode: GENERATE); |
|
707 return value; |
694 return value; |
708 } |
695 } |
709 |
696 |
710 intptr_t ObjectSynchronizer::FastHashCode(Thread * Self, oop obj) { |
697 intptr_t ObjectSynchronizer::FastHashCode(Thread * Self, oop obj) { |
711 if (UseBiasedLocking) { |
698 if (UseBiasedLocking) { |
1152 omRelease(Self, take, false); |
1139 omRelease(Self, take, false); |
1153 } |
1140 } |
1154 Thread::muxRelease(&gListLock); |
1141 Thread::muxRelease(&gListLock); |
1155 Self->omFreeProvision += 1 + (Self->omFreeProvision/2); |
1142 Self->omFreeProvision += 1 + (Self->omFreeProvision/2); |
1156 if (Self->omFreeProvision > MAXPRIVATE) Self->omFreeProvision = MAXPRIVATE; |
1143 if (Self->omFreeProvision > MAXPRIVATE) Self->omFreeProvision = MAXPRIVATE; |
1157 TEVENT(omFirst - reprovision); |
|
1158 |
1144 |
1159 const int mx = MonitorBound; |
1145 const int mx = MonitorBound; |
1160 if (mx > 0 && (gMonitorPopulation-gMonitorFreeCount) > mx) { |
1146 if (mx > 0 && (gMonitorPopulation-gMonitorFreeCount) > mx) { |
1161 // We can't safely induce a STW safepoint from omAlloc() as our thread |
1147 // We can't safely induce a STW safepoint from omAlloc() as our thread |
1162 // state may not be appropriate for such activities and callers may hold |
1148 // state may not be appropriate for such activities and callers may hold |
1230 |
1216 |
1231 // Add the new string of objectMonitors to the global free list |
1217 // Add the new string of objectMonitors to the global free list |
1232 temp[_BLOCKSIZE - 1].FreeNext = gFreeList; |
1218 temp[_BLOCKSIZE - 1].FreeNext = gFreeList; |
1233 gFreeList = temp + 1; |
1219 gFreeList = temp + 1; |
1234 Thread::muxRelease(&gListLock); |
1220 Thread::muxRelease(&gListLock); |
1235 TEVENT(Allocate block of monitors); |
|
1236 } |
1221 } |
1237 } |
1222 } |
1238 |
1223 |
1239 // Place "m" on the caller's private per-thread omFreeList. |
1224 // Place "m" on the caller's private per-thread omFreeList. |
1240 // In practice there's no need to clamp or limit the number of |
1225 // In practice there's no need to clamp or limit the number of |
1315 tally++; |
1300 tally++; |
1316 tail = s; |
1301 tail = s; |
1317 guarantee(s->object() == NULL, "invariant"); |
1302 guarantee(s->object() == NULL, "invariant"); |
1318 guarantee(!s->is_busy(), "invariant"); |
1303 guarantee(!s->is_busy(), "invariant"); |
1319 s->set_owner(NULL); // redundant but good hygiene |
1304 s->set_owner(NULL); // redundant but good hygiene |
1320 TEVENT(omFlush - Move one); |
|
1321 } |
1305 } |
1322 guarantee(tail != NULL && list != NULL, "invariant"); |
1306 guarantee(tail != NULL && list != NULL, "invariant"); |
1323 } |
1307 } |
1324 |
1308 |
1325 ObjectMonitor * inUseList = Self->omInUseList; |
1309 ObjectMonitor * inUseList = Self->omInUseList; |
1355 gOmInUseList = inUseList; |
1339 gOmInUseList = inUseList; |
1356 gOmInUseCount += inUseTally; |
1340 gOmInUseCount += inUseTally; |
1357 } |
1341 } |
1358 |
1342 |
1359 Thread::muxRelease(&gListLock); |
1343 Thread::muxRelease(&gListLock); |
1360 TEVENT(omFlush); |
|
1361 } |
1344 } |
1362 |
1345 |
1363 static void post_monitor_inflate_event(EventJavaMonitorInflate* event, |
1346 static void post_monitor_inflate_event(EventJavaMonitorInflate* event, |
1364 const oop obj, |
1347 const oop obj, |
1365 ObjectSynchronizer::InflateCause cause) { |
1348 ObjectSynchronizer::InflateCause cause) { |
1420 // Only that thread can complete inflation -- other threads must wait. |
1403 // Only that thread can complete inflation -- other threads must wait. |
1421 // The INFLATING value is transient. |
1404 // The INFLATING value is transient. |
1422 // Currently, we spin/yield/park and poll the markword, waiting for inflation to finish. |
1405 // Currently, we spin/yield/park and poll the markword, waiting for inflation to finish. |
1423 // We could always eliminate polling by parking the thread on some auxiliary list. |
1406 // We could always eliminate polling by parking the thread on some auxiliary list. |
1424 if (mark == markOopDesc::INFLATING()) { |
1407 if (mark == markOopDesc::INFLATING()) { |
1425 TEVENT(Inflate: spin while INFLATING); |
|
1426 ReadStableMark(object); |
1408 ReadStableMark(object); |
1427 continue; |
1409 continue; |
1428 } |
1410 } |
1429 |
1411 |
1430 // CASE: stack-locked |
1412 // CASE: stack-locked |
1513 object->release_set_mark(markOopDesc::encode(m)); |
1495 object->release_set_mark(markOopDesc::encode(m)); |
1514 |
1496 |
1515 // Hopefully the performance counters are allocated on distinct cache lines |
1497 // Hopefully the performance counters are allocated on distinct cache lines |
1516 // to avoid false sharing on MP systems ... |
1498 // to avoid false sharing on MP systems ... |
1517 OM_PERFDATA_OP(Inflations, inc()); |
1499 OM_PERFDATA_OP(Inflations, inc()); |
1518 TEVENT(Inflate: overwrite stacklock); |
|
1519 if (log_is_enabled(Debug, monitorinflation)) { |
1500 if (log_is_enabled(Debug, monitorinflation)) { |
1520 if (object->is_instance()) { |
1501 if (object->is_instance()) { |
1521 ResourceMark rm; |
1502 ResourceMark rm; |
1522 log_debug(monitorinflation)("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
1503 log_debug(monitorinflation)("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
1523 p2i(object), p2i(object->mark()), |
1504 p2i(object), p2i(object->mark()), |
1564 } |
1545 } |
1565 |
1546 |
1566 // Hopefully the performance counters are allocated on distinct |
1547 // Hopefully the performance counters are allocated on distinct |
1567 // cache lines to avoid false sharing on MP systems ... |
1548 // cache lines to avoid false sharing on MP systems ... |
1568 OM_PERFDATA_OP(Inflations, inc()); |
1549 OM_PERFDATA_OP(Inflations, inc()); |
1569 TEVENT(Inflate: overwrite neutral); |
|
1570 if (log_is_enabled(Debug, monitorinflation)) { |
1550 if (log_is_enabled(Debug, monitorinflation)) { |
1571 if (object->is_instance()) { |
1551 if (object->is_instance()) { |
1572 ResourceMark rm; |
1552 ResourceMark rm; |
1573 log_debug(monitorinflation)("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
1553 log_debug(monitorinflation)("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
1574 p2i(object), p2i(object->mark()), |
1554 p2i(object), p2i(object->mark()), |
1631 deflated = false; |
1611 deflated = false; |
1632 } else { |
1612 } else { |
1633 // Deflate the monitor if it is no longer being used |
1613 // Deflate the monitor if it is no longer being used |
1634 // It's idle - scavenge and return to the global free list |
1614 // It's idle - scavenge and return to the global free list |
1635 // plain old deflation ... |
1615 // plain old deflation ... |
1636 TEVENT(deflate_idle_monitors - scavenge1); |
|
1637 if (log_is_enabled(Debug, monitorinflation)) { |
1616 if (log_is_enabled(Debug, monitorinflation)) { |
1638 if (obj->is_instance()) { |
1617 if (obj->is_instance()) { |
1639 ResourceMark rm; |
1618 ResourceMark rm; |
1640 log_debug(monitorinflation)("Deflating object " INTPTR_FORMAT " , " |
1619 log_debug(monitorinflation)("Deflating object " INTPTR_FORMAT " , " |
1641 "mark " INTPTR_FORMAT " , type %s", |
1620 "mark " INTPTR_FORMAT " , type %s", |
1717 bool deflated = false; |
1696 bool deflated = false; |
1718 |
1697 |
1719 ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors |
1698 ObjectMonitor * freeHeadp = NULL; // Local SLL of scavenged monitors |
1720 ObjectMonitor * freeTailp = NULL; |
1699 ObjectMonitor * freeTailp = NULL; |
1721 |
1700 |
1722 TEVENT(deflate_idle_monitors); |
|
1723 // Prevent omFlush from changing mids in Thread dtor's during deflation |
1701 // Prevent omFlush from changing mids in Thread dtor's during deflation |
1724 // And in case the vm thread is acquiring a lock during a safepoint |
1702 // And in case the vm thread is acquiring a lock during a safepoint |
1725 // See e.g. 6320749 |
1703 // See e.g. 6320749 |
1726 Thread::muxAcquire(&gListLock, "scavenge - return"); |
1704 Thread::muxAcquire(&gListLock, "scavenge - return"); |
1727 |
1705 |