use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class MonitorSnippets method initCounter.
@Snippet
private static void initCounter() {
final Word counter = MonitorCounterNode.counter();
counter.writeInt(0, 0, MONITOR_COUNTER_LOCATION);
}
use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class MonitorSnippets method monitorenter.
@Snippet
public static void monitorenter(Object object, KlassPointer hub, @ConstantParameter int lockDepth, @ConstantParameter Register threadRegister, @ConstantParameter Register stackPointerRegister, @ConstantParameter boolean trace, @ConstantParameter OptionValues options, @ConstantParameter Counters counters) {
verifyOop(object);
// Load the mark word - this includes a null-check on object
final Word mark = loadWordFromObject(object, markOffset(INJECTED_VMCONFIG));
final Word lock = beginLockScope(lockDepth);
Pointer objectPointer = Word.objectToTrackedPointer(object);
trace(trace, " object: 0x%016lx\n", objectPointer);
trace(trace, " lock: 0x%016lx\n", lock);
trace(trace, " mark: 0x%016lx\n", mark);
incCounter(options);
if (useBiasedLocking(INJECTED_VMCONFIG)) {
if (tryEnterBiased(object, hub, lock, mark, threadRegister, trace, options, counters)) {
return;
}
// not biased, fall-through
}
if (inlineFastLockSupported(options) && probability(SLOW_PATH_PROBABILITY, mark.and(monitorMask(INJECTED_VMCONFIG)).notEqual(0))) {
// Inflated case
if (tryEnterInflated(object, lock, mark, threadRegister, trace, options, counters)) {
return;
}
} else {
// Create the unlocked mark word pattern
Word unlockedMark = mark.or(unlockedMask(INJECTED_VMCONFIG));
trace(trace, " unlockedMark: 0x%016lx\n", unlockedMark);
// Copy this unlocked mark word into the lock slot on the stack
lock.writeWord(lockDisplacedMarkOffset(INJECTED_VMCONFIG), unlockedMark, DISPLACED_MARK_WORD_LOCATION);
// make sure previous store does not float below compareAndSwap
MembarNode.memoryBarrier(STORE_STORE);
// Test if the object's mark word is unlocked, and if so, store the
// (address of) the lock slot into the object's mark word.
Word currentMark = objectPointer.compareAndSwapWord(markOffset(INJECTED_VMCONFIG), unlockedMark, lock, MARK_WORD_LOCATION);
if (probability(FAST_PATH_PROBABILITY, currentMark.equal(unlockedMark))) {
traceObject(trace, "+lock{cas}", object, true, options);
counters.lockCas.inc();
AcquiredCASLockNode.mark(object);
return;
} else {
trace(trace, " currentMark: 0x%016lx\n", currentMark);
// The mark word in the object header was not the same.
// Either the object is locked by another thread or is already locked
// by the current thread. The latter is true if the mark word
// is a stack pointer into the current thread's stack, i.e.:
//
// 1) (currentMark & aligned_mask) == 0
// 2) rsp <= currentMark
// 3) currentMark <= rsp + page_size
//
// These 3 tests can be done by evaluating the following expression:
//
// (currentMark - rsp) & (aligned_mask - page_size)
//
// assuming both the stack pointer and page_size have their least
// significant 2 bits cleared and page_size is a power of 2
final Word alignedMask = WordFactory.unsigned(wordSize() - 1);
final Word stackPointer = registerAsWord(stackPointerRegister).add(config(INJECTED_VMCONFIG).stackBias);
if (probability(FAST_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).equal(0))) {
// Recursively locked => write 0 to the lock slot
lock.writeWord(lockDisplacedMarkOffset(INJECTED_VMCONFIG), WordFactory.zero(), DISPLACED_MARK_WORD_LOCATION);
traceObject(trace, "+lock{cas:recursive}", object, true, options);
counters.lockCasRecursive.inc();
return;
}
traceObject(trace, "+lock{stub:failed-cas/stack}", object, true, options);
counters.lockStubFailedCas.inc();
}
}
// slow-path runtime-call
monitorenterStubC(MONITORENTER, object, lock);
}
use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class MonitorSnippets method monitorexitStub.
/**
* Calls straight out to the monitorexit stub.
*/
@Snippet
public static void monitorexitStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace, @ConstantParameter OptionValues options) {
verifyOop(object);
traceObject(trace, "-lock{stub}", object, false, options);
final Word lock = CurrentLockNode.currentLock(lockDepth);
monitorexitStubC(MONITOREXIT, object, lock);
endLockScope();
decCounter(options);
}
use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class MonitorSnippets method monitorenterStub.
/**
* Calls straight out to the monitorenter stub.
*/
@Snippet
public static void monitorenterStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace, @ConstantParameter OptionValues options) {
verifyOop(object);
incCounter(options);
if (object == null) {
DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
}
// BeginLockScope nodes do not read from object so a use of object
// cannot float about the null check above
final Word lock = beginLockScope(lockDepth);
traceObject(trace, "+lock{stub}", object, true, options);
monitorenterStubC(MONITORENTER, object, lock);
}
use of org.graalvm.compiler.api.replacements.Snippet in project graal by oracle.
the class NewObjectSnippets method verifyHeap.
@Snippet
protected static void verifyHeap(@ConstantParameter Register threadRegister) {
Word thread = registerAsWord(threadRegister);
Word topValue = readTlabTop(thread);
if (!topValue.equal(WordFactory.zero())) {
Word topValueContents = topValue.readWord(0, MARK_WORD_LOCATION);
if (topValueContents.equal(WordFactory.zero())) {
AssertionSnippets.vmMessageC(AssertionSnippets.ASSERTION_VM_MESSAGE_C, true, cstring("overzeroing of TLAB detected"), 0L, 0L, 0L);
}
}
}
Aggregations