7198429: need checked categorization of caller-sensitive methods in the JDK
authortwisti
Mon, 25 Mar 2013 17:13:26 -0700
changeset 16617 6235d2c7549f
parent 16616 4c8e1c4a798b
child 16618 0d73b54bf055
7198429: need checked categorization of caller-sensitive methods in the JDK Reviewed-by: kvn, jrose
hotspot/src/share/vm/ci/ciMethod.cpp
hotspot/src/share/vm/ci/ciMethod.hpp
hotspot/src/share/vm/classfile/classFileParser.cpp
hotspot/src/share/vm/classfile/classFileParser.hpp
hotspot/src/share/vm/classfile/classLoaderData.cpp
hotspot/src/share/vm/classfile/classLoaderData.hpp
hotspot/src/share/vm/classfile/javaClasses.hpp
hotspot/src/share/vm/classfile/systemDictionary.cpp
hotspot/src/share/vm/classfile/systemDictionary.hpp
hotspot/src/share/vm/classfile/vmSymbols.hpp
hotspot/src/share/vm/oops/method.cpp
hotspot/src/share/vm/oops/method.hpp
hotspot/src/share/vm/opto/library_call.cpp
hotspot/src/share/vm/prims/jvm.cpp
hotspot/src/share/vm/prims/methodHandles.cpp
hotspot/src/share/vm/prims/unsafe.cpp
hotspot/src/share/vm/runtime/vframe.cpp
hotspot/src/share/vm/runtime/vframe.hpp
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -790,6 +790,17 @@
   return count;
 }
 
+
+// ------------------------------------------------------------------
+// ciMethod::is_special_get_caller_class_method
+//
+bool ciMethod::is_ignored_by_security_stack_walk() const {
+  check_is_loaded();
+  VM_ENTRY_MARK;
+  return get_Method()->is_ignored_by_security_stack_walk();
+}
+
+
 // ------------------------------------------------------------------
 // invokedynamic support
 
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Mon Mar 25 17:13:26 2013 -0700
@@ -166,8 +166,9 @@
   // Code size for inlining decisions.
   int code_size_for_inlining();
 
-  bool force_inline() { return get_Method()->force_inline(); }
-  bool dont_inline()  { return get_Method()->dont_inline();  }
+  bool caller_sensitive() { return get_Method()->caller_sensitive(); }
+  bool force_inline()     { return get_Method()->force_inline();     }
+  bool dont_inline()      { return get_Method()->dont_inline();      }
 
   int comp_level();
   int highest_osr_comp_level();
@@ -264,6 +265,9 @@
   int instructions_size();
   int scale_count(int count, float prof_factor = 1.);  // make MDO count commensurate with IIC
 
+  // Stack walking support
+  bool is_ignored_by_security_stack_walk() const;
+
   // JSR 292 support
   bool is_method_handle_intrinsic()  const;
   bool is_compiled_lambda_form() const;
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -1735,9 +1735,14 @@
                                                                 Symbol* name) {
   vmSymbols::SID sid = vmSymbols::find_sid(name);
   // Privileged code can use all annotations.  Other code silently drops some.
-  bool privileged = loader_data->is_the_null_class_loader_data() ||
-                    loader_data->is_anonymous();
+  const bool privileged = loader_data->is_the_null_class_loader_data() ||
+                          loader_data->is_ext_class_loader_data() ||
+                          loader_data->is_anonymous();
   switch (sid) {
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_reflect_CallerSensitive_signature):
+    if (_location != _in_method)  break;  // only allow for methods
+    if (!privileged)              break;  // only allow in privileged code
+    return _method_CallerSensitive;
   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
     if (_location != _in_method)  break;  // only allow for methods
     if (!privileged)              break;  // only allow in privileged code
@@ -1775,6 +1780,8 @@
 }
 
 void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
+  if (has_annotation(_method_CallerSensitive))
+    m->set_caller_sensitive(true);
   if (has_annotation(_method_ForceInline))
     m->set_force_inline(true);
   if (has_annotation(_method_DontInline))
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp	Mon Mar 25 17:13:26 2013 -0700
@@ -119,6 +119,7 @@
     enum Location { _in_field, _in_method, _in_class };
     enum ID {
       _unknown = 0,
+      _method_CallerSensitive,
       _method_ForceInline,
       _method_DontInline,
       _method_LambdaForm_Compiled,
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -321,6 +321,13 @@
   }
 }
 
