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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] pnet ./ChangeLog engine/engine.h engine/jitc.c ...


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] pnet ./ChangeLog engine/engine.h engine/jitc.c ...
Date: Mon, 09 Jan 2006 20:49:47 +0000

CVSROOT:        /cvsroot/dotgnu-pnet
Module name:    pnet
Branch:         
Changes by:     Klaus Treichel <address@hidden> 06/01/09 20:49:47

Modified files:
        .              : ChangeLog 
        engine         : engine.h jitc.c jitc.h jitc_call.c jitc_const.c 
                         jitc_obj.c jitc_setup.c layout.c 

Log message:
        Add more work of the jit coder.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/ChangeLog.diff?tr1=1.3272&tr2=1.3273&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/engine.h.diff?tr1=1.109&tr2=1.110&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc.c.diff?tr1=1.12&tr2=1.13&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc.h.diff?tr1=1.6&tr2=1.7&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc_call.c.diff?tr1=1.4&tr2=1.5&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc_const.c.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc_obj.c.diff?tr1=1.2&tr2=1.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/jitc_setup.c.diff?tr1=1.5&tr2=1.6&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/dotgnu-pnet/pnet/engine/layout.c.diff?tr1=1.41&tr2=1.42&r1=text&r2=text

Patches:
Index: pnet/ChangeLog
diff -u pnet/ChangeLog:1.3272 pnet/ChangeLog:1.3273
--- pnet/ChangeLog:1.3272       Sat Jan  7 12:23:42 2006
+++ pnet/ChangeLog      Mon Jan  9 20:49:46 2006
@@ -1,3 +1,26 @@
+2006-01-09  Klaus Treichel  <address@hidden>
+
+       * engine/engine.h: Add jitVtable (vtable pointers for jit functions) and
+       change imt do void ** (vtable pointers for jit interface functions) in 
the
+       classPrivate data.
+
+       * engine/layout.c: Add the management of the jit vtables and optimize 
the
+       creation of overriding virtual functuins so that they use the signature 
of
+       the ancestor.
+
+       * engine/jitc.h: Add some prototypes.
+
+       * engine/jitc.c, engine/jitc_call.c: Add more functionality for calls.
+
+       * engine/jitc_const.c: Add support for pushing a string token on the
+       evaluation stack.
+
+       * engine/jitc_setup.c: Add support for static constructors so that they 
are
+       not executed more than once.
+
+       * engine/jitc_obj.c: Fix a bug in PushToken (Value was not pushed on the
+       stack).
+
 2006-01-07  Kirill Kononenko  <address@hidden>
 
        * engine/jitc.c, engine/jitc_branch.c: Implement support for the switch
Index: pnet/engine/engine.h
diff -u pnet/engine/engine.h:1.109 pnet/engine/engine.h:1.110
--- pnet/engine/engine.h:1.109  Tue Dec 27 20:07:24 2005
+++ pnet/engine/engine.h        Mon Jan  9 20:49:47 2006
@@ -482,12 +482,17 @@
        ILClassPrivate *nextClassPrivate;       /* linked list of 
ILClassPrivate objects */
        ILExecProcess  *process;                        /* Back-pointer to the 
process this class belongs to */
 #ifdef IL_USE_JIT
+       void              **jitVtable;                  /* table with vtable 
pointers to the vtable methods. */
        ILJitTypes              jitTypes;                       /* jit types 
for this CLR type */
 #endif
 #ifdef IL_USE_IMTS
        ILUInt32                imtBase;                        /* Base for IMT 
identifiers */
+#ifdef IL_USE_JIT
+       void               *imt[IL_IMT_SIZE];   /* Interface method table with 
vtable pointers. */
+#else
        ILMethod           *imt[IL_IMT_SIZE];   /* Interface method table */
 #endif
+#endif
 
 };
 
Index: pnet/engine/jitc.c
diff -u pnet/engine/jitc.c:1.12 pnet/engine/jitc.c:1.13
--- pnet/engine/jitc.c:1.12     Sat Jan  7 12:23:42 2006
+++ pnet/engine/jitc.c  Mon Jan  9 20:49:47 2006
@@ -69,6 +69,13 @@
 static ILJitType _ILJitSignature_ILEngineAlloc = 0;
 
 /*
+ * static void *_ILRuntimeLookupInterfaceMethod(ILClassPrivate 
*objectClassPrivate,
+ *                                                                             
                ILClass *interfaceClass,
+ *                                                                             
                ILUInt32 index)
+ */
+static ILJitType _ILJitSignature_ILRuntimeLookupInterfaceMethod = 0;
+
+/*
  * ILInt32 ILRuntimeCanCastClass(ILExecThread *thread, ILObject *object, 
ILClass *toClass)
  *
  */
@@ -424,6 +431,51 @@
        return ptr;
 }
 
