You need to sign in or sign up before continuing.
提交 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 @@
_JVM_IsSupportedJNIVersion
_JVM_IsThreadAlive
_JVM_IsVMGeneratedMethodIx
_JVM_KnownToNotExist
_JVM_GetResourceLookupCacheURLs
_JVM_GetResourceLookupCache
_JVM_LatestUserDefinedLoader
_JVM_Listen
_JVM_LoadClass0
......
......@@ -187,6 +187,9 @@
_JVM_IsSupportedJNIVersion
_JVM_IsThreadAlive
_JVM_IsVMGeneratedMethodIx
_JVM_KnownToNotExist
_JVM_GetResourceLookupCacheURLs
_JVM_GetResourceLookupCache
_JVM_LatestUserDefinedLoader
_JVM_Listen
_JVM_LoadClass0
......
......@@ -217,6 +217,9 @@ SUNWprivate_1.1 {
JVM_RegisterSignal;
JVM_ReleaseUTF;
JVM_ResolveClass;
JVM_KnownToNotExist;
JVM_GetResourceLookupCacheURLs;
JVM_GetResourceLookupCache;
JVM_ResumeThread;
JVM_Send;
JVM_SendTo;
......
......@@ -217,6 +217,9 @@ SUNWprivate_1.1 {
JVM_RegisterSignal;
JVM_ReleaseUTF;
JVM_ResolveClass;
JVM_KnownToNotExist;
JVM_GetResourceLookupCacheURLs;
JVM_GetResourceLookupCache;
JVM_ResumeThread;
JVM_Send;
JVM_SendTo;
......
......@@ -189,6 +189,9 @@ SUNWprivate_1.1 {
JVM_IsSupportedJNIVersion;
JVM_IsThreadAlive;
JVM_IsVMGeneratedMethodIx;
JVM_KnownToNotExist;
JVM_GetResourceLookupCacheURLs;
JVM_GetResourceLookupCache;
JVM_LatestUserDefinedLoader;
JVM_Listen;
JVM_LoadClass0;
......
......@@ -610,7 +610,7 @@ bool ClassLoader::check_shared_paths_misc_info(void *buf, int size) {
}
#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 len = (int)strlen(class_path);
int end = 0;
......@@ -625,7 +625,13 @@ void ClassLoader::setup_search_path(const char *class_path) {
char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
strncpy(path, &class_path[start], end - start);
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 (DumpSharedSpaces) {
check_shared_classpath(path);
......
......@@ -129,8 +129,8 @@ class LazyClassPathEntry: public ClassPathEntry {
bool _has_error;
bool _throw_exception;
volatile ClassPathEntry* _resolved_entry;
ClassPathEntry* resolve_entry(TRAPS);
public:
ClassPathEntry* resolve_entry(TRAPS);
bool is_jar_file();
const char* name() { return _path; }
LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception);
......@@ -218,7 +218,7 @@ class ClassLoader: AllStatic {
static void setup_meta_index(const char* meta_index_path, const char* meta_index_dir,
int start_index);
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 ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st,
......@@ -329,6 +329,10 @@ class ClassLoader: AllStatic {
return e;
}
static int num_classpath_entries() {
return _num_entries;
}
#if INCLUDE_CDS
// Sharing dump and restore
static void copy_package_info_buckets(char** top, char* end);
......
......@@ -64,6 +64,15 @@ public:
ClassLoader::add_to_list(new_entry);
}
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
......@@ -175,6 +175,8 @@ class Ticks;
do_klass(URL_klass, java_net_URL, 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_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 ) \
\
/* It's NULL in non-1.4 JDKs. */ \
......
......@@ -116,6 +116,7 @@
template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \
template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \
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") \
\
/* Java runtime version access */ \
......
......@@ -64,6 +64,12 @@ class MetadataFactory : AllStatic {
template <typename T>
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) {
assert(loader_data != NULL, "shouldn't pass null");
assert(!data->is_shared(), "cannot deallocate array in shared spaces");
......
......@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "classfile/dictionary.hpp"
#include "classfile/classLoaderExt.hpp"
#include "classfile/loaderConstraints.hpp"
#include "classfile/placeholders.hpp"
#include "classfile/sharedClassUtil.hpp"
......@@ -39,6 +40,7 @@
#include "runtime/signature.hpp"
#include "runtime/vm_operations.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/hashtable.hpp"
#include "utilities/hashtable.inline.hpp"
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
......@@ -533,6 +535,8 @@ void VM_PopulateDumpSharedSpace::doit() {
ClassLoader::copy_package_info_table(&md_top, md_end);
ClassLoader::verify();
ClassLoaderExt::copy_lookup_cache_to_archive(&md_top, md_end);
// Write the other data to the output array.
WriteClosure wc(md_top, md_end);
MetaspaceShared::serialize(&wc);
......@@ -745,6 +749,8 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
}
tty->print_cr("Loading classes to share: done.");
ClassLoaderExt::init_lookup_cache(THREAD);
if (PrintSharedSpaces) {
tty->print_cr("Shared spaces: preloaded %d classes", class_count);
}
......@@ -1056,6 +1062,8 @@ void MetaspaceShared::initialize_shared_spaces() {
buffer += sizeof(intptr_t);
buffer += len;
buffer = ClassLoaderExt::restore_lookup_cache_from_archive(buffer);
intptr_t* array = (intptr_t*)buffer;
ReadClosure rc(&array);
serialize(&rc);
......
......@@ -32,9 +32,9 @@
#define LargeSharedArchiveSize (300*M)
#define HugeSharedArchiveSize (800*M)
#define ReadOnlyRegionPercentage 0.4
#define ReadWriteRegionPercentage 0.55
#define MiscDataRegionPercentage 0.03
#define ReadOnlyRegionPercentage 0.39
#define ReadWriteRegionPercentage 0.50
#define MiscDataRegionPercentage 0.09
#define MiscCodeRegionPercentage 0.02
#define LargeThresholdClassCount 5000
#define HugeThresholdClassCount 40000
......
......@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderExt.hpp"
#include "classfile/javaAssertions.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
......@@ -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;
JVM_END
......@@ -766,6 +775,36 @@ JVM_ENTRY(void, JVM_ResolveClass(JNIEnv* env, jclass cls))
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
// if not found. ClassNotFoundException is not thrown.
//
......
......@@ -1548,6 +1548,31 @@ JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState);
JNIEXPORT jobjectArray JNICALL
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
* 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))
return closure.found();
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)) {
return (jlong)Arguments::max_heap_for_compressed_oops();
}
......@@ -939,6 +961,11 @@ static JNINativeMethod methods[] = {
{CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen },
{CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize },
{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"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
(void*) &WB_ParseCommandLine
......
......@@ -30,6 +30,7 @@ import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;
import java.security.BasicPermission;
import java.net.URL;
import sun.hotspot.parser.DiagnosticCommand;
......@@ -84,6 +85,11 @@ public class WhiteBox {
}
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
public native boolean g1InConcurrentMark();
public native boolean g1IsHumongous(Object o);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册