changeset 6866:d4562805b030

Merge
author thartmann
date Wed, 05 Nov 2014 08:35:02 +0000
parents 468850e35e48 4cb90023bf2b
children 3c87c13918fb
files
diffstat 19 files changed, 279 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/make/bsd/makefiles/mapfile-vers-debug	Fri Oct 31 12:16:20 2014 +0100
+++ b/make/bsd/makefiles/mapfile-vers-debug	Wed Nov 05 08:35:02 2014 +0000
@@ -187,6 +187,9 @@
                 _JVM_IsSupportedJNIVersion
                 _JVM_IsThreadAlive
                 _JVM_IsVMGeneratedMethodIx
+                _JVM_KnownToNotExist
+                _JVM_GetResourceLookupCacheURLs
+                _JVM_GetResourceLookupCache
                 _JVM_LatestUserDefinedLoader
                 _JVM_Listen
                 _JVM_LoadClass0
--- a/make/bsd/makefiles/mapfile-vers-product	Fri Oct 31 12:16:20 2014 +0100
+++ b/make/bsd/makefiles/mapfile-vers-product	Wed Nov 05 08:35:02 2014 +0000
@@ -187,6 +187,9 @@
                 _JVM_IsSupportedJNIVersion
                 _JVM_IsThreadAlive
                 _JVM_IsVMGeneratedMethodIx
+                _JVM_KnownToNotExist
+                _JVM_GetResourceLookupCacheURLs
+                _JVM_GetResourceLookupCache
                 _JVM_LatestUserDefinedLoader
                 _JVM_Listen
                 _JVM_LoadClass0
--- a/make/linux/makefiles/mapfile-vers-debug	Fri Oct 31 12:16:20 2014 +0100
+++ b/make/linux/makefiles/mapfile-vers-debug	Wed Nov 05 08:35:02 2014 +0000
@@ -217,6 +217,9 @@
                 JVM_RegisterSignal;
                 JVM_ReleaseUTF;
                 JVM_ResolveClass;
+                JVM_KnownToNotExist;
+                JVM_GetResourceLookupCacheURLs;
+                JVM_GetResourceLookupCache;
                 JVM_ResumeThread;
                 JVM_Send;
                 JVM_SendTo;
--- a/make/linux/makefiles/mapfile-vers-product	Fri Oct 31 12:16:20 2014 +0100
+++ b/make/linux/makefiles/mapfile-vers-product	Wed Nov 05 08:35:02 2014 +0000
@@ -217,6 +217,9 @@
                 JVM_RegisterSignal;
                 JVM_ReleaseUTF;
                 JVM_ResolveClass;
+                JVM_KnownToNotExist;
+                JVM_GetResourceLookupCacheURLs;
+                JVM_GetResourceLookupCache;
                 JVM_ResumeThread;
                 JVM_Send;
                 JVM_SendTo;
--- a/make/solaris/makefiles/mapfile-vers	Fri Oct 31 12:16:20 2014 +0100
+++ b/make/solaris/makefiles/mapfile-vers	Wed Nov 05 08:35:02 2014 +0000
@@ -189,6 +189,9 @@
                 JVM_IsSupportedJNIVersion;
                 JVM_IsThreadAlive;
                 JVM_IsVMGeneratedMethodIx;
+                JVM_KnownToNotExist;
+                JVM_GetResourceLookupCacheURLs;
+                JVM_GetResourceLookupCache;
                 JVM_LatestUserDefinedLoader;
                 JVM_Listen;
                 JVM_LoadClass0;
--- a/src/share/vm/classfile/classLoader.cpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/classfile/classLoader.cpp	Wed Nov 05 08:35:02 2014 +0000
@@ -610,7 +610,7 @@
 }
 #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 @@
     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);
--- a/src/share/vm/classfile/classLoader.hpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/classfile/classLoader.hpp	Wed Nov 05 08:35:02 2014 +0000
@@ -129,8 +129,8 @@
   bool _has_error;
   bool _throw_exception;
   volatile ClassPathEntry* _resolved_entry;
