[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] CVS: pnet/engine cvm_call.c, 1.68, 1.69 cvm_dasm.c
From: |
Rhys Weatherley <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] CVS: pnet/engine cvm_call.c, 1.68, 1.69 cvm_dasm.c, 1.54, 1.55 cvmc_call.c, 1.27, 1.28 engine.h, 1.81, 1.82 layout.c, 1.30, 1.31 process.c, 1.52, 1.53 |
Date: |
Sun, 13 Jul 2003 08:41:03 -0400 |
Update of /cvsroot/dotgnu-pnet/pnet/engine
In directory subversions:/tmp/cvs-serv15338/engine
Modified Files:
cvm_call.c cvm_dasm.c cvmc_call.c engine.h layout.c process.c
Log Message:
Change the interface dispatch logic to use IMT's like IBM's RVM, instead
of the itable's approach we used to have.
Index: cvm_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvm_call.c,v
retrieving revision 1.68
retrieving revision 1.69
diff -C2 -r1.68 -r1.69
*** cvm_call.c 19 Jun 2003 12:19:40 -0000 1.68
--- cvm_call.c 13 Jul 2003 12:41:01 -0000 1.69
***************
*** 829,832 ****
--- 829,847 ----
{
/* Locate the method to be called */
+ #ifdef IL_USE_IMTS
+ methodToCall = GetObjectClassPrivate(tempptr)
+ ->imt[CVM_ARG_DWIDE2_SMALL];
+ if(!methodToCall)
+ {
+ methodToCall = CVM_ARG_DWIDE_PTR_SMALL(ILMethod *);
+ methodToCall = _ILLookupInterfaceMethod
+ (GetObjectClassPrivate(tempptr),
+ methodToCall->member.owner,
methodToCall->index);
+ if(!methodToCall)
+ {
+ MISSING_METHOD_EXCEPTION();
+ }
+ }
+ #else
methodToCall = _ILLookupInterfaceMethod
(GetObjectClassPrivate(tempptr),
CVM_ARG_DWIDE_PTR_SMALL(ILClass *),
***************
*** 836,839 ****
--- 851,855 ----
MISSING_METHOD_EXCEPTION();
}
+ #endif
/* Has the method already been converted? */
***************
*** 1354,1357 ****
--- 1370,1388 ----
{
/* Locate the method to be called */
+ #ifdef IL_USE_IMTS
+ methodToCall = GetObjectClassPrivate(tempptr)
+ ->imt[CVM_ARG_DWIDE2_LARGE];
+ if(!methodToCall)
+ {
+ methodToCall = CVM_ARG_DWIDE_PTR_LARGE(ILMethod *);
+ methodToCall = _ILLookupInterfaceMethod
+ (GetObjectClassPrivate(tempptr),
+ methodToCall->member.owner,
methodToCall->index);
+ if(!methodToCall)
+ {
+ MISSING_METHOD_EXCEPTION();
+ }
+ }
+ #else
methodToCall = _ILLookupInterfaceMethod
(GetObjectClassPrivate(tempptr),
CVM_ARG_DWIDE_PTR_LARGE(ILClass *),
***************
*** 1361,1364 ****
--- 1392,1396 ----
MISSING_METHOD_EXCEPTION();
}
+ #endif
/* Copy the state back into the thread object */
***************
*** 1548,1551 ****
--- 1580,1597 ----
{
/* Locate the method to be called */
+ #ifdef IL_USE_IMTS
+ methodToCall =
GetObjectClassPrivate(tempptr)->imt[CVMP_ARG_WORD2];
+ if(!methodToCall)
+ {
+ methodToCall = CVMP_ARG_WORD2_PTR(ILMethod *);
+ methodToCall = _ILLookupInterfaceMethod
+ (GetObjectClassPrivate(tempptr),
+ methodToCall->member.owner,
methodToCall->index);
+ if(!methodToCall)
+ {
+ MISSING_METHOD_EXCEPTION();
+ }
+ }
+ #else
methodToCall = _ILLookupInterfaceMethod
(GetObjectClassPrivate(tempptr),
CVMP_ARG_WORD2_PTR(ILClass *),
***************
*** 1555,1558 ****
--- 1601,1605 ----
MISSING_METHOD_EXCEPTION();
}
+ #endif
goto performTailCall;
}
Index: cvm_dasm.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvm_dasm.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -C2 -r1.54 -r1.55
*** cvm_dasm.c 19 Jun 2003 12:19:40 -0000 1.54
--- cvm_dasm.c 13 Jul 2003 12:41:01 -0000 1.55
***************
*** 22,26 ****
#include "il_dumpasm.h"
! #include "engine.h"
#ifdef __cplusplus
--- 22,26 ----
#include "il_dumpasm.h"
! #include "engine_private.h"
#ifdef __cplusplus
***************
*** 777,784 ****
--- 777,791 ----
case CVM_OPER_CALL_INTERFACE:
{
+ #ifdef IL_USE_IMTS
+ method = (ILMethod *)CVMReadPointer(pc + 3);
+ ILDumpClassName(stream, ILProgramItem_Image(currMethod),
+ ILMethod_Owner(method),
0);
+ fprintf(stream, ", %d, %d", (int)(pc[1]),
method->index);
+ #else
classInfo = (ILClass *)CVMReadPointer(pc + 3);
ILDumpClassName(stream, ILProgramItem_Image(currMethod),
classInfo, 0);
fprintf(stream, ", %d, %d", (int)(pc[1]), (int)(pc[2]));
+ #endif
size = 3 + sizeof(void *);
}
***************
*** 871,874 ****
--- 878,889 ----
case CVM_OPER_CALL_INTERFACE:
{
+ #ifdef IL_USE_IMTS
+ method = (ILMethod *)CVMReadPointer(pc
+ 10);
+ ILDumpClassName(stream,
ILProgramItem_Image(currMethod),
+
ILMethod_Owner(method), 0);
+ fprintf(stream, ", %lu, %lu",
+ (unsigned
long)IL_READ_UINT32(pc + 2),
+ (unsigned
long)(method->index));
+ #else
classInfo = (ILClass
*)CVMReadPointer(pc + 10);
ILDumpClassName(stream,
ILProgramItem_Image(currMethod),
***************
*** 877,880 ****
--- 892,896 ----
(unsigned
long)IL_READ_UINT32(pc + 2),
(unsigned
long)IL_READ_UINT32(pc + 6));
+ #endif
size = 10 + sizeof(void *);
}
***************
*** 994,997 ****
--- 1010,1021 ----
case CVM_OPER_TAIL_INTERFACE:
{
+ #ifdef IL_USE_IMTS
+ method = (ILMethod *)CVMReadPointer(pc
+ 10);
+ fprintf(stream, "%lu, %lu, ",
+ (unsigned
long)(IL_READ_UINT32(pc + 2)),
+ (unsigned
long)(method->index));
+ ILDumpClassName(stream,
ILProgramItem_Image(currMethod),
+
ILMethod_Owner(method), 0);
+ #else
classInfo = (ILClass
*)CVMReadPointer(pc + 10);
fprintf(stream, "%lu, %lu, ",
***************
*** 1000,1003 ****
--- 1024,1028 ----
ILDumpClassName(stream,
ILProgramItem_Image(currMethod),
classInfo, 0);
+ #endif
size = 10 + sizeof(void *);
}
Index: cvmc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc_call.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -r1.27 -r1.28
*** cvmc_call.c 19 Jun 2003 12:19:40 -0000 1.27
--- cvmc_call.c 13 Jul 2003 12:41:01 -0000 1.28
***************
*** 203,207 ****
ILMethod
*methodInfo)
{
- void *ptr = ILMethod_Owner(methodInfo);
ILUInt32 argSize = ComputeStackSize(coder, info->args,
info->numBaseArgs);
if(info->hasParamArray)
--- 203,206 ----
***************
*** 209,221 ****
++argSize;
}
! if(info->tailCall)
{
! CVMP_OUT_WORD2_PTR(COP_PREFIX_TAIL_CALLINTF, argSize,
! methodInfo->index, ptr);
}
! else
{
! CVM_OUT_DWIDE_PTR(COP_CALL_INTERFACE, argSize,
methodInfo->index, ptr);
}
AdjustForCall(coder, info, returnItem);
}
--- 208,247 ----
++argSize;
}
! #ifdef IL_USE_IMTS
{
! ILUInt32 index = methodInfo->index;
! ILClassPrivate *classPrivate;
! classPrivate = (ILClassPrivate
*)(methodInfo->member.owner->userData);
! if(classPrivate)
! {
! index += classPrivate->imtBase;
! }
! index %= IL_IMT_SIZE;
! if(info->tailCall)
! {
! CVMP_OUT_WORD2_PTR(COP_PREFIX_TAIL_CALLINTF, argSize,
! index, methodInfo);
! }
! else
! {
! CVM_OUT_DWIDE_PTR(COP_CALL_INTERFACE, argSize,
! index, methodInfo);
! }
}
! #else
{
! void *ptr = ILMethod_Owner(methodInfo);
! if(info->tailCall)
! {
! CVMP_OUT_WORD2_PTR(COP_PREFIX_TAIL_CALLINTF, argSize,
! methodInfo->index,
ptr);
! }
! else
! {
! CVM_OUT_DWIDE_PTR(COP_CALL_INTERFACE, argSize,
! methodInfo->index,
ptr);
! }
}
+ #endif
AdjustForCall(coder, info, returnItem);
}
Index: engine.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/engine.h,v
retrieving revision 1.81
retrieving revision 1.82
diff -C2 -r1.81 -r1.82
*** engine.h 8 Jul 2003 12:05:17 -0000 1.81
--- engine.h 13 Jul 2003 12:41:01 -0000 1.82
***************
*** 54,57 ****
--- 54,64 ----
/*
+ * Determine if we should use interface method tables.
+ */
+ #ifndef IL_CONFIG_REDUCE_CODE
+ #define IL_USE_IMTS 1
+ #endif
+
+ /*
* Structure that keeps track of a loaded external module.
*/
***************
*** 166,169 ****
--- 173,183 ----
ILUInt32 numThreadStaticSlots;
+ #ifdef IL_USE_IMTS
+
+ /* Last-allocated base identifier for interface method tables */
+ ILUInt32 imtBase;
+
+ #endif
+
};
***************
*** 251,254 ****
--- 265,275 ----
/*
+ * Define the size of the interface method table.
+ */
+ #ifdef IL_USE_IMTS
+ #define IL_IMT_SIZE 32
+ #endif
+
+ /*
* Private information that is associated with a class.
*/
***************
*** 271,274 ****
--- 292,299 ----
ILObject *staticData; /* Static data area
object */
ILImplPrivate *implements; /* Interface
implementation records */
+ #ifdef IL_USE_IMTS
+ ILUInt32 imtBase; /* Base for IMT
identifiers */
+ ILMethod *imt[IL_IMT_SIZE]; /* Interface method table */
+ #endif
};
Index: layout.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/layout.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -C2 -r1.30 -r1.31
*** layout.c 29 Jun 2003 21:26:20 -0000 1.30
--- layout.c 13 Jul 2003 12:41:01 -0000 1.31
***************
*** 426,429 ****
--- 426,545 ----
}
+ #ifdef IL_USE_IMTS
+
+ /*
+ * Build an "Interface Method Table" (IMT) for a particular class, from
+ * the interface information in that class. The mechanism is described
+ * in the following paper by IBM:
+ *
+ * "Efficient Implementation of Java Interfaces: Invokeinterface Considered
+ * Harmless", Bowen Alpern, Anthony Cocchi, Stephen Fink, David Grove,
+ * and Derek Lieber. ACM Conference on Object-Oriented Programming, Systems,
+ * Languages, and Applications (OOPSLA), Tampa, FL, USA, Oct 14-18, 2001.
+ *
+ * http://www.research.ibm.com/people/d/dgrove/papers/oopsla01.pdf
+ *
+ * Each interface method in the system is assigned a unique identifier.
+ * The identifier is used to hash into a fixed-sized table of method entry
+ * points, similar to a vtable. In most cases, the hashed position will
+ * be the right position.
+ *
+ * We modify the IMT conflict resolution mechanism slightly. IBM's RVM
+ * system generates special conflict resolution stubs for interface methods
+ * that hash to the same IMT position. We store NULL at any position where
+ * there is a conflict and bail out to the traditional lookup algorithm.
+ * This is necessary because we convert methods one at a time, instead of
+ * class at a time like RVM does.
+ */
+ static void BuildIMT(ILClass *info, ILClassPrivate *classPrivate)
+ {
+ ILExecThread *thread;
+ ILExecProcess *process;
+ ILImplPrivate *impl;
+ ILClassPrivate *implPrivate;
+ ILUInt32 posn, size;
+ ILUInt32 vtableIndex;
+ ILUInt32 imtIndex;
+
+ /* Find the process that owns the class */
+ thread = ILExecThreadCurrent();
+ if(!thread)
+ {
+ return;
+ }
+ process = thread->process;
+
+ /* Is this class itself an interface? */
+ if(ILClass_IsInterface(info))
+ {
+ /* Allocate the base identifier for the interface. We must do
+ this here in case an interface is referenced by a "callvirt"
+ instruction before any of the classes that implement it are
+ laid out */
+ if(!(classPrivate->imtBase))
+ {
+ size = (ILUInt32)(classPrivate->vtableSize);
+ classPrivate->imtBase = process->imtBase;
+ process->imtBase += size;
+ }
+ return;
+ }
+
+ /* Process the implementation records that are attached to this class */
+ impl = classPrivate->implements;
+ while(impl != 0)
+ {
+ implPrivate = (ILClassPrivate *)(impl->interface->userData);
+ if(implPrivate)
+ {
+ /* Allocate a base identifer for the interface if
necessary.
+ This will probably never be used because interfaces
are
+ typically laid out before their implementing
classes, and
+ the allocation above will catch us. But let's be
paranoid
+ and allocate the base identifier here anyway, just
in case */
+ size = (ILUInt32)(implPrivate->vtableSize);
+ if(!(implPrivate->imtBase))
+ {
+ implPrivate->imtBase = process->imtBase;
+ process->imtBase += size;
+ }
+
+ /* Process the members of this interface */
+ for(posn = 0; posn < size; ++posn)
+ {
+ imtIndex = (implPrivate->imtBase + posn) %
IL_IMT_SIZE;
+ vtableIndex = (ILImplPrivate_Table(impl))[posn];
+ if(vtableIndex != (ILUInt32)(ILUInt16)0xFFFF)
+ {
+ if(!(classPrivate->imt[imtIndex]))
+ {
+ /* No conflict at this table
position */
+ classPrivate->imt[imtIndex] =
+
classPrivate->vtable[vtableIndex];
+ }
+ else
+ {
+ /* We have encountered a
conflict in the table */
+ classPrivate->imt[imtIndex] =
+ (ILMethod
*)(ILNativeInt)(-1);
+ }
+ }
+ }
+ }
+ impl = impl->next;
+ }
+
+ /* Clear positions in the table that indicate conflicts */
+ for(posn = 0; posn < IL_IMT_SIZE; ++posn)
+ {
+ if(classPrivate->imt[posn] == (ILMethod *)(ILNativeInt)(-1))
+ {
+ classPrivate->imt[posn] = 0;
+ }
+ }
+ }
+
+ #endif /* IL_USE_IMTS */
+
/*
* Lay out a particular class. Returns zero if there
***************
*** 872,875 ****
--- 988,996 ----
classPrivate->managedStatic = layout->managedStatic;
layout->vtable = vtable;
+
+ #ifdef IL_USE_IMTS
+ /* Build the interface method table for this class */
+ BuildIMT(info, classPrivate);
+ #endif
/* Done */
Index: process.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/process.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -r1.52 -r1.53
*** process.c 9 Jul 2003 06:58:23 -0000 1.52
--- process.c 13 Jul 2003 12:41:01 -0000 1.53
***************
*** 84,87 ****
--- 84,90 ----
process->randomCount = 0;
process->numThreadStaticSlots = 0;
+ #ifdef IL_USE_IMTS
+ process->imtBase = 1;
+ #endif
/* Initialize the image loading context */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnet/engine cvm_call.c, 1.68, 1.69 cvm_dasm.c, 1.54, 1.55 cvmc_call.c, 1.27, 1.28 engine.h, 1.81, 1.82 layout.c, 1.30, 1.31 process.c, 1.52, 1.53,
Rhys Weatherley <address@hidden> <=