diff --git a/src/hotspot/share/ci/ciInstanceKlass.hpp b/src/hotspot/share/ci/ciInstanceKlass.hpp index ec8fc789c7d19..9642582598603 100644 --- a/src/hotspot/share/ci/ciInstanceKlass.hpp +++ b/src/hotspot/share/ci/ciInstanceKlass.hpp @@ -149,6 +149,10 @@ class ciInstanceKlass : public ciKlass { assert(is_loaded(), "must be loaded"); return _flags; } + + // Fetch Klass::access_flags. + jint access_flags() { return flags().as_int(); } + bool has_finalizer() { assert(is_loaded(), "must be loaded"); return _has_finalizer; } diff --git a/src/hotspot/share/ci/ciKlass.cpp b/src/hotspot/share/ci/ciKlass.cpp index f3e49634d2984..0a0379af97e0a 100644 --- a/src/hotspot/share/ci/ciKlass.cpp +++ b/src/hotspot/share/ci/ciKlass.cpp @@ -216,15 +216,6 @@ jint ciKlass::modifier_flags() { ) } -// ------------------------------------------------------------------ -// ciKlass::access_flags -jint ciKlass::access_flags() { - assert(is_loaded(), "not loaded"); - GUARDED_VM_ENTRY( - return get_Klass()->access_flags().as_unsigned_short(); - ) -} - // ------------------------------------------------------------------ // ciKlass::misc_flags klass_flags_t ciKlass::misc_flags() { diff --git a/src/hotspot/share/ci/ciKlass.hpp b/src/hotspot/share/ci/ciKlass.hpp index 8d03b910de53b..f95602b9717bf 100644 --- a/src/hotspot/share/ci/ciKlass.hpp +++ b/src/hotspot/share/ci/ciKlass.hpp @@ -122,9 +122,6 @@ class ciKlass : public ciType { // Fetch modifier flags. jint modifier_flags(); - // Fetch Klass::access_flags. - jint access_flags(); - // Fetch Klass::misc_flags. klass_flags_t misc_flags(); diff --git a/src/hotspot/share/classfile/defaultMethods.cpp b/src/hotspot/share/classfile/defaultMethods.cpp index e5cb5d8f35481..2588ebd60ca0d 100644 --- a/src/hotspot/share/classfile/defaultMethods.cpp +++ b/src/hotspot/share/classfile/defaultMethods.cpp @@ -439,7 +439,7 @@ class MethodFamily : public ResourceObj { StreamIndentor si(str, indent * 2); str->print("Selected method: "); print_method(str, _selected_target); - Klass* method_holder = _selected_target->method_holder(); + InstanceKlass* method_holder = _selected_target->method_holder(); if (!method_holder->is_interface()) { str->print(" : in superclass"); } diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index e41af70260128..f9d78eb5c206e 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1093,8 +1093,7 @@ void java_lang_Class::allocate_mirror(Klass* k, bool is_scratch, Handle protecti set_modifiers(mirror(), computed_modifiers); // Set the raw access_flags, this is used by reflection instead of modifier flags. // The Java code for array classes gets the access flags from the element type. - assert(!k->is_array_klass() || k->access_flags().as_unsigned_short() == 0, "access flags are not set for arrays"); - set_raw_access_flags(mirror(), k->access_flags().as_unsigned_short()); + set_raw_access_flags(mirror(), k->is_array_klass() ? 0 : InstanceKlass::cast(k)->access_flags().as_unsigned_short()); InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); assert(oop_size(mirror()) == mk->instance_size(k), "should have been set"); diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 5c49a32b8d04d..db4ccaaa37f5f 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -2168,9 +2168,10 @@ static bool is_always_visible_class(oop mirror) { return true; // primitive array } assert(klass->is_instance_klass(), "%s", klass->external_name()); - return klass->is_public() && - (InstanceKlass::cast(klass)->is_same_class_package(vmClasses::Object_klass()) || // java.lang - InstanceKlass::cast(klass)->is_same_class_package(vmClasses::MethodHandle_klass())); // java.lang.invoke + InstanceKlass* ik = InstanceKlass::cast(klass); + return ik->is_public() && + (ik->is_same_class_package(vmClasses::Object_klass()) || // java.lang + ik->is_same_class_package(vmClasses::MethodHandle_klass())); // java.lang.invoke } // Find or construct the Java mirror (java.lang.Class instance) for diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp index 7ef16f6e32cdc..27644f8bd8434 100644 --- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp +++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp @@ -222,6 +222,7 @@ volatile_nonstatic_field(InstanceKlass, _init_state, InstanceKlass::ClassState) \ volatile_nonstatic_field(InstanceKlass, _init_thread, JavaThread*) \ nonstatic_field(InstanceKlass, _misc_flags._flags, u2) \ + nonstatic_field(InstanceKlass, _access_flags, AccessFlags) \ nonstatic_field(InstanceKlass, _annotations, Annotations*) \ \ volatile_nonstatic_field(JavaFrameAnchor, _last_Java_sp, intptr_t*) \ @@ -281,7 +282,6 @@ nonstatic_field(Klass, _name, Symbol*) \ volatile_nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _java_mirror, OopHandle) \ - nonstatic_field(Klass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _class_loader_data, ClassLoaderData*) \ nonstatic_field(Klass, _secondary_supers_bitmap, uintx) \ nonstatic_field(Klass, _hash_slot, uint8_t) \ diff --git a/src/hotspot/share/oops/arrayKlass.cpp b/src/hotspot/share/oops/arrayKlass.cpp index cd929a3bfe10f..30a2bc5102a15 100644 --- a/src/hotspot/share/oops/arrayKlass.cpp +++ b/src/hotspot/share/oops/arrayKlass.cpp @@ -99,7 +99,8 @@ ArrayKlass::ArrayKlass(Symbol* name, KlassKind kind) : set_name(name); set_super(Universe::is_bootstrapping() ? nullptr : vmClasses::Object_klass()); set_layout_helper(Klass::_lh_neutral_value); - set_is_cloneable(); // All arrays are considered to be cloneable (See JLS 20.1.5) + // All arrays are considered to be cloneable (See JLS 20.1.5) + set_is_cloneable_fast(); JFR_ONLY(INIT_ID(this);) log_array_class_load(this); } diff --git a/src/hotspot/share/oops/fieldInfo.hpp b/src/hotspot/share/oops/fieldInfo.hpp index a98895da9cf54..b6d9c4d34e5e2 100644 --- a/src/hotspot/share/oops/fieldInfo.hpp +++ b/src/hotspot/share/oops/fieldInfo.hpp @@ -27,6 +27,7 @@ #include "memory/allocation.hpp" #include "oops/typeArrayOop.hpp" +#include "utilities/accessFlags.hpp" #include "utilities/unsigned5.hpp" #include "utilities/vmEnums.hpp" diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index 2d03b69ee92e9..7358e65b48a5e 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -552,6 +552,17 @@ InstanceKlass::InstanceKlass(const ClassFileParser& parser, KlassKind kind, Refe assert(size_helper() == parser.layout_size(), "incorrect size_helper?"); } +void InstanceKlass::set_is_cloneable() { + if (name() == vmSymbols::java_lang_invoke_MemberName()) { + assert(is_final(), "no subclasses allowed"); + // MemberName cloning should not be intrinsified and always happen in JVM_Clone. + } else if (reference_type() != REF_NONE) { + // Reference cloning should not be intrinsified and always happen in JVM_Clone. + } else { + set_is_cloneable_fast(); + } +} + void InstanceKlass::deallocate_methods(ClassLoaderData* loader_data, Array* methods) { if (methods != nullptr && methods != Universe::the_empty_method_array() && diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index 8bb9741af9f42..a03e6c05b5452 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -229,7 +229,9 @@ class InstanceKlass: public Klass { // _idnum_allocated_count. volatile ClassState _init_state; // state of class - u1 _reference_type; // reference type + u1 _reference_type; // reference type + + AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. // State is set either at parse time or while executing, atomically to not disturb other state InstanceKlassFlags _misc_flags; @@ -305,6 +307,22 @@ class InstanceKlass: public Klass { // Sets finalization state static void set_finalization_enabled(bool val) { _finalization_enabled = val; } + // Access flags + AccessFlags access_flags() const { return _access_flags; } + void set_access_flags(AccessFlags flags) { _access_flags = flags; } + + bool is_public() const { return _access_flags.is_public(); } + bool is_final() const { return _access_flags.is_final(); } + bool is_interface() const { return _access_flags.is_interface(); } + bool is_abstract() const { return _access_flags.is_abstract(); } + bool is_super() const { return _access_flags.is_super(); } + bool is_synthetic() const { return _access_flags.is_synthetic(); } + void set_is_synthetic() { _access_flags.set_is_synthetic(); } + + static ByteSize access_flags_offset() { return byte_offset_of(InstanceKlass, _access_flags); } + + void set_is_cloneable(); + // Quick checks for the loader that defined this class (without switching on this->class_loader()) bool defined_by_boot_loader() const { return _misc_flags.defined_by_boot_loader(); } bool defined_by_platform_loader() const { return _misc_flags.defined_by_platform_loader(); } diff --git a/src/hotspot/share/oops/klass.cpp b/src/hotspot/share/oops/klass.cpp index b30ec2f48879f..56a75bc0d84ee 100644 --- a/src/hotspot/share/oops/klass.cpp +++ b/src/hotspot/share/oops/klass.cpp @@ -68,17 +68,6 @@ bool Klass::is_cloneable() const { is_subtype_of(vmClasses::Cloneable_klass()); } -void Klass::set_is_cloneable() { - if (name() == vmSymbols::java_lang_invoke_MemberName()) { - assert(is_final(), "no subclasses allowed"); - // MemberName cloning should not be intrinsified and always happen in JVM_Clone. - } else if (is_instance_klass() && InstanceKlass::cast(this)->reference_type() != REF_NONE) { - // Reference cloning should not be intrinsified and always happen in JVM_Clone. - } else { - _misc_flags.set_is_cloneable_fast(true); - } -} - uint8_t Klass::compute_hash_slot(Symbol* n) { uint hash_code; // Special cases for the two superclasses of all Array instances. diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 5ac393d761409..25fb900e7d6ab 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -30,7 +30,6 @@ #include "oops/metadata.hpp" #include "oops/oop.hpp" #include "oops/oopHandle.hpp" -#include "utilities/accessFlags.hpp" #include "utilities/macros.hpp" #if INCLUDE_JFR #include "jfr/support/jfrTraceIdExtension.hpp" @@ -120,9 +119,8 @@ class Klass : public Metadata { // - Various type checking in the JVM const KlassKind _kind; - AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here. - // Some flags created by the JVM, not in the class file itself, - // are in _misc_flags below. + // Some flags created by the JVM, not in the class file itself, + // are in _misc_flags below. KlassFlags _misc_flags; // The fields _super_check_offset, _secondary_super_cache, _secondary_supers @@ -453,7 +451,6 @@ class Klass : public Metadata { static ByteSize java_mirror_offset() { return byte_offset_of(Klass, _java_mirror); } static ByteSize class_loader_data_offset() { return byte_offset_of(Klass, _class_loader_data); } static ByteSize layout_helper_offset() { return byte_offset_of(Klass, _layout_helper); } - static ByteSize access_flags_offset() { return byte_offset_of(Klass, _access_flags); } #if INCLUDE_JVMCI static ByteSize subklass_offset() { return byte_offset_of(Klass, _subklass); } static ByteSize next_sibling_offset() { return byte_offset_of(Klass, _next_sibling); } @@ -707,17 +704,10 @@ class Klass : public Metadata { bool is_typeArray_klass() const { return assert_same_query( _kind == TypeArrayKlassKind, is_typeArray_klass_slow()); } #undef assert_same_query - // Access flags - AccessFlags access_flags() const { return _access_flags; } - void set_access_flags(AccessFlags flags) { _access_flags = flags; } - - bool is_public() const { return _access_flags.is_public(); } - bool is_final() const { return _access_flags.is_final(); } - bool is_interface() const { return _access_flags.is_interface(); } - bool is_abstract() const { return _access_flags.is_abstract(); } - bool is_super() const { return _access_flags.is_super(); } - bool is_synthetic() const { return _access_flags.is_synthetic(); } - void set_is_synthetic() { _access_flags.set_is_synthetic(); } + + virtual bool is_interface() const { return false; } + virtual bool is_abstract() const { return false; } + bool has_finalizer() const { return _misc_flags.has_finalizer(); } void set_has_finalizer() { _misc_flags.set_has_finalizer(true); } bool is_hidden() const { return _misc_flags.is_hidden_class(); } @@ -730,7 +720,7 @@ class Klass : public Metadata { inline bool is_non_strong_hidden() const; bool is_cloneable() const; - void set_is_cloneable(); + void set_is_cloneable_fast() { _misc_flags.set_is_cloneable_fast(true); } inline markWord prototype_header() const; inline void set_prototype_header(markWord header); diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 6babc13e1b315..c7373e84f25db 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -1726,8 +1726,6 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr } if (flat->offset() == in_bytes(Klass::super_check_offset_offset())) alias_type(idx)->set_rewritable(false); - if (flat->offset() == in_bytes(Klass::access_flags_offset())) - alias_type(idx)->set_rewritable(false); if (flat->offset() == in_bytes(Klass::misc_flags_offset())) alias_type(idx)->set_rewritable(false); if (flat->offset() == in_bytes(Klass::java_mirror_offset())) @@ -1735,6 +1733,12 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr if (flat->offset() == in_bytes(Klass::secondary_super_cache_offset())) alias_type(idx)->set_rewritable(false); } + + if (flat->isa_instklassptr()) { + if (flat->offset() == in_bytes(InstanceKlass::access_flags_offset())) { + alias_type(idx)->set_rewritable(false); + } + } // %%% (We would like to finalize JavaThread::threadObj_offset(), // but the base pointer type is not distinctive enough to identify // references into JavaThread.) diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 7a213102efd15..33d5e73ebd3f9 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -3985,7 +3985,7 @@ Node* LibraryCallKit::generate_klass_flags_guard(Node* kls, int modifier_mask, i } Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) { return generate_klass_flags_guard(kls, JVM_ACC_INTERFACE, 0, region, - Klass::access_flags_offset(), TypeInt::CHAR, T_CHAR); + InstanceKlass::access_flags_offset(), TypeInt::CHAR, T_CHAR); } // Use this for testing if Klass is_hidden, has_finalizer, and is_cloneable_fast. @@ -4097,12 +4097,12 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { // Arrays store an intermediate super as _super, but must report Object. // Other types can report the actual _super. // (To verify this code sequence, check the asserts in JVM_IsInterface.) - if (generate_interface_guard(kls, region) != nullptr) - // A guard was added. If the guard is taken, it was an interface. - phi->add_req(null()); if (generate_array_guard(kls, region) != nullptr) // A guard was added. If the guard is taken, it was an array. phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror()))); + if (generate_interface_guard(kls, region) != nullptr) + // A guard was added. If the guard is taken, it was an interface. + phi->add_req(null()); // If we fall through, it's a plain class. Get its _super. p = basic_plus_adr(kls, in_bytes(Klass::super_offset())); kls = _gvn.transform(LoadKlassNode::make(_gvn, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeInstKlassPtr::OBJECT_OR_NULL)); diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index f42a6ea9489e9..479fecd2bec53 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -1979,10 +1979,12 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, ciKlass* klass) const { assert(!UseCompactObjectHeaders || tkls->offset() != in_bytes(Klass::prototype_header_offset()), "must not happen"); - if (tkls->offset() == in_bytes(Klass::access_flags_offset())) { - // The field is Klass::_access_flags. Return its (constant) value. + + if (tkls->isa_instklassptr() && tkls->offset() == in_bytes(InstanceKlass::access_flags_offset())) { + // The field is InstanceKlass::_access_flags. Return its (constant) value. assert(Opcode() == Op_LoadUS, "must load an unsigned short from _access_flags"); - return TypeInt::make(klass->access_flags()); + ciInstanceKlass* iklass = tkls->is_instklassptr()->instance_klass(); + return TypeInt::make(iklass->access_flags()); } if (tkls->offset() == in_bytes(Klass::misc_flags_offset())) { // The field is Klass::_misc_flags. Return its (constant) value. diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index a7342448522dd..da2cded669964 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -213,6 +213,7 @@ nonstatic_field(InstanceKlass, _annotations, Annotations*) \ nonstatic_field(InstanceKlass, _method_ordering, Array*) \ nonstatic_field(InstanceKlass, _default_vtable_indices, Array*) \ + nonstatic_field(InstanceKlass, _access_flags, AccessFlags) \ nonstatic_field(Klass, _super_check_offset, juint) \ nonstatic_field(Klass, _secondary_super_cache, Klass*) \ nonstatic_field(Klass, _secondary_supers, Array*) \ @@ -222,7 +223,6 @@ volatile_nonstatic_field(Klass, _subklass, Klass*) \ nonstatic_field(Klass, _layout_helper, jint) \ nonstatic_field(Klass, _name, Symbol*) \ - nonstatic_field(Klass, _access_flags, AccessFlags) \ volatile_nonstatic_field(Klass, _next_sibling, Klass*) \ nonstatic_field(Klass, _next_link, Klass*) \ nonstatic_field(Klass, _vtable_len, int) \ diff --git a/src/hotspot/share/utilities/accessFlags.hpp b/src/hotspot/share/utilities/accessFlags.hpp index a752c09cb4272..54bbaeb2c13e1 100644 --- a/src/hotspot/share/utilities/accessFlags.hpp +++ b/src/hotspot/share/utilities/accessFlags.hpp @@ -67,7 +67,7 @@ class AccessFlags { void set_flags(u2 flags) { _flags = flags; } private: - friend class Klass; + friend class InstanceKlass; friend class ClassFileParser; // the functions below should only be called on the _access_flags inst var directly, // otherwise they are just changing a copy of the flags diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java index 0cd743372d5b0..c3859c688c833 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java @@ -62,6 +62,16 @@ public void update(Observable o, Object data) { private static int CLASS_STATE_FULLY_INITIALIZED; private static int CLASS_STATE_INITIALIZATION_ERROR; + public long getAccessFlags() { return accessFlags.getValue(this); } + // Convenience routine + public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); } + + public boolean isPublic() { return getAccessFlagsObj().isPublic(); } + public boolean isFinal() { return getAccessFlagsObj().isFinal(); } + public boolean isInterface() { return getAccessFlagsObj().isInterface(); } + public boolean isAbstract() { return getAccessFlagsObj().isAbstract(); } + public boolean isSuper() { return getAccessFlagsObj().isSuper(); } + public boolean isSynthetic() { return getAccessFlagsObj().isSynthetic(); } private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { Type type = db.lookupType("InstanceKlass"); @@ -88,6 +98,7 @@ private static synchronized void initialize(TypeDataBase db) throws WrongTypeExc breakpoints = type.getAddressField("_breakpoints"); } headerSize = type.getSize(); + accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0); // read internal field flags constants FIELD_FLAG_IS_INITIALIZED = db.lookupIntConstant("FieldInfo::FieldFlags::_ff_initialized"); @@ -150,6 +161,7 @@ public InstanceKlass(Address addr) { private static CIntField initState; private static CIntField itableLen; private static CIntField nestHostIndex; + private static CIntField accessFlags; private static AddressField breakpoints; // type safe enum for ClassState from instanceKlass.hpp @@ -499,7 +511,7 @@ private boolean isInInnerClasses(Symbol sym, boolean includeLocals) { } } - public boolean implementsInterface(Klass k) { + public boolean implementsInterface(InstanceKlass k) { if (Assert.ASSERTS_ENABLED) { Assert.that(k.isInterface(), "should not reach here"); } @@ -511,7 +523,7 @@ public boolean implementsInterface(Klass k) { return false; } - boolean computeSubtypeOf(Klass k) { + boolean computeSubtypeOf(InstanceKlass k) { if (k.isInterface()) { return implementsInterface(k); } else { @@ -535,6 +547,7 @@ public void iterateFields(MetadataVisitor visitor) { visitor.doCInt(nonstaticOopMapSize, true); visitor.doCInt(initState, true); visitor.doCInt(itableLen, true); + visitor.doCInt(accessFlags, true); } /* diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java index 1b8a9d0ef6923..561c4683d295a 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/Klass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -57,7 +57,6 @@ private static synchronized void initialize(TypeDataBase db) throws WrongTypeExc superField = new MetadataField(type.getAddressField("_super"), 0); layoutHelper = new IntField(type.getJIntField("_layout_helper"), 0); name = type.getAddressField("_name"); - accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0); try { traceIDField = type.getField("_trace_id"); } catch(Exception e) { @@ -95,7 +94,6 @@ public int getClassStatus() { private static MetadataField superField; private static IntField layoutHelper; private static AddressField name; - private static CIntField accessFlags; private static MetadataField subklass; private static MetadataField nextSibling; private static MetadataField nextLink; @@ -117,9 +115,6 @@ public Instance getJavaMirror() { public Klass getJavaSuper() { return null; } public int getLayoutHelper() { return layoutHelper.getValue(this); } public Symbol getName() { return getSymbol(name); } - public long getAccessFlags() { return accessFlags.getValue(this); } - // Convenience routine - public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags()); } public Klass getSubklassKlass() { return (Klass) subklass.getValue(this); } public Klass getNextSiblingKlass() { return (Klass) nextSibling.getValue(this); } public Klass getNextLinkKlass() { return (Klass) nextLink.getValue(this); } @@ -175,7 +170,6 @@ public void iterateFields(MetadataVisitor visitor) { visitor.doMetadata(superField, true); visitor.doInt(layoutHelper, true); // visitor.doOop(name, true); - visitor.doCInt(accessFlags, true); visitor.doMetadata(subklass, true); visitor.doMetadata(nextSibling, true); visitor.doCInt(vtableLen, true); @@ -205,12 +199,4 @@ public Klass arrayKlassImpl(boolean orNull) { // The subclasses override this to produce the correct form, eg // Ljava/lang/String; For ArrayKlasses getName itself is the signature. public String signature() { return getName().asString(); } - - // Convenience routines - public boolean isPublic() { return getAccessFlagsObj().isPublic(); } - public boolean isFinal() { return getAccessFlagsObj().isFinal(); } - public boolean isInterface() { return getAccessFlagsObj().isInterface(); } - public boolean isAbstract() { return getAccessFlagsObj().isAbstract(); } - public boolean isSuper() { return getAccessFlagsObj().isSuper(); } - public boolean isSynthetic() { return getAccessFlagsObj().isSynthetic(); } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java index a4cdb671959d9..c71cb3156ea61 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 @@ -107,7 +107,7 @@ public void iterate(HeapVisitor visitor, ObjectFilter of) { /** iterate objects of given Klass. param 'includeSubtypes' tells whether to * include objects of subtypes or not */ - public void iterateObjectsOfKlass(HeapVisitor visitor, final Klass k, boolean includeSubtypes) { + public void iterateObjectsOfKlass(HeapVisitor visitor, final InstanceKlass k, boolean includeSubtypes) { if (includeSubtypes) { if (k.isFinal()) { // do the simpler "exact" klass loop @@ -124,7 +124,7 @@ public void iterateObjectsOfKlass(HeapVisitor visitor, final Klass k, boolean in } /** iterate objects of given Klass (objects of subtypes included) */ - public void iterateObjectsOfKlass(HeapVisitor visitor, final Klass k) { + public void iterateObjectsOfKlass(HeapVisitor visitor, final InstanceKlass k) { iterateObjectsOfKlass(visitor, k, true); } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ConcurrentLocksPrinter.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ConcurrentLocksPrinter.java index fa28a96e333df..c4abb3e946d2f 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ConcurrentLocksPrinter.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ConcurrentLocksPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2025, 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 @@ -64,7 +64,7 @@ private JavaThread getOwnerThread(Oop oop) { private void fillLocks() { VM vm = VM.getVM(); SystemDictionary sysDict = vm.getSystemDictionary(); - Klass absOwnSyncKlass = sysDict.getAbstractOwnableSynchronizerKlass(); + InstanceKlass absOwnSyncKlass = sysDict.getAbstractOwnableSynchronizerKlass(); ObjectHeap heap = vm.getObjectHeap(); // may be not loaded at all if (absOwnSyncKlass != null) { diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java index b7c470e3477c6..0e65a41c57185 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, 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 @@ -90,7 +90,7 @@ private void printClassLoaderStatistics() { VM vm = VM.getVM(); ObjectHeap heap = vm.getObjectHeap(); - Klass classLoaderKlass = vm.getSystemDictionary().getClassLoaderKlass(); + InstanceKlass classLoaderKlass = vm.getSystemDictionary().getClassLoaderKlass(); try { heap.iterateObjectsOfKlass(new DefaultHeapVisitor() { public boolean doObj(Oop oop) { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java index 46e53411deef7..6074b2b32dc16 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 @@ -165,8 +165,12 @@ public int getModifiers() { } public int getAccessFlags() { - HotSpotVMConfig config = config(); - return UNSAFE.getInt(getKlassPointer() + config.klassAccessFlagsOffset); + if (isArray()) { + return 0; // Array Metadata doesn't set access_flags + } else { + HotSpotVMConfig config = config(); + return UNSAFE.getInt(getKlassPointer() + config.instanceKlassAccessFlagsOffset); + } } public int getMiscFlags() { diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java index e4e23c6d8b807..c058f7857152e 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotVMConfig.java @@ -84,7 +84,6 @@ static String getHostArchitectureName() { */ final int javaMirrorOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle"); - final int klassAccessFlagsOffset = getFieldOffset("Klass::_access_flags", Integer.class, "AccessFlags"); final int klassLayoutHelperOffset = getFieldOffset("Klass::_layout_helper", Integer.class, "jint"); final int klassLayoutHelperNeutralValue = getConstant("Klass::_lh_neutral_value", Integer.class); @@ -93,6 +92,7 @@ static String getHostArchitectureName() { final int vtableEntrySize = getFieldValue("CompilerToVM::Data::sizeof_vtableEntry", Integer.class, "int"); final int vtableEntryMethodOffset = getFieldOffset("vtableEntry::_method", Integer.class, "Method*"); + final int instanceKlassAccessFlagsOffset = getFieldOffset("InstanceKlass::_access_flags", Integer.class, "AccessFlags"); final int instanceKlassInitStateOffset = getFieldOffset("InstanceKlass::_init_state", Integer.class, "InstanceKlass::ClassState"); final int instanceKlassConstantsOffset = getFieldOffset("InstanceKlass::_constants", Integer.class, "ConstantPool*"); final int instanceKlassFieldInfoStreamOffset = getFieldOffset("InstanceKlass::_fieldinfo_stream", Integer.class, "Array*");