This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: Interface dispatch table optimization
- From: Bryce McKinlay <mckinlay at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Thu, 09 Feb 2006 10:56:47 -0500
- Subject: Patch: Interface dispatch table optimization
It turns out that we can allocate interface dispatch (jclass->idt)
tables as a single struct, rather than a struct that contains a pointer
to another table. This means that only one idt allocation is required
for each class/interface, and _Jv_AllocBytes can be used to reduce the
memory that needs to be scanned by the GC.
In addition, this means that two less pointer dereferences are required
for every interface call!
I'm going to test this a bit more, then check it in to trunk.
Bryce
2006-02-09 Bryce McKinlay <mckinlay@redhat.com>
* java/lang/Class.h (_Jv_IDispatchTable): Put cls.itable and
iface.ioffsets inline, instead of as pointers.
* link.cc (null_idt): Update definition.
(_Jv_Linker::prepare_constant_time_tables): Allocate klass->idt and
as a single struct. Use _Jv_AllocBytes, not _Jv_AllocRawObj.
(_Jv_Linker::generate_itable): Likewise, for iface->idt.
(_Jv_Linker::find_iindex): Assign new iface->idt when resizing
ioffsets.
Index: link.cc
===================================================================
--- link.cc (revision 110767)
+++ link.cc (working copy)
@@ -552,7 +552,7 @@
#define INITIAL_IOFFSETS_LEN 4
#define INITIAL_IFACES_LEN 4
-static _Jv_IDispatchTable null_idt = { {SHRT_MAX, 0, NULL} };
+static _Jv_IDispatchTable null_idt = { {SHRT_MAX, 0, {}} };
// Generate tables for constant-time assignment testing and interface
// method lookup. This implements the technique described by Per Bothner
@@ -611,9 +611,6 @@
return;
}
- klass->idt =
- (_Jv_IDispatchTable *) _Jv_AllocRawObj (sizeof (_Jv_IDispatchTable));
-
_Jv_ifaces ifaces;
ifaces.count = 0;
ifaces.len = INITIAL_IFACES_LEN;
@@ -625,8 +622,9 @@
{
// The classes pointed to by the itable will always be reachable
// via other paths.
- klass->idt->cls.itable =
- (void **) _Jv_AllocBytes (itable_size * sizeof (void *));
+ int idt_bytes = sizeof (_Jv_IDispatchTable)
+ + (itable_size * sizeof (void *));
+ klass->idt = (_Jv_IDispatchTable *) _Jv_AllocBytes (idt_bytes);
klass->idt->cls.itable_length = itable_size;
jshort *itable_offsets =
@@ -725,17 +723,15 @@
/* Create interface dispatch table for iface */
if (iface->idt == NULL)
{
- iface->idt
- = (_Jv_IDispatchTable *) _Jv_AllocRawObj (sizeof (_Jv_IDispatchTable));
+ int idt_bytes = sizeof (_Jv_IDispatchTable)
+ + INITIAL_IOFFSETS_LEN * sizeof (jshort);
- // The first element of ioffsets is its length (itself included).
- jshort *ioffsets = (jshort *) _Jv_AllocBytes (INITIAL_IOFFSETS_LEN
- * sizeof (jshort));
+ iface->idt = (_Jv_IDispatchTable *) _Jv_AllocBytes (idt_bytes);
+
+ jshort *ioffsets = &iface->idt->iface.ioffsets[0];
ioffsets[0] = INITIAL_IOFFSETS_LEN;
for (int i = 1; i < INITIAL_IOFFSETS_LEN; i++)
ioffsets[i] = -1;
-
- iface->idt->iface.ioffsets = ioffsets;
}
}
}
@@ -931,9 +927,16 @@
int newlen = 2 * len;
if (i >= newlen)
newlen = i + 3;
+
+ int idt_bytes = sizeof (_Jv_IDispatchTable)
+ + (newlen * sizeof (jshort));
+
+ _Jv_IDispatchTable *new_idt
+ = (_Jv_IDispatchTable *) _Jv_AllocBytes (idt_bytes);
+
jshort *old_ioffsets = ifaces[j]->idt->iface.ioffsets;
- jshort *new_ioffsets = (jshort *) _Jv_AllocBytes (newlen
- * sizeof(jshort));
+ jshort *new_ioffsets = new_idt->iface.ioffsets;
+
memcpy (&new_ioffsets[1], &old_ioffsets[1],
(len - 1) * sizeof (jshort));
new_ioffsets[0] = newlen;
@@ -941,7 +944,7 @@
while (len < newlen)
new_ioffsets[len++] = -1;
- ifaces[j]->idt->iface.ioffsets = new_ioffsets;
+ ifaces[j]->idt = new_idt;
}
ifaces[j]->idt->iface.ioffsets[i] = offsets[j];
}
Index: java/lang/Class.h
===================================================================
--- java/lang/Class.h (revision 110783)
+++ java/lang/Class.h (working copy)
@@ -129,13 +129,13 @@
jshort iindex;
jshort itable_length;
// Class Interface dispatch table.
- void **itable;
+ void *itable[0];
} cls;
struct
{
// Offsets into implementation class itables.
- jshort *ioffsets;
+ jshort ioffsets[0];
} iface;
};