Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
20 changes: 8 additions & 12 deletions src/hotspot/share/memory/heapInspection.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -513,16 +513,16 @@ class HistoClosure : public KlassInfoClosure {
}
};

class FindClassByNameClosure : public KlassInfoClosure {
class FindClassByExternalNameClosure : public KlassInfoClosure {
private:
GrowableArray<Klass*>* _klasses;
Symbol* _classname;
const char* _classname;
public:
FindClassByNameClosure(GrowableArray<Klass*>* klasses, Symbol* classname) :
FindClassByExternalNameClosure(GrowableArray<Klass*>* klasses, const char* classname) :
_klasses(klasses), _classname(classname) { }

void do_cinfo(KlassInfoEntry* cie) {
if (cie->klass()->name() == _classname) {
if (strcmp(cie->klass()->external_name(), _classname) == 0) {
_klasses->append(cie->klass());
}
}
Expand Down Expand Up @@ -600,23 +600,19 @@ void PrintClassLayout::print_class_layout(outputStream* st, char* class_name) {
return;
}

Thread* THREAD = Thread::current();

Symbol* classname = SymbolTable::probe(class_name, (int)strlen(class_name));

GrowableArray<Klass*>* klasses = new (mtServiceability) GrowableArray<Klass*>(100, mtServiceability);

FindClassByNameClosure fbnc(klasses, classname);
ResourceMark rm;
FindClassByExternalNameClosure fbnc(klasses, class_name);
cit.iterate(&fbnc);

for(int i = 0; i < klasses->length(); i++) {
Klass* klass = klasses->at(i);
if (!klass->is_instance_klass()) continue; // Skip
InstanceKlass* ik = InstanceKlass::cast(klass);
int tab = 1;
st->print_cr("Class %s [@%s]:", klass->name()->as_C_string(),
st->print_cr("Class %s [@%s]:", klass->external_name(),
Comment on lines -611 to +617
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't it suffice to just make this change? If we convert to Symbol it seems more efficient than using strcmp (though I confess I'm not clear what this closure is actually doing and what set of classes it potentially generates).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree using strcmp is not very efficient, since we iterate the full KlassInfoTable. We still need to keep the external name as the argument however, but I reverted most changes for a different design. Now, we instead convert user input from dotted to slash form once, then use the same logic as before (probe the symbol table, then match on klass->name()). That way, we don't have to worry about comparing strings and we avoid lots of allocations from external_name()

As a side effect, this now also works on both internal and external names, as slashes would be left untouched.

klass->class_loader_data()->loader_name());
ResourceMark rm;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may still need this to limit the ResourceArea usage, otherwise you will be keeping all allocations from the complete loop alive.

GrowableArray<FieldDesc>* fields = new (mtServiceability) GrowableArray<FieldDesc>(100, mtServiceability);
for (AllFieldStream fd(ik); !fd.done(); fd.next()) {
if (!fd.access_flags().is_static()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ static void testCmd(String arg, int expectExitCode, String... expectStrings) thr
}

public static void main(String args[]) throws Exception {
testCmd("foo/bar", 0, "");
testCmd("foo.bar", 0, "");
testCmd("", 1, "IllegalArgumentException", "mandatory");
testCmd("java/lang/Object", 0, "java/lang/Object", "@bootstrap");
testCmd("java/lang/Class", 0, "java/lang/Class", "@bootstrap");
testCmd("runtime/valhalla/inlinetypes/ClassPrintLayoutDcmd$Line", 0, "@app", "p1", "p2");
testCmd("java.lang.Object", 0, "java.lang.Object", "@bootstrap");
testCmd("java.lang.Class", 0, "java.lang.Class", "@bootstrap");
testCmd("runtime.valhalla.inlinetypes.ClassPrintLayoutDcmd$Line", 0, "@app", "p1", "p2");
}
}