@@ -717,6 +717,17 @@ JVM_END
717717// Misc. class handling ///////////////////////////////////////////////////////////
718718
719719
720+ JVM_ENTRY (void , JVM_LinkClass(JNIEnv* env, jclass classClass, jclass arg))
721+ JVMWrapper (" JVM_LinkClass" );
722+
723+ oop r = JNIHandles::resolve(arg);
724+ Klass* klass = java_lang_Class::as_Klass(r);
725+
726+ if (!ClassForNameDeferLinking && klass->is_instance_klass ()) {
727+ InstanceKlass::cast (klass)->link_class (CHECK );
728+ }
729+ JVM_END
730+
720731JVM_ENTRY (jclass, JVM_GetCallerClass(JNIEnv* env))
721732 JVMWrapper (" JVM_GetCallerClass" );
722733
@@ -827,9 +838,10 @@ JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name,
827838
828839 Handle h_loader (THREAD , loader_oop);
829840 Handle h_prot (THREAD , protection_domain);
830- jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
831- h_prot, false , THREAD );
832841
842+ jboolean link = !ClassForNameDeferLinking;
843+ jclass result = find_class_from_class_loader(env, h_name, init, link, h_loader,
844+ h_prot, false , THREAD );
833845 if (log_is_enabled(Debug, class , resolve) && result != NULL ) {
834846 trace_class_resolution (java_lang_Class::as_Klass (JNIHandles::resolve_non_null (result)));
835847 }
@@ -866,7 +878,7 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
866878 }
867879 Handle h_loader (THREAD , class_loader);
868880 Handle h_prot (THREAD , protection_domain);
869- jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
881+ jclass result = find_class_from_class_loader(env, h_name, init, false , h_loader,
870882 h_prot, true , thread);
871883
872884 if (log_is_enabled(Debug, class , resolve) && result != NULL ) {
@@ -3424,9 +3436,12 @@ JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) {
34243436
34253437// Shared JNI/JVM entry points //////////////////////////////////////////////////////////////
34263438
3427- jclass find_class_from_class_loader (JNIEnv* env, Symbol* name, jboolean init,
3439+ jclass find_class_from_class_loader (JNIEnv* env, Symbol* name, jboolean init, jboolean link,
34283440 Handle loader, Handle protection_domain,
34293441 jboolean throwError, TRAPS ) {
3442+ // Initialization also implies linking - check for coherent args
3443+ assert ((init && link) || !init, " incorrect use of init/link arguments" );
3444+
34303445 // Security Note:
34313446 // The Java level wrapper will perform the necessary security check allowing
34323447 // us to pass the NULL as the initiating class loader. The VM is responsible for
@@ -3435,9 +3450,11 @@ jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init,
34353450 // if there is no security manager in 3-arg Class.forName().
34363451 Klass* klass = SystemDictionary::resolve_or_fail (name, loader, protection_domain, throwError != 0 , CHECK_NULL );
34373452
3438- // Check if we should initialize the class
3453+ // Check if we should initialize the class (which implies linking), or just link it
34393454 if (init && klass->is_instance_klass ()) {
34403455 klass->initialize (CHECK_NULL );
3456+ } else if (link && klass->is_instance_klass ()) {
3457+ InstanceKlass::cast (klass)->link_class (CHECK_NULL );
34413458 }
34423459 return (jclass) JNIHandles::make_local (env, klass->java_mirror ());
34433460}
0 commit comments