+/**
+ * Returns true if this class loader data is for the extension class loader.
+ */
+bool ClassLoaderData::is_ext_class_loader_data() const {
+  return SystemDictionary::is_ext_class_loader(class_loader());
+}
+
 Metaspace* ClassLoaderData::metaspace_non_null() {
   assert(!DumpSharedSpaces, "wrong metaspace!");
   // If the metaspace has not been allocated, create a new one.  Might want
--- a/hotspot/src/share/vm/classfile/classLoaderData.hpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/classfile/classLoaderData.hpp	Mon Mar 25 17:13:26 2013 -0700
@@ -191,6 +191,7 @@
   bool is_the_null_class_loader_data() const {
     return this == _the_null_class_loader_data;
   }
+  bool is_ext_class_loader_data() const;
 
   // The Metaspace is created lazily so may be NULL.  This
   // method will allocate a Metaspace if needed.
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp	Mon Mar 25 17:13:26 2013 -0700
@@ -1050,15 +1050,16 @@
 
   // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
   enum {
-    MN_IS_METHOD           = 0x00010000, // method (not constructor)
-    MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
-    MN_IS_FIELD            = 0x00040000, // field
-    MN_IS_TYPE             = 0x00080000, // nested type
+    MN_IS_METHOD            = 0x00010000, // method (not constructor)
+    MN_IS_CONSTRUCTOR       = 0x00020000, // constructor
+    MN_IS_FIELD             = 0x00040000, // field
+    MN_IS_TYPE              = 0x00080000, // nested type
+    MN_CALLER_SENSITIVE     = 0x00100000, // @CallerSensitive annotation detected
     MN_REFERENCE_KIND_SHIFT = 24, // refKind
-    MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+    MN_REFERENCE_KIND_MASK  = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
     // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
-    MN_SEARCH_SUPERCLASSES = 0x00100000, // walk super classes
-    MN_SEARCH_INTERFACES   = 0x00200000  // walk implemented interfaces
+    MN_SEARCH_SUPERCLASSES  = 0x00100000, // walk super classes
+    MN_SEARCH_INTERFACES    = 0x00200000  // walk implemented interfaces
   };
 
   // Accessors for code generation:
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -146,6 +146,17 @@
    }
    return false;
 }
+
+/**
+ * Returns true if the passed class loader is the extension class loader.
+ */
+bool SystemDictionary::is_ext_class_loader(Handle class_loader) {
+  if (class_loader.is_null()) {
+    return false;
+  }
+  return (class_loader->klass()->name() == vmSymbols::sun_misc_Launcher_ExtClassLoader());
+}
+
 // ----------------------------------------------------------------------------
 // Resolving of classes
 
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp	Mon Mar 25 17:13:26 2013 -0700
@@ -106,6 +106,7 @@
   do_klass(ThreadDeath_klass,                           java_lang_ThreadDeath,                     Pre                 ) \
   do_klass(Exception_klass,                             java_lang_Exception,                       Pre                 ) \
   do_klass(RuntimeException_klass,                      java_lang_RuntimeException,                Pre                 ) \
+  do_klass(SecurityManager_klass,                       java_lang_SecurityManager,                 Pre                 ) \
   do_klass(ProtectionDomain_klass,                      java_security_ProtectionDomain,            Pre                 ) \
   do_klass(AccessControlContext_klass,                  java_security_AccessControlContext,        Pre                 ) \
   do_klass(ClassNotFoundException_klass,                java_lang_ClassNotFoundException,          Pre                 ) \
@@ -138,13 +139,14 @@
   /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */                              \
   /* Universe::is_gte_jdk14x_version() is not set up by this point. */                                                   \
   /* It's okay if this turns out to be NULL in non-1.4 JDKs. */                                                          \
-  do_klass(lambda_MagicLambdaImpl_klass,                java_lang_invoke_MagicLambdaImpl, Opt ) \
+  do_klass(lambda_MagicLambdaImpl_klass,                java_lang_invoke_MagicLambdaImpl,          Opt                 ) \
   do_klass(reflect_MagicAccessorImpl_klass,             sun_reflect_MagicAccessorImpl,             Opt                 ) \
   do_klass(reflect_MethodAccessorImpl_klass,            sun_reflect_MethodAccessorImpl,            Opt_Only_JDK14NewRef) \
   do_klass(reflect_ConstructorAccessorImpl_klass,       sun_reflect_ConstructorAccessorImpl,       Opt_Only_JDK14NewRef) \
   do_klass(reflect_DelegatingClassLoader_klass,         sun_reflect_DelegatingClassLoader,         Opt                 ) \
   do_klass(reflect_ConstantPool_klass,                  sun_reflect_ConstantPool,                  Opt_Only_JDK15      ) \
   do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15      ) \
