hotspot/src/share/vm/prims/unsafe.cpp
changeset 16617 6235d2c7549f
parent 15482 470d0b0c09f1
child 17316 c1f00a6ecf59
--- a/hotspot/src/share/vm/prims/unsafe.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -868,7 +868,7 @@
   env->ThrowNew(cls, msg);
 }
 
-static jclass Unsafe_DefineClass(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
+static jclass Unsafe_DefineClass_impl(JNIEnv *env, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd) {
   {
     // Code lifted from JDK 1.3 ClassLoader.c
 
@@ -939,6 +939,15 @@
 }
 
 
+UNSAFE_ENTRY(jclass, Unsafe_DefineClass(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd))
+  UnsafeWrapper("Unsafe_DefineClass");
+  {
+    ThreadToNativeFromVM ttnfv(thread);
+    return Unsafe_DefineClass_impl(env, name, data, offset, length, loader, pd);
+  }
+UNSAFE_END
+
+
 UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length))
   UnsafeWrapper("Unsafe_DefineClass");
   {
@@ -949,20 +958,11 @@
     jobject loader = (caller == NULL) ? NULL : JVM_GetClassLoader(env, caller);
     jobject pd     = (caller == NULL) ? NULL : JVM_GetProtectionDomain(env, caller);
 
-    return Unsafe_DefineClass(env, name, data, offset, length, loader, pd);
+    return Unsafe_DefineClass_impl(env, name, data, offset, length, loader, pd);
   }
 UNSAFE_END
 
 
-UNSAFE_ENTRY(jclass, Unsafe_DefineClass1(JNIEnv *env, jobject unsafe, jstring name, jbyteArray data, int offset, int length, jobject loader, jobject pd))
-  UnsafeWrapper("Unsafe_DefineClass");
-  {
-    ThreadToNativeFromVM ttnfv(thread);
-
-    return Unsafe_DefineClass(env, name, data, offset, length, loader, pd);
-  }
-UNSAFE_END
-
 #define DAC_Args CLS"[B["OBJ
 // define a class but do not make it known to the class loader or system dictionary
 // - host_class:  supplies context for linkage, access control, protection domain, and class loader
@@ -1323,7 +1323,7 @@
 #define THR LANG"Throwable;"
 
 #define DC0_Args LANG"String;[BII"
-#define DC1_Args DC0_Args LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"
+#define DC_Args  DC0_Args LANG"ClassLoader;" "Ljava/security/ProtectionDomain;"
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
@@ -1352,10 +1352,8 @@
 
 
 
