Mercurial > hg > graal-jvmci-8
comparison src/share/vm/runtime/objectMonitor.cpp @ 17805:bbfbe9b06038
Merge
author | kvn |
---|---|
date | Thu, 13 Mar 2014 14:57:01 -0700 |
parents | 75ef1a499665 d35df3079834 |
children | a7d4d4655766 |
comparison
equal
deleted
inserted
replaced
17804:fd1b9f02cc91 | 17805:bbfbe9b06038 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
380 JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this); | 380 JavaThreadBlockedOnMonitorEnterState jtbmes(jt, this); |
381 | 381 |
382 DTRACE_MONITOR_PROBE(contended__enter, this, object(), jt); | 382 DTRACE_MONITOR_PROBE(contended__enter, this, object(), jt); |
383 if (JvmtiExport::should_post_monitor_contended_enter()) { | 383 if (JvmtiExport::should_post_monitor_contended_enter()) { |
384 JvmtiExport::post_monitor_contended_enter(jt, this); | 384 JvmtiExport::post_monitor_contended_enter(jt, this); |
385 | |
386 // The current thread does not yet own the monitor and does not | |
387 // yet appear on any queues that would get it made the successor. | |
388 // This means that the JVMTI_EVENT_MONITOR_CONTENDED_ENTER event | |
389 // handler cannot accidentally consume an unpark() meant for the | |
390 // ParkEvent associated with this ObjectMonitor. | |
385 } | 391 } |
386 | 392 |
387 OSThreadContendState osts(Self->osthread()); | 393 OSThreadContendState osts(Self->osthread()); |
388 ThreadBlockInVM tbivm(jt); | 394 ThreadBlockInVM tbivm(jt); |
389 | 395 |
437 // spinning we could increment JVMStat counters, etc. | 443 // spinning we could increment JVMStat counters, etc. |
438 | 444 |
439 DTRACE_MONITOR_PROBE(contended__entered, this, object(), jt); | 445 DTRACE_MONITOR_PROBE(contended__entered, this, object(), jt); |
440 if (JvmtiExport::should_post_monitor_contended_entered()) { | 446 if (JvmtiExport::should_post_monitor_contended_entered()) { |
441 JvmtiExport::post_monitor_contended_entered(jt, this); | 447 JvmtiExport::post_monitor_contended_entered(jt, this); |
448 | |
449 // The current thread already owns the monitor and is not going to | |
450 // call park() for the remainder of the monitor enter protocol. So | |
451 // it doesn't matter if the JVMTI_EVENT_MONITOR_CONTENDED_ENTERED | |
452 // event handler consumed an unpark() issued by the thread that | |
453 // just exited the monitor. | |
442 } | 454 } |
443 | 455 |
444 if (event.should_commit()) { | 456 if (event.should_commit()) { |
445 event.set_klass(((oop)this->object())->klass()); | 457 event.set_klass(((oop)this->object())->klass()); |
446 event.set_previousOwner((TYPE_JAVALANGTHREAD)_previous_owner_tid); | 458 event.set_previousOwner((TYPE_JAVALANGTHREAD)_previous_owner_tid); |
1454 // post monitor waited event. Note that this is past-tense, we are done waiting. | 1466 // post monitor waited event. Note that this is past-tense, we are done waiting. |
1455 if (JvmtiExport::should_post_monitor_waited()) { | 1467 if (JvmtiExport::should_post_monitor_waited()) { |
1456 // Note: 'false' parameter is passed here because the | 1468 // Note: 'false' parameter is passed here because the |
1457 // wait was not timed out due to thread interrupt. | 1469 // wait was not timed out due to thread interrupt. |
1458 JvmtiExport::post_monitor_waited(jt, this, false); | 1470 JvmtiExport::post_monitor_waited(jt, this, false); |
1471 | |
1472 // In this short circuit of the monitor wait protocol, the | |
1473 // current thread never drops ownership of the monitor and | |
1474 // never gets added to the wait queue so the current thread | |
1475 // cannot be made the successor. This means that the | |
1476 // JVMTI_EVENT_MONITOR_WAITED event handler cannot accidentally | |
1477 // consume an unpark() meant for the ParkEvent associated with | |
1478 // this ObjectMonitor. | |
1459 } | 1479 } |
1460 if (event.should_commit()) { | 1480 if (event.should_commit()) { |
1461 post_monitor_wait_event(&event, 0, millis, false); | 1481 post_monitor_wait_event(&event, 0, millis, false); |
1462 } | 1482 } |
1463 TEVENT (Wait - Throw IEX) ; | 1483 TEVENT (Wait - Throw IEX) ; |
1496 intptr_t save = _recursions; // record the old recursion count | 1516 intptr_t save = _recursions; // record the old recursion count |
1497 _waiters++; // increment the number of waiters | 1517 _waiters++; // increment the number of waiters |
1498 _recursions = 0; // set the recursion level to be 1 | 1518 _recursions = 0; // set the recursion level to be 1 |
1499 exit (true, Self) ; // exit the monitor | 1519 exit (true, Self) ; // exit the monitor |
1500 guarantee (_owner != Self, "invariant") ; | 1520 guarantee (_owner != Self, "invariant") ; |
1501 | |
1502 // As soon as the ObjectMonitor's ownership is dropped in the exit() | |
1503 // call above, another thread can enter() the ObjectMonitor, do the | |
1504 // notify(), and exit() the ObjectMonitor. If the other thread's | |
1505 // exit() call chooses this thread as the successor and the unpark() | |
1506 // call happens to occur while this thread is posting a | |
1507 // MONITOR_CONTENDED_EXIT event, then we run the risk of the event | |
1508 // handler using RawMonitors and consuming the unpark(). | |
1509 // | |
1510 // To avoid the problem, we re-post the event. This does no harm | |
1511 // even if the original unpark() was not consumed because we are the | |
1512 // chosen successor for this monitor. | |
1513 if (node._notified != 0 && _succ == Self) { | |
1514 node._event->unpark(); | |
1515 } | |
1516 | 1521 |
1517 // The thread is on the WaitSet list - now park() it. | 1522 // The thread is on the WaitSet list - now park() it. |
1518 // On MP systems it's conceivable that a brief spin before we park | 1523 // On MP systems it's conceivable that a brief spin before we park |
1519 // could be profitable. | 1524 // could be profitable. |
1520 // | 1525 // |
1593 // (Don't cache naked oops over safepoints, of course). | 1598 // (Don't cache naked oops over safepoints, of course). |
1594 | 1599 |
1595 // post monitor waited event. Note that this is past-tense, we are done waiting. | 1600 // post monitor waited event. Note that this is past-tense, we are done waiting. |
1596 if (JvmtiExport::should_post_monitor_waited()) { | 1601 if (JvmtiExport::should_post_monitor_waited()) { |
1597 JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT); | 1602 JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT); |
1603 } | |
1604 | |
1605 // Without the fix for 8028280, it is possible for the above call: | |
1606 // | |
1607 // Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ; | |
1608 // | |
1609 // to consume the unpark() that was done when the successor was set. | |
1610 // The solution for this very rare possibility is to redo the unpark() | |
1611 // outside of the JvmtiExport::should_post_monitor_waited() check. | |
1612 // | |
1613 if (node._notified != 0 && _succ == Self) { | |
1614 // In this part of the monitor wait-notify-reenter protocol it | |
1615 // is possible (and normal) for another thread to do a fastpath | |
1616 // monitor enter-exit while this thread is still trying to get | |
1617 // to the reenter portion of the protocol. | |
1618 // | |
1619 // The ObjectMonitor was notified and the current thread is | |
1620 // the successor which also means that an unpark() has already | |
1621 // been done. The JVMTI_EVENT_MONITOR_WAITED event handler can | |
1622 // consume the unpark() that was done when the successor was | |
1623 // set because the same ParkEvent is shared between Java | |
1624 // monitors and JVM/TI RawMonitors (for now). | |
1625 // | |
1626 // We redo the unpark() to ensure forward progress, i.e., we | |
1627 // don't want all pending threads hanging (parked) with none | |
1628 // entering the unlocked monitor. | |
1629 node._event->unpark(); | |
1598 } | 1630 } |
1599 | 1631 |
1600 if (event.should_commit()) { | 1632 if (event.should_commit()) { |
1601 post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT); | 1633 post_monitor_wait_event(&event, node._notifier_tid, millis, ret == OS_TIMEOUT); |
1602 } | 1634 } |