8247296: Optimize JVM_GetDeclaringClass

Co-authored-by: Christoph Dreis <christoph.dreis@freenet.de>
Reviewed-by: shade, minqi
This commit is contained in:
David Holmes 2020-07-26 20:29:42 -04:00
parent 112bbcb396
commit 3dba35d248
2 changed files with 56 additions and 40 deletions

View file

@ -1171,11 +1171,12 @@ static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str); THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
} }
Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)); oop mirror = JNIHandles::resolve_non_null(clazz);
Klass* klass = java_lang_Class::as_Klass(mirror);
// Throw a NoSuchMethodError exception if we have an instance of a // Throw a NoSuchMethodError exception if we have an instance of a
// primitive java.lang.Class // primitive java.lang.Class
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) { if (java_lang_Class::is_primitive(mirror)) {
ResourceMark rm; ResourceMark rm;
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), err_msg("%s%s.%s%s", is_static ? "static " : "", klass->signature_name(), name_str, sig)); THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), err_msg("%s%s.%s%s", is_static ? "static " : "", klass->signature_name(), name_str, sig));
} }

View file

@ -1304,12 +1304,13 @@ JVM_END
JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls)) JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))
JVMWrapper("JVM_GetClassSigners"); JVMWrapper("JVM_GetClassSigners");
JvmtiVMObjectAllocEventCollector oam; JvmtiVMObjectAllocEventCollector oam;
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { oop mirror = JNIHandles::resolve_non_null(cls);
if (java_lang_Class::is_primitive(mirror)) {
// There are no signers for primitive types // There are no signers for primitive types
return NULL; return NULL;
} }
objArrayHandle signers(THREAD, java_lang_Class::signers(JNIHandles::resolve_non_null(cls))); objArrayHandle signers(THREAD, java_lang_Class::signers(mirror));
// If there are no signers set in the class, or if the class // If there are no signers set in the class, or if the class
// is an array, return NULL. // is an array, return NULL.
@ -1329,11 +1330,12 @@ JVM_END
JVM_ENTRY(void, JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)) JVM_ENTRY(void, JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers))
JVMWrapper("JVM_SetClassSigners"); JVMWrapper("JVM_SetClassSigners");
if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { oop mirror = JNIHandles::resolve_non_null(cls);
if (!java_lang_Class::is_primitive(mirror)) {
// This call is ignored for primitive types and arrays. // This call is ignored for primitive types and arrays.
// Signers are only set once, ClassLoader.java, and thus shouldn't // Signers are only set once, ClassLoader.java, and thus shouldn't
// be called with an array. Only the bootstrap loader creates arrays. // be called with an array. Only the bootstrap loader creates arrays.
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); Klass* k = java_lang_Class::as_Klass(mirror);
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers))); java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers)));
} }
@ -1343,16 +1345,17 @@ JVM_END
JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls)) JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))
JVMWrapper("JVM_GetProtectionDomain"); JVMWrapper("JVM_GetProtectionDomain");
if (JNIHandles::resolve(cls) == NULL) { oop mirror = JNIHandles::resolve_non_null(cls);
if (mirror == NULL) {
THROW_(vmSymbols::java_lang_NullPointerException(), NULL); THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
} }
if (java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { if (java_lang_Class::is_primitive(mirror)) {
// Primitive types does not have a protection domain. // Primitive types does not have a protection domain.
return NULL; return NULL;
} }
oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls)); oop pd = java_lang_Class::protection_domain(mirror);
return (jobject) JNIHandles::make_local(THREAD, pd); return (jobject) JNIHandles::make_local(THREAD, pd);
JVM_END JVM_END
@ -1474,12 +1477,13 @@ JVM_END
JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls)) JVM_ENTRY(jint, JVM_GetClassModifiers(JNIEnv *env, jclass cls))
JVMWrapper("JVM_GetClassModifiers"); JVMWrapper("JVM_GetClassModifiers");
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { oop mirror = JNIHandles::resolve_non_null(cls);
if (java_lang_Class::is_primitive(mirror)) {
// Primitive type // Primitive type
return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;
} }
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); Klass* k = java_lang_Class::as_Klass(mirror);
debug_only(int computed_modifiers = k->compute_modifier_flags(CHECK_0)); debug_only(int computed_modifiers = k->compute_modifier_flags(CHECK_0));
assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK"); assert(k->modifier_flags() == computed_modifiers, "modifiers cache is OK");
return k->modifier_flags(); return k->modifier_flags();
@ -1492,14 +1496,14 @@ JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))
JvmtiVMObjectAllocEventCollector oam; JvmtiVMObjectAllocEventCollector oam;
// ofClass is a reference to a java_lang_Class object. The mirror object // ofClass is a reference to a java_lang_Class object. The mirror object
// of an InstanceKlass // of an InstanceKlass
oop ofMirror = JNIHandles::resolve_non_null(ofClass);
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || if (java_lang_Class::is_primitive(ofMirror) ||
! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_instance_klass()) { ! java_lang_Class::as_Klass(ofMirror)->is_instance_klass()) {
oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL); oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);
return (jobjectArray)JNIHandles::make_local(THREAD, result); return (jobjectArray)JNIHandles::make_local(THREAD, result);
} }
InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror));
InnerClassesIterator iter(k); InnerClassesIterator iter(k);
if (iter.length() == 0) { if (iter.length() == 0) {
@ -1557,15 +1561,18 @@ JVM_END
JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass)) JVM_ENTRY(jclass, JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass))
{ {
// ofClass is a reference to a java_lang_Class object. // ofClass is a reference to a java_lang_Class object.
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || oop ofMirror = JNIHandles::resolve_non_null(ofClass);
! java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_instance_klass()) { if (java_lang_Class::is_primitive(ofMirror)) {
return NULL;
}
Klass* klass = java_lang_Class::as_Klass(ofMirror);
if (!klass->is_instance_klass()) {
return NULL; return NULL;
} }
bool inner_is_member = false; bool inner_is_member = false;
Klass* outer_klass Klass* outer_klass
= InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass)) = InstanceKlass::cast(klass)->compute_enclosing_class(&inner_is_member, CHECK_NULL);
)->compute_enclosing_class(&inner_is_member, CHECK_NULL);
if (outer_klass == NULL) return NULL; // already a top-level class if (outer_klass == NULL) return NULL; // already a top-level class
if (!inner_is_member) return NULL; // a hidden or unsafe anonymous class (inside a method) if (!inner_is_member) return NULL; // a hidden or unsafe anonymous class (inside a method)
return (jclass) JNIHandles::make_local(THREAD, outer_klass->java_mirror()); return (jclass) JNIHandles::make_local(THREAD, outer_klass->java_mirror());
@ -1575,11 +1582,14 @@ JVM_END
JVM_ENTRY(jstring, JVM_GetSimpleBinaryName(JNIEnv *env, jclass cls)) JVM_ENTRY(jstring, JVM_GetSimpleBinaryName(JNIEnv *env, jclass cls))
{ {
oop mirror = JNIHandles::resolve_non_null(cls); oop mirror = JNIHandles::resolve_non_null(cls);
if (java_lang_Class::is_primitive(mirror) || if (java_lang_Class::is_primitive(mirror)) {
!java_lang_Class::as_Klass(mirror)->is_instance_klass()) {
return NULL; return NULL;
} }
InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(mirror)); Klass* klass = java_lang_Class::as_Klass(mirror);
if (!klass->is_instance_klass()) {
return NULL;
}
InstanceKlass* k = InstanceKlass::cast(klass);
int ooff = 0, noff = 0; int ooff = 0, noff = 0;
if (k->find_inner_classes_attr(&ooff, &noff, THREAD)) { if (k->find_inner_classes_attr(&ooff, &noff, THREAD)) {
if (noff != 0) { if (noff != 0) {
@ -1598,9 +1608,10 @@ JVM_ENTRY(jstring, JVM_GetClassSignature(JNIEnv *env, jclass cls))
JVMWrapper("JVM_GetClassSignature"); JVMWrapper("JVM_GetClassSignature");
JvmtiVMObjectAllocEventCollector oam; JvmtiVMObjectAllocEventCollector oam;
ResourceMark rm(THREAD); ResourceMark rm(THREAD);
oop mirror = JNIHandles::resolve_non_null(cls);
// Return null for arrays and primatives // Return null for arrays and primatives
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { if (!java_lang_Class::is_primitive(mirror)) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); Klass* k = java_lang_Class::as_Klass(mirror);
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
Symbol* sym = InstanceKlass::cast(k)->generic_signature(); Symbol* sym = InstanceKlass::cast(k)->generic_signature();
if (sym == NULL) return NULL; if (sym == NULL) return NULL;
@ -1615,10 +1626,10 @@ JVM_END
JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls)) JVM_ENTRY(jbyteArray, JVM_GetClassAnnotations(JNIEnv *env, jclass cls))
assert (cls != NULL, "illegal class"); assert (cls != NULL, "illegal class");
JVMWrapper("JVM_GetClassAnnotations"); JVMWrapper("JVM_GetClassAnnotations");
oop mirror = JNIHandles::resolve_non_null(cls);
// Return null for arrays and primitives // Return null for arrays and primitives
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { if (!java_lang_Class::is_primitive(mirror)) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); Klass* k = java_lang_Class::as_Klass(mirror);
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->class_annotations(), CHECK_NULL); typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->class_annotations(), CHECK_NULL);
return (jbyteArray) JNIHandles::make_local(THREAD, a); return (jbyteArray) JNIHandles::make_local(THREAD, a);
@ -1797,15 +1808,16 @@ JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass,
JVMWrapper("JVM_GetClassDeclaredFields"); JVMWrapper("JVM_GetClassDeclaredFields");
JvmtiVMObjectAllocEventCollector oam; JvmtiVMObjectAllocEventCollector oam;
oop ofMirror = JNIHandles::resolve_non_null(ofClass);
// Exclude primitive types and array types // Exclude primitive types and array types
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) || if (java_lang_Class::is_primitive(ofMirror) ||
java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_array_klass()) { java_lang_Class::as_Klass(ofMirror)->is_array_klass()) {
// Return empty array // Return empty array
oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL); oop res = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), 0, CHECK_NULL);
return (jobjectArray) JNIHandles::make_local(THREAD, res); return (jobjectArray) JNIHandles::make_local(THREAD, res);
} }
InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror));
constantPoolHandle cp(THREAD, k->constants()); constantPoolHandle cp(THREAD, k->constants());
// Ensure class is linked // Ensure class is linked
@ -1905,15 +1917,16 @@ static jobjectArray get_class_declared_methods_helper(
JvmtiVMObjectAllocEventCollector oam; JvmtiVMObjectAllocEventCollector oam;
oop ofMirror = JNIHandles::resolve_non_null(ofClass);
// Exclude primitive types and array types // Exclude primitive types and array types
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) if (java_lang_Class::is_primitive(ofMirror)
|| java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->is_array_klass()) { || java_lang_Class::as_Klass(ofMirror)->is_array_klass()) {
// Return empty array // Return empty array
oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL); oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL);
return (jobjectArray) JNIHandles::make_local(THREAD, res); return (jobjectArray) JNIHandles::make_local(THREAD, res);
} }
InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(ofMirror));
// Ensure class is linked // Ensure class is linked
k->link_class(CHECK_NULL); k->link_class(CHECK_NULL);
@ -1987,12 +2000,13 @@ JVM_END
JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)) JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls))
{ {
JVMWrapper("JVM_GetClassAccessFlags"); JVMWrapper("JVM_GetClassAccessFlags");
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { oop mirror = JNIHandles::resolve_non_null(cls);
if (java_lang_Class::is_primitive(mirror)) {
// Primitive type // Primitive type
return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC; return JVM_ACC_ABSTRACT | JVM_ACC_FINAL | JVM_ACC_PUBLIC;
} }
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); Klass* k = java_lang_Class::as_Klass(mirror);
return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS; return k->access_flags().as_int() & JVM_ACC_WRITTEN_FLAGS;
} }
JVM_END JVM_END
@ -2107,8 +2121,9 @@ JVM_END
JVM_ENTRY(jobjectArray, JVM_GetPermittedSubclasses(JNIEnv* env, jclass current)) JVM_ENTRY(jobjectArray, JVM_GetPermittedSubclasses(JNIEnv* env, jclass current))
{ {
JVMWrapper("JVM_GetPermittedSubclasses"); JVMWrapper("JVM_GetPermittedSubclasses");
assert(!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(current)), "should not be"); oop mirror = JNIHandles::resolve_non_null(current);
Klass* c = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(current)); assert(!java_lang_Class::is_primitive(mirror), "should not be");
Klass* c = java_lang_Class::as_Klass(mirror);
assert(c->is_instance_klass(), "must be"); assert(c->is_instance_klass(), "must be");
InstanceKlass* ik = InstanceKlass::cast(c); InstanceKlass* ik = InstanceKlass::cast(c);
{ {
@ -2137,10 +2152,10 @@ JVM_ENTRY(jobject, JVM_GetClassConstantPool(JNIEnv *env, jclass cls))
{ {
JVMWrapper("JVM_GetClassConstantPool"); JVMWrapper("JVM_GetClassConstantPool");
JvmtiVMObjectAllocEventCollector oam; JvmtiVMObjectAllocEventCollector oam;
oop mirror = JNIHandles::resolve_non_null(cls);
// Return null for primitives and arrays // Return null for primitives and arrays
if (!java_lang_Class::is_primitive(JNIHandles::resolve_non_null(cls))) { if (!java_lang_Class::is_primitive(mirror)) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls)); Klass* k = java_lang_Class::as_Klass(mirror);
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
InstanceKlass* k_h = InstanceKlass::cast(k); InstanceKlass* k_h = InstanceKlass::cast(k);
Handle jcp = reflect_ConstantPool::create(CHECK_NULL); Handle jcp = reflect_ConstantPool::create(CHECK_NULL);