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]

RFC: libffi usage in link.cc & late String creation


Hi,
the following patch should fix PR 26073 (ARM build failure because of libffi
usage in link.cc) and parts of PR 26063. There was a String instance which was
created without being referenced by any other object so it may possible that the
GC collects it to early (at least this is how I understood it).

Please comment.

The ChangeLog:

2006-02-02  Robert Schuster  <robertschuster@fsfe.org>

	* include/jvm.h:
	(_Jv_Linker::create_error_method): New method declaration.
	* link.cc:
	(_Jv_Linker::create_error_method): New method.
	(_Jv_Linker::link_symbol_table): Use new method above.

cya
Robert
Index: include/jvm.h
===================================================================
--- include/jvm.h	(Revision 110517)
+++ include/jvm.h	(Arbeitskopie)
@@ -264,6 +264,7 @@
   static _Jv_Method *search_method_in_class (jclass, jclass,
 					     _Jv_Utf8Const *,
 					     _Jv_Utf8Const *);
+  static void *create_error_method(_Jv_Utf8Const *);
 
 public:
 
Index: link.cc
===================================================================
--- link.cc	(Revision 110517)
+++ link.cc	(Arbeitskopie)
@@ -767,6 +767,7 @@
   throw new java::lang::NoSuchMethodError;
 }
 
+#ifdef USE_LIBFFI
 // A function whose invocation is prepared using libffi. It gets called
 // whenever a static method of a missing class is invoked. The data argument
 // holds a reference to a String denoting the missing class.
@@ -777,14 +778,18 @@
                                         void **,
                                         void *data)
 {
-  throw new java::lang::NoClassDefFoundError((jstring) data);
+  throw new java::lang::NoClassDefFoundError(
+    _Jv_NewStringUtf8Const( (_Jv_Utf8Const *) data));
 }
-
+#else
+// A variant of the NoClassDefFoundError throwing method that can
+// be used without libffi.
 void
 _Jv_ThrowNoClassDefFoundError()
 {
   throw new java::lang::NoClassDefFoundError();
 }
+#endif
 
 // Throw a NoSuchFieldError.  Called by compiler-generated code when
 // an otable entry is zero.  OTABLE_INDEX is the index in the caller's
@@ -950,6 +955,51 @@
 }
 
 
+void *
+_Jv_Linker::create_error_method (_Jv_Utf8Const *class_name)
+{
+#ifdef USE_LIBFFI
+  // TODO: The following structs/objects are heap allocated are
+  // unreachable by the garbage collector:
+  // - cif, arg_types
+
+  ffi_closure *closure = (ffi_closure *) _Jv_Malloc( sizeof( ffi_closure ));
+  ffi_cif *cif = (ffi_cif *) _Jv_Malloc( sizeof( ffi_cif ));
+
+  // Pretends that we want to call a void (*) (void) function via
+  // ffi_call.
+  ffi_type **arg_types = (ffi_type **) _Jv_Malloc( sizeof( ffi_type * ));
+  arg_types[0] = &ffi_type_void;
+
+  // Initializes the cif and the closure. If that worked the closure is
+  // stored as a function pointer in the atable.
+  if (ffi_prep_cif (
+        cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, arg_types) == FFI_OK
+      && (ffi_prep_closure (
+            closure, cif, _Jv_ThrowNoClassDefFoundErrorTrampoline,
+            (void *) class_name) == FFI_OK))
+    {
+      return (void *) closure;
+    }
+    else
+    {
+      java::lang::StringBuffer *buffer = new java::lang::StringBuffer();
+      buffer->append(
+        JvNewStringLatin1("Error setting up FFI closure"
+                          " for static method of missing class: "));
+      
+      buffer->append (_Jv_NewStringUtf8Const(class_name));
+
+      throw new java::lang::InternalError(buffer->toString());
+    }
+#else
+  // Codepath for platforms which do not support (or want) libffi.
+  // You have to accept that it is impossible to provide the name
+  // of the missing class then.
+  return (void *) _Jv_ThrowNoClassDefFoundError;
+#endif
+}
+
 // Functions for indirect dispatch (symbolic virtual binding) support.
 
 // There are three tables, atable otable and itable.  atable is an
@@ -1118,46 +1168,7 @@
       // code in classes where the missing class is part of the
       // execution environment as long as it is never referenced.
       if (target_class == NULL)
-        {
-          // TODO: The following structs/objects are heap allocated are
-          // unreachable by the garbage collector:
-          // - cif, arg_types
-          // - the Java string inside the if-statement
-
-          ffi_closure *closure =
-            (ffi_closure *) _Jv_Malloc( sizeof( ffi_closure ));
-          ffi_cif *cif = (ffi_cif *) _Jv_Malloc( sizeof( ffi_cif ));
-
-          // Pretends that we want to call a void (*) (void) function via
-          // ffi_call.
-          ffi_type **arg_types = (ffi_type **) _Jv_Malloc( sizeof( ffi_type * ));
-          arg_types[0] = &ffi_type_void;
-
-          // Initializes the cif and the closure. If that worked the closure is
-          // stored as a function pointer in the atable.
-          if ( ffi_prep_cif(cif, FFI_DEFAULT_ABI, 1,
-                            &ffi_type_void, arg_types) == FFI_OK
-               && (ffi_prep_closure 
-                   (closure, cif,
-                   _Jv_ThrowNoClassDefFoundErrorTrampoline,
-                   (void *) _Jv_NewStringUtf8Const(sym.class_name))
-                   == FFI_OK))
-            {
-              klass->atable->addresses[index] = (void *) closure;
-            }
-          else
-            {
-              // If you land here it is possible that your architecture does
-              // not support the Closure API yet. Let's port it!
-              java::lang::StringBuffer *buffer = new java::lang::StringBuffer();
-              buffer->append 
-                (JvNewStringLatin1("Error setting up FFI closure"
-                                   " for static method of missing class: "));
-              buffer->append (_Jv_NewStringUtf8Const(sym.class_name));
-
-              throw new java::lang::InternalError(buffer->toString());
-            }
-        }
+        klass->atable->addresses[index] = create_error_method(sym.class_name);
       // We're looking for a static field or a static method, and we
       // can tell which is needed by looking at the signature.
       else if (signature->first() == '(' && signature->len() >= 2)
@@ -1198,10 +1209,8 @@
 		}
 	    }
 	  else
-            // TODO: Use _Jv_ThrowNoClassDefFoundErrorTrampoline to be able
-            // to print the class name.
 	    klass->atable->addresses[index]
-		= (void *) _Jv_ThrowNoClassDefFoundError;
+              = create_error_method(sym.class_name);
 
 	  continue;
 	}

Attachment: signature.asc
Description: OpenPGP digital signature


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