From f0133fcf7e3e1d847969b11cf43724cf72131279 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 10 Feb 2025 13:30:43 +0000 Subject: [PATCH 01/12] Make isArray non-native --- src/hotspot/share/classfile/vmIntrinsics.cpp | 1 - src/hotspot/share/classfile/vmIntrinsics.hpp | 2 -- src/hotspot/share/opto/c2compiler.cpp | 1 - src/hotspot/share/opto/library_call.cpp | 14 -------------- src/hotspot/share/prims/jvm.cpp | 6 ------ src/java.base/share/classes/java/lang/Class.java | 12 ++++-------- src/java.base/share/native/libjava/Class.c | 1 - 7 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index aaeb54f0d32fe..3690bf0be9175 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -257,7 +257,6 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) { case vmIntrinsics::_isInstance: case vmIntrinsics::_isAssignableFrom: case vmIntrinsics::_isInterface: - case vmIntrinsics::_isArray: case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 16f6ff024d0c6..795e42ad8f697 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -306,8 +306,6 @@ class methodHandle; do_name( isInstance_name, "isInstance") \ do_intrinsic(_isInterface, java_lang_Class, isInterface_name, void_boolean_signature, F_RN) \ do_name( isInterface_name, "isInterface") \ - do_intrinsic(_isArray, java_lang_Class, isArray_name, void_boolean_signature, F_RN) \ - do_name( isArray_name, "isArray") \ do_intrinsic(_isPrimitive, java_lang_Class, isPrimitive_name, void_boolean_signature, F_RN) \ do_name( isPrimitive_name, "isPrimitive") \ do_intrinsic(_isHidden, java_lang_Class, isHidden_name, void_boolean_signature, F_RN) \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index e126697ed05d3..2263efa4d1fc0 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -750,7 +750,6 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_isAssignableFrom: case vmIntrinsics::_isInstance: case vmIntrinsics::_isInterface: - case vmIntrinsics::_isArray: case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 1e503ca6bef0f..404877720ae36 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -516,7 +516,6 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_isInstance: case vmIntrinsics::_isInterface: - case vmIntrinsics::_isArray: case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: @@ -3893,10 +3892,6 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { case vmIntrinsics::_isInterface: prim_return_value = intcon(0); break; - case vmIntrinsics::_isArray: - prim_return_value = intcon(0); - expect_prim = true; // cf. ObjectStreamClass.getClassSignature - break; case vmIntrinsics::_isPrimitive: prim_return_value = intcon(1); expect_prim = true; // obviously @@ -3978,15 +3973,6 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { query_value = intcon(0); break; - case vmIntrinsics::_isArray: - // (To verify this code sequence, check the asserts in JVM_IsArrayClass.) - if (generate_array_guard(kls, region) != nullptr) - // A guard was added. If the guard is taken, it was an array. - phi->add_req(intcon(1)); - // If we fall through, it's a plain class. - query_value = intcon(0); - break; - case vmIntrinsics::_isPrimitive: query_value = intcon(0); // "normal" path produces false break; diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 33d82045b6eae..fa25383c9dbdf 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1259,12 +1259,6 @@ JVM_ENTRY(jobject, JVM_FindScopedValueBindings(JNIEnv *env, jclass cls)) return nullptr; JVM_END -JVM_ENTRY(jboolean, JVM_IsArrayClass(JNIEnv *env, jclass cls)) - Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); - return (k != nullptr) && k->is_array_klass() ? true : false; -JVM_END - - JVM_ENTRY(jboolean, JVM_IsPrimitiveClass(JNIEnv *env, jclass cls)) oop mirror = JNIHandles::resolve_non_null(cls); return (jboolean) java_lang_Class::is_primitive(mirror); diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 4607858faa8c5..23bb763efda85 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -801,8 +801,9 @@ public T newInstance() * {@code false} otherwise. * @since 1.1 */ - @IntrinsicCandidate - public native boolean isArray(); + public boolean isArray() { + return componentType != null; + } /** @@ -1284,12 +1285,7 @@ public Type[] getGenericInterfaces() { * @since 1.1 */ public Class getComponentType() { - // Only return for array types. Storage may be reused for Class for instance types. - if (isArray()) { - return componentType; - } else { - return null; - } + return componentType; } private final Class componentType; diff --git a/src/java.base/share/native/libjava/Class.c b/src/java.base/share/native/libjava/Class.c index 47eedaa59d95f..3ac0079a57813 100644 --- a/src/java.base/share/native/libjava/Class.c +++ b/src/java.base/share/native/libjava/Class.c @@ -57,7 +57,6 @@ static JNINativeMethod methods[] = { {"getSuperclass", "()" CLS, NULL}, {"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces}, {"isInterface", "()Z", (void *)&JVM_IsInterface}, - {"isArray", "()Z", (void *)&JVM_IsArrayClass}, {"isHidden", "()Z", (void *)&JVM_IsHiddenClass}, {"isPrimitive", "()Z", (void *)&JVM_IsPrimitiveClass}, {"getDeclaredFields0","(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields}, From 072f332423b59f96515732f6c6a34f646f52ca2e Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 10 Feb 2025 16:39:59 +0000 Subject: [PATCH 02/12] Make isInterface non-native. --- src/hotspot/share/classfile/vmIntrinsics.cpp | 1 - src/hotspot/share/classfile/vmIntrinsics.hpp | 2 -- src/hotspot/share/opto/c2compiler.cpp | 1 - src/hotspot/share/opto/library_call.cpp | 13 -------- src/hotspot/share/prims/jvm.cpp | 32 ++++++++++--------- .../share/classes/java/lang/Class.java | 5 +-- src/java.base/share/native/libjava/Class.c | 1 - 7 files changed, 20 insertions(+), 35 deletions(-) diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index 3690bf0be9175..5426ebe9d73f3 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -256,7 +256,6 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) { switch (id) { case vmIntrinsics::_isInstance: case vmIntrinsics::_isAssignableFrom: - case vmIntrinsics::_isInterface: case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 795e42ad8f697..1c79cff0399bc 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -304,8 +304,6 @@ class methodHandle; do_name( isAssignableFrom_name, "isAssignableFrom") \ do_intrinsic(_isInstance, java_lang_Class, isInstance_name, object_boolean_signature, F_RN) \ do_name( isInstance_name, "isInstance") \ - do_intrinsic(_isInterface, java_lang_Class, isInterface_name, void_boolean_signature, F_RN) \ - do_name( isInterface_name, "isInterface") \ do_intrinsic(_isPrimitive, java_lang_Class, isPrimitive_name, void_boolean_signature, F_RN) \ do_name( isPrimitive_name, "isPrimitive") \ do_intrinsic(_isHidden, java_lang_Class, isHidden_name, void_boolean_signature, F_RN) \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index 2263efa4d1fc0..807ee8e7e184e 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -749,7 +749,6 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_clone: case vmIntrinsics::_isAssignableFrom: case vmIntrinsics::_isInstance: - case vmIntrinsics::_isInterface: case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 404877720ae36..194ba51551111 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -515,7 +515,6 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_isAssignableFrom: return inline_native_subtype_check(); case vmIntrinsics::_isInstance: - case vmIntrinsics::_isInterface: case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: @@ -3889,9 +3888,6 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { prim_return_value = intcon(0); obj = argument(1); break; - case vmIntrinsics::_isInterface: - prim_return_value = intcon(0); - break; case vmIntrinsics::_isPrimitive: prim_return_value = intcon(1); expect_prim = true; // obviously @@ -3964,15 +3960,6 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { query_value = gen_instanceof(obj, kls, safe_for_replace); break; - case vmIntrinsics::_isInterface: - // (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(intcon(1)); - // If we fall through, it's a plain class. - query_value = intcon(0); - break; - case vmIntrinsics::_isPrimitive: query_value = intcon(0); // "normal" path produces false break; diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index fa25383c9dbdf..08b8f334dd476 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1187,20 +1187,6 @@ JVM_ENTRY(jobjectArray, JVM_GetClassInterfaces(JNIEnv *env, jclass cls)) JVM_END -JVM_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls)) - oop mirror = JNIHandles::resolve_non_null(cls); - if (java_lang_Class::is_primitive(mirror)) { - return JNI_FALSE; - } - Klass* k = java_lang_Class::as_Klass(mirror); - jboolean result = k->is_interface(); - assert(!result || k->is_instance_klass(), - "all interfaces are instance types"); - // The compiler intrinsic for isInterface tests the - // Klass::_access_flags bits in the same way. - return result; -JVM_END - JVM_ENTRY(jboolean, JVM_IsHiddenClass(JNIEnv *env, jclass cls)) oop mirror = JNIHandles::resolve_non_null(cls); if (java_lang_Class::is_primitive(mirror)) { @@ -2299,7 +2285,23 @@ JVM_END // The function returns a Klass* of the _scratch_class if the verifier // was invoked in the middle of the class redefinition. // Otherwise it returns its argument value which is the _the_class Klass*. -// Please, refer to the description in the jvmtiThreadSate.hpp. +// Please, refer to the description in the jvmtiThreadState.hpp. + +JVM_ENTRY(jboolean, JVM_IsInterface(JNIEnv *env, jclass cls)) + oop mirror = JNIHandles::resolve_non_null(cls); + if (java_lang_Class::is_primitive(mirror)) { + return JNI_FALSE; + } + Klass* k = java_lang_Class::as_Klass(mirror); + // This isn't necessary since answer is the same since redefinition + // has already checked this matches for the scratch class. + // k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); + jboolean result = k->is_interface(); + assert(!result || k->is_instance_klass(), + "all interfaces are instance types"); + return result; +JVM_END + JVM_ENTRY(const char*, JVM_GetClassNameUTF(JNIEnv *env, jclass cls)) Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 23bb763efda85..23d066bd55640 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -790,8 +790,9 @@ public T newInstance() * @return {@code true} if this {@code Class} object represents an interface; * {@code false} otherwise. */ - @IntrinsicCandidate - public native boolean isInterface(); + public boolean isInterface() { + return Modifier.isInterface(getModifiers()); + } /** diff --git a/src/java.base/share/native/libjava/Class.c b/src/java.base/share/native/libjava/Class.c index 3ac0079a57813..92b2f1b46e517 100644 --- a/src/java.base/share/native/libjava/Class.c +++ b/src/java.base/share/native/libjava/Class.c @@ -56,7 +56,6 @@ static JNINativeMethod methods[] = { {"initClassName", "()" STR, (void *)&JVM_InitClassName}, {"getSuperclass", "()" CLS, NULL}, {"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces}, - {"isInterface", "()Z", (void *)&JVM_IsInterface}, {"isHidden", "()Z", (void *)&JVM_IsHiddenClass}, {"isPrimitive", "()Z", (void *)&JVM_IsPrimitiveClass}, {"getDeclaredFields0","(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields}, From c0e991900c2f447531ac260b0529f97c85c90d27 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 11 Feb 2025 18:20:48 +0000 Subject: [PATCH 03/12] Remove isPrimitive intrinsic in favor of a boolean. --- src/hotspot/share/c1/c1_Canonicalizer.cpp | 11 ---------- src/hotspot/share/c1/c1_Compiler.cpp | 1 - src/hotspot/share/c1/c1_LIRGenerator.cpp | 20 ------------------- src/hotspot/share/c1/c1_LIRGenerator.hpp | 1 - src/hotspot/share/classfile/javaClasses.cpp | 11 +++++++++- src/hotspot/share/classfile/javaClasses.hpp | 2 ++ .../share/classfile/javaClasses.inline.hpp | 6 ++++-- src/hotspot/share/classfile/vmIntrinsics.cpp | 1 - src/hotspot/share/classfile/vmIntrinsics.hpp | 2 -- src/hotspot/share/opto/c2compiler.cpp | 1 - src/hotspot/share/opto/library_call.cpp | 9 --------- src/hotspot/share/prims/jvm.cpp | 6 ------ .../share/classes/java/lang/Class.java | 9 ++++++--- .../jdk/internal/reflect/Reflection.java | 2 +- src/java.base/share/native/libjava/Class.c | 1 - .../ci/runtime/test/TestResolvedJavaType.java | 10 ++++++---- .../ModuleSetAccessibleTest.java | 2 +- .../TrySetAccessibleTest.java | 2 +- .../reflect/Reflection/Filtering.java | 1 + 19 files changed, 32 insertions(+), 66 deletions(-) diff --git a/src/hotspot/share/c1/c1_Canonicalizer.cpp b/src/hotspot/share/c1/c1_Canonicalizer.cpp index 15b21029b6808..f5a1d14e69431 100644 --- a/src/hotspot/share/c1/c1_Canonicalizer.cpp +++ b/src/hotspot/share/c1/c1_Canonicalizer.cpp @@ -536,17 +536,6 @@ void Canonicalizer::do_Intrinsic (Intrinsic* x) { } break; } - case vmIntrinsics::_isPrimitive : { - assert(x->number_of_arguments() == 1, "wrong type"); - - // Class.isPrimitive is known on constant classes: - InstanceConstant* c = x->argument_at(0)->type()->as_InstanceConstant(); - if (c != nullptr && !c->value()->is_null_object()) { - ciType* t = c->value()->java_mirror_type(); - set_constant(t->is_primitive_type()); - } - break; - } default: break; } diff --git a/src/hotspot/share/c1/c1_Compiler.cpp b/src/hotspot/share/c1/c1_Compiler.cpp index 7d2e6ee75d9ae..1e55b7006dd9a 100644 --- a/src/hotspot/share/c1/c1_Compiler.cpp +++ b/src/hotspot/share/c1/c1_Compiler.cpp @@ -155,7 +155,6 @@ bool Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_longBitsToDouble: case vmIntrinsics::_getClass: case vmIntrinsics::_isInstance: - case vmIntrinsics::_isPrimitive: case vmIntrinsics::_currentCarrierThread: case vmIntrinsics::_currentThread: case vmIntrinsics::_scopedValueCache: diff --git a/src/hotspot/share/c1/c1_LIRGenerator.cpp b/src/hotspot/share/c1/c1_LIRGenerator.cpp index 325b8d193ea2d..959e49749c5e5 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.cpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp @@ -1278,25 +1278,6 @@ void LIRGenerator::do_getClass(Intrinsic* x) { LIR_OprFact::address(new LIR_Address(temp, T_OBJECT)), result); } -// java.lang.Class::isPrimitive() -void LIRGenerator::do_isPrimitive(Intrinsic* x) { - assert(x->number_of_arguments() == 1, "wrong type"); - - LIRItem rcvr(x->argument_at(0), this); - rcvr.load_item(); - LIR_Opr temp = new_register(T_METADATA); - LIR_Opr result = rlock_result(x); - - CodeEmitInfo* info = nullptr; - if (x->needs_null_check()) { - info = state_for(x); - } - - __ move(new LIR_Address(rcvr.result(), java_lang_Class::klass_offset(), T_ADDRESS), temp, info); - __ cmp(lir_cond_notEqual, temp, LIR_OprFact::metadataConst(nullptr)); - __ cmove(lir_cond_notEqual, LIR_OprFact::intConst(0), LIR_OprFact::intConst(1), result, T_BOOLEAN); -} - void LIRGenerator::do_getObjectSize(Intrinsic* x) { assert(x->number_of_arguments() == 3, "wrong type"); LIR_Opr result_reg = rlock_result(x); @@ -2914,7 +2895,6 @@ void LIRGenerator::do_Intrinsic(Intrinsic* x) { case vmIntrinsics::_Object_init: do_RegisterFinalizer(x); break; case vmIntrinsics::_isInstance: do_isInstance(x); break; - case vmIntrinsics::_isPrimitive: do_isPrimitive(x); break; case vmIntrinsics::_getClass: do_getClass(x); break; case vmIntrinsics::_getObjectSize: do_getObjectSize(x); break; case vmIntrinsics::_currentCarrierThread: do_currentCarrierThread(x); break; diff --git a/src/hotspot/share/c1/c1_LIRGenerator.hpp b/src/hotspot/share/c1/c1_LIRGenerator.hpp index 18997e2dd1a72..73bd883a7468e 100644 --- a/src/hotspot/share/c1/c1_LIRGenerator.hpp +++ b/src/hotspot/share/c1/c1_LIRGenerator.hpp @@ -254,7 +254,6 @@ class LIRGenerator: public InstructionVisitor, public BlockClosure { void do_RegisterFinalizer(Intrinsic* x); void do_isInstance(Intrinsic* x); - void do_isPrimitive(Intrinsic* x); void do_getClass(Intrinsic* x); void do_getObjectSize(Intrinsic* x); void do_currentCarrierThread(Intrinsic* x); diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index d6d1f799253cc..73c82ab00ccfc 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -868,6 +868,7 @@ int java_lang_Class::_classData_offset; int java_lang_Class::_classRedefinedCount_offset; int java_lang_Class::_reflectionData_offset; int java_lang_Class::_modifiers_offset; +int java_lang_Class::_is_primitive_offset; bool java_lang_Class::_offsets_computed = false; GrowableArray* java_lang_Class::_fixup_mirror_list = nullptr; @@ -1347,6 +1348,12 @@ void java_lang_Class::set_source_file(oop java_class, oop source_file) { java_class->obj_field_put(_source_file_offset, source_file); } +void java_lang_Class::set_is_primitive(oop java_class) { + assert(_is_primitive_offset != 0, "must be set"); + java_class->bool_field_put(_is_primitive_offset, true); +} + + oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { // This should be improved by adding a field at the Java level or by // introducing a new VM klass (see comment in ClassFileParser) @@ -1361,6 +1368,7 @@ oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, Basic assert(static_oop_field_count(java_class) == 0, "should have been zeroed by allocation"); #endif set_modifiers(java_class, JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC); + set_is_primitive(java_class); return java_class; } @@ -1501,7 +1509,8 @@ oop java_lang_Class::primitive_mirror(BasicType t) { macro(_reflectionData_offset, k, "reflectionData", java_lang_ref_SoftReference_signature, false); \ macro(_signers_offset, k, "signers", object_array_signature, false); \ macro(_modifiers_offset, k, vmSymbols::modifiers_name(), int_signature, false); \ - macro(_protection_domain_offset, k, "protectionDomain", java_security_ProtectionDomain_signature, false); + macro(_protection_domain_offset, k, "protectionDomain", java_security_ProtectionDomain_signature, false); \ + macro(_is_primitive_offset, k, "isPrimitiveType", bool_signature, false); void java_lang_Class::compute_offsets() { if (_offsets_computed) { diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 43b358f6c4642..ee95aa131de84 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -257,6 +257,7 @@ class java_lang_Class : AllStatic { static int _classRedefinedCount_offset; static int _reflectionData_offset; static int _modifiers_offset; + static int _is_primitive_offset; static bool _offsets_computed; @@ -302,6 +303,7 @@ class java_lang_Class : AllStatic { static bool is_instance(oop obj); static bool is_primitive(oop java_class); + static void set_is_primitive(oop java_class); static BasicType primitive_type(oop java_class); static oop primitive_mirror(BasicType t); // JVM_NewArray support diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp index 6a698e02298bf..313e0b0fbd511 100644 --- a/src/hotspot/share/classfile/javaClasses.inline.hpp +++ b/src/hotspot/share/classfile/javaClasses.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -293,10 +293,12 @@ inline Klass* java_lang_Class::as_Klass(oop java_class) { inline bool java_lang_Class::is_primitive(oop java_class) { // should assert: - //assert(java_lang_Class::is_instance(java_class), "must be a Class object"); + // assert(java_lang_Class::is_instance(java_class), "must be a Class object"); bool is_primitive = (java_class->metadata_field(_klass_offset) == nullptr); #ifdef ASSERT + // The heapwalker walks through Classes that have had their Klass pointers removed, so can't assert this. + // assert(is_primitive == java_class->bool_field(_is_primitive_offset), "must match what we told Java"); if (is_primitive) { Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset)); assert(k == nullptr || is_java_primitive(ArrayKlass::cast(k)->element_type()), diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp index 5426ebe9d73f3..2943f9d4af379 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.cpp +++ b/src/hotspot/share/classfile/vmIntrinsics.cpp @@ -256,7 +256,6 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) { switch (id) { case vmIntrinsics::_isInstance: case vmIntrinsics::_isAssignableFrom: - case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_Class_cast: diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp index 1c79cff0399bc..8262472481117 100644 --- a/src/hotspot/share/classfile/vmIntrinsics.hpp +++ b/src/hotspot/share/classfile/vmIntrinsics.hpp @@ -304,8 +304,6 @@ class methodHandle; do_name( isAssignableFrom_name, "isAssignableFrom") \ do_intrinsic(_isInstance, java_lang_Class, isInstance_name, object_boolean_signature, F_RN) \ do_name( isInstance_name, "isInstance") \ - do_intrinsic(_isPrimitive, java_lang_Class, isPrimitive_name, void_boolean_signature, F_RN) \ - do_name( isPrimitive_name, "isPrimitive") \ do_intrinsic(_isHidden, java_lang_Class, isHidden_name, void_boolean_signature, F_RN) \ do_name( isHidden_name, "isHidden") \ do_intrinsic(_getSuperclass, java_lang_Class, getSuperclass_name, void_class_signature, F_RN) \ diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp index 807ee8e7e184e..0d0cb73d8470e 100644 --- a/src/hotspot/share/opto/c2compiler.cpp +++ b/src/hotspot/share/opto/c2compiler.cpp @@ -749,7 +749,6 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) { case vmIntrinsics::_clone: case vmIntrinsics::_isAssignableFrom: case vmIntrinsics::_isInstance: - case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_getClassAccessFlags: diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 194ba51551111..3b5fbde24a5c3 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -515,7 +515,6 @@ bool LibraryCallKit::try_to_inline(int predicate) { case vmIntrinsics::_isAssignableFrom: return inline_native_subtype_check(); case vmIntrinsics::_isInstance: - case vmIntrinsics::_isPrimitive: case vmIntrinsics::_isHidden: case vmIntrinsics::_getSuperclass: case vmIntrinsics::_getClassAccessFlags: return inline_native_Class_query(intrinsic_id()); @@ -3888,10 +3887,6 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { prim_return_value = intcon(0); obj = argument(1); break; - case vmIntrinsics::_isPrimitive: - prim_return_value = intcon(1); - expect_prim = true; // obviously - break; case vmIntrinsics::_isHidden: prim_return_value = intcon(0); break; @@ -3960,10 +3955,6 @@ bool LibraryCallKit::inline_native_Class_query(vmIntrinsics::ID id) { query_value = gen_instanceof(obj, kls, safe_for_replace); break; - case vmIntrinsics::_isPrimitive: - query_value = intcon(0); // "normal" path produces false - break; - case vmIntrinsics::_isHidden: // (To verify this code sequence, check the asserts in JVM_IsHiddenClass.) if (generate_hidden_class_guard(kls, region) != nullptr) diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 08b8f334dd476..ccb15485b07e5 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1245,12 +1245,6 @@ JVM_ENTRY(jobject, JVM_FindScopedValueBindings(JNIEnv *env, jclass cls)) return nullptr; JVM_END -JVM_ENTRY(jboolean, JVM_IsPrimitiveClass(JNIEnv *env, jclass cls)) - oop mirror = JNIHandles::resolve_non_null(cls); - return (jboolean) java_lang_Class::is_primitive(mirror); -JVM_END - - JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)) JvmtiVMObjectAllocEventCollector oam; // ofClass is a reference to a java_lang_Class object. The mirror object diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 23d066bd55640..bb77a47cce328 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -236,13 +236,14 @@ private static void runtimeSetup() { * This constructor is not used and prevents the default constructor being * generated. */ - private Class(ClassLoader loader, Class arrayComponentType, int mods, ProtectionDomain pd) { + private Class(ClassLoader loader, Class arrayComponentType, int mods, ProtectionDomain pd, boolean primitive) { // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. classLoader = loader; componentType = arrayComponentType; modifiers = mods; protectionDomain = pd; + isPrimitiveType = primitive; } /** @@ -845,8 +846,9 @@ public boolean isArray() { * @since 1.1 * @jls 15.8.2 Class Literals */ - @IntrinsicCandidate - public native boolean isPrimitive(); + public boolean isPrimitive() { + return isPrimitiveType; + } /** * Returns true if this {@code Class} object represents an annotation @@ -1005,6 +1007,7 @@ public Module getModule() { private transient Object classData; // Set by VM private transient Object[] signers; // Read by VM, mutable private final transient int modifiers; // Set by the VM + private final transient boolean isPrimitiveType; // Set by the VM // package-private Object getClassData() { diff --git a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java index e1fe26684c82f..60346c697fc8b 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java @@ -56,7 +56,7 @@ public class Reflection { fieldFilterMap = Map.of( Reflection.class, ALL_MEMBERS, AccessibleObject.class, ALL_MEMBERS, - Class.class, Set.of("classLoader", "classData", "modifiers", "protectionDomain"), + Class.class, Set.of("classLoader", "classData", "modifiers", "protectionDomain", "isPrimitiveType"), ClassLoader.class, ALL_MEMBERS, Constructor.class, ALL_MEMBERS, Field.class, ALL_MEMBERS, diff --git a/src/java.base/share/native/libjava/Class.c b/src/java.base/share/native/libjava/Class.c index 92b2f1b46e517..3ab3e764bff8d 100644 --- a/src/java.base/share/native/libjava/Class.c +++ b/src/java.base/share/native/libjava/Class.c @@ -57,7 +57,6 @@ static JNINativeMethod methods[] = { {"getSuperclass", "()" CLS, NULL}, {"getInterfaces0", "()[" CLS, (void *)&JVM_GetClassInterfaces}, {"isHidden", "()Z", (void *)&JVM_IsHiddenClass}, - {"isPrimitive", "()Z", (void *)&JVM_IsPrimitiveClass}, {"getDeclaredFields0","(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields}, {"getDeclaredMethods0","(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods}, {"getDeclaredConstructors0","(Z)[" CTR, (void *)&JVM_GetClassDeclaredConstructors}, diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index 6450f9e1e2968..04fcfc7c18de1 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -929,10 +929,12 @@ private static boolean isHiddenFromReflection(ResolvedJavaField f) { return true; } if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Class.class))) { - return f.getName().equals("classLoader") || - f.getName().equals("classData") || - f.getName().equals("modifiers") || - f.getName().equals("protectionDomain"); + String name = f.getName(); + return name.equals("classLoader") || + name.equals("classData") || + name.equals("modifiers") || + name.equals("protectionDomain" || + name.equals("isPrimitiveType"); } if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Lookup.class))) { return f.getName().equals("allowedModes") || f.getName().equals("lookupClass"); diff --git a/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java b/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java index 08db3265c94a1..3be39fd8f753e 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java @@ -148,7 +148,7 @@ public void testJavaLangClass() throws Exception { // non-public constructor Constructor ctor - = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, int.class, ProtectionDomain.class); + = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, int.class, ProtectionDomain.class, boolean.class); AccessibleObject[] ctors = { ctor }; try { diff --git a/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java b/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java index d08798c8757b3..4689423203b85 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java @@ -194,7 +194,7 @@ public void testJavaLangClass() throws Exception { // non-public constructor Constructor ctor - = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, int.class, ProtectionDomain.class); + = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, int.class, ProtectionDomain.class, boolean.class); AccessibleObject[] ctors = { ctor }; assertFalse(ctor.trySetAccessible()); diff --git a/test/jdk/jdk/internal/reflect/Reflection/Filtering.java b/test/jdk/jdk/internal/reflect/Reflection/Filtering.java index c399b8ff42da3..855b6207a35df 100644 --- a/test/jdk/jdk/internal/reflect/Reflection/Filtering.java +++ b/test/jdk/jdk/internal/reflect/Reflection/Filtering.java @@ -57,6 +57,7 @@ private Object[][] sensitiveFields() { { Class.class, "classData" }, { Class.class, "modifiers" }, { Class.class, "protectionDomain" }, + { Class.class, "isPrimitiveType" }, { ClassLoader.class, "parent" }, { Field.class, "clazz" }, { Field.class, "modifiers" }, From e8119a25cd557b141caf1f0d01fe4d819dce4d81 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 11 Feb 2025 18:58:51 +0000 Subject: [PATCH 04/12] Shrink modifiers flag so isPrimitive can share word. --- src/hotspot/share/classfile/javaClasses.cpp | 10 +++++----- src/hotspot/share/classfile/javaClasses.hpp | 2 +- src/java.base/share/classes/java/lang/Class.java | 4 ++-- .../AccessibleObject/ModuleSetAccessibleTest.java | 2 +- .../reflect/AccessibleObject/TrySetAccessibleTest.java | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 73c82ab00ccfc..7dd7a061e2821 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1063,7 +1063,7 @@ void java_lang_Class::allocate_mirror(Klass* k, bool is_scratch, Handle protecti set_klass(mirror(), k); // Set the modifiers flag. - int computed_modifiers = k->compute_modifier_flags(); + u2 computed_modifiers = k->compute_modifier_flags(); set_modifiers(mirror(), computed_modifiers); InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass()); @@ -1508,7 +1508,7 @@ oop java_lang_Class::primitive_mirror(BasicType t) { macro(_classData_offset, k, "classData", object_signature, false); \ macro(_reflectionData_offset, k, "reflectionData", java_lang_ref_SoftReference_signature, false); \ macro(_signers_offset, k, "signers", object_array_signature, false); \ - macro(_modifiers_offset, k, vmSymbols::modifiers_name(), int_signature, false); \ + macro(_modifiers_offset, k, vmSymbols::modifiers_name(), char_signature, false); \ macro(_protection_domain_offset, k, "protectionDomain", java_security_ProtectionDomain_signature, false); \ macro(_is_primitive_offset, k, "isPrimitiveType", bool_signature, false); @@ -1546,12 +1546,12 @@ void java_lang_Class::set_classRedefinedCount(oop the_class_mirror, int value) { int java_lang_Class::modifiers(oop the_class_mirror) { assert(_modifiers_offset != 0, "offsets should have been initialized"); - return the_class_mirror->int_field(_modifiers_offset); + return the_class_mirror->char_field(_modifiers_offset); } -void java_lang_Class::set_modifiers(oop the_class_mirror, int value) { +void java_lang_Class::set_modifiers(oop the_class_mirror, u2 value) { assert(_modifiers_offset != 0, "offsets should have been initialized"); - the_class_mirror->int_field_put(_modifiers_offset, value); + the_class_mirror->char_field_put(_modifiers_offset, value); } diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index ee95aa131de84..37ca22e92957b 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -340,7 +340,7 @@ class java_lang_Class : AllStatic { static void set_source_file(oop java_class, oop source_file); static int modifiers(oop java_class); - static void set_modifiers(oop java_class, int value); + static void set_modifiers(oop java_class, u2 value); static size_t oop_size(oop java_class); static void set_oop_size(HeapWord* java_class, size_t size); diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index bb77a47cce328..adee97875dc39 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -236,7 +236,7 @@ private static void runtimeSetup() { * This constructor is not used and prevents the default constructor being * generated. */ - private Class(ClassLoader loader, Class arrayComponentType, int mods, ProtectionDomain pd, boolean primitive) { + private Class(ClassLoader loader, Class arrayComponentType, char mods, ProtectionDomain pd, boolean primitive) { // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. classLoader = loader; @@ -1006,7 +1006,7 @@ public Module getModule() { private transient Object classData; // Set by VM private transient Object[] signers; // Read by VM, mutable - private final transient int modifiers; // Set by the VM + private final transient char modifiers; // Set by the VM private final transient boolean isPrimitiveType; // Set by the VM // package-private diff --git a/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java b/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java index 3be39fd8f753e..8ee5179ea818e 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java @@ -148,7 +148,7 @@ public void testJavaLangClass() throws Exception { // non-public constructor Constructor ctor - = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, int.class, ProtectionDomain.class, boolean.class); + = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, char.class, ProtectionDomain.class, boolean.class); AccessibleObject[] ctors = { ctor }; try { diff --git a/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java b/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java index 4689423203b85..9574afee40729 100644 --- a/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java +++ b/test/jdk/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java @@ -194,7 +194,7 @@ public void testJavaLangClass() throws Exception { // non-public constructor Constructor ctor - = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, int.class, ProtectionDomain.class, boolean.class); + = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class, char.class, ProtectionDomain.class, boolean.class); AccessibleObject[] ctors = { ctor }; assertFalse(ctor.trySetAccessible()); From 2d9b9ff529408b7e6c8c1178c30e4e5f9d163ace Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 18 Feb 2025 18:51:59 +0000 Subject: [PATCH 05/12] Add ')' removed from jvmci test. --- .../src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index 04fcfc7c18de1..6e702ea7baf69 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -933,7 +933,7 @@ private static boolean isHiddenFromReflection(ResolvedJavaField f) { return name.equals("classLoader") || name.equals("classData") || name.equals("modifiers") || - name.equals("protectionDomain" || + name.equals("protectionDomain") || name.equals("isPrimitiveType"); } if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Lookup.class))) { From 3e731b9f91be598ae173e6af9523e97dbc658b77 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 19 Feb 2025 18:37:10 +0000 Subject: [PATCH 06/12] Code review comments. --- src/hotspot/share/classfile/javaClasses.cpp | 10 ++++++---- src/hotspot/share/classfile/javaClasses.inline.hpp | 2 +- src/hotspot/share/include/jvm.h | 9 --------- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 7dd7a061e2821..d6434950eab26 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1273,8 +1273,11 @@ void java_lang_Class::set_protection_domain(oop java_class, oop pd) { void java_lang_Class::set_component_mirror(oop java_class, oop comp_mirror) { assert(_component_mirror_offset != 0, "must be set"); - java_class->obj_field_put(_component_mirror_offset, comp_mirror); - } + assert(java_lang_Class::as_Klass(java_class) != nullptr && + java_lang_Class::as_Klass(java_class)->is_array_klass(), "must be"); + java_class->obj_field_put(_component_mirror_offset, comp_mirror); +} + oop java_lang_Class::component_mirror(oop java_class) { assert(_component_mirror_offset != 0, "must be set"); return java_class->obj_field(_component_mirror_offset); @@ -1355,8 +1358,7 @@ void java_lang_Class::set_is_primitive(oop java_class) { oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { - // This should be improved by adding a field at the Java level or by - // introducing a new VM klass (see comment in ClassFileParser) + // Mirrors for basic types have a null klass field, which makes them special. oop java_class = InstanceMirrorKlass::cast(vmClasses::Class_klass())->allocate_instance(nullptr, CHECK_NULL); if (type != T_VOID) { Klass* aklass = Universe::typeArrayKlass(type); diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp index 313e0b0fbd511..66ecca4bbeaa4 100644 --- a/src/hotspot/share/classfile/javaClasses.inline.hpp +++ b/src/hotspot/share/classfile/javaClasses.inline.hpp @@ -299,7 +299,7 @@ inline bool java_lang_Class::is_primitive(oop java_class) { #ifdef ASSERT // The heapwalker walks through Classes that have had their Klass pointers removed, so can't assert this. // assert(is_primitive == java_class->bool_field(_is_primitive_offset), "must match what we told Java"); - if (is_primitive) { + if (java_class->bool_field(_is_primitive_offset)) { Klass* k = ((Klass*)java_class->metadata_field(_array_klass_offset)); assert(k == nullptr || is_java_primitive(ArrayKlass::cast(k)->element_type()), "Should be either the T_VOID primitive or a java primitive"); diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index c2a1a3f53f6ca..c2370ce76c04a 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -546,15 +546,6 @@ JVM_GetClassInterfaces(JNIEnv *env, jclass cls); JNIEXPORT jboolean JNICALL JVM_IsInterface(JNIEnv *env, jclass cls); -JNIEXPORT jobject JNICALL -JVM_GetProtectionDomain(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsArrayClass(JNIEnv *env, jclass cls); - -JNIEXPORT jboolean JNICALL -JVM_IsPrimitiveClass(JNIEnv *env, jclass cls); - JNIEXPORT jboolean JNICALL JVM_IsHiddenClass(JNIEnv *env, jclass cls); From d08091ac6a62c86a68392e977642bcdd21d889de Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Wed, 19 Feb 2025 20:27:38 +0000 Subject: [PATCH 07/12] Rename isPrimitiveType field to primitive. --- src/hotspot/share/classfile/javaClasses.cpp | 2 +- src/java.base/share/classes/java/lang/Class.java | 12 +++++++----- .../classes/jdk/internal/reflect/Reflection.java | 2 +- .../jdk/vm/ci/runtime/test/TestResolvedJavaType.java | 2 +- .../jdk/internal/reflect/Reflection/Filtering.java | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index d6434950eab26..a224ef481b025 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1512,7 +1512,7 @@ oop java_lang_Class::primitive_mirror(BasicType t) { macro(_signers_offset, k, "signers", object_array_signature, false); \ macro(_modifiers_offset, k, vmSymbols::modifiers_name(), char_signature, false); \ macro(_protection_domain_offset, k, "protectionDomain", java_security_ProtectionDomain_signature, false); \ - macro(_is_primitive_offset, k, "isPrimitiveType", bool_signature, false); + macro(_is_primitive_offset, k, "primitive", bool_signature, false); void java_lang_Class::compute_offsets() { if (_offsets_computed) { diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index adee97875dc39..98b1cf573e508 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -236,14 +236,14 @@ private static void runtimeSetup() { * This constructor is not used and prevents the default constructor being * generated. */ - private Class(ClassLoader loader, Class arrayComponentType, char mods, ProtectionDomain pd, boolean primitive) { + private Class(ClassLoader loader, Class arrayComponentType, char mods, ProtectionDomain pd, boolean isPrim) { // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. classLoader = loader; componentType = arrayComponentType; modifiers = mods; protectionDomain = pd; - isPrimitiveType = primitive; + primitive = isPrim; } /** @@ -847,7 +847,7 @@ public boolean isArray() { * @jls 15.8.2 Class Literals */ public boolean isPrimitive() { - return isPrimitiveType; + return primitive; } /** @@ -1007,7 +1007,7 @@ public Module getModule() { private transient Object classData; // Set by VM private transient Object[] signers; // Read by VM, mutable private final transient char modifiers; // Set by the VM - private final transient boolean isPrimitiveType; // Set by the VM + private final transient boolean primitive; // Set by the VM if the Class is a primitive type. // package-private Object getClassData() { @@ -1292,7 +1292,9 @@ public Class getComponentType() { return componentType; } - private final Class componentType; + // The componentType field's null value is the sole indication that the class is an array, + // see isArray(). + private transient final Class componentType; /* * Returns the {@code Class} representing the element type of an array class. diff --git a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java index 60346c697fc8b..5025b81dd10ed 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java @@ -56,7 +56,7 @@ public class Reflection { fieldFilterMap = Map.of( Reflection.class, ALL_MEMBERS, AccessibleObject.class, ALL_MEMBERS, - Class.class, Set.of("classLoader", "classData", "modifiers", "protectionDomain", "isPrimitiveType"), + Class.class, Set.of("classLoader", "classData", "modifiers", "protectionDomain", "primitive"), ClassLoader.class, ALL_MEMBERS, Constructor.class, ALL_MEMBERS, Field.class, ALL_MEMBERS, diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index 6e702ea7baf69..52b52cf647fce 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -934,7 +934,7 @@ private static boolean isHiddenFromReflection(ResolvedJavaField f) { name.equals("classData") || name.equals("modifiers") || name.equals("protectionDomain") || - name.equals("isPrimitiveType"); + name.equals("primitive"); } if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Lookup.class))) { return f.getName().equals("allowedModes") || f.getName().equals("lookupClass"); diff --git a/test/jdk/jdk/internal/reflect/Reflection/Filtering.java b/test/jdk/jdk/internal/reflect/Reflection/Filtering.java index 855b6207a35df..88d7e23ba5962 100644 --- a/test/jdk/jdk/internal/reflect/Reflection/Filtering.java +++ b/test/jdk/jdk/internal/reflect/Reflection/Filtering.java @@ -57,7 +57,7 @@ private Object[][] sensitiveFields() { { Class.class, "classData" }, { Class.class, "modifiers" }, { Class.class, "protectionDomain" }, - { Class.class, "isPrimitiveType" }, + { Class.class, "primitive" }, { ClassLoader.class, "parent" }, { Field.class, "clazz" }, { Field.class, "modifiers" }, From 7a4c595bd90f5aab7d1a8ae51d7a29738fa4d6e1 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 20 Feb 2025 15:08:12 -0500 Subject: [PATCH 08/12] Update src/java.base/share/classes/java/lang/Class.java Co-authored-by: David Holmes <62092539+dholmes-ora@users.noreply.github.com> --- src/java.base/share/classes/java/lang/Class.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 98b1cf573e508..f001fed0a2f3f 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -1292,8 +1292,8 @@ public Class getComponentType() { return componentType; } - // The componentType field's null value is the sole indication that the class is an array, - // see isArray(). + // The componentType field's null value is the sole indication that the class + // is an array - see isArray(). private transient final Class componentType; /* From 023474335db306180d6dd19de963c821f65354ca Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Thu, 20 Feb 2025 20:15:42 +0000 Subject: [PATCH 09/12] Fix whitespace --- src/java.base/share/classes/java/lang/Class.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index f001fed0a2f3f..a179687192b56 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -1292,7 +1292,7 @@ public Class getComponentType() { return componentType; } - // The componentType field's null value is the sole indication that the class + // The componentType field's null value is the sole indication that the class // is an array - see isArray(). private transient final Class componentType; From c23718b330407db15b8a1ca0dc2fe96a2741d52f Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Fri, 21 Feb 2025 12:24:19 +0000 Subject: [PATCH 10/12] Remove JVM_GetClassModifiers from jvm.h too. --- src/hotspot/share/include/jvm.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index c2370ce76c04a..c1d20387d0db9 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -549,9 +549,6 @@ JVM_IsInterface(JNIEnv *env, jclass cls); JNIEXPORT jboolean JNICALL JVM_IsHiddenClass(JNIEnv *env, jclass cls); -JNIEXPORT jint JNICALL -JVM_GetClassModifiers(JNIEnv *env, jclass cls); - JNIEXPORT jobjectArray JNICALL JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass); From db7c9782ea8beeb55528a97ec7d8fb4adff320c2 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Sat, 22 Feb 2025 14:46:18 +0000 Subject: [PATCH 11/12] Use modifiers field directly in isInterface. --- src/java.base/share/classes/java/lang/Class.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index a179687192b56..9f6d47023a7a7 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -792,7 +792,7 @@ public T newInstance() * {@code false} otherwise. */ public boolean isInterface() { - return Modifier.isInterface(getModifiers()); + return Modifier.isInterface(modifiers); } From 591abdda6920617fa19aa4dc1106c32878b100f1 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Mon, 24 Feb 2025 19:26:36 +0000 Subject: [PATCH 12/12] Add a comment about Class constructor. --- src/java.base/share/classes/java/lang/Class.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 9f6d47023a7a7..d86baaac3621a 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -239,6 +239,7 @@ private static void runtimeSetup() { private Class(ClassLoader loader, Class arrayComponentType, char mods, ProtectionDomain pd, boolean isPrim) { // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. + // The following assignments are done directly by the VM without calling this constructor. classLoader = loader; componentType = arrayComponentType; modifiers = mods;