aboutsummaryrefslogtreecommitdiff
path: root/libjava/java/lang/natClass.cc
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2005-09-27 20:03:09 +0000
committerTom Tromey <tromey@gcc.gnu.org>2005-09-27 20:03:09 +0000
commitb9e6a2e5de4e94b5c3bfbe6c60e3231a200e46bc (patch)
tree18763461cdb28ee640435eb7d63f5a857583660c /libjava/java/lang/natClass.cc
parentab3fa9d34434e2aa491c216a3b9b20122179db64 (diff)
downloadgcc-b9e6a2e5de4e94b5c3bfbe6c60e3231a200e46bc.zip
gcc-b9e6a2e5de4e94b5c3bfbe6c60e3231a200e46bc.tar.gz
gcc-b9e6a2e5de4e94b5c3bfbe6c60e3231a200e46bc.tar.bz2
re PR libgcj/23367 (_Jv_FindMethodInCache is not thread-safe)
PR libgcj/23367: * include/jvm.h (_Jv_FreeMethodCache): Declare. * 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. (_Jv_FreeMethodCache): New function. * java/lang/natThread.cc (finish_): Call _Jv_FreeMethodCache. * aclocal.m4, configure, include/config.h.in: Rebuilt. * configure.ac: Invoke GCC_CHECK_TLS. From-SVN: r104707
Diffstat (limited to 'libjava/java/lang/natClass.cc')
-rw-r--r--libjava/java/lang/natClass.cc65
1 files changed, 45 insertions, 20 deletions
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc
index fa52713..bd68eb2 100644
--- a/libjava/java/lang/natClass.cc
+++ b/libjava/java/lang/natClass.cc
@@ -879,8 +879,10 @@ _Jv_LookupDeclaredMethod (jclass klass, _Jv_Utf8Const *name,
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,60 @@ struct _Jv_mcache
_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$);
-
- int index = method->name->hash16 () & MCACHE_SIZE;
-
- method_cache[index].method = method;
- method_cache[index].klass = klass;
+#ifdef HAVE_TLS
+ if (method_cache == NULL)
+ method_cache = (_Jv_mcache *) _Jv_MallocUnchecked((MCACHE_SIZE + 1)
+ * sizeof (_Jv_mcache));
+ // If the allocation failed, just keep going.
+ if (method_cache != NULL)
+ {
+ int index = method->name->hash16 () & MCACHE_SIZE;
+ method_cache[index].method = method;
+ method_cache[index].klass = klass;
+ }
+#endif // HAVE_TLS
+}
- _Jv_MonitorExit (&java::lang::Class::class$);
+// Free this thread's method cache. We explicitly manage this memory
+// as the GC does not yet know how to scan TLS on all platforms.
+void
+_Jv_FreeMethodCache ()
+{
+#ifdef HAVE_TLS
+ if (method_cache != NULL)
+ {
+ _Jv_Free(method_cache);
+ method_cache = NULL;
+ }
+#endif // HAVE_TLS
}
void *