+ public:
   ClassPathEntry* resolve_entry(TRAPS);
- public:
   bool is_jar_file();
   const char* name()  { return _path; }
   LazyClassPathEntry(const char* path, const struct stat* st, bool throw_exception);
@@ -218,7 +218,7 @@
   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 @@
     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);
--- a/src/share/vm/classfile/classLoaderExt.hpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/classfile/classLoaderExt.hpp	Wed Nov 05 08:35:02 2014 +0000
@@ -64,6 +64,15 @@
     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
--- a/src/share/vm/classfile/systemDictionary.hpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Wed Nov 05 08:35:02 2014 +0000
@@ -175,6 +175,8 @@
   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. */                                                                                       \
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Wed Nov 05 08:35:02 2014 +0000
@@ -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 */                                                               \
--- a/src/share/vm/memory/metadataFactory.hpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/memory/metadataFactory.hpp	Wed Nov 05 08:35:02 2014 +0000
@@ -64,6 +64,12 @@
 
   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");
--- a/src/share/vm/memory/metaspaceShared.cpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/memory/metaspaceShared.cpp	Wed Nov 05 08:35:02 2014 +0000
@@ -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 @@
   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 @@
   }
   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 @@
   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);
--- a/src/share/vm/memory/metaspaceShared.hpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/memory/metaspaceShared.hpp	Wed Nov 05 08:35:02 2014 +0000
@@ -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
--- a/src/share/vm/prims/jvm.cpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/prims/jvm.cpp	Wed Nov 05 08:35:02 2014 +0000
@@ -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 @@
     }
   }
 
+  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_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.
 //
--- a/src/share/vm/prims/jvm.h	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/prims/jvm.h	Wed Nov 05 08:35:02 2014 +0000
@@ -1548,6 +1548,31 @@
 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
