This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Proxies, again


Andrew Haley writes:
 > OK, I'm going with this.

Argh.  Nooo, that's broken too.  This is just so totally FUBAR.  One
more time, with feeling...

Andrew.


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.

Index: java/lang/reflect/natVMProxy.cc
===================================================================
--- java/lang/reflect/natVMProxy.cc	(revision 123861)
+++ java/lang/reflect/natVMProxy.cc	(working copy)
@@ -66,7 +66,7 @@
 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 @@
     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 @@
   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 @@
   _Jv_ClosureList list;
   ffi_cif   cif;
   _Jv_Method *self;
+  int method_index;
   ffi_type *arg_types[0];
 } ncode_closure;
 
@@ -306,17 +323,26 @@
   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 @@
 // 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_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,
Index: headers.txt
===================================================================
--- headers.txt	(revision 123861)
+++ headers.txt	(working copy)
@@ -57,13 +57,11 @@
 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;
Index: java/lang/Class.h
===================================================================
--- java/lang/Class.h	(revision 123861)
+++ java/lang/Class.h	(working copy)
@@ -237,8 +237,6 @@
 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 @@
   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: java/lang/natClass.cc
===================================================================
--- java/lang/natClass.cc	(revision 123861)
+++ java/lang/natClass.cc	(working copy)
@@ -1653,39 +1653,6 @@
   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)
Index: java/lang/reflect/Method.h
===================================================================
--- java/lang/reflect/Method.h	(revision 123861)
+++ java/lang/reflect/Method.h	(working copy)
@@ -13,7 +13,6 @@
 jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
 jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);
 ::java::lang::reflect::Method *_Jv_GetReflectedMethod (jclass, _Jv_Utf8Const*, _Jv_Utf8Const*);
-::java::lang::reflect::Method *_Jv_LookupProxyMethod (jclass, _Jv_Utf8Const *, _Jv_Utf8Const *);
 
 class java::lang::reflect::Method : public ::java::lang::reflect::AccessibleObject
 {
@@ -80,7 +79,6 @@
   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 *);
 };
 
 #endif // __java_lang_reflect_Method__


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]