|
189 | 189 | * appropriately to comply with the layouts above.
|
190 | 190 | */
|
191 | 191 | // @formatter:off
|
192 |
| -@SyncPort(from = "https://github.com/openjdk/jdk/blob/180affc5718c9bf2f009d6a7aa129cc36335384a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp#L175-L532", |
193 |
| - sha1 = "6269b3e841e4a6be49042270f3489eae292fc05f") |
| 192 | +@SyncPort(from = "https://github.com/openjdk/jdk/blob/d8430efb5e159b8e08d2cac66b46cb4ff1112927/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp#L175-L532", |
| 193 | + sha1 = "042c4a5c1730525a53c24ee194a182dfd34bf754") |
194 | 194 | // @formatter:on
|
195 | 195 | public class MonitorSnippets implements Snippets {
|
196 | 196 |
|
@@ -515,8 +515,8 @@ private static boolean tryStackUnlocking(Object object, Word thread, Word lock,
|
515 | 515 | }
|
516 | 516 |
|
517 | 517 | // @formatter:off
|
518 |
| - @SyncPort(from = "https://github.com/openjdk/jdk/blob/dcac4b0a532f2ca6cb374da7ece331e8266ab351/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp#L694-L855", |
519 |
| - sha1 = "410864d3b17fd0e3f1026b9c06e4d383446896ba") |
| 518 | + @SyncPort(from = "https://github.com/openjdk/jdk/blob/d8430efb5e159b8e08d2cac66b46cb4ff1112927/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp#L694-L858", |
| 519 | + sha1 = "57536f7432c20e2e785059b464948f9aeee3804b") |
520 | 520 | // @formatter:on
|
521 | 521 | private static boolean tryLightweightUnlocking(Object object, Word thread, Word lock, boolean trace, Counters counters) {
|
522 | 522 | // Load top
|
@@ -597,12 +597,10 @@ private static boolean tryExitInflated(Object object, Word thread, Word lock, bo
|
597 | 597 | if (probability(FAST_PATH_PROBABILITY, recursions.equal(0))) {
|
598 | 598 | if (JavaVersionUtil.JAVA_SPEC == 21) {
|
599 | 599 | // recursions == 0
|
600 |
| - int cxqOffset = objectMonitorCxqOffset(INJECTED_VMCONFIG); |
601 |
| - Word cxq = monitor.readWord(cxqOffset, OBJECT_MONITOR_CXQ_LOCATION); |
602 |
| - int entryListOffset = objectMonitorEntryListOffset(INJECTED_VMCONFIG); |
603 |
| - Word entryList = monitor.readWord(entryListOffset, OBJECT_MONITOR_ENTRY_LIST_LOCATION); |
604 |
| - if (probability(FREQUENT_PROBABILITY, cxq.or(entryList).equal(0))) { |
605 |
| - // cxq == 0 && entryList == 0 |
| 600 | + Word entryList = monitor.readWord(objectMonitorEntryListOffset(INJECTED_VMCONFIG), OBJECT_MONITOR_ENTRY_LIST_LOCATION); |
| 601 | + Word cxq = monitor.readWord(objectMonitorCxqOffset(INJECTED_VMCONFIG), OBJECT_MONITOR_CXQ_LOCATION); |
| 602 | + if (probability(FREQUENT_PROBABILITY, entryList.or(cxq).equal(0))) { |
| 603 | + // entryList == 0 && cxq == 0 |
606 | 604 | // Nobody is waiting, success
|
607 | 605 | // release_store
|
608 | 606 | memoryBarrier(MembarNode.FenceKind.STORE_RELEASE);
|
@@ -641,10 +639,17 @@ private static boolean tryExitInflated(Object object, Word thread, Word lock, bo
|
641 | 639 | memoryBarrier(MembarNode.FenceKind.STORE_RELEASE);
|
642 | 640 | monitor.writeWord(ownerOffset, zero());
|
643 | 641 | memoryBarrier(MembarNode.FenceKind.STORE_LOAD);
|
644 |
| - Word cxq = monitor.readWord(objectMonitorCxqOffset(INJECTED_VMCONFIG), OBJECT_MONITOR_CXQ_LOCATION); |
| 642 | + // Note that we read the EntryList and then the cxq after dropping the |
| 643 | + // lock, so the values need not form a stable snapshot. In particular, |
| 644 | + // after reading the (empty) EntryList, another thread could acquire |
| 645 | + // and release the lock, moving any entries in the cxq to the |
| 646 | + // EntryList, causing the current thread to see an empty cxq and |
| 647 | + // conclude there are no waiters. But this is okay as the thread that |
| 648 | + // moved the cxq is responsible for waking the successor. |
645 | 649 | Word entryList = monitor.readWord(objectMonitorEntryListOffset(INJECTED_VMCONFIG), OBJECT_MONITOR_ENTRY_LIST_LOCATION);
|
| 650 | + Word cxq = monitor.readWord(objectMonitorCxqOffset(INJECTED_VMCONFIG), OBJECT_MONITOR_CXQ_LOCATION); |
646 | 651 | // Check if the entry lists are empty.
|
647 |
| - if (probability(FREQUENT_PROBABILITY, cxq.or(entryList).equal(0))) { |
| 652 | + if (probability(FREQUENT_PROBABILITY, entryList.or(cxq).equal(0))) { |
648 | 653 | traceObject(trace, "-lock{heavyweight:simple}", object, false);
|
649 | 654 | counters.unlockHeavySimple.inc();
|
650 | 655 | return true;
|
|
0 commit comments