+static void *_ILRuntimeLookupInterfaceMethod(ILClassPrivate 
*objectClassPrivate,
+                                                                               
         ILClass *interfaceClass,
+                                                                               
         ILUInt32 index)
+{
+       ILImplPrivate *implements;
+       ILClassPrivate *searchClass = objectClassPrivate;
+       ILClass *parent;
+
+       /* Locate the interface table within the class hierarchy for the object 
*/
+       while(searchClass != 0)
+       {
+               implements = searchClass->implements;
+               while(implements != 0)
+               {
+                       if(implements->interface == interfaceClass)
+                       {
+                               /* We've found the interface, so look in the 
interface
+                                  table to find the vtable slot, which is then 
used to
+                                  look in the class's vtable for the actual 
method */
+                               index = 
(ILUInt32)((ILImplPrivate_Table(implements))[index]);
+                               if(index != (ILUInt32)(ILUInt16)0xFFFF)
+                               {
+                                       return 
objectClassPrivate->jitVtable[index];
+                               }
+                               else
+                               {
+                                       /* The interface slot is abstract.  
This shouldn't
+                                          happen in practice, but let's be 
paranoid anyway */
+                                       return 0;
+                               }
+                       }
+                       implements = implements->next;
+               }
+               parent = ILClassGetParent(searchClass->classInfo);
+               if(!parent)
+               {
+                       break;
+               }
+               searchClass = (ILClassPrivate *)(parent->userData);
+       }
+
+       /* The interface implementation was not found */
+       return 0;
+}
+
 /*
  * Get the pointer to base type from the JitTypes.
  * The pointer type is created on demand if not allready present.
@@ -523,6 +575,56 @@
 }
 
 /*
+ * Call the static constructor for a class if necessary.
+ */
+static void _ILJitCallStaticConstructor(ILJITCoder *coder, ILClass *classInfo,
+                                                                 int isCtor)
+{
+       if((classInfo->attributes & IL_META_TYPEDEF_CCTOR_ONCE) != 0)
+       {
+               /* We already know that the static constructor has been called,
+                  so there is no point outputting a call to it again */
+               return;
+       }
+       if(isCtor ||
+          (classInfo->attributes & IL_META_TYPEDEF_BEFORE_FIELD_INIT) == 0)
+       {
+               /* We must call the static constructor before instance
+                  constructors, or before static methods when the
+                  "beforefieldinit" attribute is not present */
+               ILMethod *cctor = 0;
+               while((cctor = (ILMethod *)ILClassNextMemberByKind
+                                       (classInfo, (ILMember *)cctor,
+                                        IL_META_MEMBERKIND_METHOD)) != 0)
+               {
+                       if(ILMethod_IsStaticConstructor(cctor))
+                       {
+                               break;
+                       }
+               }
+               if(cctor != 0)
+               {
+                       /* Don't call it if we are within the constructor 
already */
+                       if(cctor != coder->currentMethod)
+                       {
+                               /* Output a call to the static constructor */
+                               jit_value_t thread = 
jit_value_get_param(coder->jitFunction, 0);
+
+                               jit_insn_call(coder->jitFunction, "cctor",
+                                                               
ILJitFunctionFromILMethod(cctor), 0,
+                                                               &thread, 1, 0);
+                       }
+               }
+               else
+               {
+                       /* This class does not have a static constructor,
+                          so mark it so that we never do this test again */
+                       classInfo->attributes |= IL_META_TYPEDEF_CCTOR_ONCE;
+               }
+       }
+}
+
+/*
  * Generate the code to throw the current exception in the thread in libjit.
  */
 static void _ILJitThrowCurrentException(ILJITCoder *coder)
@@ -617,6 +719,16 @@
                return 0;
        }
 
+       args[0] = _IL_JIT_TYPE_VPTR;
+       args[1] = _IL_JIT_TYPE_VPTR;
+       args[2] = _IL_JIT_TYPE_UINT32;
+       returnType = _IL_JIT_TYPE_VPTR;
+       if(!(_ILJitSignature_ILRuntimeLookupInterfaceMethod = 
+               jit_type_create_signature(IL_JIT_CALLCONV_CDECL, returnType, 
args, 3, 1)))
+       {
+               return 0;
+       }
+
        return 1;
 }
 /*
@@ -916,7 +1028,6 @@
  */
 static int _ILJitOnDemandFunc(jit_function_t func)
 {
-       /* TODO */
        ILExecThread *thread = ILExecThreadCurrent();
        ILMethod *method = (ILMethod *)jit_function_get_meta(func, 
IL_JIT_META_METHOD);
        ILMethodCode code;
@@ -1067,14 +1178,13 @@
 }
 
 /*
- * Create the jit function header for an ILMethod.
- * We allways pass the ILExecThread as arg 0.
+ * Create the signature type for an ILMethod.
  */
