diff --git a/src/class.c b/src/class.c index af81530..26d078d 100644 --- a/src/class.c +++ b/src/class.c @@ -379,6 +379,7 @@ Class *parseClass(char *classname, char *data, int offset, int len, } classblock->class_loader = class_loader; + classlibSetClassLoader(class, class_loader); READ_U2(intf_count = classblock->interfaces_count, ptr, len); interfaces = classblock->interfaces = @@ -813,6 +814,7 @@ Class *createArrayClass(char *classname, Object *class_loader) { /* The array's classloader is the loader of the element class */ classblock->class_loader = elem_cb->class_loader; + classlibSetClassLoader(class, elem_cb->class_loader); /* The array's visibility (i.e. public, etc.) is that of the element */ classblock->access_flags = (elem_cb->access_flags & ~ACC_INTERFACE) | @@ -1474,6 +1476,9 @@ void linkClass(Class *class) { cb->flags |= CLASS_LOADER; } + if(cb->flags & CLASS_CLASS) + classlibCacheClassFields(class); + cb->state = CLASS_LINKED; unlock: diff --git a/src/classlib/gnuclasspath/classlib.h b/src/classlib/gnuclasspath/classlib.h index dacc273..1ecf9f9 100644 --- a/src/classlib/gnuclasspath/classlib.h +++ b/src/classlib/gnuclasspath/classlib.h @@ -76,6 +76,9 @@ extern void classlibNewLibraryUnloader(Object *class_loader, void *entry); #define classlibSkipReflectionLoader(loader) \ loader +#define classlibCacheClassFields(class) {} +#define classlibSetClassLoader(class, loader) {} + #define classlibInjectedFieldsCount(classname) 0 #define classlibFillInInjectedFields(classname, field) {} diff --git a/src/classlib/openjdk/class.c b/src/classlib/openjdk/class.c index 3206ed0..148445c 100644 --- a/src/classlib/openjdk/class.c +++ b/src/classlib/openjdk/class.c @@ -26,6 +26,11 @@ #include "excep.h" #include "symbol.h" +/* Cached offset of classLoader field in java.lang.Class. + Since JDK-6642881, Class.getClassLoader0() reads this + field directly rather than calling a native method. */ +static int cls_classLoader_offset = -1; + /* Cached offset of classes field in java.lang.ClassLoader objects */ int ldr_classes_offset; int ldr_parent_offset; @@ -53,6 +58,18 @@ void classlibCacheClassLoaderFields(Class *loader_class) { ldr_parent_offset = parent_fb->u.offset; } +void classlibCacheClassFields(Class *class) { + FieldBlock *cl_fb = findField(class, SYMBOL(classLoader), + SYMBOL(sig_java_lang_ClassLoader)); + if(cl_fb != NULL) + cls_classLoader_offset = cl_fb->u.offset; +} + +void classlibSetClassLoader(Class *class, Object *loader) { + if(loader != NULL && cls_classLoader_offset != -1) + INST_DATA(class, Object*, cls_classLoader_offset) = loader; +} + HashTable *classlibLoaderTable(Object *class_loader) { void *pntr = INST_DATA(class_loader, void*, ldr_classes_offset); diff --git a/src/classlib/openjdk/classlib.h b/src/classlib/openjdk/classlib.h index 23c1b4c..015dfb2 100644 --- a/src/classlib/openjdk/classlib.h +++ b/src/classlib/openjdk/classlib.h @@ -53,6 +53,8 @@ extern void classlibSignalThread(Thread *self); /* NOTHING TO DO */ TRUE extern void classlibCacheClassLoaderFields(Class *loader_class); +extern void classlibCacheClassFields(Class *class); +extern void classlibSetClassLoader(Class *class, Object *loader); extern HashTable *classlibLoaderTable(Object *class_loader); extern HashTable *classlibCreateLoaderTable(Object *class_loader); extern Object *classlibBootPackage(PackageEntry *entry); diff --git a/src/classlib/openjdk/jvm.c b/src/classlib/openjdk/jvm.c index 223f668..cd31b4d 100644 --- a/src/classlib/openjdk/jvm.c +++ b/src/classlib/openjdk/jvm.c @@ -669,6 +669,35 @@ void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers) { } +/* JVM_GetResourceLookupCacheURLs + is part of the + JDK-8061651 JDK8u API +*/ + +jobjectArray JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader) { + return NULL; // tell OpenJDK 8 that the lookup cache API is unavailable +} + +/* JVM_GetResourceLookupCache + is unused however it is part of the + JDK-8061651 JDK8u API +*/ + +jintArray JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name) { + UNIMPLEMENTED("JVM_GetResourceLookupCache"); + return 0; +} + +/* JVM_KnownToNotExist + is unused however it is part of the + JDK-8061651 JDK8u API +*/ + +jboolean JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname) { + UNIMPLEMENTED("JVM_KnownToNotExist"); + return 0; +} + /* JVM_GetProtectionDomain */ jobject JVM_GetProtectionDomain(JNIEnv *env, jclass cls) { diff --git a/src/symbol.h b/src/symbol.h index 8864fcb..b910dd5 100644 --- a/src/symbol.h +++ b/src/symbol.h @@ -53,6 +53,7 @@ extern char *symbol_values[]; action(initCause, "initCause"), \ action(loadClass, "loadClass"), \ action(returnType, "returnType"), \ + action(classLoader, "classLoader"), \ action(declaringClass, "declaringClass"), \ action(parameterTypes, "parameterTypes"), \ action(printStackTrace, "printStackTrace"), \