7198429: need checked categorization of caller-sensitive methods in the JDK
Reviewed-by: kvn, jrose
This commit is contained in:
parent
e4b1cf5f02
commit
6964a690ed
@ -790,6 +790,17 @@ int ciMethod::scale_count(int count, float prof_factor) {
|
||||
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
|
||||
|
||||
|
@ -166,8 +166,9 @@ class ciMethod : public ciMetadata {
|
||||
// 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 @@ class ciMethod : public ciMetadata {
|
||||
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;
|
||||
|
@ -1735,9 +1735,14 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d
|
||||
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 @@ ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() {
|
||||
}
|
||||
|
||||
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))
|
||||
|
@ -119,6 +119,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
enum Location { _in_field, _in_method, _in_class };
|
||||
enum ID {
|
||||
_unknown = 0,
|
||||
_method_CallerSensitive,
|
||||
_method_ForceInline,
|
||||
_method_DontInline,
|
||||
_method_LambdaForm_Compiled,
|
||||
|
@ -321,6 +321,13 @@ ClassLoaderData::~ClassLoaderData() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -191,6 +191,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
|
||||
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.
|
||||
|
@ -1050,15 +1050,16 @@ class java_lang_invoke_MemberName: AllStatic {
|
||||
|
||||
// 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:
|
||||
|
@ -146,6 +146,17 @@ bool SystemDictionary::is_parallelDefine(Handle class_loader) {
|
||||
}
|
||||
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
|
||||
|
||||
|
@ -106,6 +106,7 @@ class SymbolPropertyTable;
|
||||
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 @@ class SymbolPropertyTable;
|
||||
/* 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 @@ private:
|
||||
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.
|
||||
|
||||
|
@ -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") \
|
||||
|
@ -967,6 +967,32 @@ bool Method::should_not_be_cached() const {
|
||||
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 @@ vmSymbols::SID Method::klass_id_for_intrinsics(Klass* holder) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -118,11 +118,12 @@ class Method : public Metadata {
|
||||
#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 @@ class Method : public Metadata {
|
||||
// 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 @@ class Method : public Metadata {
|
||||
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();
|
||||
}
|
||||
|
@ -231,7 +231,6 @@ class LibraryCallKit : public GraphKit {
|
||||
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 @@ CallGenerator* Compile::make_vm_intrinsic(ciMethod* m, bool is_virtual) {
|
||||
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 @@ bool LibraryCallKit::inline_native_getClass() {
|
||||
}
|
||||
|
||||
//-----------------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 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
|
||||
}
|
||||
#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 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
|
||||
#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;
|
||||
// depth.
|
||||
JVMState* caller_jvms = jvms();
|
||||
|
||||
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;
|
||||
}
|
||||
caller_jvms = caller_jvms->caller();
|
||||
--inlining_depth;
|
||||
} while (inlining_depth > 0);
|
||||
}
|
||||
|
||||
if (inlining_depth == 0) {
|
||||
// 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 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(" Bailing out: CallerSensitive annotation expected at frame %d", n);
|
||||
}
|
||||
#endif
|
||||
return false; // Reached end of inlining
|
||||
return false; // bail-out; let JVM_GetCallerClass do the work
|
||||
}
|
||||
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(" 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 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) {
|
||||
|
@ -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_END
|
||||
|
||||
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 @@ JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env))
|
||||
KlassLink* first = NULL;
|
||||
KlassLink* last = NULL;
|
||||
int depth = 0;
|
||||
vframeStream vfst(thread);
|
||||
|
||||
for(vframeStream vfst(thread); !vfst.at_end(); vfst.security_get_caller_frame(1)) {
|
||||
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));
|
||||
|
@ -105,14 +105,15 @@ void MethodHandles::set_enabled(bool z) {
|
||||
|
||||
// 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 @@ oop MethodHandles::init_method_MemberName(oop mname_oop, Method* m, bool do_disp
|
||||
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 @@ JVM_END
|
||||
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) \
|
||||
|
@ -868,7 +868,7 @@ static inline void throw_new(JNIEnv *env, const char *ename) {
|
||||
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 @@ static jclass Unsafe_DefineClass(JNIEnv *env, jstring name, jbyteArray data, int
|
||||
}
|
||||
|
||||
|
||||
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 @@ UNSAFE_ENTRY(jclass, Unsafe_DefineClass0(JNIEnv *env, jobject unsafe, jstring na
|
||||
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 @@ UNSAFE_END
|
||||
#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 @@ UNSAFE_END
|
||||
|
||||
|
||||
|
||||
// %%% 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 @@ static JNINativeMethod methods_140[] = {
|
||||
|
||||
{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 @@ static JNINativeMethod methods_140[] = {
|
||||
{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 @@ static JNINativeMethod methods_141[] = {
|
||||
|
||||
{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 @@ static JNINativeMethod methods_141[] = {
|
||||
{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 @@ static JNINativeMethod methods_141[] = {
|
||||
|
||||
};
|
||||
|
||||
// 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 @@ static JNINativeMethod methods_15[] = {
|
||||
|
||||
{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 @@ static JNINativeMethod methods_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)},
|
||||
@ -1509,15 +1499,13 @@ static JNINativeMethod methods_15[] = {
|
||||
|
||||
};
|
||||
|
||||
// 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),
|
||||
@ -1540,8 +1528,6 @@ static JNINativeMethod methods[] = {
|
||||
|
||||
{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)},
|
||||
@ -1554,7 +1540,7 @@ static JNINativeMethod methods[] = {
|
||||
{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 +1552,68 @@ static JNINativeMethod methods[] = {
|
||||
{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)},
|
||||
// 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)},
|
||||
|
||||
// {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)}
|
||||
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"("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)}
|
||||
};
|
||||
|
||||
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 @@ JNINativeMethod prefetch_methods[] = {
|
||||
{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 @@ JNINativeMethod lform_methods[] = {
|
||||
{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 @@ JNINativeMethod lform_methods[] = {
|
||||
#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 @@ JVM_ENTRY(void, JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls))
|
||||
UnsafeWrapper("JVM_RegisterUnsafeMethods");
|
||||
{
|
||||
ThreadToNativeFromVM ttnfv(thread);
|
||||
|
||||
// Unsafe methods
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
{
|
||||
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;
|
||||
// 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
|
||||
{
|
||||
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();
|
||||
}
|
||||
register_natives("1.7 define anonymous class method", env, unsafecls, anonk_methods, sizeof(anonk_methods)/sizeof(JNINativeMethod));
|
||||
}
|
||||
|
||||
// Unsafe.shouldBeInitialized
|
||||
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 LambdaForm support", env, unsafecls, lform_methods, sizeof(lform_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));
|
||||
}
|
||||
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
|
||||
|
@ -391,40 +391,27 @@ vframeStream::vframeStream(JavaThread* thread, frame top_frame,
|
||||
// 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;
|
||||
|
||||
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;
|
||||
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
|
||||
}
|
||||
if (method()->is_prefixed_native()) {
|
||||
skip_prefixed_method_and_wrappers();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
// 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.
|
||||
}
|
||||
|
||||
|
||||
void vframeStreamCommon::security_next() {
|
||||
if (method()->is_prefixed_native()) {
|
||||
skip_prefixed_method_and_wrappers(); // calls next()
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -336,6 +336,7 @@ class vframeStreamCommon : StackObj {
|
||||
_frame = _frame.sender(&_reg_map);
|
||||
} while (!fill_from_frame());
|
||||
}
|
||||
void security_next();
|
||||
|
||||
bool at_end() const { return _mode == at_end_mode; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user