-int ILJitFunctionCreate(ILCoder *_coder, ILMethod *method)
+static ILJitType _ILJitCreateMethodSignature(ILJITCoder *coder, ILMethod 
*method)
 {
-       ILJITCoder *coder = ((ILJITCoder *)_coder);
        ILType *signature = ILMethod_Signature(method);
        ILType *type;
+
        /* number of args in the bytecode */
        /* Argument 0 is the type of the return value. */
        ILUInt32 num = ILTypeNumParams(signature);
@@ -1092,20 +1202,13 @@
        /* calling convention for this function. */
        /* The type of the jit signature for this function. */
        ILJitType jitSignature;
-       /* The new created function. */
-       ILJitFunction jitFunction;
-       /* Some infos that we'll need later. */
-       ILClass *info = ILMethod_Owner(method);
        /* Flag if this is an array or string constructor. */
        int isArrayOrString = 0;
        /* Flag if the method is a ctor. */
        int isCtor = ILMethodIsConstructor(method);
+       /* Some infos that we'll need later. */
+       ILClass *info = ILMethod_Owner(method);
 
-       /* Don't create the jit function twice. */
-       if(method->userData)
-       {
-               return 1;
-       }
        if(ILType_HasThis(signature))
        {
                if(!isCtor)
@@ -1130,6 +1233,7 @@
                }
        }
 
+       /* Array to hold the parameter types. */
        ILJitType jitArgs[total];
 
        /* Get the return type for this function */
@@ -1193,7 +1297,31 @@
        {
                return 0;
        }
+       return jitSignature;
+}
 
+/*
+ * Create the jit function header for an ILMethod.
+ * We allways pass the ILExecThread as arg 0.
+ */
+int ILJitFunctionCreate(ILCoder *_coder, ILMethod *method)
+{
+       ILJITCoder *coder = ((ILJITCoder *)_coder);
+       /* The type of the jit signature for this function. */
+       ILJitType jitSignature;
+       /* The new created function. */
+       ILJitFunction jitFunction;
+
+       /* Don't create the jit function twice. */
+       if(method->userData)
+       {
+               return 1;
+       }
+       if(!(jitSignature = _ILJitCreateMethodSignature(coder, method)))
+       {
+               return 0;
+       }
+       
        /* Now we can create the jit function itself. */
        /* We must be able to create jit function prototypes while an other */
        /* function is on demand compiled. */
@@ -1222,6 +1350,59 @@
        return 1;
 }
 
+/*
+ * Create the jit function header for an ILMethod with the information from
+ * a virtual ancestor.
+ * We can reuse the signature in this case.
+ */
+int ILJitFunctionCreateFromAncestor(ILCoder *_coder, ILMethod *method,
+                                                                               
                         ILMethod *virtualAncestor)
+{
+       ILJITCoder *jitCoder = ((ILJITCoder *)_coder);
+       ILJitFunction ancestor = virtualAncestor->userData;
+       ILJitFunction jitFunction;
+       ILJitType jitSignature;
+
+       /* Don't create the jit function twice. */
+       if(method->userData)
+       {
+               return 1;
+       }
+
+       if(!ancestor)
+       {
+               /* Tha ancestor has no jit function (might be abstract). */
+               /* So we need to do it the hard way. */
+               return ILJitFunctionCreate(_coder, method);
+       }
+
+       jitSignature = jit_function_get_signature(ancestor);
+
+       /* Now we can create the jit function itself. */
+       /* We must be able to create jit function prototypes while an other */
+       /* function is on demand compiled. */
+       if(!(jitFunction = jit_function_create(jitCoder->context, 
jitSignature)))
+       {
+               return 0;
+       }
+
+       /* Set the ILMethod in the new functions metadata. */
+       /* Because there has nothing to be freed we can use 0 for the 
free_func. */
+       if(!jit_function_set_meta(jitFunction, IL_JIT_META_METHOD, method, 0, 
0))
+       {
+               return 0;
+       }
+       
+       /* now set the on demand compiler function */
+       jit_function_set_on_demand_compiler(jitFunction, _ILJitOnDemandFunc);
+
+       /* and link the new jitFunction to the method. */
+       method->userData = jitFunction;
+
+       /* are we ready now ? */
+
+       return 1;
+}
 
 /*
  * Create all jitMethods for the given class.
@@ -1289,23 +1470,59 @@
 }
 
 /*
+ * Handle special cases of the Type creation like handles, ...
+ * Returns the jit type for the special case or 0 if is no special case.
+ */
+static ILJitType _ILJitTypeSpecials(ILClassName *className)
+{
+       if(className->namespace && !strcmp(className->namespace, "System"))
+       {
+               if(!strcmp(className->name, "RuntimeTypeHandle"))
+               {
+                       return _IL_JIT_TYPE_NINT;
+               }
+               if(!strcmp(className->name, "RuntimeMethodHandle"))
+               {
+                       return _IL_JIT_TYPE_NINT;
+               }
+               if(!strcmp(className->name, "RuntimeFieldHandle"))
+               {
+                       return _IL_JIT_TYPE_NINT;
+               }
+               if(!strcmp(className->name, "RuntimeArgumentHandle"))
+               {
+                       return _IL_JIT_TYPE_NINT;
+               }
+       }
+       return 0;
+}
+
+/*
  * Create the class/struct representation of a clr type for libjit.
  * and store the type in classPrivate.
  * Returns the 1 on success else 0
  */
