Search in sources :

Example 26 with Word

use of org.graalvm.compiler.word.Word in project graal by oracle.

the class MonitorSnippets method tryEnterBiased.

private static boolean tryEnterBiased(Object object, KlassPointer hub, Word lock, Word mark, Register threadRegister, boolean trace, OptionValues options, Counters counters) {
    // See whether the lock is currently biased toward our thread and
    // whether the epoch is still valid.
    // Note that the runtime guarantees sufficient alignment of JavaThread
    // pointers to allow age to be placed into low bits.
    final Word biasableLockBits = mark.and(biasedLockMaskInPlace(INJECTED_VMCONFIG));
    // Check whether the bias pattern is present in the object's mark word
    // and the bias owner and the epoch are both still current.
    final Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION);
    final Word thread = registerAsWord(threadRegister);
    final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace(INJECTED_VMCONFIG));
    trace(trace, "prototypeMarkWord: 0x%016lx\n", prototypeMarkWord);
    trace(trace, "           thread: 0x%016lx\n", thread);
    trace(trace, "              tmp: 0x%016lx\n", tmp);
    if (probability(FAST_PATH_PROBABILITY, tmp.equal(0))) {
        // Object is already biased to current thread -> done
        traceObject(trace, "+lock{bias:existing}", object, true, options);
        counters.lockBiasExisting.inc();
        FastAcquireBiasedLockNode.mark(object);
        return true;
    }
    // Now check to see whether biasing is enabled for this object
    if (probability(NOT_FREQUENT_PROBABILITY, biasableLockBits.equal(WordFactory.unsigned(biasedLockPattern(INJECTED_VMCONFIG))))) {
        Pointer objectPointer = Word.objectToTrackedPointer(object);
        // the bias on this object.
        if (probability(FREQUENT_PROBABILITY, tmp.and(biasedLockMaskInPlace(INJECTED_VMCONFIG)).equal(0))) {
            // illegal.
            if (probability(FREQUENT_PROBABILITY, tmp.and(epochMaskInPlace(INJECTED_VMCONFIG)).equal(0))) {
                // The epoch of the current bias is still valid but we know nothing
                // about the owner; it might be set or it might be clear. Try to
                // acquire the bias of the object using an atomic operation. If this
                // fails we will go in to the runtime to revoke the object's bias.
                // Note that we first construct the presumed unbiased header so we
                // don't accidentally blow away another thread's valid bias.
                Word unbiasedMark = mark.and(biasedLockMaskInPlace(INJECTED_VMCONFIG) | ageMaskInPlace(INJECTED_VMCONFIG) | epochMaskInPlace(INJECTED_VMCONFIG));
                Word biasedMark = unbiasedMark.or(thread);
                trace(trace, "     unbiasedMark: 0x%016lx\n", unbiasedMark);
                trace(trace, "       biasedMark: 0x%016lx\n", biasedMark);
                if (probability(VERY_FAST_PATH_PROBABILITY, objectPointer.logicCompareAndSwapWord(markOffset(INJECTED_VMCONFIG), unbiasedMark, biasedMark, MARK_WORD_LOCATION))) {
                    // Object is now biased to current thread -> done
                    traceObject(trace, "+lock{bias:acquired}", object, true, options);
                    counters.lockBiasAcquired.inc();
                    return true;
                }
                // If the biasing toward our thread failed, this means that another thread
                // owns the bias and we need to revoke that bias. The revocation will occur
                // in the interpreter runtime.
                traceObject(trace, "+lock{stub:revoke}", object, true, options);
                counters.lockStubRevoke.inc();
            } else {
                // At this point we know the epoch has expired, meaning that the
                // current bias owner, if any, is actually invalid. Under these
                // circumstances _only_, are we allowed to use the current mark word
                // value as the comparison value when doing the CAS to acquire the
                // bias in the current epoch. In other words, we allow transfer of
                // the bias from one thread to another directly in this situation.
                Word biasedMark = prototypeMarkWord.or(thread);
                trace(trace, "       biasedMark: 0x%016lx\n", biasedMark);
                if (probability(VERY_FAST_PATH_PROBABILITY, objectPointer.logicCompareAndSwapWord(markOffset(INJECTED_VMCONFIG), mark, biasedMark, MARK_WORD_LOCATION))) {
                    // Object is now biased to current thread -> done
                    traceObject(trace, "+lock{bias:transfer}", object, true, options);
                    counters.lockBiasTransfer.inc();
                    return true;
                }
                // If the biasing toward our thread failed, then another thread
                // succeeded in biasing it toward itself and we need to revoke that
                // bias. The revocation will occur in the runtime in the slow case.
                traceObject(trace, "+lock{stub:epoch-expired}", object, true, options);
                counters.lockStubEpochExpired.inc();
            }
            // slow-path runtime-call
            monitorenterStubC(MONITORENTER, object, lock);
            return true;
        } else {
            // The prototype mark word doesn't have the bias bit set any
            // more, indicating that objects of this data type are not supposed
            // to be biased any more. We are going to try to reset the mark of
            // this object to the prototype value and fall through to the
            // CAS-based locking scheme. Note that if our CAS fails, it means
            // that another thread raced us for the privilege of revoking the
            // bias of this particular object, so it's okay to continue in the
            // normal locking code.
            Word result = objectPointer.compareAndSwapWord(markOffset(INJECTED_VMCONFIG), mark, prototypeMarkWord, MARK_WORD_LOCATION);
            if (ENABLE_BREAKPOINT) {
                bkpt(object, mark, tmp, result);
            }
            counters.revokeBias.inc();
            return false;
        }
    } else {
        // Biasing not enabled -> fall through to lightweight locking
        counters.unbiasable.inc();
        return false;
    }
}
Also used : Word(org.graalvm.compiler.word.Word) HotSpotReplacementsUtil.registerAsWord(org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord) Pointer(org.graalvm.word.Pointer) KlassPointer(org.graalvm.compiler.hotspot.word.KlassPointer)