+  do_klass(reflect_CallerSensitive_klass,               sun_reflect_CallerSensitive,               Opt                 ) \
                                                                                                                          \
   /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */                                            \
   do_klass(MethodHandle_klass,                          java_lang_invoke_MethodHandle,             Pre_JSR292          ) \
@@ -628,12 +630,15 @@
   static bool is_parallelCapable(Handle class_loader);
   static bool is_parallelDefine(Handle class_loader);
 
+public:
+  static bool is_ext_class_loader(Handle class_loader);
+
+private:
   static Klass* find_shared_class(Symbol* class_name);
 
   // Setup link to hierarchy
   static void add_to_hierarchy(instanceKlassHandle k, TRAPS);
 
-private:
   // We pass in the hashtable index so we can calculate it outside of
   // the SystemDictionary_lock.
 
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Mon Mar 25 17:13:26 2013 -0700
@@ -91,6 +91,7 @@
   template(java_lang_StringBuffer,                    "java/lang/StringBuffer")                   \
   template(java_lang_StringBuilder,                   "java/lang/StringBuilder")                  \
   template(java_lang_CharSequence,                    "java/lang/CharSequence")                   \
+  template(java_lang_SecurityManager,                 "java/lang/SecurityManager")                \
   template(java_security_AccessControlContext,        "java/security/AccessControlContext")       \
   template(java_security_ProtectionDomain,            "java/security/ProtectionDomain")           \
   template(java_io_OutputStream,                      "java/io/OutputStream")                     \
@@ -211,6 +212,8 @@
   template(sun_reflect_SerializationConstructorAccessorImpl, "sun/reflect/SerializationConstructorAccessorImpl") \
   template(sun_reflect_DelegatingClassLoader,         "sun/reflect/DelegatingClassLoader")        \
   template(sun_reflect_Reflection,                    "sun/reflect/Reflection")                   \
+  template(sun_reflect_CallerSensitive,               "sun/reflect/CallerSensitive")              \
+  template(sun_reflect_CallerSensitive_signature,     "Lsun/reflect/CallerSensitive;")            \
   template(checkedExceptions_name,                    "checkedExceptions")                        \
   template(clazz_name,                                "clazz")                                    \
   template(exceptionTypes_name,                       "exceptionTypes")                           \
@@ -343,6 +346,7 @@
   template(contextClassLoader_name,                   "contextClassLoader")                       \
   template(inheritedAccessControlContext_name,        "inheritedAccessControlContext")            \
   template(isPrivileged_name,                         "isPrivileged")                             \
+  template(getClassContext_name,                      "getClassContext")                          \
   template(wait_name,                                 "wait")                                     \
   template(checkPackageAccess_name,                   "checkPackageAccess")                       \
   template(stackSize_name,                            "stackSize")                                \
@@ -463,6 +467,7 @@
   template(void_classloader_signature,                "()Ljava/lang/ClassLoader;")                                \
   template(void_object_signature,                     "()Ljava/lang/Object;")                                     \
   template(void_class_signature,                      "()Ljava/lang/Class;")                                      \
+  template(void_class_array_signature,                "()[Ljava/lang/Class;")                                     \
   template(void_string_signature,                     "()Ljava/lang/String;")                                     \
   template(object_array_object_signature,             "([Ljava/lang/Object;)Ljava/lang/Object;")                  \
   template(object_object_array_object_signature,      "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")\
@@ -705,9 +710,8 @@
   do_intrinsic(_getLength,                java_lang_reflect_Array, getLength_name, object_int_signature,         F_SN)  \
    do_name(     getLength_name,                                   "getLength")                                          \
                                                                                                                         \
-  do_intrinsic(_getCallerClass,           sun_reflect_Reflection, getCallerClass_name, getCallerClass_signature, F_SN)  \
+  do_intrinsic(_getCallerClass,           sun_reflect_Reflection, getCallerClass_name, void_class_signature,     F_SN)  \
    do_name(     getCallerClass_name,                             "getCallerClass")                                      \
