-
Notifications
You must be signed in to change notification settings - Fork 737
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new DumpAllSparseHeapEntriesCommand in DDR
- new DumpAllSparseHeapEntriesCommand provides a way to list all off-heap entries in the core file, which contain sparse heap data (only when off-heap has been enabled in jvm and gcpolicy has been set to Balanced GC mode). - for the rest of cases(off-heap has been disabled or "old core file", which did not contain off heap option at all), print out error message "This command only works with the core file, which contains sparse heap." - off heap entry information includes the address of the Array Object, the data address and the size of array data Signed-off-by: lhu <[email protected]>
- Loading branch information
Showing
4 changed files
with
182 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
81 changes: 81 additions & 0 deletions
81
debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/ObjectToSparseDataHashTable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright IBM Corp. and others 2025 | ||
* | ||
* This program and the accompanying materials are made available under | ||
* the terms of the Eclipse Public License 2.0 which accompanies this | ||
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/ | ||
* or the Apache License, Version 2.0 which accompanies this distribution and | ||
* is available at https://www.apache.org/licenses/LICENSE-2.0. | ||
* | ||
* This Source Code may also be made available under the following | ||
* Secondary Licenses when the conditions for such availability set | ||
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU | ||
* General Public License, version 2 with the GNU Classpath | ||
* Exception [1] and GNU General Public License, version 2 with the | ||
* OpenJDK Assembly Exception [2]. | ||
* | ||
* [1] https://www.gnu.org/software/classpath/license.html | ||
* [2] https://openjdk.org/legal/assembly-exception.html | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0 | ||
*/ | ||
package com.ibm.j9ddr.vm29.j9; | ||
|
||
import com.ibm.j9ddr.CorruptDataException; | ||
import com.ibm.j9ddr.vm29.pointer.generated.J9HashTablePointer; | ||
import com.ibm.j9ddr.vm29.pointer.generated.MM_SparseDataTableEntryPointer; | ||
import com.ibm.j9ddr.vm29.pointer.VoidPointer; | ||
import com.ibm.j9ddr.vm29.types.UDATA; | ||
|
||
/** | ||
* ObjectToSparseDataHashTable is used for accessing hash tables in SparseDataTableEntry | ||
* (e.g. readAccessHashTable) | ||
*/ | ||
|
||
public class ObjectToSparseDataHashTable extends HashTable_V1<MM_SparseDataTableEntryPointer> | ||
{ | ||
protected ObjectToSparseDataHashTable(J9HashTablePointer hashTablePointer, boolean isInline, Class<MM_SparseDataTableEntryPointer> structType, | ||
HashEqualFunction<MM_SparseDataTableEntryPointer> equalFn, | ||
HashFunction<MM_SparseDataTableEntryPointer> hashFn) throws CorruptDataException | ||
{ | ||
super(hashTablePointer, isInline, structType, equalFn, hashFn); | ||
} | ||
|
||
/** | ||
* Opens J9HashTable from J9HashTablePointer | ||
* | ||
* @param structure | ||
* the J9HashTablePointer | ||
* | ||
* @throws CorruptDataException | ||
* when fails to read from structure | ||
*/ | ||
public static HashTable<MM_SparseDataTableEntryPointer> fromJ9HashTable(J9HashTablePointer structure) throws CorruptDataException | ||
{ | ||
return new ObjectToSparseDataHashTable(structure, false, MM_SparseDataTableEntryPointer.class, new SparseDataHashEqualFn(), new SparseDataHashFn()); | ||
} | ||
|
||
private static class SparseDataHashFn implements HashFunction<MM_SparseDataTableEntryPointer> | ||
{ | ||
SparseDataHashFn() | ||
{ | ||
super(); | ||
} | ||
|
||
public UDATA hash(MM_SparseDataTableEntryPointer entry) throws CorruptDataException { | ||
return UDATA.cast(entry._dataPtr()); | ||
} | ||
} | ||
|
||
private static class SparseDataHashEqualFn implements HashEqualFunction<MM_SparseDataTableEntryPointer> | ||
{ | ||
SparseDataHashEqualFn() | ||
{ | ||
super(); | ||
} | ||
|
||
public boolean equal(MM_SparseDataTableEntryPointer entry1, MM_SparseDataTableEntryPointer entry2) throws CorruptDataException { | ||
return (entry1._dataPtr().getAddress() == entry2._dataPtr().getAddress()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
...src/com/ibm/j9ddr/vm29/tools/ddrinteractive/commands/DumpAllSparseHeapEntriesCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.ibm.j9ddr.vm29.tools.ddrinteractive.commands; | ||
|
||
import java.io.PrintStream; | ||
|
||
import com.ibm.j9ddr.CorruptDataException; | ||
import com.ibm.j9ddr.NoSuchFieldException; | ||
import com.ibm.j9ddr.tools.ddrinteractive.Context; | ||
import com.ibm.j9ddr.tools.ddrinteractive.DDRInteractiveCommandException; | ||
import com.ibm.j9ddr.tools.ddrinteractive.Command; | ||
import com.ibm.j9ddr.vm29.j9.HashTable; | ||
import com.ibm.j9ddr.vm29.j9.ObjectToSparseDataHashTable; | ||
import com.ibm.j9ddr.vm29.j9.SlotIterator; | ||
import com.ibm.j9ddr.vm29.j9.gc.GCBase; | ||
import com.ibm.j9ddr.vm29.pointer.generated.J9BuildFlags; | ||
import com.ibm.j9ddr.vm29.pointer.generated.J9HashTablePointer; | ||
import com.ibm.j9ddr.vm29.pointer.generated.MM_GCExtensionsPointer; | ||
import com.ibm.j9ddr.vm29.pointer.generated.MM_SparseAddressOrderedFixedSizeDataPoolPointer; | ||
import com.ibm.j9ddr.vm29.pointer.generated.MM_SparseDataTableEntryPointer; | ||
import com.ibm.j9ddr.vm29.pointer.generated.MM_SparseVirtualMemoryPointer; | ||
import com.ibm.j9ddr.vm29.pointer.VoidPointer; | ||
import com.ibm.j9ddr.vm29.types.UDATA; | ||
|
||
|
||
public class DumpAllSparseHeapEntriesCommand extends Command | ||
{ | ||
public DumpAllSparseHeapEntriesCommand() | ||
{ | ||
addCommand("dumpalloffheapentries", "cmd|help", "dump all off heap entries"); | ||
} | ||
|
||
public void run(String command, String[] args, Context context, PrintStream out) throws DDRInteractiveCommandException | ||
{ | ||
if (0 != args.length) { | ||
String argument = args[0]; | ||
|
||
if(argument.equalsIgnoreCase("help")) { | ||
help(out); | ||
return; | ||
} | ||
} | ||
|
||
try { | ||
MM_GCExtensionsPointer extensions = GCBase.getExtensions(); | ||
MM_SparseVirtualMemoryPointer sparseVirualMemory = extensions.largeObjectVirtualMemory(); | ||
if (sparseVirualMemory.notNull()) { | ||
MM_SparseAddressOrderedFixedSizeDataPoolPointer sparseAddressOrderedFixedSizeDataPool = sparseVirualMemory._sparseDataPool(); | ||
if (sparseAddressOrderedFixedSizeDataPool.notNull()) { | ||
J9HashTablePointer objectToSparseDataTable = sparseAddressOrderedFixedSizeDataPool._objectToSparseDataTable(); | ||
if (objectToSparseDataTable.notNull()) { | ||
try { | ||
HashTable<MM_SparseDataTableEntryPointer> readObjectToSparseDataTable = ObjectToSparseDataHashTable.fromJ9HashTable(objectToSparseDataTable); | ||
SlotIterator<MM_SparseDataTableEntryPointer> readSlotIterator = readObjectToSparseDataTable.iterator(); | ||
long count = readObjectToSparseDataTable.getCount(); | ||
out.printf("List off heap entries(%,d entries)\n", count); | ||
if (0 < count) { | ||
if (!J9BuildFlags.J9VM_ENV_DATA64) { | ||
throw new CorruptDataException("off heap would not be supported in 32 bit platform."); | ||
} | ||
out.printf("+------------------+------------------+------------------\n"); | ||
out.printf("| array object | data address | size \n"); | ||
out.printf("+------------------+------------------+------------------\n"); | ||
String outputFormat = " 0x%016x 0x%016x 0x%016x\n"; | ||
|
||
while (readSlotIterator.hasNext()) { | ||
MM_SparseDataTableEntryPointer readSparseDataTableEntryPtr2 = MM_SparseDataTableEntryPointer.cast(readSlotIterator.nextAddress()); | ||
VoidPointer dataPrt = readSparseDataTableEntryPtr2._dataPtr(); | ||
VoidPointer proxyObjPtr = readSparseDataTableEntryPtr2._proxyObjPtr(); | ||
UDATA size = readSparseDataTableEntryPtr2._size(); | ||
|
||
out.append(String.format( | ||
outputFormat, | ||
proxyObjPtr.getAddress(), | ||
dataPrt.getAddress(), | ||
size.longValue())); | ||
} | ||
out.printf("+------------------+------------------+------------------\n"); | ||
} | ||
} catch (CorruptDataException e) { | ||
throw new DDRInteractiveCommandException(e); | ||
} | ||
} | ||
} | ||
} | ||
} catch (CorruptDataException | NoSuchFieldException e) { | ||
out.printf("This command only works with the core file, which contains sparse heap.\n"); | ||
} | ||
} | ||
|
||
private void help(PrintStream out) { | ||
out.append("!dumpalloffheapentries -- dump all off heap entries"); | ||
out.append(nl); | ||
} | ||
} |