Skip to content

Commit

Permalink
Update !vthread command to use GC continuation list
Browse files Browse the repository at this point in the history
Fixes #17084

Signed-off-by: Gengchen Tuo <[email protected]>
  • Loading branch information
thallium committed Apr 11, 2023
1 parent ff024fc commit 5d0db8b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 36 deletions.
6 changes: 4 additions & 2 deletions debugtools/DDR_VM/src/com/ibm/j9ddr/AuxFieldInfo29.dat
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,6 @@ J9JavaVM.jitConfig = required
J9JavaVM.jniGlobalReferences = required
J9JavaVM.jniWeakGlobalReferences = required
J9JavaVM.jvmtiData = required
J9JavaVM.liveVirtualThreadList = J9Object**
J9JavaVM.longArrayClass = required
J9JavaVM.longReflectClass = required
J9JavaVM.mainThread = required
Expand All @@ -286,7 +285,6 @@ J9JavaVM.sharedInvariantInternTable = required
J9JavaVM.shortReflectClass = required
J9JavaVM.systemClassLoader = required
J9JavaVM.systemProperties = required
J9JavaVM.virtualThreadLinkNextOffset = UDATA
J9JavaVM.vmArgsArray = required
J9JavaVM.voidReflectClass = required
J9LineNumber.lineNumber = required
Expand Down Expand Up @@ -625,12 +623,15 @@ MM_AllocationContextTarok._allocationContextType = required
MM_CardTable._cardTableStart = required
MM_CardTable._cardTableVirtualStart = required
MM_CardTable._heapBase = required
MM_ContinuationObjectList._head = J9Object*
MM_ContinuationObjectList._nextList = MM_ContinuationObjectList*
MM_CopyScanCache.cacheAlloc = required
MM_CopyScanCache.cacheTop = required
MM_EnvironmentStandard._survivorCopyScanCache = required
MM_EnvironmentStandard._tenureCopyScanCache = required
MM_GCExtensions.accessBarrier = required
MM_GCExtensions.collectStringConstants = required
MM_GCExtensions.continuationObjectLists = MM_ContinuationObjectList*
MM_GCExtensions.dynamicClassUnloading = required
MM_GCExtensions.finalizeListManager = required
MM_GCExtensions.ownableSynchronizerObjectLists = required
Expand Down Expand Up @@ -713,6 +714,7 @@ MM_MemorySpace._name = required
MM_MemorySubSpace._memorySpace = required
MM_MemorySubSpace._memoryType = required
MM_MemorySubSpaceGeneric._memoryPool = required
MM_ObjectAccessBarrier._continuationLinkOffset = UDATA
MM_ObjectAccessBarrier._ownableSynchronizerLinkOffset = required
MM_ObjectAccessBarrier._referenceLinkOffset = required
MM_OwnableSynchronizerObjectList._head = required
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@
import com.ibm.j9ddr.tools.ddrinteractive.DDRInteractiveCommandException;
import com.ibm.j9ddr.vm29.j9.DataType;
import com.ibm.j9ddr.vm29.j9.J9ObjectFieldOffset;
import com.ibm.j9ddr.vm29.j9.gc.GCBase;
import com.ibm.j9ddr.vm29.pointer.ObjectReferencePointer;
import com.ibm.j9ddr.vm29.pointer.PointerPointer;
import com.ibm.j9ddr.vm29.pointer.generated.J9JavaVMPointer;
import com.ibm.j9ddr.vm29.pointer.generated.J9ObjectPointer;
import com.ibm.j9ddr.vm29.pointer.generated.MM_ContinuationObjectListPointer;
import com.ibm.j9ddr.vm29.pointer.generated.MM_GCExtensionsPointer;
import com.ibm.j9ddr.vm29.pointer.helper.J9ObjectHelper;
import com.ibm.j9ddr.vm29.pointer.helper.J9RASHelper;
import com.ibm.j9ddr.vm29.types.UDATA;
Expand All @@ -49,6 +51,31 @@
* ...
*/
public class VirtualThreadsCommand extends Command {
private static J9ObjectFieldOffset vthreadOffset;
private static J9ObjectFieldOffset vmRefOffset;
private static J9ObjectFieldOffset nameOffset;

private static J9ObjectPointer getVirtualThread(J9ObjectPointer continuation) throws CorruptDataException {
if (vthreadOffset == null) {
vthreadOffset = J9ObjectHelper.getFieldOffset(continuation, "vthread", "Ljava/lang/Thread;");
}
return J9ObjectHelper.getObjectField(continuation, vthreadOffset);
}

private static long getVmRef(J9ObjectPointer continuation) throws CorruptDataException {
if (vmRefOffset == null) {
vmRefOffset = J9ObjectHelper.getFieldOffset(continuation, "vmRef", "J");
}
return J9ObjectHelper.getLongField(continuation, vmRefOffset);
}

private static J9ObjectPointer getName(J9ObjectPointer vthread) throws CorruptDataException {
if (nameOffset == null) {
nameOffset = J9ObjectHelper.getFieldOffset(vthread, "name", "Ljava/lang/String;");
}
return J9ObjectHelper.getObjectField(vthread, nameOffset);
}

public VirtualThreadsCommand() {
addCommand("vthreads", "", "Lists virtual threads");
}
Expand All @@ -72,43 +99,31 @@ public void run(String command, String[] args, Context context, PrintStream out)
* @param out the PrintStream to write output to
*/
private static void displayVirtualThreads(J9JavaVMPointer vm, PrintStream out) throws CorruptDataException, NoSuchFieldException {
PointerPointer mainVirtualThread = vm.liveVirtualThreadList();
if (mainVirtualThread.isNull()) {
return;
}

J9ObjectPointer root = J9ObjectPointer.cast(mainVirtualThread.at(0));
if (root.isNull()) {
return;
}

UDATA linkNextOffset = vm.virtualThreadLinkNextOffset();
/*
* liveVirtualThreadList is a circular doubly-linked list storing all the live virtual threads.
* The root node is a dummy virtual thread marking the start and the end of the list.
*/
J9ObjectPointer node = ObjectReferencePointer.cast(root.addOffset(linkNextOffset)).at(0);
J9ObjectFieldOffset nameOffset = J9ObjectHelper.getFieldOffset(node, "name", "Ljava/lang/String;");
J9ObjectFieldOffset contOffset = J9ObjectHelper.getFieldOffset(node, "cont", "Ljdk/internal/vm/Continuation;");
J9ObjectPointer cont = J9ObjectHelper.getObjectField(node, contOffset);
J9ObjectFieldOffset vmRefOffset = J9ObjectHelper.getFieldOffset(cont, "vmRef", "J");

String addressFormat = "0x%0" + (UDATA.SIZEOF * 2) + "x";
String outputFormat = "!continuationstack " + addressFormat
+ " !j9vmcontinuation " + addressFormat
+ " !j9object %s (Continuation) !j9object %s (VThread) - %s%n";
while (!node.eq(root)) {
J9ObjectPointer name = J9ObjectHelper.getObjectField(node, nameOffset);
cont = J9ObjectHelper.getObjectField(node, contOffset);
long vmRef = J9ObjectHelper.getLongField(cont, vmRefOffset);
out.format(
outputFormat,
vmRef,
vmRef,
cont.getHexAddress(),
node.getHexAddress(),
J9ObjectHelper.stringValue(name));
node = ObjectReferencePointer.cast(node.addOffset(linkNextOffset)).at(0);
MM_GCExtensionsPointer extensions = GCBase.getExtensions();
UDATA linkOffset = extensions.accessBarrier()._continuationLinkOffset();
MM_ContinuationObjectListPointer continuationObjectList = extensions.continuationObjectLists();

while (continuationObjectList.notNull()) {
J9ObjectPointer continuation = continuationObjectList._head();
while (continuation.notNull()) {
long vmRef = getVmRef(continuation);
J9ObjectPointer vthread = getVirtualThread(continuation);
J9ObjectPointer name = getName(vthread);

out.format(
outputFormat,
vmRef,
vmRef,
continuation.getHexAddress(),
vthread.getHexAddress(),
J9ObjectHelper.stringValue(name));
continuation = ObjectReferencePointer.cast(continuation.addOffset(linkOffset)).at(0);
}
continuationObjectList = continuationObjectList._nextList();
}
}
}
1 change: 1 addition & 0 deletions runtime/rasdump/trigger.c
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ prepareForDump(struct J9JavaVM *vm, struct J9RASdumpAgent *agent, struct J9RASdu
/* If exclusive access has been obtained, do the requested preparation */
if (newState & J9RAS_DUMP_GOT_EXCLUSIVE_VM_ACCESS) {
vm->memoryManagerFunctions->j9gc_flush_caches_for_walk(vm);
vm->memoryManagerFunctions->j9gc_flush_nonAllocationCaches_for_walk(vm);
newState |= J9RAS_DUMP_HEAP_PREPARED;
}
}
Expand Down

0 comments on commit 5d0db8b

Please sign in to comment.