This is the mail archive of the
java-discuss@sourceware.cygnus.com
mailing list for the Java project.
libgcj performance: _Jv_LookupInterfaceMethod
- To: java-discuss at sourceware dot cygnus dot com
- Subject: libgcj performance: _Jv_LookupInterfaceMethod
- From: Jeff Sturm <jsturm at sigma6 dot com>
- Date: Thu, 04 Nov 1999 12:46:02 -0500
- Organization: AppNet
Following up on my libgcj performance issues last week... I've narrowed
the problem down to this method. The cache functions
(_Jv_FindMethodInCache, _Jv_AddMethodToCache) seem to be completely
broken... I was getting a cache miss on each call. The JDBC code relies
extensively on interfaces, and these methods were high in CPU
consumption (according to gprof).
Rewriting these two methods solves the problem. My gcj-compiled program
now outperforms the JIT compiler. It runs literally twice as fast as
before. I wonder if others weren't having the same problem?
I was quick to blame the boehm-gc. It actually performs very well.
Mark/sweep times are on the order of 30ms for a 32MB heap.
Below is my simple patch...
*** natClass.cc.orig Fri Sep 10 18:03:08 1999
--- natClass.cc Thu Nov 4 11:34:48 1999
***************
*** 515,542 ****
};
static _Jv_mcache method_cache[MCACHE_SIZE];
! static int method_cache_count;
static void*
_Jv_FindMethodInCache (jclass klass,
_Jv_Utf8Const *name,
_Jv_Utf8Const *signature)
{
! for (int index = name->hash % MCACHE_SIZE;
! method_cache[index].klass != NULL;
! index = (index+1) % 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;
}
- }
return NULL;
}
--- 515,538 ----
};
static _Jv_mcache method_cache[MCACHE_SIZE];
! //static int method_cache_count;
static void*
_Jv_FindMethodInCache (jclass klass,
_Jv_Utf8Const *name,
_Jv_Utf8Const *signature)
{
! int index = name->hash & 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;
}
return NULL;
}
***************
*** 546,567 ****
{
_Jv_MonitorEnter (&ClassClass);
! if (method_cache_count > MCACHE_SIZE*2/3)
! {
! for (int i = 0; i < MCACHE_SIZE; i++)
! method_cache[i].klass = 0;
! }
!
! for (int index = method->name->hash % MCACHE_SIZE;
! method_cache[index].klass != NULL;
! index = (index+1) % MCACHE_SIZE)
! {
! method_cache[index].method = method;
! method_cache[index].klass = klass;
! }
- method_cache_count += 1;
-
_Jv_MonitorExit (&ClassClass);
}
--- 542,552 ----
{
_Jv_MonitorEnter (&ClassClass);
! int index = method->name->hash & MCACHE_SIZE;
!
! method_cache[index].method = method;
! method_cache[index].klass = klass;
_Jv_MonitorExit (&ClassClass);
}
--
Jeff Sturm
jsturm@sigma6.com