-int ILJitTypeCreate(ILClassPrivate *classPrivate)
+int ILJitTypeCreate(ILClassPrivate *classPrivate, ILExecProcess *process)
 {
-       ILJitType type;
+       ILJitType type = 0;
 
        if(classPrivate->size >= 0)
        {
-               if(!(type = jit_type_create_struct(0, 0, 0)))
+               /* When it's a runtime object check if it has to be handled 
special. */
+               if(process->context->systemImage == 
classPrivate->classInfo->programItem.image)
                {
-                       return 0;
+                       type = 
_ILJitTypeSpecials(classPrivate->classInfo->className);
+               }
+               if(!type)
+               {
+                       if(!(type = jit_type_create_struct(0, 0, 0)))
+                       {
+                               return 0;
+                       }
+                       jit_type_set_size_and_alignment(type,
+                                                                               
        classPrivate->size,
+                                                                               
        classPrivate->alignment);
                }
-               jit_type_set_size_and_alignment(type,
-                                                                               
classPrivate->size,
-                                                                               
classPrivate->alignment);
                classPrivate->jitTypes.jitTypeBase = type;
                if(!(classPrivate->jitTypes.jitTypePtr = 
jit_type_create_pointer(type, 1)))
                {
Index: pnet/engine/jitc.h
diff -u pnet/engine/jitc.h:1.6 pnet/engine/jitc.h:1.7
--- pnet/engine/jitc.h:1.6      Wed Jan  4 18:54:39 2006
+++ pnet/engine/jitc.h  Mon Jan  9 20:49:47 2006
@@ -117,6 +117,14 @@
 int ILJitFunctionCreate(ILCoder *_coder, ILMethod *method);
 
 /*
+ * Create the jit function header for an ILMethod with the information from
+ * a virtual ancestor.
+ * We can reuse the signature in this case.
+ */
+int ILJitFunctionCreateFromAncestor(ILCoder *_coder, ILMethod *method,
+                                                                               
                         ILMethod *virtualAncestor);
+
+/*
  * Create all jitMethods for the given class.
  * Returns 1 on success and 0 on error.
  */
@@ -140,7 +148,7 @@
  * and store the type in classPrivate.
  * Returns the jit type on success else 0
  */
-int ILJitTypeCreate(ILClassPrivate *classPrivate);
+int ILJitTypeCreate(ILClassPrivate *classPrivate, ILExecProcess *process);
 
 /*
  * Destroy the given type in libjit.
Index: pnet/engine/jitc_call.c
diff -u pnet/engine/jitc_call.c:1.4 pnet/engine/jitc_call.c:1.5
--- pnet/engine/jitc_call.c:1.4 Thu Jan  5 20:15:06 2006
+++ pnet/engine/jitc_call.c     Mon Jan  9 20:49:47 2006
@@ -21,58 +21,6 @@
 #ifdef IL_JITC_CODE
 
 /*
- * Call the static constructor for a class if necessary.
- */
-static void _ILJitCallStaticConstructor(ILCoder *_coder, ILClass *classInfo,
-                                                                 int isCtor)
-{
-       if((classInfo->attributes & IL_META_TYPEDEF_CCTOR_ONCE) != 0)
-       {
-               /* We already know that the static constructor has been called,
-                  so there is no point outputting a call to it again */
-               return;
-       }
-       if(isCtor ||
-          (classInfo->attributes & IL_META_TYPEDEF_BEFORE_FIELD_INIT) == 0)
-       {
-               ILJITCoder *coder = _ILCoderToILJITCoder(_coder);
-
-               /* We must call the static constructor before instance
-                  constructors, or before static methods when the
-                  "beforefieldinit" attribute is not present */
-               ILMethod *cctor = 0;
-               while((cctor = (ILMethod *)ILClassNextMemberByKind
-                                       (classInfo, (ILMember *)cctor,
-                                        IL_META_MEMBERKIND_METHOD)) != 0)
-               {
-                       if(ILMethod_IsStaticConstructor(cctor))
-                       {
-                               break;
-                       }
-               }
-               if(cctor != 0)
-               {
-                       /* Don't call it if we are within the constructor 
already */
-                       if(cctor != coder->currentMethod)
-                       {
-                               /* Output a call to the static constructor */
-                               jit_value_t thread = 
jit_value_get_param(coder->jitFunction, 0);
-
-                               jit_insn_call(coder->jitFunction, "cctor",
-                                                               
ILJitFunctionFromILMethod(cctor), 0,
-                                                               &thread, 1, 0);
-                       }
-               }
-               else
-               {
-                       /* This class does not have a static constructor,
-                          so mark it so that we never do this test again */
-                       classInfo->attributes |= IL_META_TYPEDEF_CCTOR_ONCE;
-               }
-       }
-}
-
-/*
  * Fill the argument array for the methodcall with the args on the stack.
  * This function pops the arguments off the stack too.
  */
@@ -133,13 +81,6 @@
        return 0;
 }
 
-/*
- * Call a Method.
- */
-static void _ILJitCallMethod(ILJITCoder *coder, ILJitValue *stackTop, int 
isCtor)
-{
-}
-
 static void JITCoder_UpConvertArg(ILCoder *coder, ILEngineStackItem *args,
                                                          ILUInt32 numArgs, 
ILUInt32 param,
                                                          ILType *paramType)
@@ -214,6 +155,9 @@
        ILJitValue jitParams[argCount + 2];
        ILJitValue returnValue;
        
+       /* Output a call to the static constructor */
+       _ILJitCallStaticConstructor(jitCoder, ILMethod_Owner(methodInfo), 1);
+
        /* Output a call to the constructor */
        jitParams[0] = jit_value_get_param(jitCoder->jitFunction, 0); // we add 
the current function thread as the first param
                
@@ -245,47 +189,55 @@
 
        ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
        int argCount = info->numBaseArgs + info->numVarArgs;
+       ILJitFunction func = methodInfo->userData;
+       ILJitType  signature;
        ILJitValue jitParams[argCount + 2];
        ILJitValue returnValue;
        ILJitValue classPrivate;
        ILJitValue vtable;
        ILJitValue vtableIndex;
-       ILJitValue method;
        ILJitValue jitFunction;
 
+       if(!func)
+       {
+               signature = _ILJitCreateMethodSignature(jitCoder, methodInfo);
+       }
+       else
+       {
+               signature = jit_function_get_signature(func);
+       }
        jitParams[0] = jit_value_get_param(jitCoder->jitFunction, 0);
        _ILJitFillArguments(jitCoder, &(jitParams[1]), info);
+       /* TODO: handle varargs here and create a call signature. */
+
        jit_insn_check_null(jitCoder->jitFunction, jitParams[1]);
        classPrivate = _ILJitGetObjectClassPrivate(jitCoder->jitFunction, 
jitParams[1]);
        vtable = jit_insn_load_relative(jitCoder->jitFunction, classPrivate, 
-                                                                       
offsetof(ILClassPrivate, vtable), 
+                                                                       
offsetof(ILClassPrivate, jitVtable), 
                                                                        
_IL_JIT_TYPE_VPTR);
        vtableIndex = jit_value_create_nint_constant(jitCoder->jitFunction,
                                                                                
                 _IL_JIT_TYPE_INT32,
                                                                                
                 (jit_nint)methodInfo->index);
-       method = jit_insn_load_elem(jitCoder->jitFunction, vtable,
+       jitFunction = jit_insn_load_elem(jitCoder->jitFunction, vtable,
                                                                         
vtableIndex, _IL_JIT_TYPE_VPTR);
-       jitFunction = jit_insn_load_relative(jitCoder->jitFunction, method, 
-                                                                       
offsetof(ILClassPrivate, vtable), 
-                                                                       
_IL_JIT_TYPE_VPTR);
        if(info->tailCall == 1)
        {
-               returnValue = jit_insn_call_indirect(jitCoder->jitFunction,
-                                                                               
         jitFunction, 0,
-                                                                               
         jitParams, argCount,
-                                                                               
         JIT_CALL_TAIL);
+               returnValue = 
jit_insn_call_indirect_vtable(jitCoder->jitFunction,
+                                                                               
                        jitFunction, signature,
+                                                                               
                        jitParams, argCount,
+                                                                               
                        JIT_CALL_TAIL);
        }
        else
        {
-               returnValue = jit_insn_call_indirect(jitCoder->jitFunction,
-                                                                               
         jitFunction, 0,
-                                                                               
         jitParams, argCount,
-                                                                               
         0);
-               if(returnItem->engineType != ILEngineType_Invalid)
-               {
-                       jitCoder->jitStack[jitCoder->stackTop] = returnValue;
-                       JITC_ADJUST(jitCoder, 1);
-               }
+               returnValue = 
jit_insn_call_indirect_vtable(jitCoder->jitFunction,
+                                                                               
                        jitFunction, signature,
+                                                                               
                        jitParams, argCount,
+                                                                               
                        0);
+       }
+       if(returnItem->engineType != ILEngineType_Invalid)
+       {
+               jitCoder->jitStack[jitCoder->stackTop] = returnValue;
+               JITC_ADJUST(jitCoder, 1);
        }
 }
 
@@ -293,6 +245,69 @@
                                                                   
ILEngineStackItem *returnItem,
                                                                   ILMethod 
*methodInfo)
 {
+       ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
+       int argCount = info->numBaseArgs + info->numVarArgs;
+       ILJitFunction func = methodInfo->userData;
+       ILJitType  signature;
+       ILJitValue jitParams[argCount + 2];
+       ILJitValue returnValue;
+       ILJitValue classPrivate;
+       ILJitValue jitFunction;
+       ILJitValue interfaceClass;
+       ILJitValue methodIndex;
+       ILJitValue args[3];
+       jit_label_t label = jit_label_undefined;
+
+       if(!func)
+       {
+               signature = _ILJitCreateMethodSignature(jitCoder, methodInfo);
+       }
+       else
+       {
+               signature = jit_function_get_signature(func);
+       }
+       jitParams[0] = jit_value_get_param(jitCoder->jitFunction, 0);
+       _ILJitFillArguments(jitCoder, &(jitParams[1]), info);
+       /* TODO: handle varargs here and create a call signature. */
+
+       jit_insn_check_null(jitCoder->jitFunction, jitParams[1]);
+       classPrivate = _ILJitGetObjectClassPrivate(jitCoder->jitFunction, 
jitParams[1]);
+       interfaceClass = jit_value_create_nint_constant(jitCoder->jitFunction,
+                                                                               
                        _IL_JIT_TYPE_VPTR,
+                                                                               
                        (jit_nint)methodInfo->member.owner);
+       methodIndex = jit_value_create_nint_constant(jitCoder->jitFunction,
+                                                                               
                 _IL_JIT_TYPE_UINT32,
+                                                                               
                 (jit_nint)methodInfo->index);
+       args[0] = classPrivate;
+       args[1] = interfaceClass;
+       args[2] = methodIndex;
+       jitFunction = jit_insn_call_native(jitCoder->jitFunction, 0,
+                                                                          
_ILRuntimeLookupInterfaceMethod,
+                                                                          
_ILJitSignature_ILRuntimeLookupInterfaceMethod,
+                                                                          
args, 3, 0);
+       jit_insn_branch_if(jitCoder->jitFunction, jitFunction, &label);
+       /* TODO: raise a MissingMethodException here. */
+
+       jit_insn_label(jitCoder->jitFunction, &label);
+       if(info->tailCall == 1)
+       {
+               returnValue = 
jit_insn_call_indirect_vtable(jitCoder->jitFunction,
+                                                                               
                        jitFunction, signature,
+                                                                               
                        jitParams, argCount,
+                                                                               
                        JIT_CALL_TAIL);
+       }
+       else
+       {
+               returnValue = 
jit_insn_call_indirect_vtable(jitCoder->jitFunction,
+                                                                               
                        jitFunction, signature,
+                                                                               
                        jitParams, argCount,
+                                                                               
                        0);
+       }
+       if(returnItem->engineType != ILEngineType_Invalid)
+       {
+               jitCoder->jitStack[jitCoder->stackTop] = returnValue;
+               JITC_ADJUST(jitCoder, 1);
+       }
 }
 
 static int JITCoder_CallInlineable(ILCoder *coder, int inlineType,
Index: pnet/engine/jitc_const.c
diff -u pnet/engine/jitc_const.c:1.2 pnet/engine/jitc_const.c:1.3
--- pnet/engine/jitc_const.c:1.2        Thu Dec 29 15:56:52 2005
+++ pnet/engine/jitc_const.c    Mon Jan  9 20:49:47 2006
@@ -116,12 +116,15 @@
                        jit_value_create_nint_constant(jitCoder->jitFunction,
                                                                                
        jit_type_void_ptr,
                                                                                
        (jit_nint)object);
-               JITC_ADJUST(jitCoder, 1);
        }
        else
        {
-               /* TODO */
+               jitCoder->jitStack[jitCoder->stackTop] = 
+                       jit_value_create_nint_constant(jitCoder->jitFunction,
+                                                                               
   _IL_JIT_TYPE_VPTR, 
+                                                                          
(jit_nint)token);
        }
+       JITC_ADJUST(jitCoder, 1);
 }
 
 #endif /* IL_JITC_CODE */