-   do_signature(getCallerClass_signature,                        "(I)Ljava/lang/Class;")                                \
                                                                                                                         \
   do_intrinsic(_newArray,                 java_lang_reflect_Array, newArray_name, newArray_signature,            F_SN)  \
    do_name(     newArray_name,                                    "newArray")                                           \
--- a/hotspot/src/share/vm/oops/method.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -967,6 +967,32 @@
   return false;
 }
 
+
+/**
+ *  Returns true if this is one of the specially treated methods for
+ *  security related stack walks (like Reflection.getCallerClass).
+ */
+bool Method::is_ignored_by_security_stack_walk() const {
+  const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection;
+
+  assert(intrinsic_id() != vmIntrinsics::_invoke || Universe::reflect_invoke_cache()->is_same_method((Method*)this), "sanity");
+  if (intrinsic_id() == vmIntrinsics::_invoke) {
+    // This is Method.invoke() -- ignore it
+    return true;
+  }
+  if (use_new_reflection &&
+      method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
+    // This is an auxilary frame -- ignore it
+    return true;
+  }
+  if (is_method_handle_intrinsic() || is_compiled_lambda_form()) {
+    // This is an internal adapter frame for method handles -- ignore it
+    return true;
+  }
+  return false;
+}
+
+
 // Constant pool structure for invoke methods:
 enum {
   _imcp_invoke_name = 1,        // utf8: 'invokeExact', etc.
@@ -1178,13 +1204,13 @@
   // because we are not loading from core libraries
   // exception: the AES intrinsics come from lib/ext/sunjce_provider.jar
   // which does not use the class default class loader so we check for its loader here
-  if ((InstanceKlass::cast(holder)->class_loader() != NULL) &&
-       InstanceKlass::cast(holder)->class_loader()->klass()->name() != vmSymbols::sun_misc_Launcher_ExtClassLoader()) {
+  InstanceKlass* ik = InstanceKlass::cast(holder);
+  if ((ik->class_loader() != NULL) && !SystemDictionary::is_ext_class_loader(ik->class_loader())) {
     return vmSymbols::NO_SID;   // regardless of name, no intrinsics here
   }
 
   // see if the klass name is well-known:
-  Symbol* klass_name = InstanceKlass::cast(holder)->name();
+  Symbol* klass_name = ik->name();
   return vmSymbols::find_sid(klass_name);
 }
 
--- a/hotspot/src/share/vm/oops/method.hpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp	Mon Mar 25 17:13:26 2013 -0700
@@ -118,11 +118,12 @@
 #endif
   u2                _method_size;                // size of this object
   u1                _intrinsic_id;               // vmSymbols::intrinsic_id (0 == _none)
-  u1                _jfr_towrite  : 1,           // Flags
-                    _force_inline : 1,
-                    _hidden       : 1,
-                    _dont_inline  : 1,
-                                  : 4;
+  u1                _jfr_towrite      : 1,       // Flags
+                    _caller_sensitive : 1,
+                    _force_inline     : 1,
+                    _hidden           : 1,
+                    _dont_inline      : 1,
+                                      : 3;
   u2                _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
   u2                _number_of_breakpoints;      // fullspeed debugging support
   InvocationCounter _invocation_counter;         // Incremented before each activation of the method - used to trigger frequency-based optimizations
@@ -618,6 +619,9 @@
   // Reflection support
   bool is_overridden_in(Klass* k) const;
 
+  // Stack walking support
+  bool is_ignored_by_security_stack_walk() const;
+
   // JSR 292 support
   bool is_method_handle_intrinsic() const;          // MethodHandles::is_signature_polymorphic_intrinsic(intrinsic_id)
   bool is_compiled_lambda_form() const;             // intrinsic_id() == vmIntrinsics::_compiledLambdaForm
@@ -705,15 +709,16 @@
   void init_intrinsic_id();     // updates from _none if a match
   static vmSymbols::SID klass_id_for_intrinsics(Klass* holder);
 
-  bool jfr_towrite()                 { return _jfr_towrite; }
-  void set_jfr_towrite(bool towrite) { _jfr_towrite = towrite; }
-
-  bool     force_inline()       { return _force_inline;     }
-  void set_force_inline(bool x) {        _force_inline = x; }
-  bool     dont_inline()        { return _dont_inline;      }
-  void set_dont_inline(bool x)  {        _dont_inline = x;  }
-  bool  is_hidden()             { return _hidden;           }
-  void set_hidden(bool x)       {        _hidden = x;       }
+  bool     jfr_towrite()            { return _jfr_towrite;          }
+  void set_jfr_towrite(bool x)      {        _jfr_towrite = x;      }
+  bool     caller_sensitive()       { return _caller_sensitive;     }
+  void set_caller_sensitive(bool x) {        _caller_sensitive = x; }
+  bool     force_inline()           { return _force_inline;         }
+  void set_force_inline(bool x)     {        _force_inline = x;     }
+  bool     dont_inline()            { return _dont_inline;          }
+  void set_dont_inline(bool x)      {        _dont_inline = x;      }
+  bool  is_hidden()                 { return _hidden;               }
+  void set_hidden(bool x)           {        _hidden = x;           }
   ConstMethod::MethodType method_type() const {
       return _constMethod->method_type();
   }
--- a/hotspot/src/share/vm/opto/library_call.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -231,7 +231,6 @@
   void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark);
   bool inline_native_clone(bool is_virtual);
   bool inline_native_Reflection_getCallerClass();
