Skip to content
Closed
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
18 changes: 16 additions & 2 deletions src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3702,13 +3702,27 @@ const char* InstanceKlass::init_state_name() const {
return state_names[init_state()];
}

void InstanceKlass::print_class_flags(outputStream* st) const {
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.

This is incomplete. If the class is an inner class then additional access flags are possible (private, protected, static).
EDIT: Hmm jvm_constants.h does not recognise this either via JVM_RECOGNIZED_CLASS_MODIFIERS. Not sure how this should be handled.

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.

Also do we need to handle ACC_MODULE, or do we not actually create an instanceKlass for those?

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.

On jdk side we never have Class for modules. These classfiles are exclusively handled by Java code in ModuleDescriptor I think?

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 have now changed it to use compute_modifier_flags() instead of access_flags() directly. With this, we get member-class modifiers printed. I expanded the test which shows that private/protected static gets printed. This matches the class' modifiers, which feels like the correct behavior.

ACC_MODULE is not needed here because it never becomes an InstanceKlass. It is rejected as a normal class during parsing.

AccessFlags flags(compute_modifier_flags());
if (flags.is_public ()) st->print("public ");
if (flags.is_private ()) st->print("private ");
if (flags.is_protected ()) st->print("protected ");
if (flags.is_static ()) st->print("static ");
if (flags.is_final ()) st->print("final ");
if (flags.is_interface ()) st->print("interface ");
if (flags.is_abstract ()) st->print("abstract ");
if (flags.is_annotation()) st->print("annotation ");
if (flags.is_enum ()) st->print("enum ");
if (flags.is_synthetic ()) st->print("synthetic ");
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.

The bit for SYNTHETIC, 0x1000, comes before ANNOTATION, 0x2000, and ENUM, 0x4000. That should be tracked in a separate issue though.

}