Index: pnet/engine/jitc_obj.c
diff -u pnet/engine/jitc_obj.c:1.2 pnet/engine/jitc_obj.c:1.3
--- pnet/engine/jitc_obj.c:1.2  Fri Jan  6 17:38:56 2006
+++ pnet/engine/jitc_obj.c      Mon Jan  9 20:49:47 2006
@@ -209,9 +209,11 @@
 static void JITCoder_PushToken(ILCoder *coder, ILProgramItem *item)
 {
        ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
-       ILJitValue token = jit_value_create_nint_constant(jitCoder->jitFunction,
-                                                                               
                          _IL_JIT_TYPE_VPTR, 
-                                                                               
                 (jit_nint)item);
+
+       jitCoder->jitStack[jitCoder->stackTop] = 
+               jit_value_create_nint_constant(jitCoder->jitFunction,
+                                                                          
_IL_JIT_TYPE_VPTR, 
+                                                                  
(jit_nint)item);
 
        JITC_ADJUST(jitCoder, 1);
 }
Index: pnet/engine/jitc_setup.c
diff -u pnet/engine/jitc_setup.c:1.5 pnet/engine/jitc_setup.c:1.6
--- pnet/engine/jitc_setup.c:1.5        Thu Jan  5 19:40:07 2006
+++ pnet/engine/jitc_setup.c    Mon Jan  9 20:49:47 2006
@@ -116,6 +116,38 @@
        /* And reset the stack top. */
        coder->stackTop = 0;
 
