Search in sources :

Example 86 with Log

use of com.oracle.svm.core.log.Log 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 87 with Log

use of com.oracle.svm.core.log.Log in project graal by oracle.

the class FirstObjectTable method getImpreciseFirstObjectPointer.

/**
 * Return a Pointer into a memory region indicated by the entry at a given index.
 *
 * For an imprecise mark, this means I can skip past any object that crosses onto 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 the first object that could be imprecisely marked at this index. Returns
 *         the null Pointer if no object could be imprecisely marked at this index, e.g., if the
 *         object that crosses onto this card either also crosses off of this card, or runs up
 *         to the memory limit.
 */
protected static Pointer getImpreciseFirstObjectPointer(Pointer tableStart, Pointer memoryStart, Pointer memoryLimit, UnsignedWord index) {
    final Log trace = Log.noopLog().string("[FirstObjectTable.getImpreciseFirstObjectPointer:");
    trace.string("  tableStart: ").hex(tableStart).string("  memoryStart: ").hex(memoryStart).string("  memoryLimit: ").hex(memoryLimit).string("  index: ").unsigned(index).newline();
    final Pointer preciseFirstPointer = getPreciseFirstObjectPointer(tableStart, memoryStart, memoryLimit, index);
    /* If the object starts before the memory for this index, skip over it. */
    final Pointer indexedMemoryStart = indexToMemoryPointer(index, memoryStart);
    final Pointer result;
    if (preciseFirstPointer.belowThan(indexedMemoryStart)) {
        final Object crossingObject = preciseFirstPointer.toObject();
        result = LayoutEncoding.getObjectEnd(crossingObject);
    } else {
        assert preciseFirstPointer.equal(indexedMemoryStart) : "preciseFirstPointer.equal(indexedMemoryStart)";
        result = indexedMemoryStart;
    }
    trace.string("  returns: ").hex(result);
    assert memoryStart.belowOrEqual(result) : "memoryStart.belowOrEqual(result)";
    assert result.belowOrEqual(memoryLimit) : "result.belowOrEqual(memoryLimit)";
    trace.string("]").newline();
    return result;
}
Also used : Log(com.oracle.svm.core.log.Log) Pointer(org.graalvm.word.Pointer)

Example 88 with Log

use of com.oracle.svm.core.log.Log 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)

Example 89 with Log

use of com.oracle.svm.core.log.Log in project graal by oracle.

the class GarbageCollectorManagementFactory method promotePinnedObject.

private static void promotePinnedObject(PinnedObjectImpl pinned) {
    final Log trace = Log.noopLog().string("[GCImpl.promotePinnedObject").string("  pinned: ").object(pinned);
    final HeapImpl heap = HeapImpl.getHeapImpl();
    final OldGeneration oldGen = heap.getOldGeneration();
    final Space toSpace = oldGen.getToSpace();
    /* Find the chunk the object is in, and if necessary, move it to To space. */
    final Object referent = pinned.getObject();
    if (referent != null && ObjectHeaderImpl.getObjectHeaderImpl().isHeapAllocated(referent)) {
        trace.string("  referent: ").object(referent);
        /*
             * The referent doesn't move, so I can ignore the result of the promotion because I
             * don't have to update any pointers to it.
             */
        toSpace.promoteObjectChunk(referent);
    }
    trace.string("]").newline();
}
Also used : Log(com.oracle.svm.core.log.Log)

Example 90 with Log

use of com.oracle.svm.core.log.Log in project graal by oracle.

the class GarbageCollectorManagementFactory method verbosePostCondition.

