< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java
Print this page
*** 23,32 ****
--- 23,33 ----
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;
import static org.graalvm.compiler.hotspot.nodes.AcquiredCASLockNode.mark;
import static org.graalvm.compiler.hotspot.nodes.BeginLockScopeNode.beginLockScope;
*** 36,45 ****
--- 37,47 ----
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.MARK_WORD_LOCATION;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.OBJECT_MONITOR_CXQ_LOCATION;
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;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.biasedLockPattern;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.epochMaskInPlace;
*** 49,58 ****
--- 51,61 ----
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.monitorMask;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.objectMonitorCxqOffset;
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;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.stackBias;
import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.unlockedMask;
*** 572,581 ****
--- 575,610 ----
memoryBarrier(LOAD_STORE | STORE_STORE);
monitor.writeWord(ownerOffset, zero());
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();
traceObject(trace, "-lock{stub:inflated}", object, false);
monitorexitStubC(MONITOREXIT, object, lock);
*** 690,699 ****
--- 719,729 ----
public final SnippetCounter unlockCas;
public final SnippetCounter unlockCasRecursive;
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");
SnippetCounter.Group exit = factory.createSnippetCounterGroup("MonitorExits");
lockBiasExisting = new SnippetCounter(enter, "lock{bias:existing}", "bias-locked previously biased object");
*** 714,723 ****
--- 744,754 ----
unlockCas = new SnippetCounter(exit, "unlock{cas}", "cas-unlocked an object");
unlockCasRecursive = new SnippetCounter(exit, "unlock{cas:recursive}", "cas-unlocked an object, recursive");
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");
}
}
public static class Templates extends AbstractTemplates {
< prev index next >