Search in sources :

Example 91 with UnsignedWord

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

the class DiscoverableReferenceProcessing method processReferent.

/**
 * Determine if a referent is live, and adjust it as necessary.
 */
private static boolean processReferent(DiscoverableReference dr) {
    final Log trace = Log.noopLog().string("[DiscoverableReference.processReferent:").string("  this: ").object(dr);
    final Pointer refPointer = dr.getReferentPointer();
    trace.string("  referent: ").hex(refPointer);
    if (refPointer.isNull()) {
        /* If the referent is null don't look at it further. */
        trace.string("  null referent").string("]").newline();
        return false;
    }
    /* Read the header. */
    final UnsignedWord header = ObjectHeader.readHeaderFromPointer(refPointer);
    /* It might be a forwarding pointer. */
    if (ObjectHeaderImpl.getObjectHeaderImpl().isForwardedHeader(header)) {
        /* If the referent got forwarded, then update the referent. */
        final Pointer forwardedPointer = ObjectHeaderImpl.getObjectHeaderImpl().getForwardingPointer(header);
        dr.setReferentPointer(forwardedPointer);
        trace.string("  forwarded header: updated referent: ").hex(forwardedPointer).string("]").newline();
        return true;
    }
    /*
         * It's a real object. See if the referent has survived.
         */
    final Object refObject = refPointer.toObject();
    if (HeapImpl.getHeapImpl().hasSurvivedThisCollection(refObject)) {
        /* The referent has survived, it does not need to be updated. */
        trace.string("  referent will survive: not updated").string("]").newline();
        return true;
    }
    /*
         * Otherwise, referent has not survived.
         *
         * Note that we must use the Object-level store here, not the Pointer-level store: the
         * static analysis must see that the field can be null. This means that we get a write
         * barrier for this store.
         */
    dr.clear();
    trace.string("  has not survived: nulled referent").string("]").newline();
    return false;
}
Also used : Log(com.oracle.svm.core.log.Log) UnsignedWord(org.graalvm.word.UnsignedWord) Pointer(org.graalvm.word.Pointer)

Example 92 with UnsignedWord

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

the class FirstObjectTable method entryToMemoryOffset.

/**
 * Turn a table entry into a memory offset. This only handles memory offset entries.
 */
private static UnsignedWord entryToMemoryOffset(int entry) {
    /* Negate the entry to a magnitude and scale it to an offset. */
    assert isMemoryOffsetEntry(entry) : "Entry out of bounds.";
    final UnsignedWord entryUnsigned = WordFactory.unsigned(-entry);
    final UnsignedWord result = entryUnsigned.multiply(memoryOffsetScale());
    assert (result.belowThan(MEMORY_BYTES_PER_ENTRY)) : "Entry out of bounds.";
    return result;
}
Also used : UnsignedWord(org.graalvm.word.UnsignedWord)

Example 93 with UnsignedWord

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

the class FirstObjectTable method getPreciseFirstObjectPointer.

/**
 * Return a Pointer to an object that could be precisely marked by this card.
 *
 * For a precise mark, this means I have to back up to the start of the object that crosses onto
 * (or starts) this entry.
 *
 * @param tableStart The start of the first object table.
 * @param memoryStart The start of the memory region corresponding to the first object table.
 * @param memoryLimit The end of the memory region corresponding to the first object table.
 * @param index The index into the first object table.
 * @return A Pointer to first object that could be precisely marked at this index.
 */
protected static Pointer getPreciseFirstObjectPointer(Pointer tableStart, Pointer memoryStart, Pointer memoryLimit, UnsignedWord index) {
    final Log trace = Log.noopLog().string("[FirstObjectTable.getPreciseFirstObjectPointer:").string("  index: ").unsigned(index);
    UnsignedWord currentIndex = index;
    int currentEntry = getEntryAtIndex(tableStart, currentIndex);
    if (trace.isEnabled()) {
        trace.string("  entry: ");
        entryToLog(trace, currentEntry);
    }
    assert (currentEntry != UNINITIALIZED_ENTRY) : "uninitialized first object table entry";
    if (MEMORY_OFFSET_MAX < currentEntry) {
        /* The current entry is an entry offset. */
        while (LINEAR_OFFSET_MAX < currentEntry) {
            /* The current entry is a exponential offset. */
            /* - Subtract off the bias to get the exponent. */
            final int exponent = unbiasExponent(currentEntry);
            /* - Compute 2^exponent. */
            final UnsignedWord deltaIndex = exponentToOffset(exponent);
            /* - Adjust the current index. */
            currentIndex = indexMinusDelta(currentIndex, deltaIndex);
            /* - Get the entry at the new index. */
            currentEntry = getEntryAtIndex(tableStart, currentIndex);
        }
        if (MEMORY_OFFSET_MAX < currentEntry) {
            /* The current entry is a linear offset. */
            currentIndex = currentIndex.subtract(currentEntry);
            currentEntry = getEntryAtIndex(tableStart, currentIndex);
        }
    }
    /* The current entry is a memory offset. */
    final Pointer result = getPointerAtOffset(memoryStart, currentIndex, currentEntry);
    trace.string("  returns: ").hex(result);
    assert memoryStart.belowOrEqual(result) : "memoryStart.belowOrEqual(result)";
    assert result.belowThan(memoryLimit) : "result.belowThan(memoryLimit)";
    trace.string("]").newline();
    return result;
}
Also used : Log(com.oracle.svm.core.log.Log) UnsignedWord(org.graalvm.word.UnsignedWord) Pointer(org.graalvm.word.Pointer)

