< 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 >