-  bool is_method_invoke_or_aux_frame(JVMState* jvms);
   // Helper function for inlining native object hash method
   bool inline_native_hashcode(bool is_virtual, bool is_static);
   bool inline_native_getClass();
@@ -393,7 +392,7 @@
   case vmIntrinsics::_getCallerClass:
     if (!UseNewReflection)  return NULL;
     if (!InlineReflectionGetCallerClass)  return NULL;
-    if (!JDK_Version::is_gte_jdk14x_version())  return NULL;
+    if (SystemDictionary::reflect_CallerSensitive_klass() == NULL)  return NULL;
     break;
 
   case vmIntrinsics::_bitCount_i:
@@ -3872,13 +3871,13 @@
 }
 
 //-----------------inline_native_Reflection_getCallerClass---------------------
-// public static native Class<?> sun.reflect.Reflection.getCallerClass(int realFramesToSkip);
+// public static native Class<?> sun.reflect.Reflection.getCallerClass();
 //
 // In the presence of deep enough inlining, getCallerClass() becomes a no-op.
 //
-// NOTE that this code must perform the same logic as
-// vframeStream::security_get_caller_frame in that it must skip
-// Method.invoke() and auxiliary frames.
+// NOTE: This code must perform the same logic as JVM_GetCallerClass
+// in that it must skip particular security frames and checks for
+// caller sensitive methods.
 bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
 #ifndef PRODUCT
   if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
@@ -3886,35 +3885,6 @@
   }
 #endif
 
-  Node* caller_depth_node = argument(0);
-
-  // The depth value must be a constant in order for the runtime call
-  // to be eliminated.
-  const TypeInt* caller_depth_type = _gvn.type(caller_depth_node)->isa_int();
-  if (caller_depth_type == NULL || !caller_depth_type->is_con()) {
-#ifndef PRODUCT
-    if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
-      tty->print_cr("  Bailing out because caller depth was not a constant");
-    }
-#endif
-    return false;
-  }
-  // Note that the JVM state at this point does not include the
-  // getCallerClass() frame which we are trying to inline. The
-  // semantics of getCallerClass(), however, are that the "first"
-  // frame is the getCallerClass() frame, so we subtract one from the
-  // requested depth before continuing. We don't inline requests of
-  // getCallerClass(0).
-  int caller_depth = caller_depth_type->get_con() - 1;
-  if (caller_depth < 0) {
-#ifndef PRODUCT
-    if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
-      tty->print_cr("  Bailing out because caller depth was %d", caller_depth);
-    }
-#endif
-    return false;
-  }
-
   if (!jvms()->has_method()) {
 #ifndef PRODUCT
     if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
@@ -3923,95 +3893,67 @@
 #endif
     return false;
   }
-  int _depth = jvms()->depth();  // cache call chain depth
 
   // Walk back up the JVM state to find the caller at the required
