Skip to content
Open
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
4 changes: 4 additions & 0 deletions src/hotspot/share/ci/ciInstanceKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
9 changes: 0 additions & 9 deletions src/hotspot/share/ci/ciKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
3 changes: 0 additions & 3 deletions src/hotspot/share/ci/ciKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/classfile/defaultMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
3 changes: 1 addition & 2 deletions src/hotspot/share/classfile/javaClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
7 changes: 4 additions & 3 deletions src/hotspot/share/classfile/systemDictionary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/jvmci/vmStructs_jvmci.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*) \
Expand Down Expand Up @@ -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) \
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/oops/arrayKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/oops/fieldInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "memory/allocation.hpp"
#include "oops/typeArrayOop.hpp"
#include "utilities/accessFlags.hpp"
#include "utilities/unsigned5.hpp"
#include "utilities/vmEnums.hpp"

Expand Down
11 changes: 11 additions & 0 deletions src/hotspot/share/oops/instanceKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Method*>* methods) {
if (methods != nullptr && methods != Universe::the_empty_method_array() &&
Expand Down
20 changes: 19 additions & 1 deletion src/hotspot/share/oops/instanceKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(); }
Expand Down
11 changes: 0 additions & 11 deletions src/hotspot/share/oops/klass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
24 changes: 7 additions & 17 deletions src/hotspot/share/oops/klass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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); }
Expand Down Expand Up @@ -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(); }
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1726,7 +1726,7 @@ 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()))
if (flat->isa_instklassptr() && flat->offset() == in_bytes(InstanceKlass::access_flags_offset()))
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd place the check separately. Otherwise, looks good.

diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index 6babc13e1b3..9215c0fc03f 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,11 @@ 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.)

alias_type(idx)->set_rewritable(false);
if (flat->offset() == in_bytes(Klass::misc_flags_offset()))
alias_type(idx)->set_rewritable(false);
Expand Down
8 changes: 4 additions & 4 deletions src/hotspot/share/opto/library_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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));
Expand Down
8 changes: 5 additions & 3 deletions src/hotspot/share/opto/memnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/runtime/vmStructs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
nonstatic_field(InstanceKlass, _annotations, Annotations*) \
nonstatic_field(InstanceKlass, _method_ordering, Array<int>*) \
nonstatic_field(InstanceKlass, _default_vtable_indices, Array<int>*) \
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<Klass*>*) \
Expand All @@ -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) \
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/utilities/accessFlags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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");
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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");
}
Expand All @@ -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 {
Expand All @@ -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);
}

/*
Expand Down
Loading