提交 d732eca9 编写于 作者: K ksrini

6755845: JVM_FindClassFromBoot triggers assertions

Summary: Fixes assertions caused by one jvm_entry calling another, solved by refactoring code and modified gamma test.
Reviewed-by: dholmes, xlu
上级 cf804415
...@@ -1110,7 +1110,7 @@ static jstring getPlatformEncoding(JNIEnv *env) { ...@@ -1110,7 +1110,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
if (propname) { if (propname) {
jclass cls; jclass cls;
jmethodID mid; jmethodID mid;
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System")); NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID( NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls, env, cls,
"getProperty", "getProperty",
...@@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) { ...@@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) { static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
jclass cls; jclass cls;
jmethodID mid; jmethodID mid;
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset")); NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID( NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls, env, cls,
"isSupported", "isSupported",
...@@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s) ...@@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s)
#else #else
if (isEncodingSupported(env, enc) == JNI_TRUE) { if (isEncodingSupported(env, enc) == JNI_TRUE) {
#endif #endif
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>", NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([BLjava/lang/String;)V")); "([BLjava/lang/String;)V"));
str = (*env)->NewObject(env, cls, mid, ary, enc); str = (*env)->NewObject(env, cls, mid, ary, enc);
...@@ -1172,7 +1172,7 @@ NewPlatformString(JNIEnv *env, char *s) ...@@ -1172,7 +1172,7 @@ NewPlatformString(JNIEnv *env, char *s)
the encoding name, in which the StringCoding class will the encoding name, in which the StringCoding class will
pickup the iso-8859-1 as the fallback converter for us. pickup the iso-8859-1 as the fallback converter for us.
*/ */
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>", NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([B)V")); "([B)V"));
str = (*env)->NewObject(env, cls, mid, ary); str = (*env)->NewObject(env, cls, mid, ary);
...@@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc) ...@@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
jarray ary; jarray ary;
int i; int i;
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0)); NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
for (i = 0; i < strc; i++) { for (i = 0; i < strc; i++) {
jstring str = NewPlatformString(env, *strv++); jstring str = NewPlatformString(env, *strv++);
...@@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name) ...@@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name)
c = *t++; c = *t++;
*s++ = (c == '.') ? '/' : c; *s++ = (c == '.') ? '/' : c;
} while (c != '\0'); } while (c != '\0');
// use the application class loader for main-class
cls = (*env)->FindClass(env, buf); cls = (*env)->FindClass(env, buf);
free(buf); free(buf);
...@@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname) ...@@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname)
jobject jar, man, attr; jobject jar, man, attr;
jstring str, result = 0; jstring str, result = 0;
NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile")); NULL_CHECK0(cls = FindBootStrapClass(env, "java/util/jar/JarFile"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>", NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/lang/String;)V")); "(Ljava/lang/String;)V"));
NULL_CHECK0(str = NewPlatformString(env, jarname)); NULL_CHECK0(str = NewPlatformString(env, jarname));
...@@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env) ...@@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env)
jclass ver; jclass ver;
jmethodID print; jmethodID print;
NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version")); NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V")); NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
(*env)->CallStaticVoidMethod(env, ver, print); (*env)->CallStaticVoidMethod(env, ver, print);
......
...@@ -100,5 +100,15 @@ void* MemAlloc(size_t size); ...@@ -100,5 +100,15 @@ void* MemAlloc(size_t size);
* Make launcher spit debug output. * Make launcher spit debug output.
*/ */
extern jboolean _launcher_debug; extern jboolean _launcher_debug;
/*
* This allows for finding classes from the VM's bootstrap class loader
* directly, FindClass uses the application class loader internally, this will
* cause unnecessary searching of the classpath for the required classes.
*/
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
const char *name,
jboolean throwError));
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
#endif /* _JAVA_H_ */ #endif /* _JAVA_H_ */
...@@ -1826,3 +1826,23 @@ UnsetEnv(char *name) ...@@ -1826,3 +1826,23 @@ UnsetEnv(char *name)
{ {
return(borrowed_unsetenv(name)); return(borrowed_unsetenv(name));
} }
/*
* The implementation for finding classes from the bootstrap
* class loader, refer to java.h
*/
static FindClassFromBootLoader_t *findBootClass = NULL;
jclass
FindBootStrapClass(JNIEnv *env, const char* classname)
{
if (findBootClass == NULL) {
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
"JVM_FindClassFromBootLoader");
if (findBootClass == NULL) {
fprintf(stderr, "Error: could load method JVM_FindClassFromBootLoader");
return NULL;
}
}
return findBootClass(env, classname, JNI_FALSE);
}
...@@ -1110,7 +1110,7 @@ static jstring getPlatformEncoding(JNIEnv *env) { ...@@ -1110,7 +1110,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
if (propname) { if (propname) {
jclass cls; jclass cls;
jmethodID mid; jmethodID mid;
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/lang/System")); NULL_CHECK0 (cls = FindBootStrapClass(env, "java/lang/System"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID( NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls, env, cls,
"getProperty", "getProperty",
...@@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) { ...@@ -1125,7 +1125,7 @@ static jstring getPlatformEncoding(JNIEnv *env) {
static jboolean isEncodingSupported(JNIEnv *env, jstring enc) { static jboolean isEncodingSupported(JNIEnv *env, jstring enc) {
jclass cls; jclass cls;
jmethodID mid; jmethodID mid;
NULL_CHECK0 (cls = (*env)->FindClass(env, "java/nio/charset/Charset")); NULL_CHECK0 (cls = FindBootStrapClass(env, "java/nio/charset/Charset"));
NULL_CHECK0 (mid = (*env)->GetStaticMethodID( NULL_CHECK0 (mid = (*env)->GetStaticMethodID(
env, cls, env, cls,
"isSupported", "isSupported",
...@@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s) ...@@ -1161,7 +1161,7 @@ NewPlatformString(JNIEnv *env, char *s)
#else #else
if (isEncodingSupported(env, enc) == JNI_TRUE) { if (isEncodingSupported(env, enc) == JNI_TRUE) {
#endif #endif
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>", NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([BLjava/lang/String;)V")); "([BLjava/lang/String;)V"));
str = (*env)->NewObject(env, cls, mid, ary, enc); str = (*env)->NewObject(env, cls, mid, ary, enc);
...@@ -1172,7 +1172,7 @@ NewPlatformString(JNIEnv *env, char *s) ...@@ -1172,7 +1172,7 @@ NewPlatformString(JNIEnv *env, char *s)
the encoding name, in which the StringCoding class will the encoding name, in which the StringCoding class will
pickup the iso-8859-1 as the fallback converter for us. pickup the iso-8859-1 as the fallback converter for us.
*/ */
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>", NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"([B)V")); "([B)V"));
str = (*env)->NewObject(env, cls, mid, ary); str = (*env)->NewObject(env, cls, mid, ary);
...@@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc) ...@@ -1195,7 +1195,7 @@ NewPlatformStringArray(JNIEnv *env, char **strv, int strc)
jarray ary; jarray ary;
int i; int i;
NULL_CHECK0(cls = (*env)->FindClass(env, "java/lang/String")); NULL_CHECK0(cls = FindBootStrapClass(env, "java/lang/String"));
NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0)); NULL_CHECK0(ary = (*env)->NewObjectArray(env, strc, cls, 0));
for (i = 0; i < strc; i++) { for (i = 0; i < strc; i++) {
jstring str = NewPlatformString(env, *strv++); jstring str = NewPlatformString(env, *strv++);
...@@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name) ...@@ -1224,6 +1224,7 @@ LoadClass(JNIEnv *env, char *name)
c = *t++; c = *t++;
*s++ = (c == '.') ? '/' : c; *s++ = (c == '.') ? '/' : c;
} while (c != '\0'); } while (c != '\0');
// use the application class loader for the main-class
cls = (*env)->FindClass(env, buf); cls = (*env)->FindClass(env, buf);
free(buf); free(buf);
...@@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname) ...@@ -1250,7 +1251,7 @@ GetMainClassName(JNIEnv *env, char *jarname)
jobject jar, man, attr; jobject jar, man, attr;
jstring str, result = 0; jstring str, result = 0;
NULL_CHECK0(cls = (*env)->FindClass(env, "java/util/jar/JarFile")); NULL_CHECK0(cls = FindBootStrapClass(env, "java/util/jar/JarFile"));
NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>", NULL_CHECK0(mid = (*env)->GetMethodID(env, cls, "<init>",
"(Ljava/lang/String;)V")); "(Ljava/lang/String;)V"));
NULL_CHECK0(str = NewPlatformString(env, jarname)); NULL_CHECK0(str = NewPlatformString(env, jarname));
...@@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env) ...@@ -1471,7 +1472,7 @@ PrintJavaVersion(JNIEnv *env)
jclass ver; jclass ver;
jmethodID print; jmethodID print;
NULL_CHECK(ver = (*env)->FindClass(env, "sun/misc/Version")); NULL_CHECK(ver = FindBootStrapClass(env, "sun/misc/Version"));
NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V")); NULL_CHECK(print = (*env)->GetStaticMethodID(env, ver, "print", "()V"));
(*env)->CallStaticVoidMethod(env, ver, print); (*env)->CallStaticVoidMethod(env, ver, print);
......
...@@ -101,4 +101,15 @@ void* MemAlloc(size_t size); ...@@ -101,4 +101,15 @@ void* MemAlloc(size_t size);
*/ */
extern jboolean _launcher_debug; extern jboolean _launcher_debug;
/*
* This allows for finding classes from the VM's bootstrap class loader
* directly, FindClass uses the application class loader internally, this will
* cause unnecessary searching of the classpath for the required classes.
*/
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
const char *name,
jboolean throwError));
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
#endif /* _JAVA_H_ */ #endif /* _JAVA_H_ */
...@@ -1826,3 +1826,24 @@ UnsetEnv(char *name) ...@@ -1826,3 +1826,24 @@ UnsetEnv(char *name)
{ {
return(borrowed_unsetenv(name)); return(borrowed_unsetenv(name));
} }
/*
* The implementation for finding classes from the bootstrap
* class loader, refer to java.h
*/
static FindClassFromBootLoader_t *findBootClass = NULL;
jclass
FindBootStrapClass(JNIEnv *env, const char* classname)
{
if (findBootClass == NULL) {
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
"JVM_FindClassFromBootLoader");
if (findBootClass == NULL) {
fprintf(stderr, "Error: could not load method JVM_FindClassFromBootLoader");
return NULL;
}
}
return findBootClass(env, classname, JNI_FALSE);
}
...@@ -628,6 +628,32 @@ JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls)) ...@@ -628,6 +628,32 @@ JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls))
if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented"); if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented");
JVM_END JVM_END
// Common implementation for JVM_FindClassFromBootLoader and
// JVM_FindClassFromLoader
static jclass jvm_find_class_from_class_loader(JNIEnv* env, const char* name,
jboolean init, jobject loader,
jboolean throwError, TRAPS) {
// Java libraries should ensure that name is never null...
if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
// It's impossible to create this class; the name cannot fit
// into the constant pool.
if (throwError) {
THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
} else {
THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
}
}
symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL);
Handle h_loader(THREAD, JNIHandles::resolve(loader));
jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
Handle(), throwError, THREAD);
if (TraceClassResolution && result != NULL) {
trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
}
return result;
}
// Rationale behind JVM_FindClassFromBootLoader // Rationale behind JVM_FindClassFromBootLoader
// a> JVM_FindClassFromClassLoader was never exported in the export tables. // a> JVM_FindClassFromClassLoader was never exported in the export tables.
// b> because of (a) java.dll has a direct dependecy on the unexported // b> because of (a) java.dll has a direct dependecy on the unexported
...@@ -649,8 +675,8 @@ JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env, ...@@ -649,8 +675,8 @@ JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env,
jboolean throwError)) jboolean throwError))
JVMWrapper3("JVM_FindClassFromBootLoader %s throw %s", name, JVMWrapper3("JVM_FindClassFromBootLoader %s throw %s", name,
throwError ? "error" : "exception"); throwError ? "error" : "exception");
return JVM_FindClassFromClassLoader(env, name, JNI_FALSE, return jvm_find_class_from_class_loader(env, name, JNI_FALSE,
(jobject)NULL, throwError); (jobject)NULL, throwError, THREAD);
JVM_END JVM_END
JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
...@@ -658,26 +684,8 @@ JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, ...@@ -658,26 +684,8 @@ JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
jboolean throwError)) jboolean throwError))
JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name, JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name,
throwError ? "error" : "exception"); throwError ? "error" : "exception");
// Java libraries should ensure that name is never null... return jvm_find_class_from_class_loader(env, name, init, loader,
if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) { throwError, THREAD);
// It's impossible to create this class; the name cannot fit
// into the constant pool.
if (throwError) {
THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
} else {
THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
}
}
symbolHandle h_name = oopFactory::new_symbol_handle(name, CHECK_NULL);
Handle h_loader(THREAD, JNIHandles::resolve(loader));
jclass result = find_class_from_class_loader(env, h_name, init, h_loader,
Handle(), throwError, thread);
if (TraceClassResolution && result != NULL) {
trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
}
return result;
JVM_END JVM_END
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册