Example 94 with UnsignedWord

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

the class FirstObjectTable method setTableForObjectUnchecked.

private static void setTableForObjectUnchecked(Pointer table, Pointer memory, Pointer start, Pointer end) {
    /* Find the table entry for the start of the object. */
    assert memory.belowOrEqual(start) : "memory.belowOrEqual(start)";
    assert start.belowThan(end) : "start.belowThan(end)";
    final UnsignedWord startOffset = start.subtract(memory);
    /* The argument "end" is just past the real end of the object, so back it up one byte. */
    final UnsignedWord endOffset = end.subtract(1).subtract(memory);
    final UnsignedWord startIndex = memoryOffsetToIndex(startOffset);
    final UnsignedWord endIndex = memoryOffsetToIndex(endOffset);
    final UnsignedWord startMemoryOffset = indexToMemoryOffset(startIndex);
    if (startIndex.equal(endIndex) && startOffset.unsignedRemainder(MEMORY_BYTES_PER_ENTRY).notEqual(0)) {
        /* The object does not cross, or start on, a card boundary: nothing to do. */
        return;
    }
    /* Fill in one or more table entries. */
    final UnsignedWord memoryOffsetIndex;
    if (startOffset.equal(startMemoryOffset)) {
        /* The startOffset is at the beginning of the memory for startIndex. */
        /* The memory offset entry is a 0 at startIndex. */
        memoryOffsetIndex = startIndex;
        setEntryAtIndex(table, memoryOffsetIndex, 0);
    } else {
        /*
             * The startOffset is in the middle of the memory for startIndex. That is, before the
             * memory for startIndex+1.
             */
        memoryOffsetIndex = startIndex.add(1);
        final UnsignedWord memoryIndexOffset = indexToMemoryOffset(memoryOffsetIndex);
        final int entry = memoryOffsetToEntry(memoryIndexOffset.subtract(startOffset));
        setEntryAtIndex(table, memoryOffsetIndex, entry);
    }
    /*
         * Fill from memoryOffsetIndex towards endIndex with offset entries referring back to
         * memoryOffsetIndex.
         */
    /* - First, as many linear offsets as are needed, or as I can have. */
    final UnsignedWord linearIndexMax = UnsignedUtils.min(endIndex, memoryOffsetIndex.add(LINEAR_OFFSET_MAX));
    /* - - Step entryIndex and entry linearly. */
    UnsignedWord entryIndex = memoryOffsetIndex.add(1);
    int entry = LINEAR_OFFSET_MIN;
    while (entryIndex.belowOrEqual(linearIndexMax)) {
        setEntryAtIndex(table, entryIndex, entry);
        entryIndex = entryIndex.add(1);
        entry += 1;
    }
    /* - Next, as many exponential offsets as are needed. */
    /*
         * -- Step entryIndex by 1 (then bias it) while stepping the unbiased entry exponentially.
         */
    int unbiasedExponent = EXPONENT_MIN;
    while (entryIndex.belowOrEqual(endIndex)) {
        /* There are 2^N entries with the exponent N. */
        for (int count = 0; count < (1 << unbiasedExponent); count += 1) {
            final int biasedEntry = biasExponent(unbiasedExponent);
            setEntryAtIndex(table, entryIndex, biasedEntry);
            entryIndex = entryIndex.add(1);
            /* I might be done. */
            if (!entryIndex.belowOrEqual(endIndex)) {
                break;
            }
        }
        unbiasedExponent += 1;
    }
}
Also used : UnsignedWord(org.graalvm.word.UnsignedWord)

Example 95 with UnsignedWord

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

the class FirstObjectTable method verify.

/**
 * Verify a FirstObjectTable.
 */
