diff options
author | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-18 17:10:32 +0000 |
---|---|---|
committer | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-04-18 17:10:32 +0000 |
commit | cbc001af5c6f23907e7c79210570040737c803b3 (patch) | |
tree | 53c69afa81897fd48bf2309e77c09532bfa1178f /libjava/java | |
parent | e1681564dbd59ff9305c9c1a4f935d40af2a500e (diff) | |
download | gcc-cbc001af5c6f23907e7c79210570040737c803b3.tar.gz |
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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123953 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/java')
-rw-r--r-- | libjava/java/lang/Class.h | 5 | ||||
-rw-r--r-- | libjava/java/lang/natClass.cc | 33 | ||||
-rw-r--r-- | libjava/java/lang/reflect/natVMProxy.cc | 51 |
3 files changed, 39 insertions, 50 deletions
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, |