提交 2d886b2d 编写于 作者: I iklam

8061651: Interface to the Lookup Index Cache to improve URLClassPath search time

Summary: Implemented the interface in sun.misc.URLClassPath and corresponding JVM_XXX APIs
Reviewed-by: mchung, acorn, jiangli, dholmes
上级 a3f60e43
...@@ -187,6 +187,9 @@ ...@@ -187,6 +187,9 @@
_JVM_IsSupportedJNIVersion _JVM_IsSupportedJNIVersion
_JVM_IsThreadAlive _JVM_IsThreadAlive
_JVM_IsVMGeneratedMethodIx _JVM_IsVMGeneratedMethodIx
_JVM_KnownToNotExist
_JVM_GetResourceLookupCacheURLs
_JVM_GetResourceLookupCache
_JVM_LatestUserDefinedLoader _JVM_LatestUserDefinedLoader
_JVM_Listen _JVM_Listen
_JVM_LoadClass0 _JVM_LoadClass0
......
...@@ -187,6 +187,9 @@ ...@@ -187,6 +187,9 @@
_JVM_IsSupportedJNIVersion _JVM_IsSupportedJNIVersion
_JVM_IsThreadAlive _JVM_IsThreadAlive
_JVM_IsVMGeneratedMethodIx _JVM_IsVMGeneratedMethodIx
_JVM_KnownToNotExist
_JVM_GetResourceLookupCacheURLs
_JVM_GetResourceLookupCache
_JVM_LatestUserDefinedLoader _JVM_LatestUserDefinedLoader
_JVM_Listen _JVM_Listen
_JVM_LoadClass0 _JVM_LoadClass0
......
...@@ -217,6 +217,9 @@ SUNWprivate_1.1 { ...@@ -217,6 +217,9 @@ SUNWprivate_1.1 {
JVM_RegisterSignal; JVM_RegisterSignal;
JVM_ReleaseUTF; JVM_ReleaseUTF;
JVM_ResolveClass; JVM_ResolveClass;
JVM_KnownToNotExist;
JVM_GetResourceLookupCacheURLs;
JVM_GetResourceLookupCache;
JVM_ResumeThread; JVM_ResumeThread;
JVM_Send; JVM_Send;
JVM_SendTo; JVM_SendTo;
......
...@@ -217,6 +217,9 @@ SUNWprivate_1.1 { ...@@ -217,6 +217,9 @@ SUNWprivate_1.1 {
JVM_RegisterSignal; JVM_RegisterSignal;
JVM_ReleaseUTF; JVM_ReleaseUTF;
JVM_ResolveClass; JVM_ResolveClass;
JVM_KnownToNotExist;
JVM_GetResourceLookupCacheURLs;
JVM_GetResourceLookupCache;
JVM_ResumeThread; JVM_ResumeThread;
JVM_Send; JVM_Send;
JVM_SendTo; JVM_SendTo;
......
...@@ -189,6 +189,9 @@ SUNWprivate_1.1 { ...@@ -189,6 +189,9 @@ SUNWprivate_1.1 {
JVM_IsSupportedJNIVersion; JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive; JVM_IsThreadAlive;
JVM_IsVMGeneratedMethodIx; JVM_IsVMGeneratedMethodIx;
JVM_KnownToNotExist;
JVM_GetResourceLookupCacheURLs;
JVM_GetResourceLookupCache;
JVM_LatestUserDefinedLoader; JVM_LatestUserDefinedLoader;
JVM_Listen; JVM_Listen;
JVM_LoadClass0; JVM_LoadClass0;
......
...@@ -610,7 +610,7 @@ bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) { ...@@ -610,7 +610,7 @@ bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
} }
#endif #endif
void ClassLoader::setup_search_path(const char *class_path) { void ClassLoader::setup_search_path(const char *class_path, bool canonicalize) {
int offset = 0; int offset = 0;
int len = (int)strlen(class_path); int len = (int)strlen(class_path);
int end = 0; int end = 0;
...@@ -625,7 +625,13 @@ void ClassLoader::setup_search_path(const char *class_path) { ...@@ -625,7 +625,13 @@ void ClassLoader::setup_search_path(const char *class_path) {
char* path = NEW_RESOURCE_ARRAY(char, end - start + 1); char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
strncpy(path, &class_path[start], end - start); strncpy(path, &class_path[start], end - start);
path[end - start] = '\0'; path[end - start] = '\0';
update_class_path_entry_list(path, false); if (canonicalize) {
char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN + 1);
if (get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
path = canonical_path;
}
}
update_class_path_entry_list(path, /*check_for_duplicates=*/canonicalize);
#if INCLUDE_CDS #if INCLUDE_CDS
if (DumpSharedSpaces) { if (DumpSharedSpaces) {
check_shared_classpath(path); check_shared_classpath(path);
......
...@@ -129,8 +129,8 @@ class LazyClassPathEntry: public ClassPathEntry { ...@@ -129,8 +129,8 @@ class LazyClassPathEntry: public ClassPathEntry {
bool _has_error; bool _has_error;
bool _throw_exception; bool _throw_exception;
volatile ClassPathEntry* _resolved_entry; volatile ClassPathEntry* _resolved_entry;
ClassPathEntry* resolve_entry(TRAPS);
public: public:
ClassPathEntry* resolve_entry(TRAPS);
bool is_jar_file(); bool is_jar_file();
const char* name() { return _path; } const char* name() { return _path; }
LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception); LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception);
...@@ -218,7 +218,7 @@ class ClassLoader: AllStatic { ...@@ -218,7 +218,7 @@ class ClassLoader: AllStatic {
static void setup_meta_index(const char* meta_index_path, const char* meta_index_dir, static void setup_meta_index(const char* meta_index_path, const char* meta_index_dir,
int start_index); int start_index);
static void setup_bootstrap_search_path(); static void setup_bootstrap_search_path();
static void setup_search_path(const char *class_path); static void setup_search_path(const char *class_path, bool canonicalize=false);
static void load_zip_library(); static void load_zip_library();
static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st, static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
...@@ -329,6 +329,10 @@ class ClassLoader: AllStatic { ...@@ -329,6 +329,10 @@ class ClassLoader: AllStatic {
return e; return e;
} }
static int num_classpath_entries() {
return _num_entries;
}
#if INCLUDE_CDS #if INCLUDE_CDS
// Sharing dump and restore // Sharing dump and restore
static void copy_package_info_buckets(char** top, char* end); static void copy_package_info_buckets(char** top, char* end);
......
...@@ -64,6 +64,15 @@ public: ...@@ -64,6 +64,15 @@ public:
ClassLoader::add_to_list(new_entry); ClassLoader::add_to_list(new_entry);
} }
static void setup_search_paths() {} static void setup_search_paths() {}
static void init_lookup_cache(TRAPS) {}
static void copy_lookup_cache_to_archive(char** top, char* end) {}
static char* restore_lookup_cache_from_archive(char* buffer) {return buffer;}
static inline bool is_lookup_cache_enabled() {return false;}
static bool known_to_not_exist(JNIEnv *env, jobject loader, const char *classname, TRAPS) {return false;}
static jobjectArray get_lookup_cache_urls(JNIEnv *env, jobject loader, TRAPS) {return NULL;}
static jintArray get_lookup_cache(JNIEnv *env, jobject loader, const char *pkgname, TRAPS) {return NULL;}
}; };
#endif // SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP #endif // SHARE_VM_CLASSFILE_CLASSLOADEREXT_HPP
...@@ -175,6 +175,8 @@ class Ticks; ...@@ -175,6 +175,8 @@ class Ticks;
do_klass(URL_klass, java_net_URL, Pre ) \ do_klass(URL_klass, java_net_URL, Pre ) \
do_klass(Jar_Manifest_klass, java_util_jar_Manifest, Pre ) \ do_klass(Jar_Manifest_klass, java_util_jar_Manifest, Pre ) \
do_klass(sun_misc_Launcher_klass, sun_misc_Launcher, Pre ) \ do_klass(sun_misc_Launcher_klass, sun_misc_Launcher, Pre ) \
do_klass(sun_misc_Launcher_AppClassLoader_klass, sun_misc_Launcher_AppClassLoader, Pre ) \
do_klass(sun_misc_Launcher_ExtClassLoader_klass, sun_misc_Launcher_ExtClassLoader, Pre ) \
do_klass(CodeSource_klass, java_security_CodeSource, Pre ) \ do_klass(CodeSource_klass, java_security_CodeSource, Pre ) \
\ \
/* It's NULL in non-1.4 JDKs. */ \ /* It's NULL in non-1.4 JDKs. */ \
......
...@@ -116,6 +116,7 @@ ...@@ -116,6 +116,7 @@
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \ template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \ template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
template(sun_misc_PostVMInitHook, "sun/misc/PostVMInitHook") \ template(sun_misc_PostVMInitHook, "sun/misc/PostVMInitHook") \
template(sun_misc_Launcher_AppClassLoader, "sun/misc/Launcher$AppClassLoader") \
template(sun_misc_Launcher_ExtClassLoader, "sun/misc/Launcher$ExtClassLoader") \ template(sun_misc_Launcher_ExtClassLoader, "sun/misc/Launcher$ExtClassLoader") \
\ \
/* Java runtime version access */ \ /* Java runtime version access */ \
......
...@@ -64,6 +64,12 @@ class MetadataFactory : AllStatic { ...@@ -64,6 +64,12 @@ class MetadataFactory : AllStatic {
template <typename T> template <typename T>
static void free_array(ClassLoaderData* loader_data, Array<T>* data) { static void free_array(ClassLoaderData* loader_data, Array<T>* data) {
if (DumpSharedSpaces) {
// FIXME: the freeing code is buggy, especially when PrintSharedSpaces is enabled.
// Disable for now -- this means if you specify bad classes in your classlist you
// may have wasted space inside the archive.
return;
}
if (data != NULL) { if (data != NULL) {
assert(loader_data != NULL, "shouldn't pass null"); assert(loader_data != NULL, "shouldn't pass null");
assert(!data->is_shared(), "cannot deallocate array in shared spaces"); assert(!data->is_shared(), "cannot deallocate array in shared spaces");
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "classfile/dictionary.hpp" #include "classfile/dictionary.hpp"
#include "classfile/classLoaderExt.hpp"
#include "classfile/loaderConstraints.hpp" #include "classfile/loaderConstraints.hpp"
#include "classfile/placeholders.hpp" #include "classfile/placeholders.hpp"
#include "classfile/sharedClassUtil.hpp" #include "classfile/sharedClassUtil.hpp"
...@@ -39,6 +40,7 @@ ...@@ -39,6 +40,7 @@
#include "runtime/signature.hpp" #include "runtime/signature.hpp"
#include "runtime/vm_operations.hpp" #include "runtime/vm_operations.hpp"
#include "runtime/vmThread.hpp" #include "runtime/vmThread.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/hashtable.inline.hpp" #include "utilities/hashtable.inline.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
...@@ -533,6 +535,8 @@ void VM_PopulateDumpSharedSpace::doit() { ...@@ -533,6 +535,8 @@ void VM_PopulateDumpSharedSpace::doit() {
ClassLoader::copy_package_info_table(&md_top, md_end); ClassLoader::copy_package_info_table(&md_top, md_end);
ClassLoader::verify(); ClassLoader::verify();
ClassLoaderExt::copy_lookup_cache_to_archive(&md_top, md_end);
// Write the other data to the output array. // Write the other data to the output array.
WriteClosure wc(md_top, md_end); WriteClosure wc(md_top, md_end);
MetaspaceShared::serialize(&wc); MetaspaceShared::serialize(&wc);
...@@ -745,6 +749,8 @@ void MetaspaceShared::preload_and_dump(TRAPS) { ...@@ -745,6 +749,8 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
} }
tty->print_cr("Loading classes to share: done."); tty->print_cr("Loading classes to share: done.");
ClassLoaderExt::init_lookup_cache(THREAD);
if (PrintSharedSpaces) { if (PrintSharedSpaces) {
tty->print_cr("Shared spaces: preloaded %d classes", class_count); tty->print_cr("Shared spaces: preloaded %d classes", class_count);
} }
...@@ -1056,6 +1062,8 @@ void MetaspaceShared::initialize_shared_spaces() { ...@@ -1056,6 +1062,8 @@ void MetaspaceShared::initialize_shared_spaces() {
buffer += sizeof(intptr_t); buffer += sizeof(intptr_t);
buffer += len; buffer += len;
buffer = ClassLoaderExt::restore_lookup_cache_from_archive(buffer);
intptr_t* array = (intptr_t*)buffer; intptr_t* array = (intptr_t*)buffer;
ReadClosure rc(&array); ReadClosure rc(&array);
serialize(&rc); serialize(&rc);
......
...@@ -32,9 +32,9 @@ ...@@ -32,9 +32,9 @@
#define LargeSharedArchiveSize (300*M) #define LargeSharedArchiveSize (300*M)
#define HugeSharedArchiveSize (800*M) #define HugeSharedArchiveSize (800*M)
#define ReadOnlyRegionPercentage 0.4 #define ReadOnlyRegionPercentage 0.39
#define ReadWriteRegionPercentage 0.55 #define ReadWriteRegionPercentage 0.50
#define MiscDataRegionPercentage 0.03 #define MiscDataRegionPercentage 0.09
#define MiscCodeRegionPercentage 0.02 #define MiscCodeRegionPercentage 0.02
#define LargeThresholdClassCount 5000 #define LargeThresholdClassCount 5000
#define HugeThresholdClassCount 40000 #define HugeThresholdClassCount 40000
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "classfile/classLoader.hpp" #include "classfile/classLoader.hpp"
#include "classfile/classLoaderExt.hpp"
#include "classfile/javaAssertions.hpp" #include "classfile/javaAssertions.hpp"
#include "classfile/javaClasses.hpp" #include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp" #include "classfile/symbolTable.hpp"
...@@ -393,6 +394,14 @@ JVM_ENTRY(jobject, JVM_InitProperties(JNIEnv *env, jobject properties)) ...@@ -393,6 +394,14 @@ JVM_ENTRY(jobject, JVM_InitProperties(JNIEnv *env, jobject properties))
} }
} }
const char* enableSharedLookupCache = "false";
#if INCLUDE_CDS
if (ClassLoaderExt::is_lookup_cache_enabled()) {
enableSharedLookupCache = "true";
}
#endif
PUTPROP(props, "sun.cds.enableSharedLookupCache", enableSharedLookupCache);
return properties; return properties;
JVM_END JVM_END
...@@ -766,6 +775,36 @@ JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls)) ...@@ -766,6 +775,36 @@ JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls))
JVM_END JVM_END
JVM_ENTRY(jboolean, JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname))
JVMWrapper("JVM_KnownToNotExist");
#if INCLUDE_CDS
return ClassLoaderExt::known_to_not_exist(env, loader, classname, CHECK_(false));
#else
return false;
#endif
JVM_END
JVM_ENTRY(jobjectArray, JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader))
JVMWrapper("JVM_GetResourceLookupCacheURLs");
#if INCLUDE_CDS
return ClassLoaderExt::get_lookup_cache_urls(env, loader, CHECK_NULL);
#else
return NULL;
#endif
JVM_END
JVM_ENTRY(jintArray, JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name))
JVMWrapper("JVM_GetResourceLookupCache");
#if INCLUDE_CDS
return ClassLoaderExt::get_lookup_cache(env, loader, resource_name, CHECK_NULL);
#else
return NULL;
#endif
JVM_END
// Returns a class loaded by the bootstrap class loader; or null // Returns a class loaded by the bootstrap class loader; or null
// if not found. ClassNotFoundException is not thrown. // if not found. ClassNotFoundException is not thrown.
// //
......
...@@ -1548,6 +1548,31 @@ JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState); ...@@ -1548,6 +1548,31 @@ JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState);
JNIEXPORT jobjectArray JNICALL JNIEXPORT jobjectArray JNICALL
JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values); JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values);
/*
* Returns true if the JVM's lookup cache indicates that this class is
* known to NOT exist for the given loader.
*/
JNIEXPORT jboolean JNICALL
JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname);
/*
* Returns an array of all URLs that are stored in the JVM's lookup cache
* for the given loader. NULL if the lookup cache is unavailable.
*/
JNIEXPORT jobjectArray JNICALL
JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader);
/*
* Returns an array of all URLs that *may* contain the resource_name for the
* given loader. This function returns an integer array, each element
* of which can be used to index into the array returned by
* JVM_GetResourceLookupCacheURLs of the same loader to determine the
* URLs.
*/
JNIEXPORT jintArray JNICALL
JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name);
/* ========================================================================= /* =========================================================================
* The following defines a private JVM interface that the JDK can query * The following defines a private JVM interface that the JDK can query
* for the JVM version and capabilities. sun.misc.Version defines * for the JVM version and capabilities. sun.misc.Version defines
......
...@@ -104,6 +104,28 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name)) ...@@ -104,6 +104,28 @@ WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
return closure.found(); return closure.found();
WB_END WB_END
WB_ENTRY(jboolean, WB_ClassKnownToNotExist(JNIEnv* env, jobject o, jobject loader, jstring name))
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
const char* class_name = env->GetStringUTFChars(name, NULL);
jboolean result = JVM_KnownToNotExist(env, loader, class_name);
env->ReleaseStringUTFChars(name, class_name);
return result;
WB_END
WB_ENTRY(jobjectArray, WB_GetLookupCacheURLs(JNIEnv* env, jobject o, jobject loader))
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
return JVM_GetResourceLookupCacheURLs(env, loader);
WB_END
WB_ENTRY(jintArray, WB_GetLookupCacheMatches(JNIEnv* env, jobject o, jobject loader, jstring name))
ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
const char* resource_name = env->GetStringUTFChars(name, NULL);
jintArray result = JVM_GetResourceLookupCache(env, loader, resource_name);
env->ReleaseStringUTFChars(name, resource_name);
return result;
WB_END
WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) { WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
return (jlong)Arguments::max_heap_for_compressed_oops(); return (jlong)Arguments::max_heap_for_compressed_oops();
} }
...@@ -939,6 +961,11 @@ static JNINativeMethod methods[] = { ...@@ -939,6 +961,11 @@ static JNINativeMethod methods[] = {
{CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen }, {CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen },
{CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize }, {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize },
{CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive }, {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive },
{CC"classKnownToNotExist",
CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)Z",(void*)&WB_ClassKnownToNotExist},
{CC"getLookupCacheURLs", CC"(Ljava/lang/ClassLoader;)[Ljava/net/URL;", (void*)&WB_GetLookupCacheURLs},
{CC"getLookupCacheMatches", CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)[I",
(void*)&WB_GetLookupCacheMatches},
{CC"parseCommandLine", {CC"parseCommandLine",
CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
(void*) &WB_ParseCommandLine (void*) &WB_ParseCommandLine
......
...@@ -30,6 +30,7 @@ import java.util.List; ...@@ -30,6 +30,7 @@ import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.security.BasicPermission; import java.security.BasicPermission;
import java.net.URL;
import sun.hotspot.parser.DiagnosticCommand; import sun.hotspot.parser.DiagnosticCommand;
...@@ -84,6 +85,11 @@ public class WhiteBox { ...@@ -84,6 +85,11 @@ public class WhiteBox {
} }
private native boolean isClassAlive0(String name); private native boolean isClassAlive0(String name);
// Resource/Class Lookup Cache
public native boolean classKnownToNotExist(ClassLoader loader, String name);
public native URL[] getLookupCacheURLs(ClassLoader loader);
public native int[] getLookupCacheMatches(ClassLoader loader, String name);
// G1 // G1
public native boolean g1InConcurrentMark(); public native boolean g1InConcurrentMark();
public native boolean g1IsHumongous(Object o); public native boolean g1IsHumongous(Object o);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册