提交 7aa0c342 编写于 作者: T twisti

6914206: change way of permission checking for generated MethodHandle adapters

Summary: Put generated MH adapter in InvokeDynamic/MethodHandle classes to be able to indentify them easily in the compiler.
Reviewed-by: kvn, never, jrose
上级 550662f1
/* /*
* Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -700,6 +700,12 @@ bool ciMethod::is_method_handle_invoke() const { ...@@ -700,6 +700,12 @@ bool ciMethod::is_method_handle_invoke() const {
return flag; return flag;
} }
bool ciMethod::is_method_handle_adapter() const {
check_is_loaded();
VM_ENTRY_MARK;
return get_methodOop()->is_method_handle_adapter();
}
ciInstance* ciMethod::method_handle_type() { ciInstance* ciMethod::method_handle_type() {
check_is_loaded(); check_is_loaded();
VM_ENTRY_MARK; VM_ENTRY_MARK;
......
/* /*
* Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -215,7 +215,10 @@ class ciMethod : public ciObject { ...@@ -215,7 +215,10 @@ class ciMethod : public ciObject {
bool check_call(int refinfo_index, bool is_static) const; bool check_call(int refinfo_index, bool is_static) const;
void build_method_data(); // make sure it exists in the VM also void build_method_data(); // make sure it exists in the VM also
int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC
bool is_method_handle_invoke() const;
// JSR 292 support
bool is_method_handle_invoke() const;
bool is_method_handle_adapter() const;
ciInstance* method_handle_type(); ciInstance* method_handle_type();
// What kind of ciObject is this? // What kind of ciObject is this?
......
/* /*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -145,7 +145,7 @@ class SymbolPropertyTable; ...@@ -145,7 +145,7 @@ class SymbolPropertyTable;
template(Linkage_klass, java_dyn_Linkage, Opt) \ template(Linkage_klass, java_dyn_Linkage, Opt) \
template(CallSite_klass, java_dyn_CallSite, Opt) \ template(CallSite_klass, java_dyn_CallSite, Opt) \
template(InvokeDynamic_klass, java_dyn_InvokeDynamic, Opt) \ template(InvokeDynamic_klass, java_dyn_InvokeDynamic, Opt) \
/* Note: MethodHandle must be first, and Dynamic last in group */ \ /* Note: MethodHandle must be first, and InvokeDynamic last in group */ \
\ \
template(StringBuffer_klass, java_lang_StringBuffer, Pre) \ template(StringBuffer_klass, java_lang_StringBuffer, Pre) \
template(StringBuilder_klass, java_lang_StringBuilder, Pre) \ template(StringBuilder_klass, java_lang_StringBuilder, Pre) \
......
// //
// Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. // Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
// //
// This code is free software; you can redistribute it and/or modify it // This code is free software; you can redistribute it and/or modify it
...@@ -3503,6 +3503,7 @@ reflection.cpp javaCalls.hpp ...@@ -3503,6 +3503,7 @@ reflection.cpp javaCalls.hpp
reflection.cpp javaClasses.hpp reflection.cpp javaClasses.hpp
reflection.cpp jvm.h reflection.cpp jvm.h
reflection.cpp linkResolver.hpp reflection.cpp linkResolver.hpp
reflection.cpp methodHandleWalk.hpp
reflection.cpp objArrayKlass.hpp reflection.cpp objArrayKlass.hpp
reflection.cpp objArrayOop.hpp reflection.cpp objArrayOop.hpp
reflection.cpp oopFactory.hpp reflection.cpp oopFactory.hpp
......
/* /*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -821,6 +821,18 @@ jint* methodOopDesc::method_type_offsets_chain() { ...@@ -821,6 +821,18 @@ jint* methodOopDesc::method_type_offsets_chain() {
return pchase; return pchase;
} }
//------------------------------------------------------------------------------
// methodOopDesc::is_method_handle_adapter
//
// Tests if this method is an internal adapter frame from the
// MethodHandleCompiler.
bool methodOopDesc::is_method_handle_adapter() const {
return ((name() == vmSymbols::invoke_name() &&
method_holder() == SystemDictionary::MethodHandle_klass())
||
method_holder() == SystemDictionary::InvokeDynamic_klass());
}
methodHandle methodOopDesc::make_invoke_method(KlassHandle holder, methodHandle methodOopDesc::make_invoke_method(KlassHandle holder,
symbolHandle signature, symbolHandle signature,
Handle method_type, TRAPS) { Handle method_type, TRAPS) {
......
/* /*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -525,6 +525,9 @@ class methodOopDesc : public oopDesc { ...@@ -525,6 +525,9 @@ class methodOopDesc : public oopDesc {
// JSR 292 support // JSR 292 support
bool is_method_handle_invoke() const { return access_flags().is_method_handle_invoke(); } bool is_method_handle_invoke() const { return access_flags().is_method_handle_invoke(); }
// Tests if this method is an internal adapter frame from the
// MethodHandleCompiler.
bool is_method_handle_adapter() const;
static methodHandle make_invoke_method(KlassHandle holder, static methodHandle make_invoke_method(KlassHandle holder,
symbolHandle signature, symbolHandle signature,
Handle method_type, Handle method_type,
...@@ -538,6 +541,7 @@ class methodOopDesc : public oopDesc { ...@@ -538,6 +541,7 @@ class methodOopDesc : public oopDesc {
// all without checking for a stack overflow // all without checking for a stack overflow
static int extra_stack_entries() { return (EnableMethodHandles ? (int)MethodHandlePushLimit : 0) + (EnableInvokeDynamic ? 3 : 0); } static int extra_stack_entries() { return (EnableMethodHandles ? (int)MethodHandlePushLimit : 0) + (EnableInvokeDynamic ? 3 : 0); }
static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize() static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize()
// RedefineClasses() support: // RedefineClasses() support:
bool is_old() const { return access_flags().is_old(); } bool is_old() const { return access_flags().is_old(); }
void set_is_old() { _access_flags.set_is_old(); } void set_is_old() { _access_flags.set_is_old(); }
......
/* /*
* Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1999-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -3697,12 +3697,14 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() { ...@@ -3697,12 +3697,14 @@ bool LibraryCallKit::inline_native_Reflection_getCallerClass() {
// Helper routine for above // Helper routine for above
bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) { bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) {
ciMethod* method = jvms->method();
// Is this the Method.invoke method itself? // Is this the Method.invoke method itself?
if (jvms->method()->intrinsic_id() == vmIntrinsics::_invoke) if (method->intrinsic_id() == vmIntrinsics::_invoke)
return true; return true;
// Is this a helper, defined somewhere underneath MethodAccessorImpl. // Is this a helper, defined somewhere underneath MethodAccessorImpl.
ciKlass* k = jvms->method()->holder(); ciKlass* k = method->holder();
if (k->is_instance_klass()) { if (k->is_instance_klass()) {
ciInstanceKlass* ik = k->as_instance_klass(); ciInstanceKlass* ik = k->as_instance_klass();
for (; ik != NULL; ik = ik->super()) { for (; ik != NULL; ik = ik->super()) {
...@@ -3712,6 +3714,10 @@ bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) { ...@@ -3712,6 +3714,10 @@ bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) {
} }
} }
} }
else if (method->is_method_handle_adapter()) {
// This is an internal adapter frame from the MethodHandleCompiler -- skip it
return true;
}
return false; return false;
} }
......
...@@ -631,6 +631,7 @@ MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, boo ...@@ -631,6 +631,7 @@ MethodHandleCompiler::MethodHandleCompiler(Handle root, methodHandle callee, boo
Handle first_mtype(THREAD, chain().method_type_oop()); Handle first_mtype(THREAD, chain().method_type_oop());
// _rklass is NULL for primitives. // _rklass is NULL for primitives.
_rtype = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(first_mtype()), &_rklass); _rtype = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(first_mtype()), &_rklass);
if (_rtype == T_ARRAY) _rtype = T_OBJECT;
int params = _callee->size_of_parameters(); // Incoming arguments plus receiver. int params = _callee->size_of_parameters(); // Incoming arguments plus receiver.
_num_params = for_invokedynamic() ? params - 1 : params; // XXX Check if callee is static? _num_params = for_invokedynamic() ? params - 1 : params; // XXX Check if callee is static?
...@@ -957,10 +958,13 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid, ...@@ -957,10 +958,13 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
symbolOop name = m->name(); symbolOop name = m->name();
symbolOop signature = m->signature(); symbolOop signature = m->signature();
// This generated adapter method should be in the same class as the
// DMH target method (for accessability reasons).
if (tailcall) { if (tailcall) {
_target_klass = klass; // Actually, in order to make these methods more recognizable,
// let's put them in holder classes MethodHandle and InvokeDynamic.
// That way stack walkers and compiler heuristics can recognize them.
_target_klass = (for_invokedynamic()
? SystemDictionary::InvokeDynamic_klass()
: SystemDictionary::MethodHandle_klass());
} }
// instanceKlass* ik = instanceKlass::cast(klass); // instanceKlass* ik = instanceKlass::cast(klass);
...@@ -1017,6 +1021,7 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid, ...@@ -1017,6 +1021,7 @@ MethodHandleCompiler::make_invoke(methodOop m, vmIntrinsics::ID iid,
// If tailcall, we have walked all the way to a direct method handle. // If tailcall, we have walked all the way to a direct method handle.
// Otherwise, make a recursive call to some helper routine. // Otherwise, make a recursive call to some helper routine.
BasicType rbt = m->result_type(); BasicType rbt = m->result_type();
if (rbt == T_ARRAY) rbt = T_OBJECT;
ArgToken ret; ArgToken ret;
if (tailcall) { if (tailcall) {
if (rbt != _rtype) { if (rbt != _rtype) {
......
...@@ -404,4 +404,10 @@ public: ...@@ -404,4 +404,10 @@ public:
// Compile the given MH chain into bytecode. // Compile the given MH chain into bytecode.
methodHandle compile(TRAPS); methodHandle compile(TRAPS);
// Tests if the given class is a MH adapter holder.
static bool klass_is_method_handle_adapter_holder(klassOop klass) {
return (klass == SystemDictionary::MethodHandle_klass() ||
klass == SystemDictionary::InvokeDynamic_klass());
}
}; };
/* /*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -482,6 +482,11 @@ bool Reflection::can_relax_access_check_for( ...@@ -482,6 +482,11 @@ bool Reflection::can_relax_access_check_for(
under_host_klass(accessee_ik, accessor)) under_host_klass(accessee_ik, accessor))
return true; return true;
// Adapter frames can access anything.
if (MethodHandleCompiler::klass_is_method_handle_adapter_holder(accessor))
// This is an internal adapter frame from the MethodHandleCompiler.
return true;
if (RelaxAccessControlCheck || if (RelaxAccessControlCheck ||
(accessor_ik->major_version() < JAVA_1_5_VERSION && (accessor_ik->major_version() < JAVA_1_5_VERSION &&
accessee_ik->major_version() < JAVA_1_5_VERSION)) { accessee_ik->major_version() < JAVA_1_5_VERSION)) {
......
/* /*
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. * Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -432,6 +432,8 @@ void vframeStreamCommon::security_get_caller_frame(int depth) { ...@@ -432,6 +432,8 @@ void vframeStreamCommon::security_get_caller_frame(int depth) {
Klass::cast(method()->method_holder()) Klass::cast(method()->method_holder())
->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) { ->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
// This is an auxilary frame -- skip it // This is an auxilary frame -- skip it
} else if (method()->is_method_handle_adapter()) {
// This is an internal adapter frame from the MethodHandleCompiler -- skip it
} else { } else {
// This is non-excluded frame, we need to count it against the depth // This is non-excluded frame, we need to count it against the depth
if (depth-- <= 0) { if (depth-- <= 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册