protected static boolean verify(Pointer tableStart, Pointer memoryStart, Pointer memoryLimit) {
    /*
         * Walk the table checking that I can find the start of the object that crosses onto this
         * entry.
         */
    final Log trace = HeapImpl.getHeapImpl().getHeapVerifierImpl().getTraceLog().string("[FirstObjectTable.verify:");
    trace.string("  tableStart: ").hex(tableStart).string("  memoryStart: ").hex(memoryStart).string("  memoryLimit: ").hex(memoryLimit);
    final UnsignedWord indexLimit = getTableSizeForMemoryPointers(memoryStart, memoryLimit);
    for (UnsignedWord index = WordFactory.unsigned(0); index.belowThan(indexLimit); index = index.add(1)) {
        trace.newline().string("  FirstObjectTable.verify: index: ").unsigned(index).newline();
        final Pointer objStart = getPreciseFirstObjectPointer(tableStart, memoryStart, memoryLimit, index);
        trace.string("  objStart: ").hex(objStart).newline();
        if (objStart.belowThan(memoryStart)) {
            /* Map points below memory. */
            trace.string("  FirstObjectTable.verify: objStart.belowThan(memoryStart) => false]").newline();
            return false;
        }
        if (memoryLimit.belowOrEqual(objStart)) {
            /* Map points above memory. */
            trace.string("  FirstObjectTable.verify: memoryLimit.belowOrEqual(objStart) => false]").newline();
            return false;
        }
        if (!HeapImpl.getHeapImpl().getHeapVerifierImpl().verifyObjectAt(objStart)) {
            /* Bad object. */
            final Log witness = HeapImpl.getHeapImpl().getHeapVerifierImpl().getWitnessLog().string("[FirstObjectTable.verify:");
            witness.string("  tableStart: ").hex(tableStart).string("  memoryStart: ").hex(memoryStart).string("  memoryLimit: ").hex(memoryLimit);
            witness.string("  objStart: ").hex(objStart).string("  fails to verify").string("]").newline();
            return false;
        }
        /* Check that the object crosses onto this entry. */
        /*
             * - Things are okay if ((objStart <= entryStart) && (entryStart < objEnd)) so I need to
             * return false if either of those conditions is false
             */
        final Pointer entryStart = memoryStart.add(indexToMemoryOffset(index));
        trace.string("  entryStart: ").hex(entryStart);
        if (!(objStart.belowOrEqual(entryStart))) {
            /* Object doesn't start before this entry. */
            final Log witness = HeapImpl.getHeapImpl().getHeapVerifierImpl().getWitnessLog().string("[FirstObjectTable.verify:");
            witness.string("  tableStart: ").hex(tableStart).string("  memoryStart: ").hex(memoryStart).string("  memoryLimit: ").hex(memoryLimit);
            witness.string("  objStart: ").hex(objStart).string("  entryStart: ").hex(entryStart).string("  !(objStart.belowOrEqual(entryStart))").string("]").newline();
            return false;
        }
        final Object obj = objStart.toObject();
        final Pointer objEnd = LayoutEncoding.getObjectEnd(obj);
        trace.string("  ");
        trace.string(obj.getClass().getName());
        trace.string("  objEnd: ").hex(objEnd);
        if (!(entryStart.belowThan(objEnd))) {
            /* Object doesn't continue onto this entry. */
            final Log witness = HeapImpl.getHeapImpl().getHeapVerifierImpl().getWitnessLog().string("[FirstObjectTable.verify:");
            witness.string("  tableStart: ").hex(tableStart).string("  memoryStart: ").hex(memoryStart).string("  memoryLimit: ").hex(memoryLimit);
            witness.string("  objEnd: ").hex(objEnd).string("  entryStart: ").hex(entryStart).string("  !(entryStart.belowThan(objEnd))").string("]").newline();
            return false;
        }
    }
    trace.string("  => true]").newline();
    return true;
}
Also used : Log(com.oracle.svm.core.log.Log) UnsignedWord(org.graalvm.word.UnsignedWord) Pointer(org.graalvm.word.Pointer)

Aggregations

UnsignedWord (org.graalvm.word.UnsignedWord)137 Pointer (org.graalvm.word.Pointer)43 Log (com.oracle.svm.core.log.Log)30 DynamicHub (com.oracle.svm.core.hub.DynamicHub)11 Fold (org.graalvm.compiler.api.replacements.Fold)11 Uninterruptible (com.oracle.svm.core.annotate.Uninterruptible)9 Snippet (org.graalvm.compiler.api.replacements.Snippet)9 CCharPointer (org.graalvm.nativeimage.c.type.CCharPointer)6 AlignedHeader (com.oracle.svm.core.genscavenge.AlignedHeapChunk.AlignedHeader)4 WordBase (org.graalvm.word.WordBase)4 AlwaysInline (com.oracle.svm.core.annotate.AlwaysInline)3 ValueInfo (com.oracle.svm.core.code.FrameInfoQueryResult.ValueInfo)3 UnalignedHeader (com.oracle.svm.core.genscavenge.UnalignedHeapChunk.UnalignedHeader)3 XOptions (com.oracle.svm.core.option.XOptions)3 CEntryPoint (org.graalvm.nativeimage.c.function.CEntryPoint)3 ObjectLayout (com.oracle.svm.core.config.ObjectLayout)2 DeoptEntryInfopoint (com.oracle.svm.core.deopt.DeoptEntryInfopoint)2 SubstrateForeignCallTarget (com.oracle.svm.core.snippets.SubstrateForeignCallTarget)2 Infopoint (jdk.vm.ci.code.site.Infopoint)2 JavaKind (jdk.vm.ci.meta.JavaKind)2