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]

Patch: PR libgcj/23367


This patch fixes PR 23367, a thread safety bug in
_Jv_FindMethodInCache.

It works by changing the method cache to be per-thread and to be
stored in TLS.  It also makes the method cache much smaller.

I tested this on a system with TLS to ensure that the method cache was
not prematurely collected by the GC (I did this by registering a
finalizer that called abort).  This seemed to work.

I'm not checking this in yet as I want to re-use some configury from
mudflap; a patch to move this into gcc/config/ is pending.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	PR libgcj/23367:
	* java/lang/natClass.cc (MCACHE_SIZE): Conditional on HAVE_TLS.
	(struct _Jv_mcache): Likewise.
	(method_cache): Likewise.
	(_Jv_FindMethodInCache): Do nothing unless TLS is available.
	(_Jv_AddMethodToCache): Likewise.
	* aclocal.m4, configure, include/config.h.in: Rebuilt.
	* configure.ac: Invoke GCC_CHECK_TLS.

Index: configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/libjava/configure.ac,v
retrieving revision 1.37
diff -u -r1.37 configure.ac
--- configure.ac 22 Aug 2005 22:39:11 -0000 1.37
+++ configure.ac 19 Sep 2005 19:55:03 -0000
@@ -1412,6 +1412,8 @@
   multilib_arg=
 fi
 
+# See if we support thread-local storage.
+GCC_CHECK_TLS
 
 
 here=`${PWDCMD-pwd}`
Index: java/lang/natClass.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClass.cc,v
retrieving revision 1.89
diff -u -r1.89 natClass.cc
--- java/lang/natClass.cc 14 Jun 2005 18:51:54 -0000 1.89
+++ java/lang/natClass.cc 19 Sep 2005 19:55:03 -0000
@@ -879,8 +879,10 @@
   return NULL;
 }
 
+#ifdef HAVE_TLS
+
 // NOTE: MCACHE_SIZE should be a power of 2 minus one.
-#define MCACHE_SIZE 1023
+#define MCACHE_SIZE 31
 
 struct _Jv_mcache
 {
@@ -888,37 +890,42 @@
   _Jv_Method *method;
 };
 
-static _Jv_mcache method_cache[MCACHE_SIZE + 1];
+static __thread _Jv_mcache *method_cache;
+#endif // HAVE_TLS
 
 static void *
 _Jv_FindMethodInCache (jclass klass,
                        _Jv_Utf8Const *name,
                        _Jv_Utf8Const *signature)
 {
-  int index = name->hash16 () & MCACHE_SIZE;
-  _Jv_mcache *mc = method_cache + index;
-  _Jv_Method *m = mc->method;
-
-  if (mc->klass == klass
-      && m != NULL             // thread safe check
-      && _Jv_equalUtf8Consts (m->name, name)
-      && _Jv_equalUtf8Consts (m->signature, signature))
-    return mc->method->ncode;
+#ifdef HAVE_TLS
+  _Jv_mcache *cache = method_cache;
+  if (cache)
+    {
+      int index = name->hash16 () & MCACHE_SIZE;
+      _Jv_mcache *mc = &cache[index];
+      _Jv_Method *m = mc->method;
+
+      if (mc->klass == klass
+	  && _Jv_equalUtf8Consts (m->name, name)
+	  && _Jv_equalUtf8Consts (m->signature, signature))
+	return mc->method->ncode;
+    }
+#endif // HAVE_TLS
   return NULL;
 }
 
 static void
-_Jv_AddMethodToCache (jclass klass,
-                       _Jv_Method *method)
+_Jv_AddMethodToCache (jclass klass, _Jv_Method *method)
 {
-  _Jv_MonitorEnter (&java::lang::Class::class$); 
-
+#ifdef HAVE_TLS
+  if (method_cache == NULL)
+    method_cache = (_Jv_mcache *) _Jv_AllocBytes((MCACHE_SIZE + 1)
+						 * sizeof (_Jv_mcache));
   int index = method->name->hash16 () & MCACHE_SIZE;
-
   method_cache[index].method = method;
   method_cache[index].klass = klass;
-
-  _Jv_MonitorExit (&java::lang::Class::class$);
+#endif // HAVE_TLS
 }
 
 void *


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