re PR libgcj/11780 (Method.invoke() is slow)

PR libgcj/11780:
	* java/lang/reflect/natMethod.cc (invoke): Look up caller and
	perform accessibility check only if target is non-public and
	accessible flag is not set.
	* java/lang/reflect/natField.cc (getAddr): Likewise.

From-SVN: r72918
This commit is contained in:
Bryce McKinlay 2003-10-25 06:49:20 +00:00 committed by Bryce McKinlay
parent b2398b4947
commit a10fd35601
3 changed files with 57 additions and 36 deletions

View file

@ -1,3 +1,11 @@
2003-10-25 Bryce McKinlay <bryce@mckinlay.net.nz>
PR libgcj/11780:
* java/lang/reflect/natMethod.cc (invoke): Look up caller and perform
accessibility check only if target is non-public and accessible flag
is not set.
* java/lang/reflect/natField.cc (getAddr): Likewise.
2003-10-24 Thomas Fitzsimmons <fitzsim@redhat.com> 2003-10-24 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkDialogPeer.java (handleEvent): * gnu/java/awt/peer/gtk/GtkDialogPeer.java (handleEvent):

View file

@ -58,27 +58,32 @@ getAddr (java::lang::reflect::Field* field, jclass caller, jobject obj)
// have the compiler insert the caller as a hidden argument in some // have the compiler insert the caller as a hidden argument in some
// calls. However, we never implemented that, so we have to find // calls. However, we never implemented that, so we have to find
// the caller by hand instead. // the caller by hand instead.
using namespace java::lang::reflect;
jfieldID fld = _Jv_FromReflectedField (field);
_Jv_ushort flags = fld->getModifiers();
// Check accessibility, if required.
if (! (Modifier::isPublic (flags) || field->isAccessible()))
{
gnu::gcj::runtime::StackTrace *t gnu::gcj::runtime::StackTrace *t
= new gnu::gcj::runtime::StackTrace(7); = new gnu::gcj::runtime::StackTrace(7);
try try
{ {
// We want to skip all the frames on the stack from this class. // We want to skip all the frames on the stack from this class.
for (int i = 1; for (int i = 1; !caller || caller == &Field::class$; i++)
!caller || caller == &java::lang::reflect::Field::class$;
i++)
caller = t->classAt (i); caller = t->classAt (i);
} }
catch (::java::lang::ArrayIndexOutOfBoundsException *e) catch (::java::lang::ArrayIndexOutOfBoundsException *e)
{ {
} }
jfieldID fld = _Jv_FromReflectedField (field); if (! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags))
_Jv_ushort flags = fld->getModifiers();
if (! field->isAccessible ()
&& ! _Jv_CheckAccess (caller, field->getDeclaringClass(), flags))
throw new java::lang::IllegalAccessException; throw new java::lang::IllegalAccessException;
}
if (flags & java::lang::reflect::Modifier::STATIC) if (flags & Modifier::STATIC)
{ {
jclass fldClass = field->getDeclaringClass (); jclass fldClass = field->getDeclaringClass ();
JvInitClass(fldClass); JvInitClass(fldClass);

View file

@ -28,6 +28,7 @@ details. */
#include <java/lang/Long.h> #include <java/lang/Long.h>
#include <java/lang/Float.h> #include <java/lang/Float.h>
#include <java/lang/Double.h> #include <java/lang/Double.h>
#include <java/lang/IllegalAccessException.h>
#include <java/lang/IllegalArgumentException.h> #include <java/lang/IllegalArgumentException.h>
#include <java/lang/NullPointerException.h> #include <java/lang/NullPointerException.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h> #include <java/lang/ArrayIndexOutOfBoundsException.h>
@ -141,26 +142,15 @@ get_ffi_type (jclass klass)
jobject jobject
java::lang::reflect::Method::invoke (jobject obj, jobjectArray args) java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
{ {
using namespace java::lang::reflect;
if (parameter_types == NULL) if (parameter_types == NULL)
getType (); getType ();
gnu::gcj::runtime::StackTrace *t
= new gnu::gcj::runtime::StackTrace(4);
Class *caller = NULL;
try
{
for (int i = 1; !caller; i++)
{
caller = t->classAt (i);
}
}
catch (::java::lang::ArrayIndexOutOfBoundsException *e)
{
}
jmethodID meth = _Jv_FromReflectedMethod (this); jmethodID meth = _Jv_FromReflectedMethod (this);
jclass klass; jclass klass;
if (! java::lang::reflect::Modifier::isStatic(meth->accflags)) if (! Modifier::isStatic(meth->accflags))
{ {
if (! obj) if (! obj)
throw new java::lang::NullPointerException; throw new java::lang::NullPointerException;
@ -181,8 +171,26 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
klass = declaringClass; klass = declaringClass;
} }
if (! isAccessible() && ! _Jv_CheckAccess(caller, klass, meth->accflags)) // Check accessibility, if required.
throw new IllegalArgumentException; if (! (Modifier::isPublic (meth->accflags) || this->isAccessible()))
{
gnu::gcj::runtime::StackTrace *t
= new gnu::gcj::runtime::StackTrace(4);
Class *caller = NULL;
try
{
for (int i = 1; !caller; i++)
{
caller = t->classAt (i);
}
}
catch (::java::lang::ArrayIndexOutOfBoundsException *e)
{
}
if (! _Jv_CheckAccess(caller, klass, meth->accflags))
throw new IllegalAccessException;
}
return _Jv_CallAnyMethodA (obj, return_type, meth, false, return _Jv_CallAnyMethodA (obj, return_type, meth, false,
parameter_types, args); parameter_types, args);