src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java Mon May 06 12:17:54 2019 -0700
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java Mon May 06 21:50:20 2019 +0200
@@ -25,6 +25,7 @@
package org.graalvm.compiler.hotspot.replacements;
import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
+import static jdk.vm.ci.code.MemoryBarriers.STORE_LOAD;
import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_OPTIONVALUES;
import static org.graalvm.compiler.hotspot.GraalHotSpotVMConfig.INJECTED_VMCONFIG;
@@ -38,6 +39,7 @@
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_ENTRY_LIST_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_OWNER_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_RECURSION_LOCATION;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_SUCC_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.PROTOTYPE_MARK_WORD_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.ageMaskInPlace;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.biasedLockMaskInPlace;
@@ -51,6 +53,7 @@
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorEntryListOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorOwnerOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorRecursionsOffset;
+import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorSuccOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.pageSize;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.prototypeMarkWordOffset;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord;
@@ -574,6 +577,32 @@
traceObject(trace, "-lock{inflated:simple}", object, false);
counters.unlockInflatedSimple.inc();
return true;
+ } else {
+ int succOffset = objectMonitorSuccOffset(INJECTED_VMCONFIG);
+ Word succ = monitor.readWord(succOffset, OBJECT_MONITOR_SUCC_LOCATION);
+ if (probability(FREQUENT_PROBABILITY, succ.isNonNull())) {
+ // There may be a thread spinning on this monitor. Temporarily setting
+ // the monitor owner to null, and hope that the other thread will grab it.
+ monitor.writeWord(ownerOffset, zero());
+ memoryBarrier(STORE_STORE | STORE_LOAD);
+ succ = monitor.readWord(succOffset, OBJECT_MONITOR_SUCC_LOCATION);
+ if (probability(NOT_FREQUENT_PROBABILITY, succ.isNonNull())) {
+ // We manage to release the monitor before the other running thread even
+ // notices.
+ traceObject(trace, "-lock{inflated:transfer}", object, false);
+ counters.unlockInflatedTransfer.inc();
+ return true;
+ } else {
+ // Either the monitor is grabbed by a spinning thread, or the spinning
+ // thread parks. Now we attempt to reset the owner of the monitor.
+ if (probability(FREQUENT_PROBABILITY, !monitor.logicCompareAndSwapWord(ownerOffset, zero(), thread, OBJECT_MONITOR_OWNER_LOCATION))) {
+ // The monitor is stolen.
+ traceObject(trace, "-lock{inflated:transfer}", object, false);
+ counters.unlockInflatedTransfer.inc();
+ return true;
+ }
+ }
+ }
}
}
counters.unlockStubInflated.inc();
@@ -692,6 +721,7 @@
public final SnippetCounter unlockStub;
public final SnippetCounter unlockStubInflated;
public final SnippetCounter unlockInflatedSimple;
+ public final SnippetCounter unlockInflatedTransfer;
public Counters(SnippetCounter.Group.Factory factory) {
SnippetCounter.Group enter = factory.createSnippetCounterGroup("MonitorEnters");
@@ -716,6 +746,7 @@
unlockStub = new SnippetCounter(exit, "unlock{stub}", "stub-unlocked an object");
unlockStubInflated = new SnippetCounter(exit, "unlock{stub:inflated}", "stub-unlocked an object with inflated monitor");
unlockInflatedSimple = new SnippetCounter(exit, "unlock{inflated}", "unlocked an object monitor");
+ unlockInflatedTransfer = new SnippetCounter(exit, "unlock{inflated:transfer}", "unlocked an object monitor in the presence of ObjectMonitor::_succ");
}
}