-  // depth. NOTE that this code must perform the same logic as
-  // vframeStream::security_get_caller_frame in that it must skip
-  // Method.invoke() and auxiliary frames. Note also that depth is
-  // 1-based (1 is the bottom of the inlining).
-  int inlining_depth = _depth;
-  JVMState* caller_jvms = NULL;
-
-  if (inlining_depth > 0) {
-    caller_jvms = jvms();
-    assert(caller_jvms = jvms()->of_depth(inlining_depth), "inlining_depth == our depth");
-    do {
-      // The following if-tests should be performed in this order
-      if (is_method_invoke_or_aux_frame(caller_jvms)) {
-        // Skip a Method.invoke() or auxiliary frame
-      } else if (caller_depth > 0) {
-        // Skip real frame
-        --caller_depth;
-      } else {
-        // We're done: reached desired caller after skipping.
-        break;
+  // depth.
+  JVMState* caller_jvms = jvms();
+
+  // Cf. JVM_GetCallerClass
+  // NOTE: Start the loop at depth 1 because the current JVM state does
+  // not include the Reflection.getCallerClass() frame.
+  for (int n = 1; caller_jvms != NULL; caller_jvms = caller_jvms->caller(), n++) {
+    ciMethod* m = caller_jvms->method();
+    switch (n) {
+    case 0:
+      fatal("current JVM state does not include the Reflection.getCallerClass frame");
+      break;
+    case 1:
+      // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass).
+      if (!m->caller_sensitive()) {
+#ifndef PRODUCT
+        if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
+          tty->print_cr("  Bailing out: CallerSensitive annotation expected at frame %d", n);
+        }
+#endif
+        return false;  // bail-out; let JVM_GetCallerClass do the work
       }
-      caller_jvms = caller_jvms->caller();
-      --inlining_depth;
-    } while (inlining_depth > 0);
-  }
-
-  if (inlining_depth == 0) {
+      break;
+    default:
+      if (!m->is_ignored_by_security_stack_walk()) {
+        // We have reached the desired frame; return the holder class.
+        // Acquire method holder as java.lang.Class and push as constant.
+        ciInstanceKlass* caller_klass = caller_jvms->method()->holder();
+        ciInstance* caller_mirror = caller_klass->java_mirror();
+        set_result(makecon(TypeInstPtr::make(caller_mirror)));
+
 #ifndef PRODUCT
-    if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
-      tty->print_cr("  Bailing out because caller depth (%d) exceeded inlining depth (%d)", caller_depth_type->get_con(), _depth);
-      tty->print_cr("  JVM state at this point:");
-      for (int i = _depth; i >= 1; i--) {
-        ciMethod* m = jvms()->of_depth(i)->method();
-        tty->print_cr("   %d) %s.%s", i, m->holder()->name()->as_utf8(), m->name()->as_utf8());
-      }
-    }
+        if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
+          tty->print_cr("  Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth());
+          tty->print_cr("  JVM state at this point:");
+          for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
+            ciMethod* m = jvms()->of_depth(i)->method();
+            tty->print_cr("   %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8());
+          }
+        }
 #endif
-    return false; // Reached end of inlining
+        return true;
+      }
+      break;
+    }
   }
 
