40 #include "runtime/osThread.hpp" |
40 #include "runtime/osThread.hpp" |
41 #include "runtime/stubRoutines.hpp" |
41 #include "runtime/stubRoutines.hpp" |
42 #include "runtime/synchronizer.hpp" |
42 #include "runtime/synchronizer.hpp" |
43 #include "runtime/thread.inline.hpp" |
43 #include "runtime/thread.inline.hpp" |
44 #include "runtime/vframe.hpp" |
44 #include "runtime/vframe.hpp" |
|
45 #include "trace/traceMacros.hpp" |
|
46 #include "trace/tracing.hpp" |
45 #include "utilities/dtrace.hpp" |
47 #include "utilities/dtrace.hpp" |
46 #include "utilities/events.hpp" |
48 #include "utilities/events.hpp" |
47 #include "utilities/preserveException.hpp" |
49 #include "utilities/preserveException.hpp" |
48 |
50 |
49 #if defined(__GNUC__) && !defined(PPC64) |
51 #if defined(__GNUC__) && !defined(PPC64) |
127 int ObjectSynchronizer::gOmInUseCount = 0; |
129 int ObjectSynchronizer::gOmInUseCount = 0; |
128 |
130 |
129 static volatile intptr_t gListLock = 0; // protects global monitor lists |
131 static volatile intptr_t gListLock = 0; // protects global monitor lists |
130 static volatile int gMonitorFreeCount = 0; // # on gFreeList |
132 static volatile int gMonitorFreeCount = 0; // # on gFreeList |
131 static volatile int gMonitorPopulation = 0; // # Extant -- in circulation |
133 static volatile int gMonitorPopulation = 0; // # Extant -- in circulation |
|
134 |
|
135 static void post_monitor_inflate_event(EventJavaMonitorInflate&, |
|
136 const oop, |
|
137 const ObjectSynchronizer::InflateCause); |
132 |
138 |
133 #define CHAINMARKER (cast_to_oop<intptr_t>(-1)) |
139 #define CHAINMARKER (cast_to_oop<intptr_t>(-1)) |
134 |
140 |
135 |
141 |
136 // =====================> Quick functions |
142 // =====================> Quick functions |
302 TEVENT(fast_exit: release stacklock); |
308 TEVENT(fast_exit: release stacklock); |
303 return; |
309 return; |
304 } |
310 } |
305 } |
311 } |
306 |
312 |
307 ObjectSynchronizer::inflate(THREAD, object)->exit(true, THREAD); |
313 ObjectSynchronizer::inflate(THREAD, |
|
314 object, |
|
315 inflate_cause_vm_internal)->exit(true, THREAD); |
308 } |
316 } |
309 |
317 |
310 // ----------------------------------------------------------------------------- |
318 // ----------------------------------------------------------------------------- |
311 // Interpreter/Compiler Slow Case |
319 // Interpreter/Compiler Slow Case |
312 // This routine is used to handle interpreter/compiler slow case |
320 // This routine is used to handle interpreter/compiler slow case |
336 // The object header will never be displaced to this lock, |
344 // The object header will never be displaced to this lock, |
337 // so it does not matter what the value is, except that it |
345 // so it does not matter what the value is, except that it |
338 // must be non-zero to avoid looking like a re-entrant lock, |
346 // must be non-zero to avoid looking like a re-entrant lock, |
339 // and must not look locked either. |
347 // and must not look locked either. |
340 lock->set_displaced_header(markOopDesc::unused_mark()); |
348 lock->set_displaced_header(markOopDesc::unused_mark()); |
341 ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD); |
349 ObjectSynchronizer::inflate(THREAD, |
|
350 obj(), |
|
351 inflate_cause_monitor_enter)->enter(THREAD); |
342 } |
352 } |
343 |
353 |
344 // This routine is used to handle interpreter/compiler slow case |
354 // This routine is used to handle interpreter/compiler slow case |
345 // We don't need to use fast path here, because it must have |
355 // We don't need to use fast path here, because it must have |
346 // failed in the interpreter/compiler code. Simply use the heavy |
356 // failed in the interpreter/compiler code. Simply use the heavy |
366 if (UseBiasedLocking) { |
376 if (UseBiasedLocking) { |
367 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
377 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
368 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
378 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
369 } |
379 } |
370 |
380 |
371 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); |
381 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, |
|
382 obj(), |
|
383 inflate_cause_vm_internal); |
372 |
384 |
373 return monitor->complete_exit(THREAD); |
385 return monitor->complete_exit(THREAD); |
374 } |
386 } |
375 |
387 |
376 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() |
388 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() |
379 if (UseBiasedLocking) { |
391 if (UseBiasedLocking) { |
380 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
392 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
381 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
393 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
382 } |
394 } |
383 |
395 |
384 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); |
396 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, |
|
397 obj(), |
|
398 inflate_cause_vm_internal); |
385 |
399 |
386 monitor->reenter(recursion, THREAD); |
400 monitor->reenter(recursion, THREAD); |
387 } |
401 } |
388 // ----------------------------------------------------------------------------- |
402 // ----------------------------------------------------------------------------- |
389 // JNI locks on java objects |
403 // JNI locks on java objects |
394 if (UseBiasedLocking) { |
408 if (UseBiasedLocking) { |
395 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
409 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
396 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
410 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
397 } |
411 } |
398 THREAD->set_current_pending_monitor_is_from_java(false); |
412 THREAD->set_current_pending_monitor_is_from_java(false); |
399 ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD); |
413 ObjectSynchronizer::inflate(THREAD, obj(), inflate_cause_jni_enter)->enter(THREAD); |
400 THREAD->set_current_pending_monitor_is_from_java(true); |
414 THREAD->set_current_pending_monitor_is_from_java(true); |
401 } |
415 } |
402 |
416 |
403 // NOTE: must use heavy weight monitor to handle jni monitor exit |
417 // NOTE: must use heavy weight monitor to handle jni monitor exit |
404 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) { |
418 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) { |
408 BiasedLocking::revoke_and_rebias(h_obj, false, THREAD); |
422 BiasedLocking::revoke_and_rebias(h_obj, false, THREAD); |
409 obj = h_obj(); |
423 obj = h_obj(); |
410 } |
424 } |
411 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
425 assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now"); |
412 |
426 |
413 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj); |
427 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, |
|
428 obj, |
|
429 inflate_cause_jni_exit); |
414 // If this thread has locked the object, exit the monitor. Note: can't use |
430 // If this thread has locked the object, exit the monitor. Note: can't use |
415 // monitor->check(CHECK); must exit even if an exception is pending. |
431 // monitor->check(CHECK); must exit even if an exception is pending. |
416 if (monitor->check(THREAD)) { |
432 if (monitor->check(THREAD)) { |
417 monitor->exit(true, THREAD); |
433 monitor->exit(true, THREAD); |
418 } |
434 } |
451 } |
467 } |
452 if (millis < 0) { |
468 if (millis < 0) { |
453 TEVENT(wait - throw IAX); |
469 TEVENT(wait - throw IAX); |
454 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); |
470 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); |
455 } |
471 } |
456 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj()); |
472 ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, |
|
473 obj(), |
|
474 inflate_cause_wait); |
|
475 |
457 DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), THREAD, millis); |
476 DTRACE_MONITOR_WAIT_PROBE(monitor, obj(), THREAD, millis); |
458 monitor->wait(millis, true, THREAD); |
477 monitor->wait(millis, true, THREAD); |
459 |
478 |
460 // This dummy call is in place to get around dtrace bug 6254741. Once |
479 // This dummy call is in place to get around dtrace bug 6254741. Once |
461 // that's fixed we can uncomment the following line, remove the call |
480 // that's fixed we can uncomment the following line, remove the call |
471 } |
490 } |
472 if (millis < 0) { |
491 if (millis < 0) { |
473 TEVENT(wait - throw IAX); |
492 TEVENT(wait - throw IAX); |
474 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); |
493 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "timeout value is negative"); |
475 } |
494 } |
476 ObjectSynchronizer::inflate(THREAD, obj()) -> wait(millis, false, THREAD); |
495 ObjectSynchronizer::inflate(THREAD, |
|
496 obj(), |
|
497 inflate_cause_wait)->wait(millis, false, THREAD); |
477 } |
498 } |
478 |
499 |
479 void ObjectSynchronizer::notify(Handle obj, TRAPS) { |
500 void ObjectSynchronizer::notify(Handle obj, TRAPS) { |
480 if (UseBiasedLocking) { |
501 if (UseBiasedLocking) { |
481 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
502 BiasedLocking::revoke_and_rebias(obj, false, THREAD); |
484 |
505 |
485 markOop mark = obj->mark(); |
506 markOop mark = obj->mark(); |
486 if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { |
507 if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { |
487 return; |
508 return; |
488 } |
509 } |
489 ObjectSynchronizer::inflate(THREAD, obj())->notify(THREAD); |
510 ObjectSynchronizer::inflate(THREAD, |
|
511 obj(), |
|
512 inflate_cause_notify)->notify(THREAD); |
490 } |
513 } |
491 |
514 |
492 // NOTE: see comment of notify() |
515 // NOTE: see comment of notify() |
493 void ObjectSynchronizer::notifyall(Handle obj, TRAPS) { |
516 void ObjectSynchronizer::notifyall(Handle obj, TRAPS) { |
494 if (UseBiasedLocking) { |
517 if (UseBiasedLocking) { |
498 |
521 |
499 markOop mark = obj->mark(); |
522 markOop mark = obj->mark(); |
500 if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { |
523 if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) { |
501 return; |
524 return; |
502 } |
525 } |
503 ObjectSynchronizer::inflate(THREAD, obj())->notifyAll(THREAD); |
526 ObjectSynchronizer::inflate(THREAD, |
|
527 obj(), |
|
528 inflate_cause_notify)->notifyAll(THREAD); |
504 } |
529 } |
505 |
530 |
506 // ----------------------------------------------------------------------------- |
531 // ----------------------------------------------------------------------------- |
507 // Hash Code handling |
532 // Hash Code handling |
508 // |
533 // |
747 // Any change to stack may not propagate to other threads |
772 // Any change to stack may not propagate to other threads |
748 // correctly. |
773 // correctly. |
749 } |
774 } |
750 |
775 |
751 // Inflate the monitor to set hash code |
776 // Inflate the monitor to set hash code |
752 monitor = ObjectSynchronizer::inflate(Self, obj); |
777 monitor = ObjectSynchronizer::inflate(Self, obj, inflate_cause_hash_code); |
753 // Load displaced header and check it has hash code |
778 // Load displaced header and check it has hash code |
754 mark = monitor->header(); |
779 mark = monitor->header(); |
755 assert(mark->is_neutral(), "invariant"); |
780 assert(mark->is_neutral(), "invariant"); |
756 hash = mark->hash(); |
781 hash = mark->hash(); |
757 if (hash == 0) { |
782 if (hash == 0) { |
1281 if (mark->has_monitor()) { |
1306 if (mark->has_monitor()) { |
1282 assert(ObjectSynchronizer::verify_objmon_isinpool(mark->monitor()), "monitor is invalid"); |
1307 assert(ObjectSynchronizer::verify_objmon_isinpool(mark->monitor()), "monitor is invalid"); |
1283 assert(mark->monitor()->header()->is_neutral(), "monitor must record a good object header"); |
1308 assert(mark->monitor()->header()->is_neutral(), "monitor must record a good object header"); |
1284 return mark->monitor(); |
1309 return mark->monitor(); |
1285 } |
1310 } |
1286 return ObjectSynchronizer::inflate(Thread::current(), obj); |
1311 return ObjectSynchronizer::inflate(Thread::current(), |
1287 } |
1312 obj, |
1288 |
1313 inflate_cause_vm_internal); |
|
1314 } |
1289 |
1315 |
1290 ObjectMonitor * NOINLINE ObjectSynchronizer::inflate(Thread * Self, |
1316 ObjectMonitor * NOINLINE ObjectSynchronizer::inflate(Thread * Self, |
1291 oop object) { |
1317 oop object, |
|
1318 const InflateCause cause) { |
|
1319 |
1292 // Inflate mutates the heap ... |
1320 // Inflate mutates the heap ... |
1293 // Relaxing assertion for bug 6320749. |
1321 // Relaxing assertion for bug 6320749. |
1294 assert(Universe::verify_in_progress() || |
1322 assert(Universe::verify_in_progress() || |
1295 !SafepointSynchronize::is_at_safepoint(), "invariant"); |
1323 !SafepointSynchronize::is_at_safepoint(), "invariant"); |
|
1324 |
|
1325 EventJavaMonitorInflate event; |
1296 |
1326 |
1297 for (;;) { |
1327 for (;;) { |
1298 const markOop mark = object->mark(); |
1328 const markOop mark = object->mark(); |
1299 assert(!mark->has_bias_pattern(), "invariant"); |
1329 assert(!mark->has_bias_pattern(), "invariant"); |
1300 |
1330 |
1309 if (mark->has_monitor()) { |
1339 if (mark->has_monitor()) { |
1310 ObjectMonitor * inf = mark->monitor(); |
1340 ObjectMonitor * inf = mark->monitor(); |
1311 assert(inf->header()->is_neutral(), "invariant"); |
1341 assert(inf->header()->is_neutral(), "invariant"); |
1312 assert(inf->object() == object, "invariant"); |
1342 assert(inf->object() == object, "invariant"); |
1313 assert(ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid"); |
1343 assert(ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid"); |
|
1344 event.cancel(); // let's not post an inflation event, unless we did the deed ourselves |
1314 return inf; |
1345 return inf; |
1315 } |
1346 } |
1316 |
1347 |
1317 // CASE: inflation in progress - inflating over a stack-lock. |
1348 // CASE: inflation in progress - inflating over a stack-lock. |
1318 // Some other thread is converting from stack-locked to inflated. |
1349 // Some other thread is converting from stack-locked to inflated. |
1421 log_debug(monitorinflation)("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
1452 log_debug(monitorinflation)("Inflating object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s", |
1422 p2i(object), p2i(object->mark()), |
1453 p2i(object), p2i(object->mark()), |
1423 object->klass()->external_name()); |
1454 object->klass()->external_name()); |
1424 } |
1455 } |
1425 } |
1456 } |
|
1457 if (event.should_commit()) { |
|
1458 post_monitor_inflate_event(event, object, cause); |
|
1459 } |
1426 return m; |
1460 return m; |
1427 } |
1461 } |
1428 |
1462 |
1429 // CASE: neutral |
1463 // CASE: neutral |
1430 // TODO-FIXME: for entry we currently inflate and then try to CAS _owner. |
1464 // TODO-FIXME: for entry we currently inflate and then try to CAS _owner. |
1468 ResourceMark rm; |
1502 ResourceMark rm; |
1469 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", |
1470 p2i(object), p2i(object->mark()), |
1504 p2i(object), p2i(object->mark()), |
1471 object->klass()->external_name()); |
1505 object->klass()->external_name()); |
1472 } |
1506 } |
|
1507 } |
|
1508 if (event.should_commit()) { |
|
1509 post_monitor_inflate_event(event, object, cause); |
1473 } |
1510 } |
1474 return m; |
1511 return m; |
1475 } |
1512 } |
1476 } |
1513 } |
1477 |
1514 |
1740 ObjectSynchronizer::monitors_iterate(&rjmc); |
1777 ObjectSynchronizer::monitors_iterate(&rjmc); |
1741 Thread::muxRelease(&gListLock); |
1778 Thread::muxRelease(&gListLock); |
1742 THREAD->clear_pending_exception(); |
1779 THREAD->clear_pending_exception(); |
1743 } |
1780 } |
1744 |
1781 |
|
1782 const char* ObjectSynchronizer::inflate_cause_name(const InflateCause cause) { |
|
1783 switch (cause) { |
|
1784 case inflate_cause_vm_internal: return "VM Internal"; |
|
1785 case inflate_cause_monitor_enter: return "Monitor Enter"; |
|
1786 case inflate_cause_wait: return "Monitor Wait"; |
|
1787 case inflate_cause_notify: return "Monitor Notify"; |
|
1788 case inflate_cause_hash_code: return "Monitor Hash Code"; |
|
1789 case inflate_cause_jni_enter: return "JNI Monitor Enter"; |
|
1790 case inflate_cause_jni_exit: return "JNI Monitor Exit"; |
|
1791 default: |
|
1792 ShouldNotReachHere(); |
|
1793 } |
|
1794 return "Unknown"; |
|
1795 } |
|
1796 |
|
1797 static void post_monitor_inflate_event(EventJavaMonitorInflate& event, |
|
1798 const oop obj, |
|
1799 const ObjectSynchronizer::InflateCause cause) { |
|
1800 #if INCLUDE_TRACE |
|
1801 assert(event.should_commit(), "check outside"); |
|
1802 event.set_klass(obj->klass()); |
|
1803 event.set_address((TYPE_ADDRESS)(uintptr_t)(void*)obj); |
|
1804 event.set_cause((u1)cause); |
|
1805 event.commit(); |
|
1806 #endif |
|
1807 } |
|
1808 |
1745 //------------------------------------------------------------------------------ |
1809 //------------------------------------------------------------------------------ |
1746 // Debugging code |
1810 // Debugging code |
1747 |
1811 |
1748 void ObjectSynchronizer::sanity_checks(const bool verbose, |
1812 void ObjectSynchronizer::sanity_checks(const bool verbose, |
1749 const uint cache_line_size, |
1813 const uint cache_line_size, |