提交 42c7b605 编写于 作者: T thartmann

Merge

...@@ -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
......
...@@ -72,9 +72,9 @@ public abstract class CompilerWhiteBoxTest { ...@@ -72,9 +72,9 @@ public abstract class CompilerWhiteBoxTest {
/** Flag for verbose output, true if {@code -Dverbose} specified */ /** Flag for verbose output, true if {@code -Dverbose} specified */
protected static final boolean IS_VERBOSE protected static final boolean IS_VERBOSE
= System.getProperty("verbose") != null; = System.getProperty("verbose") != null;
/** count of invocation to triger compilation */ /** invocation count to trigger compilation */
protected static final int THRESHOLD; protected static final int THRESHOLD;
/** count of invocation to triger OSR compilation */ /** invocation count to trigger OSR compilation */
protected static final long BACKEDGE_THRESHOLD; protected static final long BACKEDGE_THRESHOLD;
/** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */ /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
protected static final String MODE = System.getProperty("java.vm.info"); protected static final String MODE = System.getProperty("java.vm.info");
...@@ -206,7 +206,6 @@ public abstract class CompilerWhiteBoxTest { ...@@ -206,7 +206,6 @@ public abstract class CompilerWhiteBoxTest {
* is compiled, or if {@linkplain #method} has zero * is compiled, or if {@linkplain #method} has zero
* compilation level. * compilation level.
*/ */
protected final void checkNotCompiled(int compLevel) { protected final void checkNotCompiled(int compLevel) {
if (WHITE_BOX.isMethodQueuedForCompilation(method)) { if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
throw new RuntimeException(method + " must not be in queue"); throw new RuntimeException(method + " must not be in queue");
...@@ -227,20 +226,30 @@ public abstract class CompilerWhiteBoxTest { ...@@ -227,20 +226,30 @@ public abstract class CompilerWhiteBoxTest {
* compilation level. * compilation level.
*/ */
protected final void checkNotCompiled() { protected final void checkNotCompiled() {
checkNotCompiled(true);
checkNotCompiled(false);
}
/**
* Checks, that {@linkplain #method} is not (OSR-)compiled.
*
* @param isOsr Check for OSR compilation if true
* @throws RuntimeException if {@linkplain #method} is in compiler queue or
* is compiled, or if {@linkplain #method} has zero
* compilation level.
*/
protected final void checkNotCompiled(boolean isOsr) {
waitBackgroundCompilation();
if (WHITE_BOX.isMethodQueuedForCompilation(method)) { if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
throw new RuntimeException(method + " must not be in queue"); throw new RuntimeException(method + " must not be in queue");
} }
if (WHITE_BOX.isMethodCompiled(method, false)) { if (WHITE_BOX.isMethodCompiled(method, isOsr)) {
throw new RuntimeException(method + " must be not compiled"); throw new RuntimeException(method + " must not be " +
} (isOsr ? "osr_" : "") + "compiled");
if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) {
throw new RuntimeException(method + " comp_level must be == 0");
}
if (WHITE_BOX.isMethodCompiled(method, true)) {
throw new RuntimeException(method + " must be not osr_compiled");
} }
if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) { if (WHITE_BOX.getMethodCompilationLevel(method, isOsr) != 0) {
throw new RuntimeException(method + " osr_comp_level must be == 0"); throw new RuntimeException(method + (isOsr ? " osr_" : " ") +
"comp_level must be == 0");
} }
} }
...@@ -306,12 +315,21 @@ public abstract class CompilerWhiteBoxTest { ...@@ -306,12 +315,21 @@ public abstract class CompilerWhiteBoxTest {
* Waits for completion of background compilation of {@linkplain #method}. * Waits for completion of background compilation of {@linkplain #method}.
*/ */
protected final void waitBackgroundCompilation() { protected final void waitBackgroundCompilation() {
waitBackgroundCompilation(method);
}
/**
* Waits for completion of background compilation of the given executable.
*
* @param executable Executable
*/
protected static final void waitBackgroundCompilation(Executable executable) {
if (!BACKGROUND_COMPILATION) { if (!BACKGROUND_COMPILATION) {
return; return;
} }
final Object obj = new Object(); final Object obj = new Object();
for (int i = 0; i < 10 for (int i = 0; i < 10
&& WHITE_BOX.isMethodQueuedForCompilation(method); ++i) { && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) {
synchronized (obj) { synchronized (obj) {
try { try {
obj.wait(1000); obj.wait(1000);
...@@ -425,14 +443,14 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { ...@@ -425,14 +443,14 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
/** constructor test case */ /** constructor test case */
CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false), CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false),
/** method test case */ /** method test case */
METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false), METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
/** static method test case */ /** static method test case */
STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false), STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false),
/** OSR constructor test case */ /** OSR constructor test case */
OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR, OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR,
Helper.OSR_CONSTRUCTOR_CALLABLE, true), Helper.OSR_CONSTRUCTOR_CALLABLE, true),
/** OSR method test case */ /** OSR method test case */
OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true), OSR_METHOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
/** OSR static method test case */ /** OSR static method test case */
OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true); OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true);
...@@ -494,7 +512,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { ...@@ -494,7 +512,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
= new Callable<Integer>() { = new Callable<Integer>() {
@Override @Override
public Integer call() throws Exception { public Integer call() throws Exception {
return new Helper(null).hashCode(); return new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
} }
}; };
...@@ -504,7 +522,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { ...@@ -504,7 +522,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
@Override @Override
public Integer call() throws Exception { public Integer call() throws Exception {
return helper.osrMethod(); return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
} }
}; };
...@@ -512,7 +530,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { ...@@ -512,7 +530,7 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
= new Callable<Integer>() { = new Callable<Integer>() {
@Override @Override
public Integer call() throws Exception { public Integer call() throws Exception {
return osrStaticMethod(); return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
} }
}; };
...@@ -532,25 +550,24 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { ...@@ -532,25 +550,24 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
} }
try { try {
OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor( OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
Object.class); Object.class, long.class);
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException( throw new RuntimeException(
"exception on getting method Helper.<init>(Object)", e); "exception on getting method Helper.<init>(Object, long)", e);
} }
METHOD = getMethod("method"); METHOD = getMethod("method");
STATIC = getMethod("staticMethod"); STATIC = getMethod("staticMethod");
OSR_METHOD = getMethod("osrMethod"); OSR_METHOD = getMethod("osrMethod", long.class);
OSR_STATIC = getMethod("osrStaticMethod"); OSR_STATIC = getMethod("osrStaticMethod", long.class);
} }
private static Method getMethod(String name) { private static Method getMethod(String name, Class<?>... parameterTypes) {
try { try {
return Helper.class.getDeclaredMethod(name); return Helper.class.getDeclaredMethod(name, parameterTypes);
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException( throw new RuntimeException(
"exception on getting method Helper." + name, e); "exception on getting method Helper." + name, e);
} }
} }
private static int staticMethod() { private static int staticMethod() {
...@@ -561,17 +578,84 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { ...@@ -561,17 +578,84 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
return 42; return 42;
} }
private static int osrStaticMethod() { /**
* Deoptimizes all non-osr versions of the given executable after
* compilation finished.
*
* @param e Executable
* @throws Exception
*/
private static void waitAndDeoptimize(Executable e) {
CompilerWhiteBoxTest.waitBackgroundCompilation(e);
if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) {
throw new RuntimeException(e + " must not be in queue");
}
// Deoptimize non-osr versions of executable
WhiteBox.getWhiteBox().deoptimizeMethod(e, false);
}
/**
* Executes the method multiple times to make sure we have
* enough profiling information before triggering an OSR
* compilation. Otherwise the C2 compiler may add uncommon traps.
*
* @param m Method to be executed
* @return Number of times the method was executed
* @throws Exception
*/
private static int warmup(Method m) throws Exception {
waitAndDeoptimize(m);
Helper helper = new Helper();
int result = 0;
for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
result += (int)m.invoke(helper, 1);
}
// Wait to make sure OSR compilation is not blocked by
// non-OSR compilation in the compile queue
CompilerWhiteBoxTest.waitBackgroundCompilation(m);
return result;
}
/**
* Executes the constructor multiple times to make sure we
* have enough profiling information before triggering an OSR
* compilation. Otherwise the C2 compiler may add uncommon traps.
*
* @param c Constructor to be executed
* @return Number of times the constructor was executed
* @throws Exception
*/
private static int warmup(Constructor c) throws Exception {
waitAndDeoptimize(c);
int result = 0; int result = 0;
for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
result += c.newInstance(null, 1).hashCode();
}
// Wait to make sure OSR compilation is not blocked by
// non-OSR compilation in the compile queue
CompilerWhiteBoxTest.waitBackgroundCompilation(c);
return result;
}
private static int osrStaticMethod(long limit) throws Exception {
int result = 0;
if (limit != 1) {
result = warmup(OSR_STATIC);
}
// Trigger osr compilation
for (long i = 0; i < limit; ++i) {
result += staticMethod(); result += staticMethod();
} }
return result; return result;
} }
private int osrMethod() { private int osrMethod(long limit) throws Exception {
int result = 0; int result = 0;
for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { if (limit != 1) {
result = warmup(OSR_METHOD);
}
// Trigger osr compilation
for (long i = 0; i < limit; ++i) {
result += method(); result += method();
} }
return result; return result;
...@@ -585,9 +669,13 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { ...@@ -585,9 +669,13 @@ enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
} }
// for OSR constructor test case // for OSR constructor test case
private Helper(Object o) { private Helper(Object o, long limit) throws Exception {
int result = 0; int result = 0;
for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) { if (limit != 1) {
result = warmup(OSR_CONSTRUCTOR);
}
// Trigger osr compilation
for (long i = 0; i < limit; ++i) {
result += method(); result += method();
} }
x = result; x = result;
......
...@@ -131,14 +131,15 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -131,14 +131,15 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
throw new RuntimeException(method throw new RuntimeException(method
+ " is not compilable after clearMethodState()"); + " is not compilable after clearMethodState()");
} }
// Make method not (OSR-)compilable (depending on testCase.isOsr())
makeNotCompilable(); makeNotCompilable();
if (isCompilable()) { if (isCompilable()) {
throw new RuntimeException(method + " must be not compilable"); throw new RuntimeException(method + " must be not compilable");
} }
// Try to (OSR-)compile method
compile(); compile();
checkNotCompiled(); // Method should not be (OSR-)compiled
checkNotCompiled(testCase.isOsr());
if (isCompilable()) { if (isCompilable()) {
throw new RuntimeException(method + " must be not compilable"); throw new RuntimeException(method + " must be not compilable");
} }
......
...@@ -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.
先完成此消息的编辑!
想要评论请 注册