+       /* Set the current method in the thread. */
+       _ILJitSetMethodInThread(coder->jitFunction, 
+                                                       
jit_value_get_param(coder->jitFunction, 0),
+                                                       method);
+
+       if(ILMethod_IsStaticConstructor(method))
+       {
+               /* We have to take care that the method is executed only once. 
*/
+               ILClass *info = ILMethod_Owner(method);
+               ILJitValue classInfo = 
+                       jit_value_create_nint_constant(coder->jitFunction,
+                                                                               
   _IL_JIT_TYPE_VPTR,
+                                                                               
   (jit_nint)info);
+               ILJitValue cctorOnce = 
+                       jit_value_create_nint_constant(coder->jitFunction,
+                                                                               
   _IL_JIT_TYPE_UINT32,
+                                                                               
   (jit_nint)IL_META_TYPEDEF_CCTOR_ONCE);
+               ILJitValue attributes = 
jit_insn_load_relative(coder->jitFunction,
+                                                                               
                           classInfo,
+                                                                               
                           offsetof(ILClass, attributes),
+                                                                               
                           _IL_JIT_TYPE_UINT32);
+               ILJitValue temp = jit_insn_and(coder->jitFunction, attributes, 
cctorOnce);
+               jit_label_t label1 = jit_label_undefined;
+
+               jit_insn_branch_if_not(coder->jitFunction, temp, &label1);
+               jit_insn_return(coder->jitFunction, 0);
+               jit_insn_label(coder->jitFunction, &label1);
+               temp = jit_insn_or(coder->jitFunction, attributes, cctorOnce);
+               jit_insn_store_relative(coder->jitFunction, classInfo,
+                                                               
offsetof(ILClass, attributes), temp);
+       }
+
        return 1;
 }
 