--- a/src/share/vm/prims/whitebox.cpp	Fri Oct 31 12:16:20 2014 +0100
+++ b/src/share/vm/prims/whitebox.cpp	Wed Nov 05 08:35:02 2014 +0000
@@ -104,6 +104,28 @@
   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 @@
   {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
--- a/test/compiler/whitebox/CompilerWhiteBoxTest.java	Fri Oct 31 12:16:20 2014 +0100
+++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java	Wed Nov 05 08:35:02 2014 +0000
@@ -72,9 +72,9 @@
     /** Flag for verbose output, true if {@code -Dverbose} specified */
     protected static final boolean IS_VERBOSE
             = System.getProperty("verbose") != null;
-    /** count of invocation to triger compilation */
+    /** invocation count to trigger compilation */
     protected static final int THRESHOLD;
-    /** count of invocation to triger OSR compilation */
+    /** invocation count to trigger OSR compilation */
     protected static final long BACKEDGE_THRESHOLD;
     /** Value of {@code java.vm.info} (interpreted|mixed|comp mode) */
     protected static final String MODE = System.getProperty("java.vm.info");
@@ -206,7 +206,6 @@
      *                          is compiled, or if {@linkplain #method} has zero
      *                          compilation level.
      */
-
     protected final void checkNotCompiled(int compLevel) {
         if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
             throw new RuntimeException(method + " must not be in queue");
@@ -227,20 +226,30 @@
      *                          compilation level.
      */
     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)) {
             throw new RuntimeException(method + " must not be in queue");
         }
-        if (WHITE_BOX.isMethodCompiled(method, false)) {
-            throw new RuntimeException(method + " must be not compiled");
+        if (WHITE_BOX.isMethodCompiled(method, isOsr)) {
+            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) {
-            throw new RuntimeException(method + " osr_comp_level must be == 0");
+        if (WHITE_BOX.getMethodCompilationLevel(method, isOsr) != 0) {
+            throw new RuntimeException(method + (isOsr ? " osr_" : " ") +
+                                       "comp_level must be == 0");
         }
     }
 
@@ -306,12 +315,21 @@
      * Waits for completion of background compilation of {@linkplain #method}.
      */
     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) {
             return;
         }
         final Object obj = new Object();
         for (int i = 0; i < 10
-                && WHITE_BOX.isMethodQueuedForCompilation(method); ++i) {
+                && WHITE_BOX.isMethodQueuedForCompilation(executable); ++i) {
             synchronized (obj) {
                 try {
                     obj.wait(1000);
@@ -425,14 +443,14 @@
     /** constructor test case */
     CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false),
     /** method test case */
-    METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
+    METHOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
     /** static method test case */
     STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false),
     /** OSR constructor test case */
     OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR,
             Helper.OSR_CONSTRUCTOR_CALLABLE, true),
     /** 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_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true);
 
@@ -494,7 +512,7 @@
                 = new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return new Helper(null).hashCode();
+                return new Helper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
             }
         };
 
@@ -504,7 +522,7 @@
 
             @Override
             public Integer call() throws Exception {
-                return helper.osrMethod();
+                return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
             }
         };
 
@@ -512,7 +530,7 @@
                 = new Callable<Integer>() {
             @Override
             public Integer call() throws Exception {
-                return osrStaticMethod();
+                return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
             }
         };
 
@@ -532,25 +550,24 @@
             }
             try {
                 OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
-                        Object.class);
+                        Object.class, long.class);
             } catch (NoSuchMethodException | SecurityException e) {
                 throw new RuntimeException(
-                        "exception on getting method Helper.<init>(Object)", e);
+                        "exception on getting method Helper.<init>(Object, long)", e);
             }
             METHOD = getMethod("method");
             STATIC = getMethod("staticMethod");
-            OSR_METHOD = getMethod("osrMethod");
-            OSR_STATIC = getMethod("osrStaticMethod");
+            OSR_METHOD = getMethod("osrMethod", long.class);
+            OSR_STATIC = getMethod("osrStaticMethod", long.class);
         }
 
-        private static Method getMethod(String name) {
+        private static Method getMethod(String name, Class<?>... parameterTypes) {
             try {
-                return Helper.class.getDeclaredMethod(name);
+                return Helper.class.getDeclaredMethod(name, parameterTypes);
             } catch (NoSuchMethodException | SecurityException e) {
                 throw new RuntimeException(
                         "exception on getting method Helper." + name, e);
             }
-
         }
 
         private static int staticMethod() {
@@ -561,17 +578,84 @@
             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.BACKEDGE_THRESHOLD; ++i) {
+            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;
+            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();
             }
             return result;
         }
 
-        private int osrMethod() {
+        private int osrMethod(long limit) throws Exception {
             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();
             }
             return result;
@@ -585,9 +669,13 @@
         }
 
         // for OSR constructor test case
-        private Helper(Object o) {
+        private Helper(Object o, long limit) throws Exception {
             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();
             }
             x = result;
--- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Fri Oct 31 12:16:20 2014 +0100
+++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Wed Nov 05 08:35:02 2014 +0000
@@ -131,14 +131,15 @@
             throw new RuntimeException(method
                     + " is not compilable after clearMethodState()");
         }
-
+        // Make method not (OSR-)compilable (depending on testCase.isOsr())
         makeNotCompilable();
         if (isCompilable()) {
             throw new RuntimeException(method + " must be not compilable");
         }
-
+        // Try to (OSR-)compile method
         compile();
-        checkNotCompiled();
+        // Method should not be (OSR-)compiled
+        checkNotCompiled(testCase.isOsr());
         if (isCompilable()) {
             throw new RuntimeException(method + " must be not compilable");
         }
--- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Fri Oct 31 12:16:20 2014 +0100
+++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Wed Nov 05 08:35:02 2014 +0000
@@ -30,6 +30,7 @@
 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 @@
   }
   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);