This is the mail archive of the
java-discuss@sourceware.cygnus.com
mailing list for the Java project.
Re: libgcj performance: _Jv_LookupInterfaceMethod
Tom Tromey wrote:
>
> >>>>> "Jeff" == Jeff Sturm <jsturm@sigma6.com> writes:
>
> Jeff> No cache misses here (there's only one interface method after
> Jeff> all). So it's not a great example. It's interesting though
> Jeff> that _Jv_equalUtf8Consts is the top offender, and called twice
> Jeff> for each method lookup... hmm...
>
> It is called to check that the method name and signature match what
> was found in the hash table. I think this is unavoidable given the
> current implementation.
That's right... what I found however is that a complete byte-for-byte
comparison is done on most invocations, so that more time is spent in
the _Jv_equalUtf8Consts method than any other, overall. The runtime
would do far better if all strings constants were intern'ed somehow. I
seem to recall (in the distant past) the Objective-C runtime doing
something like this, converting method names into descriptors (known as
"method selectors") which were globally-unique constants.
I also experimented with a small patch (below) that cuts down the string
compare times drastically in some programs. Specifically, for Bryce's
simple benchmark it cuts the time spent in interface calls roughly in
half, at the cost of slightly higher memory utilization.
(I know the real solution is better compiler support for interfaces... I
was just considering interim solutions.)
Index: natClass.cc
===================================================================
RCS file: /cvs/java/libgcj/libjava/java/lang/natClass.cc,v
retrieving revision 1.8
diff -b -u -r1.8 natClass.cc
--- natClass.cc 1999/11/18 07:19:00 1.8
+++ natClass.cc 1999/11/22 23:43:25
@@ -513,6 +513,8 @@
struct _Jv_mcache
{
jclass klass;
+ _Jv_Utf8Const *name;
+ _Jv_Utf8Const *signature;
_Jv_Method *method;
};
@@ -528,23 +530,27 @@
_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;
+ && _Jv_equalUtf8Consts (mc->name, name))
+ && _Jv_equalUtf8Consts (mc->signature, signature))
+ && m != NULL) // thread safe check
+ return m->ncode;
return NULL;
}
static void
_Jv_AddMethodToCache (jclass klass,
- _Jv_Method *method)
+ _Jv_Method *method,
+ _Jv_Utf8Const *name,
+ _Jv_Utf8Const *signature)
{
_Jv_MonitorEnter (&ClassClass);
int index = method->name->hash & MCACHE_SIZE;
- method_cache[index].method = method;
method_cache[index].klass = klass;
+ method_cache[index].method = method;
+ method_cache[index].name = name;
+ method_cache[index].signature = signature;
_Jv_MonitorExit (&ClassClass);
}
@@ -580,7 +586,7 @@
if (! java::lang::reflect::Modifier::isPublic(meth->accflags))
JvThrow (new java::lang::IllegalAccessError);
- _Jv_AddMethodToCache (klass, meth);
+ _Jv_AddMethodToCache (klass, meth, name, signature);
return meth->ncode;
}
--
Jeff Sturm
jsturm@sigma6.com