Index: pnet/engine/layout.c
diff -u pnet/engine/layout.c:1.41 pnet/engine/layout.c:1.42
--- pnet/engine/layout.c:1.41   Thu Dec 22 18:23:43 2005
+++ pnet/engine/layout.c        Mon Jan  9 20:49:47 2006
@@ -46,6 +46,7 @@
        int                     managedInstance;
        int                     managedStatic;
 #ifdef IL_USE_JIT
+       void      **jitVtable;
        ILJitTypes *jitTypes;
 #endif 
 } LayoutInfo;
@@ -77,6 +78,7 @@
                {
                        layout->managedInstance = 1;
                }
+               layout->jitVtable = 0;
        #else
                switch(ILType_ToElement(type))
                {
@@ -218,6 +220,7 @@
                }
                layout->size = ILJitTypeGetSize(layout->jitTypes->jitTypeBase);
                layout->alignment = 
ILJitTypeGetAlignment(layout->jitTypes->jitTypeBase);
+               layout->jitVtable = 0;
        #else
        #if defined(HAVE_LIBFFI)
                layout->size = ffi_type_pointer.size;
@@ -546,14 +549,23 @@
                                                
if(!(classPrivate->imt[imtIndex]))
                                                {
                                                        /* No conflict at this 
table position */
+                                               #ifdef IL_USE_JIT
+                                                       
classPrivate->imt[imtIndex] =
+                                                               
classPrivate->jitVtable[vtableIndex];
+                                               #else
                                                        
classPrivate->imt[imtIndex] =
                                                                
classPrivate->vtable[vtableIndex];
+                                               #endif
                                                }
                                                else
                                                {
                                                        /* We have encountered 
a conflict in the table */
                                                        
classPrivate->imt[imtIndex] =
+                                                       #ifdef IL_USE_JIT
+                                                               (void 
*)(ILNativeInt)(-1);
+                                                       #else
                                                                (ILMethod 
*)(ILNativeInt)(-1);
+                                                       #endif
                                                }
                                        }
                                }
