Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -44,6 +44,4 @@

public interface PinnedObjectSupport {
PinnedObject create(Object object);

boolean isPinned(Object object);
}
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,11 @@ boolean isInSpace(Pointer ptr) {
return space.contains(ptr);
}

@Override
boolean printLocationInfo(Log log, Pointer ptr) {
return space.printLocationInfo(log, ptr);
}

@Override
public boolean walkObjects(ObjectVisitor visitor) {
return space.walkObjects(visitor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ boolean isInSpace(Pointer ptr) {
return fromSpace.contains(ptr) || toSpace.contains(ptr);
}

@Override
boolean printLocationInfo(Log log, Pointer ptr) {
return fromSpace.printLocationInfo(log, ptr) || toSpace.printLocationInfo(log, ptr);
}

@Override
boolean verifyRememberedSets() {
boolean success = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@

import java.lang.ref.Reference;

import jdk.graal.compiler.word.Word;
import org.graalvm.nativeimage.CurrentIsolate;
import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.Platform;
Expand Down Expand Up @@ -67,9 +66,12 @@
import com.oracle.svm.core.genscavenge.UnalignedHeapChunk.UnalignedHeader;
import com.oracle.svm.core.genscavenge.remset.RememberedSet;
import com.oracle.svm.core.graal.RuntimeCompilation;
import com.oracle.svm.core.heap.AbstractPinnedObjectSupport;
import com.oracle.svm.core.heap.AbstractPinnedObjectSupport.PinnedObjectImpl;
import com.oracle.svm.core.heap.CodeReferenceMapDecoder;
import com.oracle.svm.core.heap.GC;
import com.oracle.svm.core.heap.GCCause;
import com.oracle.svm.core.heap.Heap;
import com.oracle.svm.core.heap.NoAllocationVerifier;
import com.oracle.svm.core.heap.ObjectReferenceVisitor;
import com.oracle.svm.core.heap.ObjectVisitor;
Expand Down Expand Up @@ -105,6 +107,7 @@
import com.oracle.svm.core.util.VMError;

import jdk.graal.compiler.api.replacements.Fold;
import jdk.graal.compiler.word.Word;

/**
* Garbage collector (incremental or complete) for {@link HeapImpl}.
Expand Down Expand Up @@ -429,7 +432,7 @@ private void printGCAfter(GCCause cause) {
}

if (SerialGCOptions.TraceHeapChunks.getValue()) {
HeapImpl.getHeapImpl().logChunks(Log.log());
HeapImpl.getHeapImpl().logChunks(Log.log(), false);
}
}

Expand Down Expand Up @@ -754,51 +757,22 @@ private void promoteChunksWithPinnedObjects() {
Timer promotePinnedObjectsTimer = timers.promotePinnedObjects.open();
try {
// Remove closed pinned objects from the global list. This code needs to use write
// barriers as the PinnedObjectImpls are a linked list and we don't know in which
// barriers as the PinnedObjectImpls are a linked list, and we don't know in which
// generation each individual PinnedObjectImpl lives. So, the card table will be
// modified.
PinnedObjectImpl pinnedObjects = removeClosedPinnedObjects(PinnedObjectImpl.getPinnedObjects());
PinnedObjectImpl.setPinnedObjects(pinnedObjects);
PinnedObjectImpl cur = AbstractPinnedObjectSupport.singleton().removeClosedObjectsAndGetFirstOpenObject();

// Promote all chunks that contain pinned objects. The card table of the promoted chunks
// will be cleaned.
PinnedObjectImpl cur = pinnedObjects;
while (cur != null) {
assert cur.isOpen();
promotePinnedObject(cur);
promotePinnedObject(cur.getObject());
cur = cur.getNext();
}
} finally {
promotePinnedObjectsTimer.close();
}
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
private static PinnedObjectImpl removeClosedPinnedObjects(PinnedObjectImpl list) {
PinnedObjectImpl firstOpen = null;
PinnedObjectImpl lastOpen = null;

PinnedObjectImpl cur = list;
while (cur != null) {
if (cur.isOpen()) {
if (firstOpen == null) {
assert lastOpen == null;
firstOpen = cur;
lastOpen = cur;
} else {
lastOpen.setNext(cur);
lastOpen = cur;
}
}
cur = cur.getNext();
}

if (lastOpen != null) {
lastOpen.setNext(null);
}
return firstOpen;
}

@NeverInline("Starting a stack walk in the caller frame. " +
"Note that we could start the stack frame also further down the stack, because GC stack frames must not access any objects that are processed by the GC. " +
"But we don't store stack frame information for the first frame we would need to process.")
Expand Down Expand Up @@ -1082,25 +1056,26 @@ private static Header<?> getChunk(Object obj, boolean isAligned) {
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
private void promotePinnedObject(PinnedObjectImpl pinned) {
private void promotePinnedObject(Object pinned) {
assert pinned != null;
assert !Heap.getHeap().isInImageHeap(pinned);
assert HeapChunk.getEnclosingHeapChunk(pinned).getPinnedObjectCount() > 0;

HeapImpl heap = HeapImpl.getHeapImpl();
Object referent = pinned.getObject();
if (referent != null && !heap.isInImageHeap(referent)) {
boolean isAligned = ObjectHeaderImpl.isAlignedObject(referent);
Header<?> originalChunk = getChunk(referent, isAligned);
Space originalSpace = HeapChunk.getSpace(originalChunk);
if (originalSpace.isFromSpace() || (originalSpace.isCompactingOldSpace() && completeCollection)) {
boolean promoted = false;
if (!completeCollection && originalSpace.getNextAgeForPromotion() < policy.getTenuringAge()) {
promoted = heap.getYoungGeneration().promotePinnedObject(referent, originalChunk, isAligned, originalSpace);
if (!promoted) {
accounting.onSurvivorOverflowed();
}
}
boolean isAligned = ObjectHeaderImpl.isAlignedObject(pinned);
Header<?> originalChunk = getChunk(pinned, isAligned);
Space originalSpace = HeapChunk.getSpace(originalChunk);
if (originalSpace.isFromSpace() || (originalSpace.isCompactingOldSpace() && completeCollection)) {
boolean promoted = false;
if (!completeCollection && originalSpace.getNextAgeForPromotion() < policy.getTenuringAge()) {
promoted = heap.getYoungGeneration().promotePinnedObject(pinned, originalChunk, isAligned, originalSpace);
if (!promoted) {
heap.getOldGeneration().promotePinnedObject(referent, originalChunk, isAligned, originalSpace);
accounting.onSurvivorOverflowed();
}
}
if (!promoted) {
heap.getOldGeneration().promotePinnedObject(pinned, originalChunk, isAligned, originalSpace);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ public String getName() {
/** Print some heap statistics to a log. */
public abstract void logUsage(Log log);

/** Print some information about the chunks to the log. */
public abstract void logChunks(Log log);

/**
* Promote an Object to this Generation, typically by copying and leaving a forwarding pointer
* to the new Object in place of the original Object. If the object cannot be promoted due to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.function.IntUnaryOperator;

import org.graalvm.nativeimage.c.struct.RawField;
import org.graalvm.nativeimage.c.struct.RawFieldAddress;
import org.graalvm.nativeimage.c.struct.RawStructure;
import org.graalvm.nativeimage.c.struct.UniqueLocationIdentity;
import org.graalvm.word.ComparableWord;
Expand Down Expand Up @@ -166,6 +167,12 @@ public interface Header<T extends Header<T>> extends HeaderPadding {

@RawField
void setIdentityHashSalt(UnsignedWord value, LocationIdentity identity);

@RawField
int getPinnedObjectCount();

@RawFieldAddress
Pointer addressOfPinnedObjectCount();
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,20 @@ public static void logChunks(Log log, UnalignedHeapChunk.UnalignedHeader firstCh
}

private static void logChunk(Log log, HeapChunk.Header<?> chunk, Pointer bottom, Pointer top, Pointer end, boolean isAligned, String shortSpaceName, boolean isToSpace) {
UnsignedWord used = top.subtract(bottom);
UnsignedWord capacity = end.subtract(bottom);
UnsignedWord usedPercent = used.multiply(100).unsignedDivide(capacity);

log.string("|").zhex(chunk).string("|").zhex(bottom).string(", ").zhex(top).string(", ").zhex(end);
log.string("|").unsigned(usedPercent, 3, RIGHT_ALIGN).string("%");
log.string("|");
if (top.isNonNull()) {
UnsignedWord used = top.subtract(bottom);
UnsignedWord capacity = end.subtract(bottom);
UnsignedWord usedPercent = used.multiply(100).unsignedDivide(capacity);
log.unsigned(usedPercent, 3, RIGHT_ALIGN).string("%");
} else {
log.spaces(3).string("?");
}
log.string("|").string(shortSpaceName, 3, RIGHT_ALIGN);
log.string("|").string(isAligned ? "A" : "U");
log.string("|").string(isToSpace ? "T" : "");
log.string("|").string(isToSpace ? "T" : " ");
log.string("|").signed(chunk.getPinnedObjectCount());
log.newline();
}
}
Loading
Loading