Proxies, again
Andrew Haley
aph@redhat.com
Sat Mar 31 09:41:00 GMT 2007
The devil is in the details, especially in this case. My "fast"
native version of Proxy was wrong, and returned incorrect
declaringClass fields for each Method. I really need to cache these
Method instances in the Proxy rather than generating them on the fly,
and I'll look at that later.
In the meantime, the question arises about what we should do for the
compiler that is being shipped with Fedora 7. I could disable this
"fast" native version of Proxy.
Thoughts? Go with this patch, or just fall back to Classpath's
interpreted Proxy?
Andrew.
Index: Class.h
===================================================================
--- Class.h (revision 123156)
+++ Class.h (working copy)
@@ -237,6 +237,8 @@
java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass klass,
_Jv_Utf8Const *name,
_Jv_Utf8Const *signature);
+java::lang::reflect::Method *_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *,
+ _Jv_Utf8Const *);
jfieldID JvGetFirstInstanceField (jclass);
jint JvNumInstanceFields (jclass);
jfieldID JvGetFirstStaticField (jclass);
@@ -545,6 +547,9 @@
friend java::lang::reflect::Method* ::_Jv_GetReflectedMethod (jclass klass,
_Jv_Utf8Const *name,
_Jv_Utf8Const *signature);
+ friend java::lang::reflect::Method *::_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *,
+ _Jv_Utf8Const *);
+
friend jfieldID (::JvGetFirstInstanceField) (jclass);
friend jint (::JvNumInstanceFields) (jclass);
friend jfieldID (::JvGetFirstStaticField) (jclass);
Index: natClass.cc
===================================================================
--- natClass.cc (revision 123156)
+++ natClass.cc (working copy)
@@ -29,6 +29,7 @@
#include <java/lang/reflect/Member.h>
#include <java/lang/reflect/Method.h>
#include <java/lang/reflect/Field.h>
+#include <java/lang/reflect/Proxy.h>
#include <java/lang/reflect/Constructor.h>
#include <java/lang/AbstractMethodError.h>
#include <java/lang/ArrayStoreException.h>
@@ -1653,6 +1654,35 @@
}
java::lang::reflect::Method *
+_Jv_LookupProxyMethod (jclass proxyClass, _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
+{
+ using namespace java::lang::reflect;
+ jclass declaringClass;
+ _Jv_Method * m;
+
+ for (int i = 0; i < proxyClass->interface_count; i++)
+ {
+ declaringClass = proxyClass->interfaces[i];
+ m = _Jv_GetMethodLocal (declaringClass, name, signature);
+ if (m)
+ break;
+ }
+ if (!m)
+ m = _Jv_LookupDeclaredMethod (&Proxy::class$,
+ name,
+ signature,
+ &declaringClass);
+
+ Method *rmethod = new Method ();
+ rmethod->offset = (char*) m - (char*) declaringClass->methods;
+ rmethod->declaringClass = declaringClass;
+ return rmethod;
+}
+
+
+
+java::lang::reflect::Method *
_Jv_GetReflectedMethod (jclass klass, _Jv_Utf8Const *name,
_Jv_Utf8Const *signature)
{
Index: reflect/natVMProxy.cc
===================================================================
--- reflect/natVMProxy.cc (revision 123156)
+++ reflect/natVMProxy.cc (working copy)
@@ -301,6 +301,8 @@
void **args,
void*user_data)
{
+ using namespace java::lang::reflect;
+
Proxy *proxy = *(Proxy**)args[0];
ncode_closure *self = (ncode_closure *) user_data;
@@ -312,17 +314,22 @@
Thread *thread = Thread::currentThread();
_Jv_InterpFrame frame_desc (self->self, thread, proxy->getClass());
- Method *meth = _Jv_GetReflectedMethod (proxy->getClass(),
- self->self->name,
- self->self->signature);
+ Method *meth = _Jv_LookupProxyMethod (proxy->getClass(),
+ self->self->name,
+ self->self->signature);
JArray<jclass> *parameter_types = meth->internalGetParameterTypes ();
JArray<jclass> *exception_types = meth->internalGetExceptionTypes ();
InvocationHandler *handler = proxy->h;
- void *poo
- = _Jv_NewObjectArray (parameter_types->length, &Object::class$, NULL);
- JArray<jobject> *argsArray = (JArray<jobject> *) poo;
- jobject *jargs = elements(argsArray);
+ JArray<jobject> *argsArray = NULL;
+ jobject *jargs = NULL;
+ if (parameter_types->length)
+ {
+ void *poo
+ = _Jv_NewObjectArray (parameter_types->length, &Object::class$, NULL);
+ argsArray = (JArray<jobject> *) poo;
+ jargs = elements(argsArray);
+ }
// FIXME: It must be possible to use fast interface dispatch here,
// but I've not quite figured out how to do it.
--
Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, UK
Registered in England and Wales No. 3798903
More information about the Java-patches
mailing list