From 0df38d45e19aecc86c549ec57be93b7c7d9ac867 Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Wed, 18 Apr 2007 17:10:32 +0000 Subject: [PATCH] natVMProxy.cc (ncode_closure): Add method_index. 2007-04-18 Andrew Haley * 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. From-SVN: r123953 --- libjava/ChangeLog | 11 +++++++ libjava/headers.txt | 2 -- libjava/java/lang/Class.h | 5 ---- libjava/java/lang/natClass.cc | 33 --------------------- libjava/java/lang/reflect/natVMProxy.cc | 51 +++++++++++++++++++++++++-------- 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 + + * 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 * 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 *methods = (JArray*)f->get (NULL); + Method *meth = elements(methods)[self->method_index]; - Method *meth = _Jv_LookupProxyMethod (proxy->getClass(), - self->self->name, - self->self->signature); JArray *parameter_types = meth->internalGetParameterTypes (); JArray *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, -- 2.11.4.GIT