diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp
index aff2aaf0c..83a7659a3 100644
--- a/hotspot/src/share/vm/code/codeBlob.cpp
+++ b/hotspot/src/share/vm/code/codeBlob.cpp
@@ -337,6 +337,9 @@ MethodHandlesAdapterBlob* MethodHandlesAdapterBlob::create(int buffer_size) {
     // This means that CodeCacheMinimumFreeSpace is used, if necessary
     const bool is_critical = true;
     blob = new (size, is_critical) MethodHandlesAdapterBlob(size);
+    if (blob == NULL) {
+      vm_exit_out_of_memory(size, OOM_MALLOC_ERROR, "CodeCache: no room for method handle adapter blob");
+    }
   }
   // Track memory usage statistic after releasing CodeCache_lock
   MemoryService::track_code_cache_memory_usage();
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index 231d62d29..63f333db2 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -1469,19 +1469,6 @@ static JNINativeMethod MH_methods[] = {
   {CC "invokeExact",               CC "([" OBJ ")" OBJ,                       FN_PTR(MH_invokeExact_UOE)}
 };
 
-/**
- * Helper method to register native methods.
- */
-static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
-  int status = env->RegisterNatives(clazz, methods, nMethods);
-  if (status != JNI_OK || env->ExceptionOccurred()) {
-    warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
-    env->ExceptionClear();
-    return false;
-  }
-  return true;
-}
-
 /**
  * This one function is exported, used by NativeLookup.
  */
@@ -1492,34 +1479,27 @@ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class))
   }
 
   assert(!MethodHandles::enabled(), "must not be enabled");
-  bool enable_MH = true;
+  if (!EnableInvokeDynamic || SystemDictionary::MethodHandle_klass() == NULL)  return;
 
-  jclass MH_class = NULL;
-  if (SystemDictionary::MethodHandle_klass() == NULL) {
-    enable_MH = false;
-  } else {
-    oop mirror = SystemDictionary::MethodHandle_klass()->java_mirror();
-    MH_class = (jclass) JNIHandles::make_local(env, mirror);
-  }
+  oop mirror = SystemDictionary::MethodHandle_klass()->java_mirror();
+  jclass MH_class = (jclass) JNIHandles::make_local(env, mirror);
 
-  if (enable_MH) {
+  {
     ThreadToNativeFromVM ttnfv(thread);
 
-    if (enable_MH) {
-      enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
-    }
-    if (enable_MH) {
-      enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
-    }
+    int status = env->RegisterNatives(MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod));
+    guarantee(status == JNI_OK && !env->ExceptionOccurred(),
+              "register java.lang.invoke.MethodHandleNative natives");
+
+    status = env->RegisterNatives(MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod));
+    guarantee(status == JNI_OK && !env->ExceptionOccurred(),
+              "register java.lang.invoke.MethodHandle natives");
   }
 
   if (TraceInvokeDynamic) {
     tty->print_cr("MethodHandle support loaded (using LambdaForms)");
   }
 
-  if (enable_MH) {
-    MethodHandles::generate_adapters();
-    MethodHandles::set_enabled(true);
-  }
+  MethodHandles::set_enabled(true);
 }
 JVM_END
diff --git a/hotspot/src/share/vm/runtime/init.cpp b/hotspot/src/share/vm/runtime/init.cpp
index f709db941..71caac72b 100644
--- a/hotspot/src/share/vm/runtime/init.cpp
+++ b/hotspot/src/share/vm/runtime/init.cpp
@@ -136,6 +136,7 @@ jint init_globals() {
   }
   javaClasses_init();   // must happen after vtable initialization
   stubRoutines_init2(); // note: StubRoutines need 2-phase init
+  MethodHandles::generate_adapters();
 
 #if INCLUDE_NMT
   // Solaris stack is walkable only after stubRoutines are set up.
diff --git a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp
index 7b592d9fa..68ff3afe9 100644
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp
@@ -36,6 +36,7 @@
 
 StubCodeDesc* volatile StubCodeDesc::_list = NULL;
 int                    StubCodeDesc::_count = 0;
+bool                StubCodeDesc::_frozen = false;
 
 
 StubCodeDesc* StubCodeDesc::desc_for(address pc) {
@@ -58,6 +59,10 @@ const char* StubCodeDesc::name_for(address pc) {
   return p == NULL ? NULL : p->name();
 }
 
+void StubCodeDesc::freeze() {
+  assert(!_frozen, "repeated freeze operation");
+  _frozen = true;
+}
 
 void StubCodeDesc::print_on(outputStream* st) const {
   st->print("%s", group());
diff --git a/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp b/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp
index dc2b5165b..ec157cfec 100644
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp
@@ -37,9 +37,10 @@
 // this may have to change if searching becomes too slow.
 
 class StubCodeDesc: public CHeapObj<mtCode> {
- protected:
+ private:
   static StubCodeDesc* volatile _list;         // the list of all descriptors
   static int           _count;                 // length of list
+  static bool          _frozen;                // determines whether _list modifications are allowed
 
   StubCodeDesc*        _next;                  // the next element in the linked list
   const char*          _group;                 // the group to which the stub code belongs
@@ -68,6 +69,7 @@ class StubCodeDesc: public CHeapObj<mtCode> {
   static const char*   name_for(address pc);     // returns the name of the code containing pc or NULL
 
   StubCodeDesc(const char* group, const char* name, address begin) {
+    assert(!_frozen, "no modifications allowed");
     assert(name != NULL, "no name specified");
     _next           = (StubCodeDesc*)OrderAccess::load_ptr_acquire(&_list);
     _group          = group;
@@ -78,6 +80,8 @@ class StubCodeDesc: public CHeapObj<mtCode> {
     OrderAccess::release_store_ptr(&_list, this);
   };
 
+  static void freeze();
+
   const char* group() const                      { return _group; }
   const char* name() const                       { return _name; }
   int         index() const                      { return _index; }
@@ -117,7 +121,7 @@ class StubCodeGenerator: public StackObj {
 // later via an address pointing into it.
 
 class StubCodeMark: public StackObj {
- protected:
+ private:
   StubCodeGenerator* _cgen;
   StubCodeDesc*      _cdesc;
 
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
index 50543ac73..95dbb77fb 100644
--- a/hotspot/src/share/vm/runtime/thread.cpp
+++ b/hotspot/src/share/vm/runtime/thread.cpp
@@ -3615,6 +3615,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
 
   quicken_jni_functions();
 
+  // No more stub generation allowed after that point.
+  StubCodeDesc::freeze();
+
   // Set flag that basic initialization has completed. Used by exceptions and various
   // debug stuff, that does not work until all basic classes have been initialized.
   set_init_completed();
