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
This commit is contained in:
Tom Tromey 2005-09-27 20:03:09 +00:00 committed by Tom Tromey
parent ab3fa9d344
commit b9e6a2e5de
12 changed files with 221 additions and 34 deletions

View file

@ -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;
#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
&& m != NULL // thread safe check
&& _Jv_equalUtf8Consts (m->name, name)
&& _Jv_equalUtf8Consts (m->signature, signature))
return mc->method->ncode;
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_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
}
int index = method->name->hash16 () & MCACHE_SIZE;
method_cache[index].method = method;
method_cache[index].klass = klass;
_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 *