From a286e145de1b08b1a73d4efe03d36375fa698273 Mon Sep 17 00:00:00 2001 From: Bryce McKinlay Date: Thu, 9 Feb 2006 23:59:30 +0000 Subject: [PATCH] Class.h (_Jv_IDispatchTable): Make it a struct. 2006-02-09 Bryce McKinlay * java/lang/Class.h (_Jv_IDispatchTable): Make it a struct. Put 'itable' inline, instead of as a pointer. (java::lang::Class): Put 'idt' in anonymous union with 'ioffsets'. * link.cc (null_idt): Update definition. (_Jv_Linker::prepare_constant_time_tables): Allocate klass->idt as a single struct. Use _Jv_AllocBytes, not _Jv_AllocRawObj. (_Jv_Linker::generate_itable): Update to use 'ioffsets'. (_Jv_Linker::find_iindex): Likewise. Update comment. * java/lang/natClass.cc (_Jv_LookupInterfaceMethodIdx): Update for _Jv_IDispatchTable change. (_Jv_IsAssignableFrom): Likewise. From-SVN: r110818 --- libjava/ChangeLog | 14 +++++++++++ libjava/java/lang/Class.h | 32 +++++++++++------------- libjava/java/lang/natClass.cc | 17 ++++++------- libjava/link.cc | 47 ++++++++++++++++------------------- 4 files changed, 57 insertions(+), 53 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 894add7fa3f..22afafa959b 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,17 @@ +2006-02-09 Bryce McKinlay + + * java/lang/Class.h (_Jv_IDispatchTable): Make it a struct. Put + 'itable' inline, instead of as a pointer. + (java::lang::Class): Put 'idt' in anonymous union with 'ioffsets'. + * link.cc (null_idt): Update definition. + (_Jv_Linker::prepare_constant_time_tables): Allocate klass->idt + as a single struct. Use _Jv_AllocBytes, not _Jv_AllocRawObj. + (_Jv_Linker::generate_itable): Update to use 'ioffsets'. + (_Jv_Linker::find_iindex): Likewise. Update comment. + * java/lang/natClass.cc (_Jv_LookupInterfaceMethodIdx): Update for + _Jv_IDispatchTable change. + (_Jv_IsAssignableFrom): Likewise. + 2006-02-08 Bryce McKinlay PR libgcj/25187: diff --git a/libjava/java/lang/Class.h b/libjava/java/lang/Class.h index 62e280ced82..787e2638b2b 100644 --- a/libjava/java/lang/Class.h +++ b/libjava/java/lang/Class.h @@ -120,23 +120,14 @@ struct _Jv_Method { return this + 1; } }; -// Interface Dispatch Tables -union _Jv_IDispatchTable +// The table used to resolve interface calls. +struct _Jv_IDispatchTable { - struct - { - // Index into interface's ioffsets. - jshort iindex; - jshort itable_length; - // Class Interface dispatch table. - void **itable; - } cls; - - struct - { - // Offsets into implementation class itables. - jshort *ioffsets; - } iface; + // Index into interface's ioffsets. + jshort iindex; + jshort itable_length; + // Class Interface dispatch table. + void *itable[0]; }; // Used by _Jv_Linker::get_interfaces () @@ -600,8 +591,13 @@ private: jshort depth; // Vector of this class's superclasses, ordered by decreasing depth. jclass *ancestors; - // Interface Dispatch Table. - _Jv_IDispatchTable *idt; + // In a regular class, this field points to the Class Interface Dispatch + // Table. In an interface, it points to the ioffsets table. + union + { + _Jv_IDispatchTable *idt; + jshort *ioffsets; + }; // Pointer to the class that represents an array of this class. jclass arrayclass; // Security Domain to which this class belongs (or null). diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index 04a5bc46310..8972cb2c499 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -985,8 +985,8 @@ void * _Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface, int method_idx) { _Jv_IDispatchTable *cldt = klass->idt; - int idx = iface->idt->iface.ioffsets[cldt->cls.iindex] + method_idx; - return cldt->cls.itable[idx]; + int idx = iface->ioffsets[cldt->iindex] + method_idx; + return cldt->itable[idx]; } jboolean @@ -1013,16 +1013,15 @@ _Jv_IsAssignableFrom (jclass source, jclass target) return _Jv_InterfaceAssignableFrom (source, target); _Jv_IDispatchTable *cl_idt = source->idt; - _Jv_IDispatchTable *if_idt = target->idt; - if (__builtin_expect ((if_idt == NULL), false)) + if (__builtin_expect ((target->ioffsets == NULL), false)) return false; // No class implementing TARGET has been loaded. - jshort cl_iindex = cl_idt->cls.iindex; - if (cl_iindex < if_idt->iface.ioffsets[0]) + jshort cl_iindex = cl_idt->iindex; + if (cl_iindex < target->ioffsets[0]) { - jshort offset = if_idt->iface.ioffsets[cl_iindex]; - if (offset != -1 && offset < cl_idt->cls.itable_length - && cl_idt->cls.itable[offset] == target) + jshort offset = target->ioffsets[cl_iindex]; + if (offset != -1 && offset < cl_idt->itable_length + && cl_idt->itable[offset] == target) return true; } return false; diff --git a/libjava/link.cc b/libjava/link.cc index 395b2c731b6..481f98a138b 100644 --- a/libjava/link.cc +++ b/libjava/link.cc @@ -552,7 +552,7 @@ _Jv_Linker::search_method_in_class (jclass cls, jclass klass, #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 @@ _Jv_Linker::prepare_constant_time_tables (jclass klass) return; } - klass->idt = - (_Jv_IDispatchTable *) _Jv_AllocRawObj (sizeof (_Jv_IDispatchTable)); - _Jv_ifaces ifaces; ifaces.count = 0; ifaces.len = INITIAL_IFACES_LEN; @@ -625,9 +622,10 @@ _Jv_Linker::prepare_constant_time_tables (jclass klass) { // 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 *)); - klass->idt->cls.itable_length = itable_size; + int idt_bytes = sizeof (_Jv_IDispatchTable) + (itable_size + * sizeof (void *)); + klass->idt = (_Jv_IDispatchTable *) _Jv_AllocBytes (idt_bytes); + klass->idt->itable_length = itable_size; jshort *itable_offsets = (jshort *) _Jv_Malloc (ifaces.count * sizeof (jshort)); @@ -639,18 +637,17 @@ _Jv_Linker::prepare_constant_time_tables (jclass klass) for (int i = 0; i < ifaces.count; i++) { - ifaces.list[i]->idt->iface.ioffsets[cls_iindex] = - itable_offsets[i]; + ifaces.list[i]->ioffsets[cls_iindex] = itable_offsets[i]; } - klass->idt->cls.iindex = cls_iindex; + klass->idt->iindex = cls_iindex; _Jv_Free (ifaces.list); _Jv_Free (itable_offsets); } else { - klass->idt->cls.iindex = SHRT_MAX; + klass->idt->iindex = SHRT_MAX; } } @@ -713,7 +710,7 @@ void _Jv_Linker::generate_itable (jclass klass, _Jv_ifaces *ifaces, jshort *itable_offsets) { - void **itable = klass->idt->cls.itable; + void **itable = klass->idt->itable; jshort itable_pos = 0; for (int i = 0; i < ifaces->count; i++) @@ -722,12 +719,9 @@ _Jv_Linker::generate_itable (jclass klass, _Jv_ifaces *ifaces, itable_offsets[i] = itable_pos; itable_pos = append_partial_itable (klass, iface, itable, itable_pos); - /* Create interface dispatch table for iface */ - if (iface->idt == NULL) + /* Create ioffsets table for iface */ + if (iface->ioffsets == NULL) { - iface->idt - = (_Jv_IDispatchTable *) _Jv_AllocRawObj (sizeof (_Jv_IDispatchTable)); - // The first element of ioffsets is its length (itself included). jshort *ioffsets = (jshort *) _Jv_AllocBytes (INITIAL_IOFFSETS_LEN * sizeof (jshort)); @@ -735,7 +729,7 @@ _Jv_Linker::generate_itable (jclass klass, _Jv_ifaces *ifaces, for (int i = 1; i < INITIAL_IOFFSETS_LEN; i++) ioffsets[i] = -1; - iface->idt->iface.ioffsets = ioffsets; + iface->ioffsets = ioffsets; } } } @@ -881,8 +875,8 @@ static bool iindex_mutex_initialized = false; // Interface Dispatch Table, we just compare the first element to see if it // matches the desired interface. So how can we find the correct offset? // Our solution is to keep a vector of candiate offsets in each interface -// (idt->iface.ioffsets), and in each class we have an index -// (idt->cls.iindex) used to select the correct offset from ioffsets. +// (ioffsets), and in each class we have an index (idt->iindex) used to +// select the correct offset from ioffsets. // // Calculate and return iindex for a new class. // ifaces is a vector of num interfaces that the class implements. @@ -913,9 +907,9 @@ _Jv_Linker::find_iindex (jclass *ifaces, jshort *offsets, jshort num) { if (j >= num) goto found; - if (i >= ifaces[j]->idt->iface.ioffsets[0]) + if (i >= ifaces[j]->ioffsets[0]) continue; - int ioffset = ifaces[j]->idt->iface.ioffsets[i]; + int ioffset = ifaces[j]->ioffsets[i]; /* We can potentially share this position with another class. */ if (ioffset >= 0 && ioffset != offsets[j]) break; /* Nope. Try next i. */ @@ -924,14 +918,15 @@ _Jv_Linker::find_iindex (jclass *ifaces, jshort *offsets, jshort num) found: for (j = 0; j < num; j++) { - int len = ifaces[j]->idt->iface.ioffsets[0]; + int len = ifaces[j]->ioffsets[0]; if (i >= len) { // Resize ioffsets. int newlen = 2 * len; if (i >= newlen) newlen = i + 3; - jshort *old_ioffsets = ifaces[j]->idt->iface.ioffsets; + + jshort *old_ioffsets = ifaces[j]->ioffsets; jshort *new_ioffsets = (jshort *) _Jv_AllocBytes (newlen * sizeof(jshort)); memcpy (&new_ioffsets[1], &old_ioffsets[1], @@ -941,9 +936,9 @@ _Jv_Linker::find_iindex (jclass *ifaces, jshort *offsets, jshort num) while (len < newlen) new_ioffsets[len++] = -1; - ifaces[j]->idt->iface.ioffsets = new_ioffsets; + ifaces[j]->ioffsets = new_ioffsets; } - ifaces[j]->idt->iface.ioffsets[i] = offsets[j]; + ifaces[j]->ioffsets[i] = offsets[j]; } _Jv_MutexUnlock (&iindex_mutex);