void InstanceKlass::print_on(outputStream* st) const {
assert(is_klass(), "must be klass");
Klass::print_on(st);

st->print(BULLET"instance size: %d", size_helper()); st->cr();
st->print(BULLET"klass size: %d", size()); st->cr();
st->print(BULLET"access: "); access_flags().print_on(st); st->cr();
st->print(BULLET"access: "); print_class_flags(st); st->cr();
st->print(BULLET"flags: "); _misc_flags.print_on(st); st->cr();
st->print(BULLET"state: "); st->print_cr("%s", init_state_name());
st->print(BULLET"name: "); name()->print_value_on(st); st->cr();
Expand Down Expand Up @@ -3848,7 +3862,7 @@ void InstanceKlass::print_on(outputStream* st) const {

void InstanceKlass::print_value_on(outputStream* st) const {
assert(is_klass(), "must be klass");
if (Verbose || WizardMode) access_flags().print_on(st);
if (Verbose || WizardMode) print_class_flags(st);
name()->print_value_on(st);
}

Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/oops/instanceKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,7 @@ class InstanceKlass: public Klass {
// Printing
void print_on(outputStream* st) const override;
void print_value_on(outputStream* st) const override;
void print_class_flags(outputStream* st) const;

void oop_print_value_on(oop obj, outputStream* st) override;

Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/oops/klassVtable.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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 @@ -1066,7 +1066,7 @@ void klassVtable::dump_vtable() {
Method* m = unchecked_method_at(i);
if (m != nullptr) {
tty->print(" (%5d) ", i);
m->access_flags().print_on(tty);
m->print_access_flags(tty);
if (m->is_default_method()) {
tty->print("default ");
}
Expand Down Expand Up @@ -1421,7 +1421,7 @@ void klassItable::dump_itable() {
Method* m = ime->method();
if (m != nullptr) {
tty->print(" (%5d) ", i);
m->access_flags().print_on(tty);
m->print_access_flags(tty);
if (m->is_default_method()) {
tty->print("default ");
}
Expand Down
22 changes: 19 additions & 3 deletions src/hotspot/share/oops/method.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2204,7 +2204,7 @@ void Method::print_on(outputStream* st) const {
st->print (" - method holder: "); method_holder()->print_value_on(st); st->cr();
st->print (" - constants: " PTR_FORMAT " ", p2i(constants()));
constants()->print_value_on(st); st->cr();
st->print (" - access: 0x%x ", access_flags().as_method_flags()); access_flags().print_on(st); st->cr();
st->print (" - access: 0x%x ", access_flags().as_method_flags()); print_access_flags(st); st->cr();
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.

There is an existing inconsistency here in that we print the raw flags as "method flags" only but then we print them all. Your new code implicitly filters the flags by only printing the expected method flags.

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.

as_method_flags() asserts that only recognized method modifiers are set, so these are not arbitrary raw flags. Previously, the generic printer could misinterpret overlapping bits, whereas the new method-specific printer prints them correctly. This looks like the right behavior to me.

st->print (" - flags: 0x%x ", _flags.as_int()); _flags.print_on(st); st->cr();
st->print (" - name: "); name()->print_value_on(st); st->cr();
st->print (" - signature: "); signature()->print_value_on(st); st->cr();
Expand Down Expand Up @@ -2278,8 +2278,8 @@ void Method::print_on(outputStream* st) const {
}
}

void Method::print_linkage_flags(outputStream* st) {
access_flags().print_on(st);
void Method::print_linkage_flags(outputStream* st) const {
print_access_flags(st);
if (is_default_method()) {
st->print("default ");
}
Expand All @@ -2289,6 +2289,22 @@ void Method::print_linkage_flags(outputStream* st) {
}
#endif //PRODUCT

void Method::print_access_flags(outputStream* st) const {
AccessFlags flags = access_flags();
if (flags.is_public ()) st->print("public ");
if (flags.is_private ()) st->print("private ");
if (flags.is_protected ()) st->print("protected ");
if (flags.is_static ()) st->print("static ");
if (flags.is_final ()) st->print("final ");
if (flags.is_synchronized()) st->print("synchronized ");
if (flags.is_bridge ()) st->print("bridge ");
if (flags.is_varargs ()) st->print("varargs ");
if (flags.is_native ()) st->print("native ");
if (flags.is_abstract ()) st->print("abstract ");
if (flags.is_strictfp ()) st->print("strict ");
if (flags.is_synthetic ()) st->print("synthetic ");
}

void Method::print_value_on(outputStream* st) const {
assert(is_method(), "must be method");
st->print("%s", internal_name());
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/oops/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,8 @@ class Method : public Metadata {
void print_on(outputStream* st) const;
#endif
void print_value_on(outputStream* st) const;
void print_linkage_flags(outputStream* st) PRODUCT_RETURN;
void print_access_flags(outputStream* st) const;
void print_linkage_flags(outputStream* st) const PRODUCT_RETURN;

const char* internal_name() const { return "{method}"; }

Expand Down
14 changes: 7 additions & 7 deletions src/hotspot/share/prims/jvmtiRedefineClasses.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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 @@ -4544,7 +4544,7 @@ void VM_RedefineClasses::dump_methods() {
LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _old_methods->at(j);
log_stream.print("%4d (%5d) ", j, m->vtable_index());
m->access_flags().print_on(&log_stream);
m->print_access_flags(&log_stream);
log_stream.print(" -- ");
m->print_name(&log_stream);
log_stream.cr();
Expand All @@ -4554,7 +4554,7 @@ void VM_RedefineClasses::dump_methods() {
LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _new_methods->at(j);
log_stream.print("%4d (%5d) ", j, m->vtable_index());
m->access_flags().print_on(&log_stream);
m->print_access_flags(&log_stream);
log_stream.print(" -- ");
m->print_name(&log_stream);
log_stream.cr();
Expand All @@ -4564,22 +4564,22 @@ void VM_RedefineClasses::dump_methods() {
LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _matching_old_methods[j];
log_stream.print("%4d (%5d) ", j, m->vtable_index());
m->access_flags().print_on(&log_stream);
m->print_access_flags(&log_stream);
log_stream.print(" -- ");
m->print_name();
log_stream.cr();

m = _matching_new_methods[j];
log_stream.print(" (%5d) ", m->vtable_index());
m->access_flags().print_on(&log_stream);
m->print_access_flags(&log_stream);
log_stream.cr();
}
log_trace(redefine, class, dump)("_deleted_methods --");
for (j = 0; j < _deleted_methods_length; ++j) {
LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _deleted_methods[j];
log_stream.print("%4d (%5d) ", j, m->vtable_index());
m->access_flags().print_on(&log_stream);
m->print_access_flags(&log_stream);
log_stream.print(" -- ");
m->print_name(&log_stream);
log_stream.cr();
Expand All @@ -4589,7 +4589,7 @@ void VM_RedefineClasses::dump_methods() {
LogStreamHandle(Trace, redefine, class, dump) log_stream;
Method* m = _added_methods[j];
log_stream.print("%4d (%5d) ", j, m->vtable_index());
m->access_flags().print_on(&log_stream);
m->print_access_flags(&log_stream);
log_stream.print(" -- ");
m->print_name(&log_stream);
log_stream.cr();
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/prims/methodHandles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
ls.print_cr("memberName: invokeinterface method_holder::method: %s, itableindex: %d, access_flags:",
Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
vmindex);
m->access_flags().print_on(&ls);
m->print_access_flags(&ls);
if (!m->is_abstract()) {
if (!m->is_private()) {
ls.print("default");
Expand Down Expand Up @@ -314,7 +314,7 @@ oop MethodHandles::init_method_MemberName(Handle mname, CallInfo& info) {
ls.print_cr("memberName: invokevirtual method_holder::method: %s, receiver: %s, vtableindex: %d, access_flags:",
Method::name_and_sig_as_C_string(m->method_holder(), m->name(), m->signature()),
m_klass->internal_name(), vmindex);
m->access_flags().print_on(&ls);
m->print_access_flags(&ls);
if (m->is_default_method()) {
ls.print("default");
}
Expand Down
17 changes: 15 additions & 2 deletions src/hotspot/share/runtime/fieldDescriptor.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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 @@ -108,8 +108,21 @@ void fieldDescriptor::reinitialize(InstanceKlass* ik, const FieldInfo& fieldinfo
guarantee(_fieldinfo.name_index() != 0 && _fieldinfo.signature_index() != 0, "bad constant pool index for fieldDescriptor");
}

void fieldDescriptor::print_access_flags(outputStream* st) const {
AccessFlags flags = access_flags();
if (flags.is_public ()) st->print("public ");
if (flags.is_private ()) st->print("private ");
if (flags.is_protected()) st->print("protected ");
if (flags.is_static ()) st->print("static ");
if (flags.is_final ()) st->print("final ");
if (flags.is_volatile ()) st->print("volatile ");
if (flags.is_transient()) st->print("transient ");
if (flags.is_enum ()) st->print("enum ");
if (flags.is_synthetic()) st->print("synthetic ");
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.

Same SYNTHETIC remark here.

}

void fieldDescriptor::print_on(outputStream* st) const {
access_flags().print_on(st);
print_access_flags(st);
if (field_flags().is_injected()) st->print("injected ");
name()->print_value_on(st);
st->print(" ");
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/runtime/fieldDescriptor.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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 @@ -111,6 +111,7 @@ class fieldDescriptor {
void print() const;
void print_on(outputStream* st) const;
void print_on_for(outputStream* st, oop obj);
void print_access_flags(outputStream* st) const;
};

#endif // SHARE_RUNTIME_FIELDDESCRIPTOR_HPP
23 changes: 1 addition & 22 deletions src/hotspot/share/utilities/accessFlags.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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 All @@ -22,29 +22,8 @@
*
*/

#include "oops/oop.inline.hpp"
#include "runtime/atomicAccess.hpp"
#include "utilities/accessFlags.hpp"

#if !defined(PRODUCT) || INCLUDE_JVMTI

void AccessFlags::print_on(outputStream* st) const {
if (is_public ()) st->print("public " );
if (is_private ()) st->print("private " );
if (is_protected ()) st->print("protected " );
if (is_static ()) st->print("static " );
if (is_final ()) st->print("final " );
if (is_synchronized()) st->print("synchronized ");
if (is_volatile ()) st->print("volatile " );
if (is_transient ()) st->print("transient " );
if (is_native ()) st->print("native " );
if (is_interface ()) st->print("interface " );
if (is_abstract ()) st->print("abstract " );
if (is_synthetic ()) st->print("synthetic " );
}

#endif // !PRODUCT || INCLUDE_JVMTI

void accessFlags_init() {
assert(sizeof(AccessFlags) == sizeof(u2), "just checking size of flags");
}
14 changes: 6 additions & 8 deletions src/hotspot/share/utilities/accessFlags.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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 @@ -53,10 +53,15 @@ class AccessFlags {
bool is_synchronized() const { return (_flags & JVM_ACC_SYNCHRONIZED) != 0; }
bool is_super () const { return (_flags & JVM_ACC_SUPER ) != 0; }
bool is_volatile () const { return (_flags & JVM_ACC_VOLATILE ) != 0; }
bool is_bridge () const { return (_flags & JVM_ACC_BRIDGE ) != 0; }
bool is_transient () const { return (_flags & JVM_ACC_TRANSIENT ) != 0; }
bool is_varargs () const { return (_flags & JVM_ACC_VARARGS ) != 0; }
bool is_native () const { return (_flags & JVM_ACC_NATIVE ) != 0; }
bool is_enum () const { return (_flags & JVM_ACC_ENUM ) != 0; }
bool is_annotation () const { return (_flags & JVM_ACC_ANNOTATION ) != 0; }
bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; }
bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; }
bool is_strictfp () const { return (_flags & JVM_ACC_STRICT ) != 0; }

// Attribute flags
bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; }
Expand Down Expand Up @@ -92,13 +97,6 @@ class AccessFlags {
assert((_flags & JVM_RECOGNIZED_CLASS_MODIFIERS) == _flags, "only recognized flags");
return _flags;
}

// Printing/debugging
#if INCLUDE_JVMTI
void print_on(outputStream* st) const;
#else
void print_on(outputStream* st) const PRODUCT_RETURN;
#endif
};

inline AccessFlags accessFlags_from(u2 flags) {
Expand Down
Loading