Search in sources :

Example 46 with Pointer

use of org.graalvm.word.Pointer in project graal by oracle.

the class PosixOSInterface method allocateVirtualMemoryAligned.

/**
 * Allocate the requested amount of virtual memory at the requested alignment.
 *
 * @return A Pointer to the aligned memory, or a null Pointer.
 */
@Override
public Pointer allocateVirtualMemoryAligned(UnsignedWord size, UnsignedWord alignment) {
    // This happens in stages:
    // (1) Reserve a container that is large enough for the requested size *and* the alignment.
    // (2) Locate the result at the requested alignment within the container.
    // (3) Clean up any over-allocated prefix and suffix pages.
    // All communication with mmap and munmap happen in terms of page_sized objects.
    final UnsignedWord pageSize = getPageSize();
    // (1) Reserve a container that is large enough for the requested size *and* the alignment.
    // - The container occupies the open-right interval [containerStart .. containerEnd).
    // - This will be too big, but I'll give back the extra later.
    final UnsignedWord containerSize = alignment.add(size);
    final UnsignedWord pagedContainerSize = UnsignedUtils.roundUp(containerSize, pageSize);
    final Pointer containerStart = allocateVirtualMemory(pagedContainerSize, false);
    if (containerStart.isNull()) {
        // No exception is needed: this is just a failure to reserve the virtual address space.
        return WordFactory.nullPointer();
    }
    final Pointer containerEnd = containerStart.add(pagedContainerSize);
    // (2) Locate the result at the requested alignment within the container.
    // - The result occupies [start .. end).
    final Pointer start = PointerUtils.roundUp(containerStart, alignment);
    final Pointer end = start.add(size);
    if (virtualMemoryVerboseDebugging) {
        Log.log().string("allocateVirtualMemoryAligned(size: ").unsigned(size).string(" ").hex(size).string(", alignment: ").unsigned(alignment).string(" ").hex(alignment).string(")").newline();
        Log.log().string("  container:   [").hex(containerStart).string(" .. ").hex(containerEnd).string(")").newline();
        Log.log().string("  result:      [").hex(start).string(" .. ").hex(end).string(")").newline();
    }
    // (3) Clean up any over-allocated prefix and suffix pages.
    // - The prefix occupies [containerStart .. pagedStart).
    final Pointer pagedStart = PointerUtils.roundDown(start, pageSize);
    final Pointer prefixStart = containerStart;
    final Pointer prefixEnd = pagedStart;
    final UnsignedWord prefixSize = prefixEnd.subtract(prefixStart);
    if (prefixSize.aboveOrEqual(pageSize)) {
        if (virtualMemoryVerboseDebugging) {
            Log.log().string("  prefix:      [").hex(prefixStart).string(" .. ").hex(prefixEnd).string(")").newline();
        }
        final boolean prefixUnmap = freeVirtualMemory(prefixStart, prefixSize);
        if (!prefixUnmap) {
            // that I won't be able to give back.
            return WordFactory.nullPointer();
        }
    }
    // - The suffix occupies [pagedEnd .. containerEnd).
    final Pointer pagedEnd = PointerUtils.roundUp(end, pageSize);
    final Pointer suffixStart = pagedEnd;
    final Pointer suffixEnd = containerEnd;
    final UnsignedWord suffixSize = suffixEnd.subtract(suffixStart);
    if (suffixSize.aboveOrEqual(pageSize)) {
        if (virtualMemoryVerboseDebugging) {
            Log.log().string("  suffix:      [").hex(suffixStart).string(" .. ").hex(suffixEnd).string(")").newline();
        }
        final boolean suffixUnmap = freeVirtualMemory(suffixStart, suffixSize);
        if (!suffixUnmap) {
            // that I won't be able to give back.
            return WordFactory.nullPointer();
        }
    }
    return start;
}
Also used : UnsignedWord(org.graalvm.word.UnsignedWord) Pointer(org.graalvm.word.Pointer) CCharPointer(org.graalvm.nativeimage.c.type.CCharPointer)

Example 47 with Pointer

use of org.graalvm.word.Pointer in project graal by oracle.

the class LinuxOSInterface method allocateVirtualMemory.

@Override
public Pointer allocateVirtualMemory(UnsignedWord size, boolean executable) {
    trackVirtualMemory(size);
    int protect = PROT_READ() | PROT_WRITE();
    int flags = MAP_ANON() | MAP_PRIVATE();
    if (executable) {
        protect |= PROT_EXEC();
        /*
             * First try to allocate executable memory in the 32 bit address space (which is not
             * done by default on linux!). This is to get 32-bit displacements for calls in runtime
             * compiled code to image compiled code.
             */
        final Pointer result = mmap(WordFactory.nullPointer(), size, protect, flags | MAP_32BIT(), -1, 0);
        if (!result.equal(MAP_FAILED())) {
            return result;
        }
    }
    final Pointer result = mmap(WordFactory.nullPointer(), size, protect, flags, -1, 0);
    if (result.equal(MAP_FAILED())) {
        // Turn the mmap failure into a null Pointer.
        return WordFactory.nullPointer();
    }
    return result;
}
Also used : Pointer(org.graalvm.word.Pointer)

Example 48 with Pointer

use of org.graalvm.word.Pointer in project graal by oracle.

the class JNIStructFunctionsInitializer method initialize.

public void initialize(T structure) {
    Pointer p = (Pointer) structure;
    int wordSize = FrameAccess.wordSize();
    for (int k = 0; k + wordSize <= structSize; k += wordSize) {
        p.writeWord(k, defaultValue);
    }
    for (int i = 0; i < offsets.length; i++) {
        p.writeWord(offsets[i], functions[i]);
    }
}
Also used : Pointer(org.graalvm.word.Pointer) CFunctionPointer(org.graalvm.nativeimage.c.function.CFunctionPointer)

Example 49 with Pointer

use of org.graalvm.word.Pointer 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 50 with Pointer

use of org.graalvm.word.Pointer 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)

Aggregations

Pointer (org.graalvm.word.Pointer)103 UnsignedWord (org.graalvm.word.UnsignedWord)45 Log (com.oracle.svm.core.log.Log)30 CodePointer (org.graalvm.nativeimage.c.function.CodePointer)17 Uninterruptible (com.oracle.svm.core.annotate.Uninterruptible)15 Snippet (org.graalvm.compiler.api.replacements.Snippet)14 Word (org.graalvm.compiler.word.Word)12 CCharPointer (org.graalvm.nativeimage.c.type.CCharPointer)9 HotSpotReplacementsUtil.registerAsWord (org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.registerAsWord)7 AlwaysInline (com.oracle.svm.core.annotate.AlwaysInline)5 NeverInline (com.oracle.svm.core.annotate.NeverInline)5 KnownIntrinsics.readCallerStackPointer (com.oracle.svm.core.snippets.KnownIntrinsics.readCallerStackPointer)5 KlassPointer (org.graalvm.compiler.hotspot.word.KlassPointer)4 DynamicHub (com.oracle.svm.core.hub.DynamicHub)3 CCharPointerPointer (org.graalvm.nativeimage.c.type.CCharPointerPointer)3 CIntPointer (org.graalvm.nativeimage.c.type.CIntPointer)3 SignedWord (org.graalvm.word.SignedWord)3 DeoptimizedFrame (com.oracle.svm.core.deopt.DeoptimizedFrame)2 AlignedHeader (com.oracle.svm.core.genscavenge.AlignedHeapChunk.AlignedHeader)2 Dirent.direntPointer (com.oracle.svm.core.posix.headers.Dirent.direntPointer)2