dotgnu-pnet-commits
[Top][All Lists]
Advanced

[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 */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]