RFR: 8373615: Improve HotSpot debug functions findclass() and findmethod
Ioi Lam
iklam at openjdk.org
Fri Dec 12 16:48:25 UTC 2025
On Fri, 12 Dec 2025 16:40:24 GMT, Ioi Lam <iklam at openjdk.org> wrote:
> I used the `findclass` and `findmethod` functions in debug.cpp a lot when debugging problems with class metadata.
>
> https://github.com/openjdk/jdk/blob/6ec36d348b1eaeedb993a905e42650242fac0918/src/hotspot/share/utilities/debug.cpp#L583-L603
>
> This REF improves these functions by:
>
> - Sorting the names of classes and methods
> - Allow "." to be used in class names. So both `findclass("java.lang.Object")` and `findclass("java/lang/Object")` would work
> - Print the C++/Java objects that represent classes and methods.
Example 1:
(gdb) p findclass("*.ArrayList", 0x20)
"Executing findclass"
flags (bitmask):
0x01 - print names of methods
0x02 - print bytecodes
0x04 - print the address of bytecodes
0x08 - print info for invokedynamic
0x10 - print info for invokehandle
0x20 - print details of the C++ and Java objects that represent classes
0x40 - print details of the C++ objects that represent methods
[ 0] 0x000000005527ddb8 class: java/util/ArrayList mirror: 0x00000007ff854410 loader data: 0x00007ffff010cf30 of 'bootstrap'
InstanceKlass: java.util.ArrayList {0x000000005527ddb8}
- instance size: 3
- klass size: 205
- access: public synchronized
- flags: rewritten has_nonstatic_fields has_nonstatic_concrete_methods defined_by_boot_loader has_localvariable_table has_miranda_methods
- state: fully_initialized
- name: 'java/util/ArrayList'
- super: 'java/util/AbstractList'
- sub:
- arrays: null
- methods: Array<T>(0x000000005591e538)
- method ordering: Array<T>(0x000000005577a0d8)
- default_methods: Array<T>(0x000000005591f438)
- default vtable indices: Array<T>(0x000000005577a1f0)
- local interfaces: Array<T>(0x000000005591f468)
- trans. interfaces: Array<T>(0x000000005591f490)
- secondary supers: Array<T>(0x0000000055918860)
- hash_slot: 26
- secondary bitmap: 0x4000000100220203
- constants: constant pool [516] {0x000000005591b918} for 'java/util/ArrayList' cache=0x0000000055282018
- class loader data: loader data: 0x00007ffff010cf30 of 'bootstrap'
- source file: 'ArrayList.java'
- generic signature: '<E:Ljava/lang/Object;>Ljava/util/AbstractList<TE;>;Ljava/util/List<TE;>;Ljava/util/RandomAccess;Ljava/lang/Cloneable;Ljava/io/Serializable;'
- inner classes: Array<T>(0x0000000055779f68)
- nest members: Array<T>(0x000000005577a238)
- permitted subclasses: Array<T>(0x00000000557590b0)
- java mirror: a 'java/lang/Class'{0x00000007ff854410} = 'java/util/ArrayList'
- vtable length 55 (start addr: 0x000000005527df98)
- itable length 89 (start addr: 0x000000005527e150)
- ---- static fields (3 words):
- private static final 'serialVersionUID' 'J' @128
- private static final 'DEFAULT_CAPACITY' 'I' @136
- private static final 'EMPTY_ELEMENTDATA' '[Ljava/lang/Object;' @120
- private static final 'DEFAULTCAPACITY_EMPTY_ELEMENTDATA' '[Ljava/lang/Object;' @124
- ---- non-static fields (3 words):
- protected transient 'modCount' 'I' @12
- private 'size' 'I' @16
- transient 'elementData' '[Ljava/lang/Object;' @20
- non-static oop maps (1 entries): 20-20
Java mirror oop for java/util/ArrayList: java.lang.Class
{0x00000007ff854410} - klass: 'java/lang/Class' - flags:
- ---- fields (total size 18 words):
- private volatile transient 'classRedefinedCount' 'I' @12 0 (0x00000000)
- injected 'klass' 'J' @16 1428676024 (0x000000005527ddb8)
- injected 'array_klass' 'J' @24 0 (0x0000000000000000)
- injected 'oop_size' 'I' @32 18 (0x00000012)
- injected 'static_oop_field_count' 'I' @36 2 (0x00000002)
- private final transient 'modifiers' 'C' @40 1 (0x0001)
- private final transient 'classFileAccessFlags' 'C' @42 ! 33 (0x0021)
- private final transient 'primitive' 'Z' @44 false (0x00)
- private volatile transient 'cachedConstructor' 'Ljava/lang/reflect/Constructor;' @48 null (0x00000000)
- private transient 'name' 'Ljava/lang/String;' @52 null (0x00000000)
- private transient 'module' 'Ljava/lang/Module;' @56 a 'java/lang/Module'{0x00000007ff8205a0} (0xfff040b4)
- private final 'classLoader' 'Ljava/lang/ClassLoader;' @60 null (0x00000000)
- private transient 'classData' 'Ljava/lang/Object;' @64 null (0x00000000)
- private transient 'signers' '[Ljava/lang/Object;' @68 null (0x00000000)
- private transient 'packageName' 'Ljava/lang/String;' @72 null (0x00000000)
- private final transient 'componentType' 'Ljava/lang/Class;' @76 null (0x00000000)
- private final transient 'protectionDomain' 'Ljava/security/ProtectionDomain;' @80 null (0x00000000)
- private volatile transient 'reflectionData' 'Ljava/lang/ref/SoftReference;' @84 null (0x00000000)
- private volatile transient 'genericInfo' 'Lsun/reflect/generics/repository/ClassRepository;' @88 null (0x00000000)
- private volatile transient 'enumConstants' '[Ljava/lang/Object;' @92 null (0x00000000)
- private volatile transient 'enumConstantDirectory' 'Ljava/util/Map;' @96 null (0x00000000)
- private volatile transient 'annotationData' 'Ljava/lang/Class$AnnotationData;' @100 null (0x00000000)
- private volatile transient 'annotationType' 'Lsun/reflect/annotation/AnnotationType;' @104 null (0x00000000)
- transient 'classValueMap' 'Ljava/lang/ClassValue$ClassValueMap;' @108 null (0x00000000)
- injected 'source_file' 'Ljava/lang/Object;' @112 null (0x00000000)
- injected '<init_lock>' 'Ljava/lang/Object;' @116 null (0x00000000)
- signature: Ljava/util/ArrayList;
- ---- static fields (2):
- private static final 'serialVersionUID' 'J' @128 8683452581122892189 (0x7881d21d99c7619d)
- private static final 'DEFAULT_CAPACITY' 'I' @136 10 (0x0000000a)
- private static final 'EMPTY_ELEMENTDATA' '[Ljava/lang/Object;' @120 a 'java/lang/Object'[0] {0x000000043800f188} (0x87001e31)
- private static final 'DEFAULTCAPACITY_EMPTY_ELEMENTDATA' '[Ljava/lang/Object;' @124 a 'java/lang/Object'[0] {0x000000043800f198} (0x87001e33)
Example 2 (sorting of methods):
(gdb) p findmethod("*.ArrayList", "*remove*", 0x0)
"Executing findmethod"
flags (bitmask):
0x01 - print names of methods
0x02 - print bytecodes
0x04 - print the address of bytecodes
0x08 - print info for invokedynamic
0x10 - print info for invokehandle
0x20 - print details of the C++ and Java objects that represent classes
0x40 - print details of the C++ objects that represent methods
[ 0] 0x000000009e27ddb8 class: java/util/ArrayList mirror: 0x00000007ff854410 loader data: 0x00007ffff010cef0 of 'bootstrap'
0x000000009e283470 method batchRemove : (Ljava/util/Collection;ZII)Z
0x000000009e283a20 method fastRemove : ([Ljava/lang/Object;I)V
0x000000009e282910 method remove : (I)Ljava/lang/Object;
0x000000009e282280 method remove : (Ljava/lang/Object;)Z
0x000000009e2826e0 method removeAll : (Ljava/util/Collection;)Z
0x000000009e2830f0 method removeFirst : ()Ljava/lang/Object;
0x000000009e2828a0 method removeIf : (Ljava/util/function/Predicate;)Z
0x000000009e2834e0 method removeIf : (Ljava/util/function/Predicate;II)Z
0x000000009e282ec0 method removeLast : ()Ljava/lang/Object;
0x000000009e282c90 method removeRange : (II)V
-------------
PR Comment: https://git.openjdk.org/jdk/pull/28796#issuecomment-3647317868
PR Comment: https://git.openjdk.org/jdk/pull/28796#issuecomment-3647322243
More information about the hotspot-runtime-dev
mailing list