-  // Acquire method holder as java.lang.Class
-  ciInstanceKlass* caller_klass  = caller_jvms->method()->holder();
-  ciInstance*      caller_mirror = caller_klass->java_mirror();
-
-  // Push this as a constant
-  set_result(makecon(TypeInstPtr::make(caller_mirror)));
-
 #ifndef PRODUCT
   if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) {
-    tty->print_cr("  Succeeded: caller = %s.%s, caller depth = %d, depth = %d", caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), caller_depth_type->get_con(), _depth);
+    tty->print_cr("  Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth());
     tty->print_cr("  JVM state at this point:");
-    for (int i = _depth; i >= 1; i--) {
+    for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) {
       ciMethod* m = jvms()->of_depth(i)->method();
-      tty->print_cr("   %d) %s.%s", i, m->holder()->name()->as_utf8(), m->name()->as_utf8());
+      tty->print_cr("   %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8());
     }
   }
 #endif
-  return true;
-}
-
-// Helper routine for above
-bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) {
-  ciMethod* method = jvms->method();
-
-  // Is this the Method.invoke method itself?
-  if (method->intrinsic_id() == vmIntrinsics::_invoke)
-    return true;
-
-  // Is this a helper, defined somewhere underneath MethodAccessorImpl.
-  ciKlass* k = method->holder();
-  if (k->is_instance_klass()) {
-    ciInstanceKlass* ik = k->as_instance_klass();
-    for (; ik != NULL; ik = ik->super()) {
-      if (ik->name() == ciSymbol::sun_reflect_MethodAccessorImpl() &&
-          ik == env()->find_system_klass(ik->name())) {
-        return true;
-      }
-    }
-  }
-  else if (method->is_method_handle_intrinsic() ||
-           method->is_compiled_lambda_form()) {
-    // This is an internal adapter frame from the MethodHandleCompiler -- skip it
-    return true;
-  }
-
-  return false;
+
+  return false;  // bail-out; let JVM_GetCallerClass do the work
 }
 
 bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) {
--- a/hotspot/src/share/vm/prims/jvm.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -30,6 +30,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
+#include "interpreter/bytecode.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/fieldStreams.hpp"
@@ -665,8 +666,51 @@
 
 JVM_ENTRY(jclass, JVM_GetCallerClass(JNIEnv* env, int depth))
   JVMWrapper("JVM_GetCallerClass");
-  Klass* k = thread->security_get_caller_class(depth);
-  return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror());
+
+  // Pre-JDK 8 and early builds of JDK 8 don't have a CallerSensitive annotation.
+  if (SystemDictionary::reflect_CallerSensitive_klass() == NULL) {
+    Klass* k = thread->security_get_caller_class(depth);
+    return (k == NULL) ? NULL : (jclass) JNIHandles::make_local(env, k->java_mirror());
+  } else {
+    // Basic handshaking with Java_sun_reflect_Reflection_getCallerClass
+    assert(depth == -1, "wrong handshake depth");
+  }
+
+  // Getting the class of the caller frame.
+  //
+  // The call stack at this point looks something like this:
+  //
+  // [0] [ @CallerSensitive public sun.reflect.Reflection.getCallerClass ]
+  // [1] [ @CallerSensitive API.method                                   ]
+  // [.] [ (skipped intermediate frames)                                 ]
+  // [n] [ caller                                                        ]
+  vframeStream vfst(thread);
+  // Cf. LibraryCallKit::inline_native_Reflection_getCallerClass
+  for (int n = 0; !vfst.at_end(); vfst.security_next(), n++) {
+    Method* m = vfst.method();
+    assert(m != NULL, "sanity");
+    switch (n) {
+    case 0:
+      // This must only be called from Reflection.getCallerClass
+      if (m->intrinsic_id() != vmIntrinsics::_getCallerClass) {
+        THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetCallerClass must only be called from Reflection.getCallerClass");
+      }
+      // fall-through
+    case 1:
+      // Frame 0 and 1 must be caller sensitive.
+      if (!m->caller_sensitive()) {
+        THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), err_msg("CallerSensitive annotation expected at frame %d", n));
+      }
+      break;
+    default:
+      if (!m->is_ignored_by_security_stack_walk()) {
+        // We have reached the desired frame; return the holder class.
+        return (jclass) JNIHandles::make_local(env, m->method_holder()->java_mirror());
+      }
+      break;
+    }
+  }
+  return NULL;
 JVM_END
 
 
@@ -3160,11 +3204,24 @@
   KlassLink* first = NULL;
   KlassLink* last  = NULL;
   int depth = 0;