Example 27 with Word

use of org.graalvm.compiler.word.Word 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);
}
Also used : Word(org.graalvm.compiler.word.Word) HotSpotReplacementsUtil.registerAsWord(org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord) Snippet(org.graalvm.compiler.api.replacements.Snippet)

Example 28 with Word

use of org.graalvm.compiler.word.Word 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);
}
Also used : Word(org.graalvm.compiler.word.Word) HotSpotReplacementsUtil.registerAsWord(org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord) Pointer(org.graalvm.word.Pointer) KlassPointer(org.graalvm.compiler.hotspot.word.KlassPointer) Snippet(org.graalvm.compiler.api.replacements.Snippet)

Example 29 with Word

use of org.graalvm.compiler.word.Word 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);
}
Also used : Word(org.graalvm.compiler.word.Word) HotSpotReplacementsUtil.registerAsWord(org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord) Snippet(org.graalvm.compiler.api.replacements.Snippet)

Example 30 with Word

use of org.graalvm.compiler.word.Word 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);
}
Also used : Word(org.graalvm.compiler.word.Word) HotSpotReplacementsUtil.registerAsWord(org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord) Snippet(org.graalvm.compiler.api.replacements.Snippet)

Aggregations

Word (org.graalvm.compiler.word.Word)53 HotSpotReplacementsUtil.registerAsWord (org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord)32 Snippet (org.graalvm.compiler.api.replacements.Snippet)22 Pointer (org.graalvm.word.Pointer)12 UnsignedWord (org.graalvm.word.UnsignedWord)7 MethodSubstitution (org.graalvm.compiler.api.replacements.MethodSubstitution)5 KlassPointer (org.graalvm.compiler.hotspot.word.KlassPointer)5 HotSpotReplacementsUtil.tlabIntArrayMarkWord (org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.tlabIntArrayMarkWord)4 Uninterruptible (com.oracle.svm.core.annotate.Uninterruptible)2 HotSpotReplacementsUtil.loadKlassFromObject (org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.loadKlassFromObject)2 SignedWord (org.graalvm.word.SignedWord)2 Substitute (com.oracle.svm.core.annotate.Substitute)1 SubstrateObjectConstant (com.oracle.svm.core.meta.SubstrateObjectConstant)1 Pwd.passwd (com.oracle.svm.core.posix.headers.Pwd.passwd)1 Pwd.passwdPointer (com.oracle.svm.core.posix.headers.Pwd.passwdPointer)1 PrimitiveConstant (jdk.vm.ci.meta.PrimitiveConstant)1 HotSpotReplacementsUtil.arrayPrototypeMarkWord (org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.arrayPrototypeMarkWord)1 GuardingNode (org.graalvm.compiler.nodes.extended.GuardingNode)1 Isolate (org.graalvm.nativeimage.Isolate)1 PinnedObject (org.graalvm.nativeimage.PinnedObject)1