-// %%% These are temporarily supported until the SDK sources
-// contain the necessarily updated Unsafe.java.
+// These are the methods for 1.4.0
 static JNINativeMethod methods_140[] = {
-
     {CC"getObject",        CC"("OBJ"I)"OBJ"",   FN_PTR(Unsafe_GetObject140)},
     {CC"putObject",        CC"("OBJ"I"OBJ")V",  FN_PTR(Unsafe_SetObject140)},
 
@@ -1381,12 +1379,10 @@
 
     {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
     {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-//  {CC"setMemory",          CC"("ADR"JB)V",             FN_PTR(Unsafe_SetMemory)},
-//  {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)},
     {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
 
-    {CC"fieldOffset",        CC"("FLD")I",               FN_PTR(Unsafe_FieldOffset)}, //deprecated
-    {CC"staticFieldBase",    CC"("CLS")"OBJ,             FN_PTR(Unsafe_StaticFieldBaseFromClass)}, //deprecated
+    {CC"fieldOffset",        CC"("FLD")I",               FN_PTR(Unsafe_FieldOffset)},
+    {CC"staticFieldBase",    CC"("CLS")"OBJ,             FN_PTR(Unsafe_StaticFieldBaseFromClass)},
     {CC"ensureClassInitialized",CC"("CLS")V",            FN_PTR(Unsafe_EnsureClassInitialized)},
     {CC"arrayBaseOffset",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayBaseOffset)},
     {CC"arrayIndexScale",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayIndexScale)},
@@ -1394,16 +1390,15 @@
     {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
 
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
-    {CC"defineClass",        CC"("DC1_Args")"CLS,        FN_PTR(Unsafe_DefineClass1)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
     {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
     {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
     {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)}
 };
 
-// These are the old methods prior to the JSR 166 changes in 1.5.0
+// These are the methods prior to the JSR 166 changes in 1.5.0
 static JNINativeMethod methods_141[] = {
-
     {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
     {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
 
@@ -1429,8 +1424,6 @@
 
     {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
     {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-//  {CC"setMemory",          CC"("ADR"JB)V",             FN_PTR(Unsafe_SetMemory)},
-//  {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)},
     {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
 
     {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
@@ -1443,7 +1436,7 @@
     {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
 
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
-    {CC"defineClass",        CC"("DC1_Args")"CLS,        FN_PTR(Unsafe_DefineClass1)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
     {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
     {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
@@ -1451,9 +1444,8 @@
 
 };
 
-// These are the old methods prior to the JSR 166 changes in 1.6.0
+// These are the methods prior to the JSR 166 changes in 1.6.0
 static JNINativeMethod methods_15[] = {
-
     {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
     {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
     {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObjectVolatile)},
@@ -1482,8 +1474,6 @@
 
     {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
     {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-//  {CC"setMemory",          CC"("ADR"JB)V",             FN_PTR(Unsafe_SetMemory)},
-//  {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)},
     {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
 
     {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
@@ -1496,7 +1486,7 @@
     {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
 
     {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
-    {CC"defineClass",        CC"("DC1_Args")"CLS,        FN_PTR(Unsafe_DefineClass1)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
     {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
     {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
@@ -1509,14 +1499,69 @@
 
 };
 
-// These are the correct methods, moving forward:
-static JNINativeMethod methods[] = {
-
+// These are the methods for 1.6.0 and 1.7.0
+static JNINativeMethod methods_16[] = {
     {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
     {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
     {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObjectVolatile)},
     {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObjectVolatile)},
 
+    DECLARE_GETSETOOP(Boolean, Z),
+    DECLARE_GETSETOOP(Byte, B),
+    DECLARE_GETSETOOP(Short, S),
+    DECLARE_GETSETOOP(Char, C),
+    DECLARE_GETSETOOP(Int, I),
+    DECLARE_GETSETOOP(Long, J),
+    DECLARE_GETSETOOP(Float, F),
+    DECLARE_GETSETOOP(Double, D),
+
+    DECLARE_GETSETNATIVE(Byte, B),
+    DECLARE_GETSETNATIVE(Short, S),
+    DECLARE_GETSETNATIVE(Char, C),
+    DECLARE_GETSETNATIVE(Int, I),
+    DECLARE_GETSETNATIVE(Long, J),
+    DECLARE_GETSETNATIVE(Float, F),
+    DECLARE_GETSETNATIVE(Double, D),
+
+    {CC"getAddress",         CC"("ADR")"ADR,             FN_PTR(Unsafe_GetNativeAddress)},
+    {CC"putAddress",         CC"("ADR""ADR")V",          FN_PTR(Unsafe_SetNativeAddress)},
+
+    {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
+    {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
+    {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
+
+    {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
+    {CC"staticFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_StaticFieldOffset)},
+    {CC"staticFieldBase",    CC"("FLD")"OBJ,             FN_PTR(Unsafe_StaticFieldBaseFromField)},
+    {CC"ensureClassInitialized",CC"("CLS")V",            FN_PTR(Unsafe_EnsureClassInitialized)},
+    {CC"arrayBaseOffset",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayBaseOffset)},
+    {CC"arrayIndexScale",    CC"("CLS")I",               FN_PTR(Unsafe_ArrayIndexScale)},
+    {CC"addressSize",        CC"()I",                    FN_PTR(Unsafe_AddressSize)},
+    {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
+
+    {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
+    {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
+    {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
+    {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
+    {CC"tryMonitorEnter",    CC"("OBJ")Z",               FN_PTR(Unsafe_TryMonitorEnter)},
+    {CC"throwException",     CC"("THR")V",               FN_PTR(Unsafe_ThrowException)},
+    {CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z",  FN_PTR(Unsafe_CompareAndSwapObject)},
+    {CC"compareAndSwapInt",  CC"("OBJ"J""I""I"")Z",      FN_PTR(Unsafe_CompareAndSwapInt)},
+    {CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z",      FN_PTR(Unsafe_CompareAndSwapLong)},
+    {CC"putOrderedObject",   CC"("OBJ"J"OBJ")V",         FN_PTR(Unsafe_SetOrderedObject)},
+    {CC"putOrderedInt",      CC"("OBJ"JI)V",             FN_PTR(Unsafe_SetOrderedInt)},
+    {CC"putOrderedLong",     CC"("OBJ"JJ)V",             FN_PTR(Unsafe_SetOrderedLong)},
+    {CC"park",               CC"(ZJ)V",                  FN_PTR(Unsafe_Park)},
+    {CC"unpark",             CC"("OBJ")V",               FN_PTR(Unsafe_Unpark)}
+};
+
+// These are the methods for 1.8.0
+static JNINativeMethod methods_18[] = {
+    {CC"getObject",        CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObject)},
+    {CC"putObject",        CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObject)},
+    {CC"getObjectVolatile",CC"("OBJ"J)"OBJ"",   FN_PTR(Unsafe_GetObjectVolatile)},
+    {CC"putObjectVolatile",CC"("OBJ"J"OBJ")V",  FN_PTR(Unsafe_SetObjectVolatile)},
 
     DECLARE_GETSETOOP(Boolean, Z),
     DECLARE_GETSETOOP(Byte, B),
@@ -1540,8 +1585,6 @@
 
     {CC"allocateMemory",     CC"(J)"ADR,                 FN_PTR(Unsafe_AllocateMemory)},
     {CC"reallocateMemory",   CC"("ADR"J)"ADR,            FN_PTR(Unsafe_ReallocateMemory)},
-//  {CC"setMemory",          CC"("ADR"JB)V",             FN_PTR(Unsafe_SetMemory)},
-//  {CC"copyMemory",         CC"("ADR ADR"J)V",          FN_PTR(Unsafe_CopyMemory)},
     {CC"freeMemory",         CC"("ADR")V",               FN_PTR(Unsafe_FreeMemory)},
 
     {CC"objectFieldOffset",  CC"("FLD")J",               FN_PTR(Unsafe_ObjectFieldOffset)},
@@ -1553,8 +1596,7 @@
     {CC"addressSize",        CC"()I",                    FN_PTR(Unsafe_AddressSize)},
     {CC"pageSize",           CC"()I",                    FN_PTR(Unsafe_PageSize)},
 
-    {CC"defineClass",        CC"("DC0_Args")"CLS,        FN_PTR(Unsafe_DefineClass0)},
-    {CC"defineClass",        CC"("DC1_Args")"CLS,        FN_PTR(Unsafe_DefineClass1)},
+    {CC"defineClass",        CC"("DC_Args")"CLS,         FN_PTR(Unsafe_DefineClass)},
     {CC"allocateInstance",   CC"("CLS")"OBJ,             FN_PTR(Unsafe_AllocateInstance)},
     {CC"monitorEnter",       CC"("OBJ")V",               FN_PTR(Unsafe_MonitorEnter)},
     {CC"monitorExit",        CC"("OBJ")V",               FN_PTR(Unsafe_MonitorExit)},
@@ -1566,23 +1608,12 @@
     {CC"putOrderedObject",   CC"("OBJ"J"OBJ")V",         FN_PTR(Unsafe_SetOrderedObject)},
     {CC"putOrderedInt",      CC"("OBJ"JI)V",             FN_PTR(Unsafe_SetOrderedInt)},
     {CC"putOrderedLong",     CC"("OBJ"JJ)V",             FN_PTR(Unsafe_SetOrderedLong)},
-    {CC"loadFence",          CC"()V",                    FN_PTR(Unsafe_LoadFence)},
-    {CC"storeFence",         CC"()V",                    FN_PTR(Unsafe_StoreFence)},
-    {CC"fullFence",          CC"()V",                    FN_PTR(Unsafe_FullFence)},
     {CC"park",               CC"(ZJ)V",                  FN_PTR(Unsafe_Park)},
     {CC"unpark",             CC"("OBJ")V",               FN_PTR(Unsafe_Unpark)}
-
-//    {CC"getLoadAverage",     CC"([DI)I",                 FN_PTR(Unsafe_Loadavg)},
-
-//    {CC"prefetchRead",       CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchRead)},
-//    {CC"prefetchWrite",      CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchWrite)}
-//    {CC"prefetchReadStatic", CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchRead)},
-//    {CC"prefetchWriteStatic",CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchWrite)}
-
 };
 
 JNINativeMethod loadavg_method[] = {
-    {CC"getLoadAverage",            CC"([DI)I",                 FN_PTR(Unsafe_Loadavg)}
+    {CC"getLoadAverage",     CC"([DI)I",                 FN_PTR(Unsafe_Loadavg)}
 };
 
 JNINativeMethod prefetch_methods[] = {
@@ -1592,7 +1623,7 @@
     {CC"prefetchWriteStatic",CC"("OBJ"J)V",              FN_PTR(Unsafe_PrefetchWrite)}
 };
 
-JNINativeMethod memcopy_methods[] = {
+JNINativeMethod memcopy_methods_17[] = {
     {CC"copyMemory",         CC"("OBJ"J"OBJ"JJ)V",       FN_PTR(Unsafe_CopyMemory2)},
     {CC"setMemory",          CC"("OBJ"JJB)V",            FN_PTR(Unsafe_SetMemory2)}
 };
@@ -1610,6 +1641,12 @@
     {CC"shouldBeInitialized",CC"("CLS")Z",               FN_PTR(Unsafe_ShouldBeInitialized)},
 };
 
+JNINativeMethod fence_methods[] = {
+    {CC"loadFence",          CC"()V",                    FN_PTR(Unsafe_LoadFence)},
+    {CC"storeFence",         CC"()V",                    FN_PTR(Unsafe_StoreFence)},
+    {CC"fullFence",          CC"()V",                    FN_PTR(Unsafe_FullFence)},
+};
+
 #undef CC
 #undef FN_PTR
 
@@ -1622,12 +1659,32 @@
 #undef MTH
 #undef THR
 #undef DC0_Args
-#undef DC1_Args
+#undef DC_Args
 
 #undef DECLARE_GETSETOOP
 #undef DECLARE_GETSETNATIVE
 
 
+/**
+ * Helper method to register native methods.
+ */
+static bool register_natives(const char* message, JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) {
+  int status = env->RegisterNatives(clazz, methods, nMethods);
+  if (status < 0 || env->ExceptionOccurred()) {
+    if (PrintMiscellaneous && (Verbose || WizardMode)) {
+      tty->print_cr("Unsafe:  failed registering %s", message);
+    }
+    env->ExceptionClear();
+    return false;
+  } else {
+    if (PrintMiscellaneous && (Verbose || WizardMode)) {
+      tty->print_cr("Unsafe:  successfully registered %s", message);
+    }
+    return true;
+  }
+}
+
+
 // This one function is exported, used by NativeLookup.
 // The Unsafe_xxx functions above are called only from the interpreter.
 // The optimizer looks at names and signatures to recognize
@@ -1637,83 +1694,57 @@
   UnsafeWrapper("JVM_RegisterUnsafeMethods");
   {
     ThreadToNativeFromVM ttnfv(thread);
-    {
-      env->RegisterNatives(unsafecls, loadavg_method, sizeof(loadavg_method)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.6 Unsafe.loadavg not found.");
-        }
-        env->ExceptionClear();
-      }
-    }
+
+    // Unsafe methods
     {
-      env->RegisterNatives(unsafecls, prefetch_methods, sizeof(prefetch_methods)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.6 Unsafe.prefetchRead/Write not found.");
-        }
-        env->ExceptionClear();
+      bool success = false;
+      // We need to register the 1.6 methods first because the 1.8 methods would register fine on 1.7 and 1.6
+      if (!success) {
+        success = register_natives("1.6 methods",   env, unsafecls, methods_16,  sizeof(methods_16)/sizeof(JNINativeMethod));
+      }
+      if (!success) {
+        success = register_natives("1.8 methods",   env, unsafecls, methods_18,  sizeof(methods_18)/sizeof(JNINativeMethod));
+      }
+      if (!success) {
+        success = register_natives("1.5 methods",   env, unsafecls, methods_15,  sizeof(methods_15)/sizeof(JNINativeMethod));
+      }
+      if (!success) {
+        success = register_natives("1.4.1 methods", env, unsafecls, methods_141, sizeof(methods_141)/sizeof(JNINativeMethod));
       }
+      if (!success) {
+        success = register_natives("1.4.0 methods", env, unsafecls, methods_140, sizeof(methods_140)/sizeof(JNINativeMethod));
+      }
+      guarantee(success, "register unsafe natives");
     }
+
+    // Unsafe.getLoadAverage
+    register_natives("1.6 loadavg method", env, unsafecls, loadavg_method, sizeof(loadavg_method)/sizeof(JNINativeMethod));
+
+    // Prefetch methods
+    register_natives("1.6 prefetch methods", env, unsafecls, prefetch_methods, sizeof(prefetch_methods)/sizeof(JNINativeMethod));
+
+    // Memory copy methods
     {
-      env->RegisterNatives(unsafecls, memcopy_methods, sizeof(memcopy_methods)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.7 Unsafe.copyMemory not found.");
-        }
-        env->ExceptionClear();
-        env->RegisterNatives(unsafecls, memcopy_methods_15, sizeof(memcopy_methods_15)/sizeof(JNINativeMethod));
-        if (env->ExceptionOccurred()) {
-          if (PrintMiscellaneous && (Verbose || WizardMode)) {
-            tty->print_cr("Warning:  SDK 1.5 Unsafe.copyMemory not found.");
-          }
-          env->ExceptionClear();
-        }
+      bool success = false;
+      if (!success) {
+        success = register_natives("1.7 memory copy methods", env, unsafecls, memcopy_methods_17, sizeof(memcopy_methods_17)/sizeof(JNINativeMethod));
+      }
+      if (!success) {
+        success = register_natives("1.5 memory copy methods", env, unsafecls, memcopy_methods_15, sizeof(memcopy_methods_15)/sizeof(JNINativeMethod));
       }
     }
+
+    // Unsafe.defineAnonymousClass
     if (EnableInvokeDynamic) {
-      env->RegisterNatives(unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.7 Unsafe.defineClass (anonymous version) not found.");
-        }
-        env->ExceptionClear();
-      }
-    }
-    if (EnableInvokeDynamic) {
-      env->RegisterNatives(unsafecls, lform_methods, sizeof(lform_methods)/sizeof(JNINativeMethod));
-      if (env->ExceptionOccurred()) {
-        if (PrintMiscellaneous && (Verbose || WizardMode)) {
-          tty->print_cr("Warning:  SDK 1.7 LambdaForm support in Unsafe not found.");
-        }
-        env->ExceptionClear();
-      }
+      register_natives("1.7 define anonymous class method", env, unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
     }
-    int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
-    if (env->ExceptionOccurred()) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        tty->print_cr("Warning:  SDK 1.6 version of Unsafe not found.");
-      }
-      env->ExceptionClear();
-      // %%% For now, be backward compatible with an older class:
-      status = env->RegisterNatives(unsafecls, methods_15, sizeof(methods_15)/sizeof(JNINativeMethod));
+
+    // Unsafe.shouldBeInitialized
+    if (EnableInvokeDynamic) {
+      register_natives("1.7 LambdaForm support", env, unsafecls, lform_methods, sizeof(lform_methods)/sizeof(JNINativeMethod));
     }
-    if (env->ExceptionOccurred()) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        tty->print_cr("Warning:  SDK 1.5 version of Unsafe not found.");
-      }
-      env->ExceptionClear();
-      // %%% For now, be backward compatible with an older class:
-      status = env->RegisterNatives(unsafecls, methods_141, sizeof(methods_141)/sizeof(JNINativeMethod));
-    }
-    if (env->ExceptionOccurred()) {
-      if (PrintMiscellaneous && (Verbose || WizardMode)) {
-        tty->print_cr("Warning:  SDK 1.4.1 version of Unsafe not found.");
-      }
-      env->ExceptionClear();
-      // %%% For now, be backward compatible with an older class:
-      status = env->RegisterNatives(unsafecls, methods_140, sizeof(methods_140)/sizeof(JNINativeMethod));
-    }
-    guarantee(status == 0, "register unsafe natives");
+
+    // Fence methods
+    register_natives("1.8 fence methods", env, unsafecls, fence_methods, sizeof(fence_methods)/sizeof(JNINativeMethod));
   }
 JVM_END