-
-  for(vframeStream vfst(thread); !vfst.at_end(); vfst.security_get_caller_frame(1)) {
+  vframeStream vfst(thread);
+
+  if (SystemDictionary::reflect_CallerSensitive_klass() != NULL) {
+    // This must only be called from SecurityManager.getClassContext
+    Method* m = vfst.method();
+    if (!(m->method_holder() == SystemDictionary::SecurityManager_klass() &&
+          m->name()          == vmSymbols::getClassContext_name() &&
+          m->signature()     == vmSymbols::void_class_array_signature())) {
+      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext");
+    }
+  }
+
+  // Collect method holders
+  for (; !vfst.at_end(); vfst.security_next()) {
+    Method* m = vfst.method();
     // Native frames are not returned
-    if (!vfst.method()->is_native()) {
-      Klass* holder = vfst.method()->method_holder();
+    if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) {
+      Klass* holder = m->method_holder();
       assert(holder->is_klass(), "just checking");
       depth++;
       KlassLink* l = new KlassLink(KlassHandle(thread, holder));
--- a/hotspot/src/share/vm/prims/methodHandles.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -105,14 +105,15 @@
 
 // import java_lang_invoke_MemberName.*
 enum {
-  IS_METHOD      = java_lang_invoke_MemberName::MN_IS_METHOD,
-  IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
-  IS_FIELD       = java_lang_invoke_MemberName::MN_IS_FIELD,
-  IS_TYPE        = java_lang_invoke_MemberName::MN_IS_TYPE,
+  IS_METHOD            = java_lang_invoke_MemberName::MN_IS_METHOD,
+  IS_CONSTRUCTOR       = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
+  IS_FIELD             = java_lang_invoke_MemberName::MN_IS_FIELD,
+  IS_TYPE              = java_lang_invoke_MemberName::MN_IS_TYPE,
+  CALLER_SENSITIVE     = java_lang_invoke_MemberName::MN_CALLER_SENSITIVE,
   REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
   REFERENCE_KIND_MASK  = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
-  SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
-  SEARCH_INTERFACES   = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
+  SEARCH_SUPERCLASSES  = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
+  SEARCH_INTERFACES    = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
   ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
 };
 
@@ -207,10 +208,15 @@
     vmindex = m->vtable_index();
   }
 
-  java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
+  // @CallerSensitive annotation detected
+  if (m->caller_sensitive()) {
+    flags |= CALLER_SENSITIVE;
+  }
+
+  java_lang_invoke_MemberName::set_flags(   mname_oop, flags);
   java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
-  java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);   // vtable/itable index
-  java_lang_invoke_MemberName::set_clazz(mname_oop,    receiver_limit->java_mirror());
+  java_lang_invoke_MemberName::set_vmindex( mname_oop, vmindex);   // vtable/itable index
+  java_lang_invoke_MemberName::set_clazz(   mname_oop, receiver_limit->java_mirror());
   // Note:  name and type can be lazily computed by resolve_MemberName,
   // if Java code needs them as resolved String and MethodType objects.
   // The clazz must be eagerly stored, because it provides a GC
@@ -940,6 +946,7 @@
     template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
+    template(java_lang_invoke_MemberName,MN_CALLER_SENSITIVE) \
     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
     template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
--- 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
--- a/hotspot/src/share/vm/runtime/vframe.cpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/runtime/vframe.cpp	Mon Mar 25 17:13:26 2013 -0700
@@ -391,40 +391,27 @@
 // Step back n frames, skip any pseudo frames in between.
 // This function is used in Class.forName, Class.newInstance, Method.Invoke,
 // AccessController.doPrivileged.
-//
-// NOTE that in JDK 1.4 this has been exposed to Java as
-// sun.reflect.Reflection.getCallerClass(), which can be inlined.
-// Inlined versions must match this routine's logic.
-// Native method prefixing logic does not need to match since
-// the method names don't match and inlining will not occur.
-// See, for example,
-// Parse::inline_native_Reflection_getCallerClass in
-// opto/library_call.cpp.
 void vframeStreamCommon::security_get_caller_frame(int depth) {
-  bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection;
+  assert(depth >= 0, err_msg("invalid depth: %d", depth));
+  for (int n = 0; !at_end(); security_next()) {
+    if (!method()->is_ignored_by_security_stack_walk()) {
+      if (n == depth) {
+        // We have reached the desired depth; return.
+        return;
+      }
+      n++;  // this is a non-skipped frame; count it against the depth
+    }
+  }
+  // NOTE: At this point there were not enough frames on the stack
+  // to walk to depth.  Callers of this method have to check for at_end.
+}
 
-  while (!at_end()) {
-    if (Universe::reflect_invoke_cache()->is_same_method(method())) {
-      // This is Method.invoke() -- skip it
-    } else if (use_new_reflection &&
-              method()->method_holder()
-                 ->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
-      // This is an auxilary frame -- skip it
-    } else if (method()->is_method_handle_intrinsic() ||
-               method()->is_compiled_lambda_form()) {
-      // This is an internal adapter frame for method handles -- skip it
-    } else {
-      // This is non-excluded frame, we need to count it against the depth
-      if (depth-- <= 0) {
-        // we have reached the desired depth, we are done
-        break;
-      }
-    }
-    if (method()->is_prefixed_native()) {
-      skip_prefixed_method_and_wrappers();
-    } else {
-      next();
-    }
+
+void vframeStreamCommon::security_next() {
+  if (method()->is_prefixed_native()) {
+    skip_prefixed_method_and_wrappers();  // calls next()
+  } else {
+    next();
   }
 }
 
--- a/hotspot/src/share/vm/runtime/vframe.hpp	Sun Mar 24 12:43:13 2013 -0700
+++ b/hotspot/src/share/vm/runtime/vframe.hpp	Mon Mar 25 17:13:26 2013 -0700
@@ -336,6 +336,7 @@
       _frame = _frame.sender(&_reg_map);
     } while (!fill_from_frame());
   }
+  void security_next();
 
   bool at_end() const { return _mode == at_end_mode; }