@@ -570,16 +582,22 @@
        /* Clear positions in the table that indicate conflicts */
        for(posn = 0; posn < IL_IMT_SIZE; ++posn)
        {
+       #ifdef IL_USE_JIT
+               if(classPrivate->imt[posn] == (void *)(ILNativeInt)(-1))
+       #else
                if(classPrivate->imt[posn] == (ILMethod *)(ILNativeInt)(-1))
+       #endif
                {
                        classPrivate->imt[posn] = 0;
                }
+       #ifndef IL_USE_JIT
                #if IL_DEBUG_IMTS
                if(classPrivate->imt[posn] != 0)
                {
                        fprintf(stderr, "\t %d : %s\n", posn, 
ILMethod_Name(classPrivate->imt[posn]));
                }
                #endif
+       #endif
        }
 
        #if IL_DEBUG_IMTS
@@ -613,6 +631,9 @@
        ILClass *parent;
        ILImplements *implements;
        ILMethodCode code;
+#ifdef IL_USE_JIT
+       void **jitVtable;
+#endif
 
        /* Determine if we have already tried to lay out this class */
        if(info->userData)
@@ -638,6 +659,7 @@
                        layout->managedInstance = classPrivate->managedInstance;
                        layout->managedStatic = classPrivate->managedStatic;
                #ifdef IL_USE_JIT
+                       layout->jitVtable = classPrivate->jitVtable;
                        layout->jitTypes = &(classPrivate->jitTypes);
                #endif
                        return 1;
@@ -858,6 +880,13 @@
        classPrivate->alignment = layout->alignment;
        classPrivate->nativeSize = layout->nativeSize;
        classPrivate->nativeAlignment = layout->nativeAlignment;
+#ifdef IL_USE_JIT
+       if(!ILJitTypeCreate(classPrivate, process))
+       {
+               info->userData = 0;
+               return 0;
+       }
+#endif
        classPrivate->inLayout = 0;
 
        /* Allocate the static fields.  We must do this after the
@@ -920,19 +949,6 @@
                }
        }
 
-#ifdef IL_USE_JIT
-       if(!ILJitTypeCreate(classPrivate))
-       {
-               info->userData = 0;
-               return 0;
-       }
-       if(!ILJitCreateFunctionsForClass(process->coder, info))
-       {
-               ILJitTypesDestroy(&(classPrivate->jitTypes));
-               info->userData = 0;
-               return 0;
-       }
-#endif
        /* Allocate vtable slots to the virtual methods in this class */
        method = 0;
        explicitSize = layout->vtableSize;
@@ -975,6 +991,15 @@
                        {
                                /* Use the same index as the ancestor */
                                method->index = ancestor->index;
+                       #ifdef IL_USE_JIT
+                               
if(!ILJitFunctionCreateFromAncestor(process->coder,
+                                                                               
                        method,
+                                                                               
                        ancestor))
+                               {
+                                       info->userData = 0;
+                                       return 0;
+                               }
+                       #endif
                        }
                        else
                        {
@@ -997,6 +1022,15 @@
                return 0;
        }
 
+#ifdef IL_USE_JIT
+       if(!ILJitCreateFunctionsForClass(process->coder, info))
+       {
+               ILJitTypesDestroy(&(classPrivate->jitTypes));
+               info->userData = 0;
+               return 0;
+       }
+#endif
+
        /* Allocate the vtable and copy the parent's vtable into it */
        if((vtable = (ILMethod **)
                        
ILMemStackAllocItem(&(info->programItem.image->memStack),
@@ -1005,9 +1039,21 @@
                info->userData = 0;
                return 0;
        }
+#ifdef IL_USE_JIT
+       if((jitVtable = (void **)
+                       
ILMemStackAllocItem(&(info->programItem.image->memStack),
+                                                       layout->vtableSize * 
sizeof(void *))) == 0)
+       {
+               info->userData = 0;
+               return 0;
+       }
+#endif
        if(explicitSize > 0)
        {
                ILMemCpy(vtable, layout->vtable, explicitSize * sizeof(ILMethod 
*));
+       #ifdef IL_USE_JIT
+               ILMemCpy(jitVtable, layout->jitVtable, explicitSize * 
sizeof(ILMethod *));
+       #endif
        }
 
        /* Override the vtable slots with this class's method implementations */
@@ -1018,6 +1064,9 @@
                if((method->member.attributes & IL_META_METHODDEF_VIRTUAL) != 0)
                {
                        vtable[method->index] = method;
+               #ifdef IL_USE_JIT
+                       jitVtable[method->index] = 
jit_function_to_vtable_pointer(method->userData);
+               #endif
                }
        }
 
@@ -1049,6 +1098,10 @@
        classPrivate->managedInstance = layout->managedInstance;
        classPrivate->managedStatic = layout->managedStatic;
        layout->vtable = vtable;
+#ifdef IL_USE_JIT
+       classPrivate->jitVtable = jitVtable;
+       layout->jitVtable = jitVtable;
+#endif
 
 #ifdef IL_USE_IMTS
        /* Build the interface method table for this class */




reply via email to

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