private void verbosePostCondition() {
    final HeapImpl heap = HeapImpl.getHeapImpl();
    final YoungGeneration youngGen = heap.getYoungGeneration();
    final OldGeneration oldGen = heap.getOldGeneration();
    /*
         * Note to self: I can get output similar to this *all the time* by running with
         * -R:+VerboseGC -R:+PrintHeapShape -R:+TraceHeapChunks
         */
    final boolean forceForTesting = false;
    if (runtimeAssertions() || forceForTesting) {
        final Log witness = Log.log();
        if ((!youngGen.getSpace().isEmpty()) || forceForTesting) {
            witness.string("[GCImpl.postcondition: youngGen space should be empty after a collection.").newline();
            /* Print raw fields before trying to walk the chunk lists. */
            witness.string("  These should all be 0:").newline();
            witness.string("    youngGen space first AlignedChunk:   ").hex(youngGen.getSpace().getFirstAlignedHeapChunk()).newline();
            witness.string("    youngGen space last  AlignedChunk:   ").hex(youngGen.getSpace().getLastAlignedHeapChunk()).newline();
            witness.string("    youngGen space first UnalignedChunk: ").hex(youngGen.getSpace().getFirstUnalignedHeapChunk()).newline();
            witness.string("    youngGen space last  UnalignedChunk: ").hex(youngGen.getSpace().getLastUnalignedHeapChunk()).newline();
            youngGen.getSpace().report(witness, true).newline();
            witness.string("  verifying the heap:");
            heap.verifyAfterGC("because youngGen space is not empty", getCollectionEpoch());
            witness.string("]").newline();
        }
        if ((!oldGen.getToSpace().isEmpty()) || forceForTesting) {
            witness.string("[GCImpl.postcondition: oldGen toSpace should be empty after a collection.").newline();
            /* Print raw fields before trying to walk the chunk lists. */
            witness.string("  These should all be 0:").newline();
            witness.string("    oldGen toSpace first AlignedChunk:   ").hex(oldGen.getToSpace().getFirstAlignedHeapChunk()).newline();
            witness.string("    oldGen toSpace last  AlignedChunk:   ").hex(oldGen.getToSpace().getLastAlignedHeapChunk()).newline();
            witness.string("    oldGen.toSpace first UnalignedChunk: ").hex(oldGen.getToSpace().getFirstUnalignedHeapChunk()).newline();
            witness.string("    oldGen.toSpace last  UnalignedChunk: ").hex(oldGen.getToSpace().getLastUnalignedHeapChunk()).newline();
            oldGen.getToSpace().report(witness, true).newline();
            oldGen.getFromSpace().report(witness, true).newline();
            witness.string("  verifying the heap:");
            heap.verifyAfterGC("because oldGen toSpace is not empty", getCollectionEpoch());
            witness.string("]").newline();
        }
        if ((!oldGen.getPinnedToSpace().isEmpty()) || forceForTesting) {
            witness.string("[GCImpl.postcondition: oldGen pinnedToSpace should be empty after a collection.").newline();
            /* Print raw fields before trying to walk the chunk lists. */
            witness.string("  These should all be 0:").newline();
            witness.string("    oldGen pinnedToSpace first AlignedChunk:   ").hex(oldGen.getPinnedToSpace().getFirstAlignedHeapChunk()).newline();
            witness.string("    oldGen pinnedToSpace last  AlignedChunk:   ").hex(oldGen.getPinnedToSpace().getLastAlignedHeapChunk()).newline();
            witness.string("    oldGen pinnedToSpace first UnalignedChunk: ").hex(oldGen.getPinnedToSpace().getFirstUnalignedHeapChunk()).newline();
            witness.string("    oldGen pinnedToSpace last  UnalignedChunk: ").hex(oldGen.getPinnedToSpace().getLastUnalignedHeapChunk()).newline();
            oldGen.getPinnedToSpace().report(witness, true).newline();
            oldGen.getPinnedFromSpace().report(witness, true).newline();
            witness.string("  verifying the heap:");
            heap.verifyAfterGC("because oldGen pinnedToSpace is not empty", getCollectionEpoch());
            witness.string("]").newline();
        }
    }
}
Also used : Log(com.oracle.svm.core.log.Log)

Aggregations

Log (com.oracle.svm.core.log.Log)130 Pointer (org.graalvm.word.Pointer)30 UnsignedWord (org.graalvm.word.UnsignedWord)30 IsolateThread (org.graalvm.nativeimage.IsolateThread)4 CodePointer (org.graalvm.nativeimage.c.function.CodePointer)4 Uninterruptible (com.oracle.svm.core.annotate.Uninterruptible)3 CollectionWatcher (com.oracle.svm.core.heap.CollectionWatcher)3 DiscoverableReference (com.oracle.svm.core.heap.DiscoverableReference)3 XOptions (com.oracle.svm.core.option.XOptions)3 AlwaysInline (com.oracle.svm.core.annotate.AlwaysInline)2 CEntryPointOptions (com.oracle.svm.core.c.function.CEntryPointOptions)2 KnownIntrinsics.readCallerStackPointer (com.oracle.svm.core.snippets.KnownIntrinsics.readCallerStackPointer)2 CEntryPoint (org.graalvm.nativeimage.c.function.CEntryPoint)2 RestrictHeapAccess (com.oracle.svm.core.annotate.RestrictHeapAccess)1 CodeInfoQueryResult (com.oracle.svm.core.code.CodeInfoQueryResult)1 SubstrateInstalledCode (com.oracle.svm.core.deopt.SubstrateInstalledCode)1 AlignedHeader (com.oracle.svm.core.genscavenge.AlignedHeapChunk.AlignedHeader)1 UnalignedHeader (com.oracle.svm.core.genscavenge.UnalignedHeapChunk.UnalignedHeader)1 AllocationFreeList (com.oracle.svm.core.heap.AllocationFreeList)1 NoAllocationVerifier (com.oracle.svm.core.heap.NoAllocationVerifier)1