aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2007-04-18 17:10:32 +0000
committerAndrew Haley <aph@redhat.com>2007-04-18 17:10:32 +0000
commit92a9f19b6f93538da4b19b9e11e2d520f1dd85f6 (patch)
tree53c69afa81897fd48bf2309e77c09532bfa1178f
parent37275315286bfd9881073bf1d63b27f743d49cba (diff)
2007-04-18 Andrew Haley <aph@redhat.com>
* java/lang/reflect/natVMProxy.cc (ncode_closure): Add method_index. (generateProxyClass): Add field $Proxy0.m. Store methods array in it. (run_proxy): Retrieve the method to invoke from in $Proxy0.m. * java/lang/Class.h: Remove _Jv_LookupProxyMethod. * java/lang/natClass.cc: Likewise. * headers.txt: Likewise. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@123953 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libjava/ChangeLog11
-rw-r--r--libjava/headers.txt2
-rw-r--r--libjava/java/lang/Class.h5
-rw-r--r--libjava/java/lang/natClass.cc33
-rw-r--r--libjava/java/lang/reflect/natVMProxy.cc51
5 files changed, 50 insertions, 52 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 31bbd012d2c..9a874aea297 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,14 @@
+2007-04-18 Andrew Haley <aph@redhat.com>
+
+ * java/lang/reflect/natVMProxy.cc (ncode_closure): Add
+ method_index.
+ (generateProxyClass): Add field $Proxy0.m. Store methods array in
+ it.
+ (run_proxy): Retrieve the method to invoke from in $Proxy0.m.
+ * java/lang/Class.h: Remove _Jv_LookupProxyMethod.
+ * java/lang/natClass.cc: Likewise.
+ * headers.txt: Likewise.
+
2007-04-16 Andrew Haley <aph@redhat.com>
* gnu/gcj/runtime/BootClassLoader.java (getBootURLLoader): New
diff --git a/libjava/headers.txt b/libjava/headers.txt
index 3e08f175889..c7a4caa3bf4 100644
--- a/libjava/headers.txt
+++ b/libjava/headers.txt
@@ -57,13 +57,11 @@ class java/lang/reflect/Method
prepend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
prepend jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
prepend ::java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass, _Jv_Utf8Const*, _Jv_Utf8Const*);
-prepend ::java::lang::reflect::Method *_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *, _Jv_Utf8Const *);
friend jmethodID (::_Jv_FromReflectedMethod) (java::lang::reflect::Method *);
friend jobject (::_Jv_JNI_ToReflectedMethod) (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
friend class java::lang::Class;
friend class java::io::ObjectInputStream;
friend java::lang::reflect::Method* ::_Jv_GetReflectedMethod (jclass, _Jv_Utf8Const*, _Jv_Utf8Const*);
-friend java::lang::reflect::Method* ::_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *, _Jv_Utf8Const *);
class gnu/gcj/runtime/ExtensionClassLoader
friend class ::java::lang::ClassLoader;
diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h
index a1795f7e58c..af0219892f1 100644
--- a/libjava/java/lang/Class.h
+++ b/libjava/java/lang/Class.h
@@ -237,8 +237,6 @@ _Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
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);
@@ -547,9 +545,6 @@ private:
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);
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc
index a6955fcf4ff..754681d832a 100644
--- a/libjava/java/lang/natClass.cc
+++ b/libjava/java/lang/natClass.cc
@@ -1653,39 +1653,6 @@ _Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
return NULL;
}
-// The rules for finding proxy methods are different: first we search
-// the interfaces implemented by a proxy, then the methods declared in
-// class Proxy.
-
-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)
diff --git a/libjava/java/lang/reflect/natVMProxy.cc b/libjava/java/lang/reflect/natVMProxy.cc
index f0191760794..e5f8fbe52aa 100644
--- a/libjava/java/lang/reflect/natVMProxy.cc
+++ b/libjava/java/lang/reflect/natVMProxy.cc
@@ -66,7 +66,7 @@ using namespace java::lang::reflect;
using namespace java::lang;
typedef void (*closure_fun) (ffi_cif*, void*, void**, void*);
-static void *ncode (jclass klass, _Jv_Method *self, closure_fun fun);
+static void *ncode (int method_index, jclass klass, _Jv_Method *self, closure_fun fun);
static void run_proxy (ffi_cif*, void*, void**, void*);
typedef jobject invoke_t (jobject, Proxy *, Method *, JArray< jobject > *);
@@ -92,15 +92,24 @@ java::lang::reflect::VMProxy::generateProxyClass
return (new Proxy$ClassFactory(d))->generate(loader);
jclass klass = new Class ();
- klass->superclass = &Proxy::class$;
- klass->engine = &_Jv_soleIndirectCompiledEngine;
- klass->size_in_bytes = Proxy::class$.size_in_bytes;
- klass->vtable_method_count = -1;
// Synchronize on the class, so that it is not attempted initialized
// until we're done.
JvSynchronize sync (klass);
+ klass->superclass = &Proxy::class$;
+ klass->engine = &_Jv_soleIndirectCompiledEngine;
+ klass->size_in_bytes = -1;
+ klass->vtable_method_count = -1;
+
+ // Declare private static transient java.lang.reflect.Method[] $Proxy0.m
+ klass->field_count = klass->static_field_count = 1;
+ klass->fields = (_Jv_Field*)_Jv_AllocRawObj (sizeof (_Jv_Field));
+ klass->fields[0].name = _Jv_makeUtf8Const ("m");
+ klass->fields[0].type = d->methods->getClass();
+ klass->fields[0].flags = (Modifier::PRIVATE | Modifier::STATIC
+ | Modifier::TRANSIENT);
+
// Record the defining loader. For the bootstrap class loader,
// we record NULL.
if (loader != VMClassLoader::bootLoader)
@@ -158,20 +167,27 @@ java::lang::reflect::VMProxy::generateProxyClass
for (size_t i = 0; i < count; i++)
{
_Jv_Method &method = klass->methods[method_count++];
- const _Jv_Method &imethod = *_Jv_FromReflectedMethod (elements(d->methods)[i]);
+ const _Jv_Method &imethod
+ = *_Jv_FromReflectedMethod (elements(d->methods)[i]);
// We use a shallow copy of IMETHOD rather than a deep copy;
// this means that the pointer fields of METHOD point into the
// interface. As long as this subclass of Proxy is reachable,
// the interfaces of which it is a proxy will also be reachable,
// so this is safe.
method = imethod;
- method.ncode = ncode (klass, &method, run_proxy);
+ method.ncode = ncode (i, klass, &method, run_proxy);
method.accflags &= ~Modifier::ABSTRACT;
}
_Jv_Linker::layout_vtable_methods (klass);
_Jv_RegisterInitiatingLoader (klass, klass->loader);
+ // Set $Proxy0.m to point to the methods arrray
+ java::lang::reflect::Field *f
+ = klass->getDeclaredField (JvNewStringLatin1 ("m"));
+ f->flag = true;
+ f->set(NULL, d->methods);
+
return klass;
}
@@ -292,6 +308,7 @@ typedef struct {
_Jv_ClosureList list;
ffi_cif cif;
_Jv_Method *self;
+ int method_index;
ffi_type *arg_types[0];
} ncode_closure;
@@ -306,17 +323,26 @@ run_proxy (ffi_cif *cif,
Proxy *proxy = *(Proxy**)args[0];
ncode_closure *self = (ncode_closure *) user_data;
+ jclass proxyClass = proxy->getClass();
+
// FRAME_DESC registers this particular invocation as the top-most
// interpreter frame. This lets the stack tracing code (for
// Throwable) print information about the Proxy being run rather
// than about Proxy.class itself. FRAME_DESC has a destructor so it
// cleans up automatically when this proxy invocation returns.
Thread *thread = Thread::currentThread();
- _Jv_InterpFrame frame_desc (self->self, thread, proxy->getClass());
+ _Jv_InterpFrame frame_desc (self->self, thread, proxyClass);
+
+ // The method to invoke is saved in $Proxy0.m[method_index].
+ // FIXME: We could somewhat improve efficiency by storing a pointer
+ // to the method (rather than its index) in ncode_closure. This
+ // would avoid the lookup, but it probably wouldn't make a huge
+ // difference. We'd still have to save the method array because
+ // ncode structs are not scanned by the gc.
+ Field *f = proxyClass->getDeclaredField (JvNewStringLatin1 ("m"));
+ JArray<Method*> *methods = (JArray<Method*>*)f->get (NULL);
+ Method *meth = elements(methods)[self->method_index];
- Method *meth = _Jv_LookupProxyMethod (proxy->getClass(),
- self->self->name,
- self->self->signature);
JArray<jclass> *parameter_types = meth->internalGetParameterTypes ();
JArray<jclass> *exception_types = meth->internalGetExceptionTypes ();
@@ -374,7 +400,7 @@ run_proxy (ffi_cif *cif,
// the address of its closure.
static void *
-ncode (jclass klass, _Jv_Method *self, closure_fun fun)
+ncode (int method_index, jclass klass, _Jv_Method *self, closure_fun fun)
{
using namespace java::lang::reflect;
@@ -386,6 +412,7 @@ ncode (jclass klass, _Jv_Method *self, closure_fun fun)
(ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
+ arg_count * sizeof (ffi_type*),
&code);
+ closure->method_index = method_index;
closure->list.registerClosure (klass, closure);
_Jv_init_cif (self->signature,