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/cctormgr.c engine/cctormg...


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] pnet ChangeLog engine/cctormgr.c engine/cctormg...
Date: Sun, 11 Feb 2007 14:34:33 +0000

CVSROOT:        /cvsroot/dotgnu-pnet
Module name:    pnet
Changes by:     Klaus Treichel <ktreichel>      07/02/11 14:34:33

Modified files:
        .              : ChangeLog 
        engine         : cctormgr.c cctormgr.h convert.c cvmc.c 
                         cvmc_call.c jitc.c jitc_call.c jitc_except.c 
                         jitc_inline.c jitc_obj.c jitc_setup.c 
                         null_coder.c 
        include        : il_coder.h il_thread.h 
        support        : Makefile.am no_defs.h pt_defs.c pt_defs.h 
                         w32_defs.h 
Added files:
        support        : semaphore.c 

Log message:
        Add support for method locks while class initializers are executed.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pnet/ChangeLog?cvsroot=dotgnu-pnet&r1=1.3413&r2=1.3414
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cctormgr.c?cvsroot=dotgnu-pnet&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cctormgr.h?cvsroot=dotgnu-pnet&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/convert.c?cvsroot=dotgnu-pnet&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cvmc.c?cvsroot=dotgnu-pnet&r1=1.52&r2=1.53
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cvmc_call.c?cvsroot=dotgnu-pnet&r1=1.36&r2=1.37
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc.c?cvsroot=dotgnu-pnet&r1=1.67&r2=1.68
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_call.c?cvsroot=dotgnu-pnet&r1=1.37&r2=1.38
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_except.c?cvsroot=dotgnu-pnet&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_inline.c?cvsroot=dotgnu-pnet&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_obj.c?cvsroot=dotgnu-pnet&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_setup.c?cvsroot=dotgnu-pnet&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/null_coder.c?cvsroot=dotgnu-pnet&r1=1.28&r2=1.29
http://cvs.savannah.gnu.org/viewcvs/pnet/include/il_coder.h?cvsroot=dotgnu-pnet&r1=1.53&r2=1.54
http://cvs.savannah.gnu.org/viewcvs/pnet/include/il_thread.h?cvsroot=dotgnu-pnet&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/pnet/support/Makefile.am?cvsroot=dotgnu-pnet&r1=1.55&r2=1.56
http://cvs.savannah.gnu.org/viewcvs/pnet/support/no_defs.h?cvsroot=dotgnu-pnet&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/pnet/support/pt_defs.c?cvsroot=dotgnu-pnet&r1=1.9&r2=1.10
http://cvs.savannah.gnu.org/viewcvs/pnet/support/pt_defs.h?cvsroot=dotgnu-pnet&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/pnet/support/w32_defs.h?cvsroot=dotgnu-pnet&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/pnet/support/semaphore.c?cvsroot=dotgnu-pnet&rev=1.1

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ChangeLog,v
retrieving revision 1.3413
retrieving revision 1.3414
diff -u -b -r1.3413 -r1.3414
--- ChangeLog   9 Feb 2007 21:54:16 -0000       1.3413
+++ ChangeLog   11 Feb 2007 14:34:32 -0000      1.3414
@@ -1,3 +1,43 @@
+2007-02-11 Klaus Treichel  <address@hidden>
+
+       * engine/cctormgr.c, engine/cctormgr.h: Add support for locking methods
+       that require class initializers to be executed till the class 
initializers
+       finished executing.
+
+       * engine/convert.c: Use the new coder functions to handle the method 
locks
+       for the cvm coder. Remove the execution of class initializers for the 
jit
+       coder because that's handled in the coder itself.
+
+       * engine/cvmc.c: Add the new arg to the cctors execution and the method 
to
+       handle the method locks.
+
+       * engine/cvmc_call.c: Remove the queueing of the class initializer on
+       loading a function pointer on the stack.
+
+       * engine/jitc.c: Use the new on-demand compilation feature in libjit to
+       handle the method locks. Add the new arg to the cctors execution and the
+       method to handle the method locks.
+
+       * engine/jitc_call.c, engine/jitc_except.c, engine/jitc_inline.c,
+       engine/jitc_obj.c, setup.c: Remove all conditionals if the cctor manager
+       is enabled because the other option is removed.
+
+       * engine/null_coder.c: Add the new arg to the cctors execution and the
+       method to handle the method locks.
+
+       * include/il_coder.h: Add the new arg to the cctors execution and the
+       method to handle the method locks to the coder definition.
+
+       * include/il_thread.h: Add function prototypes for semaphores.
+
+       * support/Makefile.am: Add the new file semaphores.c to the sources.
+
+       * support/pt_defs.c, support/pt_defs.h, support/no_defs.s,
+       support/win32_defs.h: Add a semaphore primitive for increasing the
+       semaphore count by more than 1.
+
+       * support/semaphore.c: Added.
+
 2007-02-09  Radek Polak  <address@hidden>
 
        * dumpasm/Makefile.am, ildasm/Makefile.am, ildasm/ildasm_main.c,

Index: engine/cctormgr.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cctormgr.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- engine/cctormgr.c   21 Jan 2007 17:53:29 -0000      1.2
+++ engine/cctormgr.c   11 Feb 2007 14:34:32 -0000      1.3
@@ -26,15 +26,317 @@
 #endif
 
 /*
- * Reenable finalizers, unlock the metadata lock and run finalizers.
+ * Acquire and release the metadata lock, while suppressing finalizers
  * Must be kept in sync with convert.c
  */
-#define        METADATA_UNLOCK(thread) \
+#define        METADATA_WRLOCK(process)        \
+                       do { \
+                               IL_METADATA_WRLOCK(process); \
+                               ILGCDisableFinalizers(0); \
+                       } while (0)
+#define        METADATA_UNLOCK(process)        \
                        do { \
                                ILGCEnableFinalizers(); \
-                               
IL_METADATA_UNLOCK(_ILExecThreadProcess(thread)); \
+                               IL_METADATA_UNLOCK(process); \
                                ILGCInvokeFinalizers(0); \
                        } while (0)
+
+/*
+ * Free an ILMethodLockEntry.
+ */
+static void _ILMethodLockEntry_Destroy(ILMethodLockPool *lockPool,
+                                                                          
ILMethodLockEntry *lockEntry)
+{
+       if(lockPool && lockEntry)
+       {
+               /* Destroy the semaphore object. */
+               ILSemaphoreDestroy(lockEntry->sem);
+
+               /* And free the memory. */
+               ILFree(lockEntry->sem);
+
+               /* Free this lock entry. */
+               ILMemPoolFree(&(lockPool->methodPool), lockEntry);
+       }
+}
+
+/*
+ * Initialize a mathod lock pool.
+ */
+static int _ILMethodLockPool_Init(ILMethodLockPool *lockPool)
+{
+       if(lockPool)
+       {
+               /* Initialize the lock mutex. */
+               if(!(lockPool->lock = ILMutexCreate()))
+               {
+                       return 0;
+               }
+
+               /* Intialize the pool for the class infos. */
+               ILMemPoolInit(&(lockPool->methodPool),
+                                         sizeof(ILMethodLockEntry),
+                                         5);
+
+               lockPool->lastLockedMethod = 0;
+
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * Destroy a mathod lock pool.
+ */
+static int _ILMethodLockPool_Destroy(ILMethodLockPool *lockPool)
+{
+       if(lockPool)
+       {
+               ILMemPoolDestroy(&(lockPool->methodPool));
+
+               if(lockPool->lock)
+               {
+                       /* Destroy the lock mutex. */
+                       ILMutexDestroy(lockPool->lock);
+
+                       ILFree(lockPool->lock);
+               }
+       }
+       return 0;
+}
+
+/*
+ * Add a method to the lock pool.
+ * Returns 0 on failure.
+ */
+static int _ILMethodLockPool_LockMethod(ILMethodLockPool *lockPool,
+                                                                               
ILMethod *method,
+                                                                               
void *userData)
+{
+       if(lockPool)
+       {
+               ILExecThread *thread = ILExecThreadCurrent();
+               ILMethodLockEntry *currentLockEntry;
+
+               ILMutexLock(lockPool->lock);
+
+               if(!(currentLockEntry = ILMemPoolAlloc(&(lockPool->methodPool),
+                                                                               
           ILMethodLockEntry)))
+               {
+                       ILMutexUnlock(lockPool->lock);
+                       return 0;
+               }
+
+               if(!(currentLockEntry->sem = ILSemaphoreCreate()))
+               {
+                       ILMemPoolFree(&(lockPool->methodPool), 
currentLockEntry);
+                       ILMutexUnlock(lockPool->lock);
+                       return 0;
+               }
+               /* We are using the support thread (ILThread) here to avoid */
+               /* blocking during execution of finalizers where the 
ILExecThread */
+               /* for the same ILThread might change. */
+               currentLockEntry->thread = thread->supportThread;
+
+               currentLockEntry->method = method;
+               currentLockEntry->numWaitingThreads = 0;
+               currentLockEntry->userData = userData;
+               currentLockEntry->nextEntry = lockPool->lastLockedMethod;
+               lockPool->lastLockedMethod = currentLockEntry;
+
+               ILMutexUnlock(lockPool->lock);
+
+               /* Return with success. */
+               return 1;
+       }
+       return 0;
+}
+
+/*
+ * Unlock a locked method.
+ */
+static void *_ILMethodLockPool_UnlockMethod(ILMethodLockPool *lockPool,
+                                                                               
   ILMethod *method)
+{
+       if(lockPool)
+       {
+               ILMethodLockEntry *currentLockEntry = 
lockPool->lastLockedMethod;
+
+               if(currentLockEntry)
+               {
+                       /* Lock the lock pool. */
+                       ILMutexLock(lockPool->lock);
+
+                       currentLockEntry = lockPool->lastLockedMethod;
+
+                       if(currentLockEntry)
+                       {
+                               if(currentLockEntry->method == method)
+                               {
+                                       lockPool->lastLockedMethod = 
currentLockEntry->nextEntry;
+                               }
+                               else
+                               {
+                                       ILMethodLockEntry *tempLockEntry;
+
+                                       while(currentLockEntry)
+                                       {
+                                               
if((currentLockEntry->nextEntry) &&
+                                                  
(currentLockEntry->nextEntry->method == method))
+                                               {
+                                                       tempLockEntry = 
currentLockEntry->nextEntry;
+                                                       
currentLockEntry->nextEntry = currentLockEntry->nextEntry->nextEntry;
+                                                       currentLockEntry = 
tempLockEntry;
+                                                       break;
+                                               }
+                                               currentLockEntry = 
currentLockEntry->nextEntry;
+                                       }
+                               }                               
+                               if(currentLockEntry)
+                               {
+                                       /* We found the lock entry for the 
given method and */
+                                       /* unlinked it from the list. */
+                                       /* So the locked method can't be found 
by any other */
+                                       /* thread now. */
+
+                                       void *userData = 
currentLockEntry->userData;
+
+                                       if(currentLockEntry->numWaitingThreads 
== 0)
+                                       {
+                                               /* There are no threads waiting 
for thie method. */
+                                               /* So we have to destroy the 
lock entry here. */
+
+                                               
_ILMethodLockEntry_Destroy(lockPool, currentLockEntry);
+                                       }
+                                       else
+                                       {
+                                               /* Release all threads waiting 
for this method. */
+                                               
ILSemaphorePostMultiple(currentLockEntry->sem,
+                                                                               
                currentLockEntry->numWaitingThreads);
+                                       }
+                                       /* Unlock the lock pool. */
+                                       ILMutexUnlock(lockPool->lock);
+
+                                       return userData;
+                               }
+                       }
+
+                       /* Unlock the lock pool. */
+                       ILMutexUnlock(lockPool->lock);
+               }
+       }
+       return 0;
+}
+
+/*
+ * Check if a method is locked and block the calling thread if the method is
+ * locked by an other thread.
+ * If the method is locked by the current thread the userData entry of the
+ * lock entry is returned.
+ * Returns 0 if the method is not locked, 
+ */
+void *ILMethodLockPool_HandleLockedMethod(ILMethodLockPool *lockPool,
+                                                                               
  ILMethod *method,
+                                                                               
  ILCCtorMgr *cctorMgr)
+{
+       if(lockPool)
+       {
+               ILMethodLockEntry *currentLockEntry = 
lockPool->lastLockedMethod;
+
+               if(currentLockEntry)
+               {
+                       /* Lock the lock pool. */
+                       ILMutexLock(lockPool->lock);
+
+                       currentLockEntry = lockPool->lastLockedMethod;
+
+                       while(currentLockEntry)
+                       {
+                               if(currentLockEntry->method == method)
+                               {
+                                       break;
+                               }
+                               currentLockEntry = currentLockEntry->nextEntry;
+                       }
+                       if(currentLockEntry)
+                       {
+                               /* The method is locked. */
+                               ILExecThread *thread = ILExecThreadCurrent();
+
+                               if(currentLockEntry->thread == 
thread->supportThread)
+                               {
+                                       /* The current thread locked the 
method. */
+
+                                       /* Unlock the lock pool. */
+                                       ILMutexUnlock(lockPool->lock);
+
+                                       /* And return the userData entry. */
+                                       return currentLockEntry->userData;
+                               }
+                               else if(cctorMgr->thread == 
thread->supportThread)
+                               {
+                                       /* We have to run the cctors queued for 
this method. */
+                                       /* TODO */
+
+                                       /* Unlock the lock pool. */
+                                       ILMutexUnlock(lockPool->lock);
+
+                                       /* And return the userData entry. */
+                                       return currentLockEntry->userData;
+                               }
+                               else
+                               {
+                                       ILExecProcess *process = 
((ILClassPrivate *)(ILMethod_Owner(method)->userData))->process;
+
+                                       /* Increase the number of waiting 
threads. */
+                                       ++(currentLockEntry->numWaitingThreads);
+
+                                       /* Unlock the lock pool. */
+                                       ILMutexUnlock(lockPool->lock);
+
+                                       /* Unlock the metadata. */
+                                       METADATA_UNLOCK(process);
+
+                                       /* And wait at the semaphore object. */
+                                       ILSemaphoreWait(currentLockEntry->sem);
+
+                                       /* Lock the metadata again. */
+                                       METADATA_WRLOCK(process);
+
+                                       /* Lock the lock pool again. */
+                                       ILMutexLock(lockPool->lock);
+
+                                       /* Decrease the number of waiting 
threads. */
+                                       --(currentLockEntry->numWaitingThreads);
+
+                                       if(currentLockEntry->numWaitingThreads 
== 0)
+                                       {
+                                               /* This is the last thread 
waiting for this method. */
+                                               void *userData = 
currentLockEntry->userData;
+
+                                               
_ILMethodLockEntry_Destroy(lockPool, currentLockEntry);
+
+                                               /* Unlock the lock pool. */
+                                               ILMutexUnlock(lockPool->lock);
+
+                                               return userData;
+                                       }
+                                       else
+                                       {
+                                               /* Unlock the lock pool. */
+                                               ILMutexUnlock(lockPool->lock);
+
+                                               return 
currentLockEntry->userData;
+                                       }
+                               }
+                       }
+                       /* Unlock the lock pool. */
+                       ILMutexUnlock(lockPool->lock);
+               }
+       }
+       return 0;
+}
+
 /*
  * Get the number of queued cctors.
  */
@@ -243,8 +545,18 @@
                {
                        return 0;
                }
+
+               if(!_ILMethodLockPool_Init(&(cctorMgr->lockPool)))
+               {
+                       ILMutexDestroy(cctorMgr->lock);
+                       return 0;
+               }
+
                cctorMgr->thread = (ILThread *)0;;
                cctorMgr->currentMethod = (ILMethod *)0;
+       #ifdef IL_USE_JIT
+               cctorMgr->currentJitFunction = 0;
+       #endif  /* IL_USE_JIT */
                cctorMgr->isStaticConstructor = 0;
                cctorMgr->isConstructor = 0;
 
@@ -255,6 +567,7 @@
                                          sizeof(ILClassEntry),
                                          numCCtorEntries);
 
+
                return 1;
        }
        return 0;
@@ -269,6 +582,8 @@
        {
                ILMemPoolDestroy(&(cctorMgr->classPool));
 
+               _ILMethodLockPool_Destroy(&(cctorMgr->lockPool));
+
                if(cctorMgr->lock)
                {
                        /* Destroy the lock mutex. */
@@ -278,6 +593,19 @@
 }
 
 /*
+ * Handle locked methods.
+ * Returns the userData of the locked method if the method is locked and
+ * 0 if the method isn't locked.
+ */
+void *ILCCtorMgr_HandleLockedMethod(ILCCtorMgr *cctorMgr,
+                                                                       
ILMethod *method)
+{
+       return ILMethodLockPool_HandleLockedMethod(&(cctorMgr->lockPool),
+                                                                               
           method,
+                                                                               
           cctorMgr);
+}
+
+/*
  * Set the current method to be compiled.
  * This checks if the class initializer of the class owning the method has
  * to be executed prior to executing the method.
@@ -287,6 +615,10 @@
 {
        if(cctorMgr)
        {
+       #ifdef IL_USE_JIT
+               cctorMgr->currentJitFunction = 0;
+       #endif  /* IL_USE_JIT */
+
                if(method)
                {
                        ILClass *methodOwner = ILMethod_Owner(method);
@@ -476,7 +808,7 @@
 /*
  * Run the queued cctors.
  */
-int ILCCtorMgr_RunCCtors(ILCCtorMgr *cctorMgr)
+int ILCCtorMgr_RunCCtors(ILCCtorMgr *cctorMgr, void *userData)
 {
        if(cctorMgr)
        {
@@ -485,14 +817,29 @@
                if(!(cctorMgr->lastClass))
                {
                        /* There are no cctors queued. */
-                       /* So unlock the metadata. */
-                       METADATA_UNLOCK(thread);
+
+                       /* So store the userdata where the coder expects it to 
be. */
+               #ifdef IL_USE_CVM
+                       cctorMgr->currentMethod->userData = userData;
+               #endif  /* IL_USE_CVM */
+               #ifdef IL_USE_JIT
+                       jit_function_setup_entry(cctorMgr->currentJitFunction, 
userData);
+               #endif  /* IL_USE_JIT */
+
+                       /* Unlock the metadata. */
+                       METADATA_UNLOCK(_ILExecThreadProcess(thread));
+
                        /* and return with success. */
                        return 1;
                }
                else
                {
                        int result;
+                       ILMethod *currentMethod = cctorMgr->currentMethod;
+               #ifdef IL_USE_JIT
+                       ILJitFunction currentJitFunction = 
cctorMgr->currentJitFunction;
+               #endif  /* IL_USE_JIT */
+       
                        ILInt32 numQueuedCCtors = 
_ILCCtorMgr_GetNumQueuedCCtors(cctorMgr);
                        ILClass *classes[numQueuedCCtors];
                        ILClassEntry *classEntry = cctorMgr->lastClass;
@@ -509,8 +856,20 @@
                        cctorMgr->lastClass = (ILClassEntry *)0;
                        ILMemPoolClear(&(cctorMgr->classPool));
 
+                       /* Lock the method. */
+                       if(!_ILMethodLockPool_LockMethod(&(cctorMgr->lockPool),
+                                                                               
         currentMethod,
+                                                                               
         userData))
+                       {
+                               /* Unlock the metadata. */
+                               METADATA_UNLOCK(_ILExecThreadProcess(thread));
+
+                               /* and return with failure. */
+                               return 0;
+                       }
+
                        /* Now unlock the metadata. */
-                       METADATA_UNLOCK(thread);
+                       METADATA_UNLOCK(_ILExecThreadProcess(thread));
 
                        if(cctorMgr->thread == thread->supportThread)
                        {
@@ -538,6 +897,26 @@
                                /* and unlock the cctor manager. */
                                ILMutexUnlock(cctorMgr->lock);
                        }
+
+                       /* Lock the metadata again. */
+                       IL_METADATA_WRLOCK(_ILExecThreadProcess(thread));
+
+                       /* Store the userdata where the coder expects it to be. 
*/
+               #ifdef IL_USE_CVM
+                       currentMethod->userData = userData;
+               #endif  /* IL_USE_CVM */
+               #ifdef IL_USE_JIT
+                       jit_function_setup_entry(currentJitFunction, userData);
+               #endif  /* IL_USE_JIT */
+
+                       /* Unlock the method. */
+                       _ILMethodLockPool_UnlockMethod(&(cctorMgr->lockPool),
+                                                                               
   currentMethod);
+
+
+                       /* Unlock the metadata. */
+                       IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));
+
                        if(!result)
                        {
                                
_ILCCtorMgr_ThrowTypeInitializationException(thread);

Index: engine/cctormgr.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cctormgr.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- engine/cctormgr.h   21 Jan 2007 17:53:29 -0000      1.2
+++ engine/cctormgr.h   11 Feb 2007 14:34:32 -0000      1.3
@@ -22,13 +22,16 @@
 #define        _ENGINE_CCTORMGR_H
 
 #include "engine_private.h"
-
+#ifdef IL_USE_JIT
+#include "jitc.h"
+#endif /* IL_USE_JIT */
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /* Forward declarations. */
+typedef struct _tagILMethodLockEntry   ILMethodLockEntry;
 typedef struct _tagILClassEntry        ILClassEntry;
 typedef struct _tagILCCtorMgr  ILCCtorMgr;
 
@@ -38,6 +41,46 @@
        ILClassEntry   *prevClass;      /* The previous class entry. */
 };
 
+/*
+ * Entry for one locked method.
+ */
+struct _tagILMethodLockEntry
+{
+       /* The next lock entryin the lock pool. */
+       ILMethodLockEntry  *nextEntry;;
+
+       /* The locked method. */
+       ILMethod                   *method;
+
+       /* The thread that created the method lock entry. */
+       ILThread                   *thread;
+
+       /* The semaphore where the other threads are waiting. */
+       ILSemaphore                *sem;
+
+       /* The number of waiting threads. */
+       ILInt32                         numWaitingThreads;
+
+       /* Slot for private use data. */
+       void                       *userData;
+};
+
+/*
+ * The memory pool to hold the locked methods.
+ */
+typedef struct
+{
+       /* Mutex to synchronize the access to the lock pool. */
+       ILMutex                    *lock;
+
+       /* Memory pool to hold the locked methods. */
+       ILMemPool                       methodPool;
+
+
+       /* The first currently locked method in the lock pool. */
+       ILMethodLockEntry  *lastLockedMethod;
+}  ILMethodLockPool;
+
 struct _tagILCCtorMgr
 {
        /* Mutex to synchronize the cctor execution. */
@@ -48,6 +91,12 @@
 
        /* The currently compiled method. */
        ILMethod           *currentMethod;
+
+#ifdef IL_USE_JIT
+       /* The currentty compiled jit function. */
+       ILJitFunction           currentJitFunction;
+#endif /* IL_USE_JIT */
+
        /* Flag if the current method is a cctor. */
        int                             isStaticConstructor : 1;
        /* Flag if the current method is a ctor. */
@@ -58,6 +107,8 @@
        /* The last classentry  in the memory pool. */
        ILClassEntry   *lastClass;
 
+       /* The memory pool to hold the currently locked methods. */
+       ILMethodLockPool        lockPool;
 };
 
 int ILCCtorMgr_Init(ILCCtorMgr *cctorMgr,
@@ -66,6 +117,13 @@
 void ILCCtorMgr_Destroy(ILCCtorMgr *cctorMgr);
 
 /*
+ * Handle locked methods.
+ * Returns the userData of the locked method if the method is locked and
+ * 0 if the method isn't locked.
+ */
+void *ILCCtorMgr_HandleLockedMethod(ILCCtorMgr *cctorMgr,
+                                                                       
ILMethod *method);
+/*
  * Set the current method to be compiled.
  * This checks if the class initializer of the class owning the method has
  * to be executed prior to executing the method.
@@ -113,9 +171,11 @@
 
 /*
  * Run the queued cctors.
+ * The userData is stored in the locked function and is returned
+ * by the call to ILCCtorMgr_HandleLockedMethod.
  * Returns != 0 on success or 0 if an exception was thrown.
  */
-int ILCCtorMgr_RunCCtors(ILCCtorMgr *cctorMgr);
+int ILCCtorMgr_RunCCtors(ILCCtorMgr *cctorMgr, void *userData);
 
 #ifdef __cplusplus
 };

Index: engine/convert.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/convert.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- engine/convert.c    16 Jan 2007 06:46:08 -0000      1.28
+++ engine/convert.c    11 Feb 2007 14:34:32 -0000      1.29
@@ -87,18 +87,13 @@
           method is written in IL or not */
        if(code.code)
        {
-               /* We need the metadata write lock */
-               METADATA_WRLOCK(thread);
                /* Use the bytecode verifier and coder to convert the method */
                if(!_ILVerify(coder, &start, method, &code,
                                          
ILImageIsSecure(ILProgramItem_Image(method)), thread))
                {
-                       METADATA_UNLOCK(thread);
                        *errorCode = IL_CONVERT_VERIFY_FAILED;
                        return 0;
                }
-               /* Run the needed cctors and unlock the metadata too */
-               ILCoderRunCCtors(coder);
        }
        else
        {
@@ -191,6 +186,14 @@
        /* We need the metadata write lock */
        METADATA_WRLOCK(thread);
 
+       /* Handle locked methods while cctors are executed. */
+       if((start = (unsigned char *)ILCoderHandleLockedMethod(coder, method)))
+       {
+               METADATA_UNLOCK(thread);
+               *errorCode = IL_CONVERT_OK;
+               return start;
+       }
+
        /* Is the method already converted? */
        if((start = (unsigned char *)(method->userData)) != 0)
        {
@@ -504,12 +507,8 @@
        }
 
        /* The method is converted now */
-       /* store the method pointer in a safe way so we can use a shortcut 
macro */
-       ILThreadAtomicStart();
-       method->userData = (void *)start;
-       ILThreadAtomicEnd();
        /* Run the needed cctors and unlock the metadata too */
-       ILCoderRunCCtors(coder);
+       ILCoderRunCCtors(coder, start);
        *errorCode = IL_CONVERT_OK;
        return start;
 }

Index: engine/cvmc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- engine/cvmc.c       23 Jan 2007 19:49:01 -0000      1.52
+++ engine/cvmc.c       11 Feb 2007 14:34:32 -0000      1.53
@@ -288,10 +288,10 @@
 /*
  * Run the class initializers queued during generation of the last method.
  */
-static ILInt32 CVMCoder_RunCCtors(ILCoder *_coder)
+static ILInt32 CVMCoder_RunCCtors(ILCoder *_coder, void *userData)
 {
        ILCVMCoder *coder = (ILCVMCoder *)_coder;
-       return ILCCtorMgr_RunCCtors(&(coder->cctorMgr));
+       return ILCCtorMgr_RunCCtors(&(coder->cctorMgr), userData);
 }
 
 /*
@@ -304,6 +304,15 @@
 }
 
 /*
+ * Handle the method lock while running class initializers.
+ */
+static void *CVMCoder_HandleLockedMethod(ILCoder *_coder, ILMethod *method)
+{
+       ILCVMCoder *coder = (ILCVMCoder *)_coder;
+       return ILCCtorMgr_HandleLockedMethod(&(coder->cctorMgr), method);
+}
+
+/*
  * Get a block of method cache memory for use in code unrolling.
  */
 int _ILCVMStartUnrollBlock(ILCoder *_coder, int align, ILCachePosn *posn)
@@ -513,6 +522,7 @@
        CVMCoder_ConvertCustom,
        CVMCoder_RunCCtors,
        CVMCoder_RunCCtor,
+       CVMCoder_HandleLockedMethod,
        "sentinel"
 };
 

Index: engine/cvmc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc_call.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -b -r1.36 -r1.37
--- engine/cvmc_call.c  21 Jan 2007 17:53:29 -0000      1.36
+++ engine/cvmc_call.c  11 Feb 2007 14:34:32 -0000      1.37
@@ -497,11 +497,6 @@
 
 static void CVMCoder_LoadFuncAddr(ILCoder *coder, ILMethod *methodInfo)
 {
-       /* Queue the cctor to run. */
-       /* TODO: leave this one because the methodpointer might be used to 
start */
-       /* a new thread. This makes sure that the class of the thread start */
-       /* function is initialized. */
-       ILCCtorMgr_OnCallMethod(&(((ILCVMCoder *)coder)->cctorMgr), methodInfo);
        CVMP_OUT_PTR(COP_PREFIX_LDFTN, methodInfo);
        CVM_ADJUST(1);
 }

Index: engine/jitc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -b -r1.67 -r1.68
--- engine/jitc.c       23 Jan 2007 19:49:02 -0000      1.67
+++ engine/jitc.c       11 Feb 2007 14:34:32 -0000      1.68
@@ -74,11 +74,6 @@
 /* #define _IL_JIT_ENABLE_INLINE 1 */
 
 /*
- * To enable the cctor manager uncomment define the following define.
- */
-#define IL_JIT_ENABLE_CCTORMGR
-
-/*
  * Acquire and release the metadata lock, while suppressing finalizers
  * Must be kept in sync with convert.c
  */
@@ -334,6 +329,11 @@
 #endif
 
 /*
+ * Handle locked methods in the jit coder.
+ */
+static void *JITCoder_HandleLockedMethod(ILCoder *coder, ILMethod *method);
+
+/*
  * Forward declaration of the JIT coder's instance block.
  */
 typedef struct _tagILJITCoder ILJITCoder;
@@ -415,9 +415,6 @@
        ILExecProcess  *process;
        jit_context_t   context;
 
-#ifndef IL_JIT_ENABLE_CCTORMGR
-       ILMethod           *currentMethod;
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
        int                             debugEnabled;
        int                             flags;
 
@@ -1966,64 +1963,6 @@
        return((ILUInt32)jit_type_get_size(classPrivate->jitTypes.jitTypeBase));
 }
 
-#ifndef IL_JIT_ENABLE_CCTORMGR
-/*
- * 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 */
-                       #ifdef IL_JIT_THREAD_IN_SIGNATURE
-                               jit_value_t thread = 
_ILJitCoderGetThread(coder);
-
-                               jit_insn_call(coder->jitFunction, "cctor",
-                                                               
ILJitFunctionFromILMethod(cctor), 0,
-                                                               &thread, 1, 0);
-                       #else
-                               jit_insn_call(coder->jitFunction, "cctor",
-                                                               
ILJitFunctionFromILMethod(cctor), 0,
-                                                               0, 0, 0);
-                       #endif
-                       }
-               }
-               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;
-               }
-       }
-}
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
-
 /*
  * The exception handler which converts libjit inbuilt exceptions
  * into clr exceptions.
@@ -2123,6 +2062,123 @@
 }
 
 /*
+ * The on demand driver function for libjit.
+ */
+static void *_ILJitOnDemandDriver(ILJitFunction func)
+{
+#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
+       char *methodName = _ILJitFunctionGetMethodName(func);
+#endif
+       ILMethod *method = (ILMethod *)jit_function_get_meta(func, 
IL_JIT_META_METHOD);
+       ILClass *info = ILMethod_Owner(method);
+       ILClassPrivate *classPrivate = (ILClassPrivate *)info->userData;
+       ILExecProcess *process = classPrivate->process;
+       ILJITCoder *jitCoder = (ILJITCoder *)process->coder;
+       void *entry_point;
+       jit_on_demand_func onDemandCompiler;
+       int result = JIT_RESULT_OK;
+       jit_context_t context = jit_function_get_context(func);
+
+       if(!context)
+       {
+               result = JIT_RESULT_COMPILE_ERROR;
+               jit_exception_builtin(result);
+       }
+
+       /* Lock the metadata. */
+       METADATA_WRLOCK(process);
+
+       /* Handle a locked method. */
+       if((entry_point = JITCoder_HandleLockedMethod(process->coder, method)))
+       {
+               /* Unlock the metadata. */
+               METADATA_UNLOCK(process);
+
+               return entry_point;
+       }
+
+       /* Set the function info in the jit coder. */
+       jitCoder->jitFunction = func;
+       ILCCtorMgr_SetCurrentMethod(&(jitCoder->cctorMgr), method);
+       jitCoder->cctorMgr.currentJitFunction = func;
+
+       /* Lock down the context. */
+       jit_context_build_start(context);
+
+       if(!(onDemandCompiler = jit_function_get_on_demand_compiler(func)))
+       {
+               result = JIT_RESULT_COMPILE_ERROR;
+
+               /* Unlock the context. */
+               jit_context_build_end(context);
+
+               /* Unlock the metadata. */
+               METADATA_UNLOCK(process);
+
+               /* And throw an exception. */
+               jit_exception_builtin(result);
+       }
+
+       if((result = (*onDemandCompiler)(func)) == JIT_RESULT_OK)
+       {
+       #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
+       #ifdef _IL_JIT_DUMP_FUNCTION
+               if(jitCoder->flags & IL_CODER_FLAG_STATS)
+               {
+                       ILMutexLock(globalTraceMutex);
+                       jit_dump_function(stdout, func, methodName);
+                       ILMutexUnlock(globalTraceMutex);
+               }
+       #endif  /* _IL_JIT_DUMP_FUNCTION */
+       #endif
+
+               /* Now compile the function to it's native form. */
+               if(!jit_function_compile_entry(func, &entry_point))
+               {
+                       /* How are errors handled ? */
+
+                       /* Unlock the context. */
+                       jit_context_build_end(context);
+
+                       /* Unlock the metadata. */
+                       METADATA_UNLOCK(process);
+
+                       /* And throw an exception. */
+                       jit_exception_builtin(JIT_RESULT_OUT_OF_MEMORY);
+               }
+
+               /* Unlock the context. */
+               jit_context_build_end(context);
+
+               /* and run the queued class initializers. */
+               ILCCtorMgr_RunCCtors(&(jitCoder->cctorMgr), entry_point);
+
+       #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
+       #ifdef _IL_JIT_DISASSEMBLE_FUNCTION
+               if(jitCoder->flags & IL_CODER_FLAG_STATS)
+               {
+                       ILMutexLock(globalTraceMutex);
+                       jit_dump_function(stdout, func, methodName);
+                       ILMutexUnlock(globalTraceMutex);
+               }
+       #endif  /* _IL_JIT_DISASSEMBLE_FUNCTION */
+       #endif
+       }
+       else
+       {
+               /* Unlock the context. */
+               jit_context_build_end(context);
+
+               /* Unlock the metadata. */
+               METADATA_UNLOCK(process);
+
+               /* And throw an exception. */
+               jit_exception_builtin(result);
+       }
+       return entry_point;
+}
+
+/*
  * Initialize the libjit coder.
  * Returns 1 on success and 0 on failure.
  */
@@ -2447,6 +2503,7 @@
 
        return 1;
 }
+
 /*
  * Create a new JIT coder instance.
  */
@@ -2481,6 +2538,10 @@
                return 0;
        }
 
+       /* Set the on demand compilation driver for this context. */
+       jit_context_set_on_demand_driver(coder->context,
+                                                                        
_ILJitOnDemandDriver);
+
 #ifndef IL_JIT_THREAD_IN_SIGNATURE
        coder->thread = 0;
 #endif
@@ -2744,11 +2805,7 @@
        {
                /* Mark breakpoint that reports current ILMethod and IL offset 
*/
                jit_insn_mark_breakpoint(jitCoder->jitFunction,
-       #ifdef IL_JIT_ENABLE_CCTORMGR
                                                                 (jit_nint) 
ILCCtorMgr_GetCurrentMethod(&(jitCoder->cctorMgr)),
-       #else   /* !IL_JIT_ENABLE_CCTORMGR */
-                                                                (jit_nint) 
jitCoder->currentMethod,
-       #endif  /* !IL_JIT_ENABLE_CCTORMGR */
                                                                 (jit_nint) 
offset);
        }
 #endif
@@ -2757,18 +2814,11 @@
 /*
  * Run the class initializers queued during generation of the last method.
  */
-static ILInt32 JITCoder_RunCCtors(ILCoder *coder)
+static ILInt32 JITCoder_RunCCtors(ILCoder *coder, void *userData)
 {
-#ifdef IL_JIT_ENABLE_CCTORMGR
        ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
 
-       return ILCCtorMgr_RunCCtors(&(jitCoder->cctorMgr));
-#else  /* !IL_JIT_ENABLE_CCTORMGR */
-       ILExecThread *thread = ILExecThreadCurrent();
-
-       METADATA_UNLOCK(_ILExecThreadProcess(thread));
-       return 1;
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
+       return ILCCtorMgr_RunCCtors(&(jitCoder->cctorMgr), userData);;
 }
 
 /*
@@ -2781,6 +2831,16 @@
        return ILCCtorMgr_RunCCtor(&(jitCoder->cctorMgr), classInfo);
 }
 
+/*
+ * Handle the method lock while running class initializers.
+ */
+static void *JITCoder_HandleLockedMethod(ILCoder *coder, ILMethod *method)
+{
+       ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
+
+       return ILCCtorMgr_HandleLockedMethod(&(jitCoder->cctorMgr), method);
+}
+
 #ifdef IL_CONFIG_PINVOKE
 
 /*
@@ -3085,7 +3145,7 @@
 static int _ILJitCompileInternal(ILJitFunction func)
 {
        ILMethod *method = (ILMethod *)jit_function_get_meta(func, 
IL_JIT_META_METHOD);
-#if (!defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)) || defined(IL_JIT_ENABLE_CCTORMGR)
+#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
        ILClassPrivate *classPrivate = (ILClassPrivate 
*)(ILMethod_Owner(method)->userData);
        ILJITCoder *jitCoder = (ILJITCoder *)(classPrivate->process->coder);
 #endif
@@ -3113,12 +3173,6 @@
        }
 #endif
 
-#ifdef IL_JIT_ENABLE_CCTORMGR
-       METADATA_WRLOCK(jitCoder->process);
-       jitCoder->jitFunction = func;
-       ILCCtorMgr_SetCurrentMethod(&(jitCoder->cctorMgr), method);
-#endif /* IL_JIT_ENABLE_CCTORMGR */
-
 #ifdef IL_JIT_THREAD_IN_SIGNATURE
        for(current = 1; current < numParams; ++current)
        {
@@ -3146,28 +3200,6 @@
 #endif
        jit_insn_return(func, returnValue);     
 
-#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
-#ifdef _IL_JIT_DUMP_FUNCTION
-       if(jitCoder->flags & IL_CODER_FLAG_STATS)
-       {
-               ILMutexLock(globalTraceMutex);
-               jit_dump_function(stdout, func, methodName);
-               ILMutexUnlock(globalTraceMutex);
-       }
-#endif
-#ifdef _IL_JIT_DISASSEMBLE_FUNCTION
-       if(jitCoder->flags & IL_CODER_FLAG_STATS)
-       {
-               if(!jit_function_compile(func))
-               {
-                       return IL_CODER_END_TOO_BIG;
-               }
-               ILMutexLock(globalTraceMutex);
-               jit_dump_function(stdout, func, methodName);
-               ILMutexUnlock(globalTraceMutex);
-       }
-#endif
-#endif
        return JIT_RESULT_OK;
 }
 
@@ -4567,6 +4599,7 @@
        JITCoder_ConvertCustom,
        JITCoder_RunCCtors,
        JITCoder_RunCCtor,
+       JITCoder_HandleLockedMethod,
        "sentinel"
 };
 #ifdef __cplusplus

Index: engine/jitc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_call.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -b -r1.37 -r1.38
--- engine/jitc_call.c  23 Jan 2007 19:49:02 -0000      1.37
+++ engine/jitc_call.c  11 Feb 2007 14:34:32 -0000      1.38
@@ -480,10 +480,6 @@
                ILMutexUnlock(globalTraceMutex);
        }
 #endif
-#ifndef IL_JIT_ENABLE_CCTORMGR
-       /* Output a call to the static constructor */
-       _ILJitCallStaticConstructor(jitCoder, ILMethod_Owner(methodInfo), 0);
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
 
 #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
        methodName = _ILJitFunctionGetMethodName(jitFunction);
@@ -516,6 +512,8 @@
        #endif
 
                /* Call the engine function directly with the supplied args. */
+               /* Queue the cctor to run. */
+               ILCCtorMgr_OnCallMethod(&(jitCoder->cctorMgr), methodInfo);
        #ifdef IL_JIT_THREAD_IN_SIGNATURE
                destroyCallSignature = _ILJitFillArguments(jitCoder,
                                                                                
                   methodInfo,
@@ -824,16 +822,14 @@
        type = ILType_FromClass(classInfo);
        synType = ILClassGetSynType(classInfo);
 
-#ifndef IL_JIT_ENABLE_CCTORMGR
-       /* Output a call to the static constructor */
-       _ILJitCallStaticConstructor(jitCoder, ILMethod_Owner(methodInfo), 1);
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
-
        /* Check if the function is implemented in the engine. */
        if((internalType = _ILJitFunctionIsInternal(jitCoder, methodInfo, 
&fnInfo, 1)))
        {
                ILJitValue thread = _ILJitCoderGetThread(jitCoder);
 
+               /* Queue the cctor to run. */
+               ILCCtorMgr_OnCallMethod(&(jitCoder->cctorMgr), methodInfo);
+       
                /* Call the engine function directly with the supplied args. */
                if(internalType == _IL_JIT_IMPL_INTERNALALLOC)
                {
@@ -1704,11 +1700,7 @@
        {
                jit_insn_mark_breakpoint(jitCoder->jitFunction,
                                                                 
JIT_DEBUGGER_DATA1_METHOD_LEAVE,
-       #ifdef IL_JIT_ENABLE_CCTORMGR
                                                                 (jit_nint) 
ILCCtorMgr_GetCurrentMethod(&(jitCoder->cctorMgr)));
-       #else   /* !IL_JIT_ENABLE_CCTORMGR */
-                                                                (jit_nint) 
jitCoder->currentMethod);
-       #endif  /* !IL_JIT_ENABLE_CCTORMGR */
        }
 #endif
 
@@ -1790,13 +1782,6 @@
                }
                jitFunction = ILJitFunctionFromILMethod(methodInfo);
        }
-#ifdef IL_JIT_ENABLE_CCTORMGR
-       /* Queue the cctor to run. */
-       ILCCtorMgr_OnCallMethod(&(jitCoder->cctorMgr), methodInfo);
-#else  /* !IL_JIT_ENABLE_CCTORMGR */
-       /* Output a call to the static constructor */
-       _ILJitCallStaticConstructor(jitCoder, ILMethod_Owner(methodInfo), 1);
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
 #ifndef IL_JIT_FNPTR_ILMETHOD
        /* Get the vtable pointer for the function. */
        function = jit_function_to_vtable_pointer(jitFunction);

Index: engine/jitc_except.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_except.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- engine/jitc_except.c        21 Jan 2007 17:53:29 -0000      1.15
+++ engine/jitc_except.c        11 Feb 2007 14:34:32 -0000      1.16
@@ -530,11 +530,7 @@
                                                                                
                                (jit_nint)classInfo);
        ILJitValue method = 
jit_value_create_nint_constant(jitCoder->jitFunction,
                                                                                
                           _IL_JIT_TYPE_VPTR,
-#ifdef IL_JIT_ENABLE_CCTORMGR
                                                                                
                           
(jit_nint)ILCCtorMgr_GetCurrentMethod(&(jitCoder->cctorMgr)));
-#else  /* !IL_JIT_ENABLE_CCTORMGR */
-                                                                               
                           (jit_nint)jitCoder->currentMethod);
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
        ILJitValue nullException = 
jit_value_create_nint_constant(jitCoder->jitFunction,
                                                                                
                                          _IL_JIT_TYPE_VPTR,
                                                                                
                                      (jit_nint)0);

Index: engine/jitc_inline.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_inline.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- engine/jitc_inline.c        21 Jan 2007 18:02:10 -0000      1.3
+++ engine/jitc_inline.c        11 Feb 2007 14:34:32 -0000      1.4
@@ -240,11 +240,7 @@
 
                /* Now check if the method is allready somewhere in the 
currently */
                /* inlined methods to avoid an endless recursion. */
-       #ifdef IL_JIT_ENABLE_CCTORMGR
                if(method == ILCCtorMgr_GetCurrentMethod(&(jitCoder->cctorMgr)))
-       #else   /* !IL_JIT_ENABLE_CCTORMGR */
-               if(method == jitCoder->currentMethod)
-       #endif  /* !IL_JIT_ENABLE_CCTORMGR */
        {
                        return 0;
                }
@@ -349,7 +345,6 @@
                        return 0;
                }
 
-       #ifdef IL_JIT_ENABLE_CCTORMGR
                /* Queue the cctor to run. */
                if(!ILCCtorMgr_OnCallMethod(&(jitCoder->cctorMgr), method))
                {
@@ -357,7 +352,6 @@
                        _ILJitCoderInlineContextPop(jitCoder);
                        return 0;
                }
-       #endif  /* IL_JIT_ENABLE_CCTORMGR */
 
                ILMemPoolClear(&(inlineContext->labelPool));
                inlineContext->labelList = 0;

Index: engine/jitc_obj.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_obj.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- engine/jitc_obj.c   21 Jan 2007 17:53:29 -0000      1.27
+++ engine/jitc_obj.c   11 Feb 2007 14:34:32 -0000      1.28
@@ -301,11 +301,7 @@
        {
                args[0] = jit_value_create_nint_constant(jitCoder->jitFunction,
                                                                                
                 _IL_JIT_TYPE_VPTR,
-#ifdef IL_JIT_ENABLE_CCTORMGR
                                                                                
                 (jit_nint)ILCCtorMgr_GetCurrentMethod(&(jitCoder->cctorMgr)));
-#else  /* !IL_JIT_ENABLE_CCTORMGR */
-                                                                               
                 (jit_nint)jitCoder->currentMethod);
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
                args[1] = _ILJitStackItemValue(object);
                args[2] = classTo;
                returnValue = jit_insn_call_native(jitCoder->jitFunction,
@@ -436,13 +432,8 @@
 #endif
        if((field->member.attributes & IL_META_FIELDDEF_HAS_FIELD_RVA) == 0)
        {
-       #ifdef IL_JIT_ENABLE_CCTORMGR
                /* Queue the cctor to run. */
                ILCCtorMgr_OnStaticFieldAccess(&(jitCoder->cctorMgr), field);   
-       #else   /* !IL_JIT_ENABLE_CCTORMGR */
-               /* Output a call to the static constructor */
-               _ILJitCallStaticConstructor(jitCoder, ILField_Owner(field), 1);
-       #endif  /* !IL_JIT_ENABLE_CCTORMGR */
 
                /* Regular or thread-static field? */
                if(!ILFieldIsThreadStatic(field))
@@ -577,13 +568,8 @@
        }
 #endif
 
-#ifdef IL_JIT_ENABLE_CCTORMGR
        /* Queue the cctor to run. */
        ILCCtorMgr_OnStaticFieldAccess(&(jitCoder->cctorMgr), field);   
-#else  /* !IL_JIT_ENABLE_CCTORMGR */
-       /* Output a call to the static constructor */
-       _ILJitCallStaticConstructor(jitCoder, ILField_Owner(field), 1);
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
 
        /* Regular or RVA field? */
        if((field->member.attributes & IL_META_FIELDDEF_HAS_FIELD_RVA) == 0)
@@ -707,13 +693,8 @@
        /* Pop the value off the stack. */
        _ILJitStackPop(jitCoder, stackItem);
 
-#ifdef IL_JIT_ENABLE_CCTORMGR
        /* Queue the cctor to run. */
        ILCCtorMgr_OnStaticFieldAccess(&(jitCoder->cctorMgr), field);   
-#else  /* !IL_JIT_ENABLE_CCTORMGR */
-       /* Output a call to the static constructor */
-       _ILJitCallStaticConstructor(jitCoder, ILField_Owner(field), 1);
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
 
 #ifdef IL_CONFIG_PINVOKE
        if((field->member.attributes & IL_META_FIELDDEF_PINVOKE_IMPL) != 0 &&

Index: engine/jitc_setup.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_setup.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- engine/jitc_setup.c 23 Jan 2007 19:49:02 -0000      1.25
+++ engine/jitc_setup.c 11 Feb 2007 14:34:32 -0000      1.26
@@ -42,15 +42,6 @@
        }
 #endif /* _IL_JIT_ENABLE_INLINE */
 
-       /* Record the current jitted function. */
-       coder->jitFunction = ILJitFunctionFromILMethod(method);
-       /* Record the current method. */
-#ifdef IL_JIT_ENABLE_CCTORMGR
-       ILCCtorMgr_SetCurrentMethod(&(coder->cctorMgr), method);
-#else  /* !IL_JIT_ENABLE_CCTORMGR */
-       coder->currentMethod = method;
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
-
 #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
        if (coder->flags & IL_CODER_FLAG_STATS)
        {
@@ -71,47 +62,6 @@
        }
 #endif
 
-#ifndef IL_JIT_ENABLE_CCTORMGR
-       if(ILMethod_IsStaticConstructor(method))
-       {
-               /* We have to take care that the method is executed only once. 
*/
-               ILClass *info;
-               ILJitValue classInfo;
-               ILJitValue cctorOnce;
-               ILJitValue attributes;
-               ILJitValue temp;
-               jit_label_t startLabel = jit_label_undefined;
-               jit_label_t endLabel = jit_label_undefined;
-               jit_label_t label1 = jit_label_undefined;
-
-               jit_insn_label(coder->jitFunction, &startLabel);
-
-               info = ILMethod_Owner(method);
-               classInfo = jit_value_create_nint_constant(coder->jitFunction,
-                                                                               
   _IL_JIT_TYPE_VPTR,
-                                                                               
   (jit_nint)info);
-               cctorOnce = jit_value_create_nint_constant(coder->jitFunction,
-                                                                               
   _IL_JIT_TYPE_UINT32,
-                                                                               
   (jit_nint)IL_META_TYPEDEF_CCTOR_ONCE);
-               attributes = jit_insn_load_relative(coder->jitFunction,
-                                                                               
                           classInfo,
-                                                                               
                           offsetof(ILClass, attributes),
-                                                                               
                           _IL_JIT_TYPE_UINT32);
-               temp = jit_insn_and(coder->jitFunction, attributes, cctorOnce);
-               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);
-
-               jit_insn_label(coder->jitFunction, &endLabel);
-               /* Make sure that this check will remain very first even if any
-                  other blocks are later moved to the function start. */
-               jit_insn_move_blocks_to_start(coder->jitFunction, startLabel, 
endLabel);
-       }
-#endif /* !IL_JIT_ENABLE_CCTORMGR */
-
 #ifdef IL_CONFIG_DEBUGGER
        /* Check if this method can be debugged */
        debugger = ILDebuggerFromProcess(coder->process);
@@ -204,9 +154,6 @@
 static int JITCoder_Finish(ILCoder *_coder)
 {
        ILJITCoder *jitCoder = ((ILJITCoder *)_coder);
-#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
-       char *methodName = _ILJitFunctionGetMethodName(jitCoder->jitFunction);
-#endif
 
 #ifdef _IL_JIT_ENABLE_INLINE
        if(jitCoder->currentInlineContext)
@@ -230,36 +177,6 @@
        }
        jitCoder->labelOutOfMemory = 0;
 
-#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
-#ifdef _IL_JIT_DUMP_FUNCTION
-       if(jitCoder->flags & IL_CODER_FLAG_STATS)
-       {
-               ILMutexLock(globalTraceMutex);
-               jit_dump_function(stdout, jitCoder->jitFunction, methodName);
-               ILMutexUnlock(globalTraceMutex);
-       }
-#endif /* _IL_JIT_DUMP_FUNCTION */
-#endif
-       if(!jit_function_compile(jitCoder->jitFunction))
-       {
-               return IL_CODER_END_TOO_BIG;
-       }
-#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) && 
defined(_IL_JIT_ENABLE_DEBUG)
-#ifdef _IL_JIT_DISASSEMBLE_FUNCTION
-       if(jitCoder->flags & IL_CODER_FLAG_STATS)
-       {
-               ILMutexLock(globalTraceMutex);
-               jit_dump_function(stdout, jitCoder->jitFunction, methodName);
-               ILMutexUnlock(globalTraceMutex);
-       }
-#endif /* _IL_JIT_DISASSEMBLE_FUNCTION */
-#endif
-#ifdef IL_JIT_ENABLE_CCTORMGR
-       /* Unlock the context because we possibly have to build cctors before */
-       /* this method will be executed. (It's a hack for now.) */
-       jit_context_build_end(jitCoder->context);
-#endif /* IL_JIT_ENABLE_CCTORMGR */
-
        return IL_CODER_END_OK;
 }
 

Index: engine/null_coder.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/null_coder.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -b -r1.28 -r1.29
--- engine/null_coder.c 16 Jan 2007 06:46:08 -0000      1.28
+++ engine/null_coder.c 11 Feb 2007 14:34:32 -0000      1.29
@@ -418,7 +418,7 @@
                                                        void *customName, void 
*customCookie)
 {
 }
-static ILInt32 Coder_RunCCtors(ILCoder *coder)
+static ILInt32 Coder_RunCCtors(ILCoder *coder, void *userData)
 {
        return 1;
 }
@@ -426,6 +426,10 @@
 {
        return 1;
 }
+static void *Coder_HandleLockedMethod(ILCoder *coder, ILMethod *method)
+{
+       return 0;
+}
 
 /*
  * Null coder class and instance.
@@ -538,6 +542,7 @@
        Coder_ConvertCustom,
        Coder_RunCCtors,
        Coder_RunCCtor,
+       Coder_HandleLockedMethod,
        "sentinel"
 };
 ILCoder _ILNullCoder = {&_ILNullCoderClass};

Index: include/il_coder.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/include/il_coder.h,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -b -r1.53 -r1.54
--- include/il_coder.h  16 Jan 2007 06:46:08 -0000      1.53
+++ include/il_coder.h  11 Feb 2007 14:34:32 -0000      1.54
@@ -817,7 +817,7 @@
         * The metadata lock must be still accuired and will be released just
         * before the cctors are executed.
      */
-       ILInt32 (*runCCtors)(ILCoder *coder);
+       ILInt32 (*runCCtors)(ILCoder *coder, void *userData);
 
        /*
         * Run the class initializer for the given class.
@@ -825,6 +825,18 @@
        ILInt32 (*runCCtor)(ILCoder *coder, ILClass *classInfo);
 
        /*
+        * Handle a locked method.
+        * If the current thread holds the method lock the userData supplied 
when
+        * the method was locked is returned.
+        * If the current thread is currently executing class initializers the
+        * cctors of the method are executed and after they are finished the
+        * the userData supplied when the method was locked is returned.
+        * In the other case the thread is blocked until the method is unlocked
+        * and then the userData supplied when the method was locked is 
returned.
+        */
+       void *(*handleLockedMethod)(ILCoder *coder, ILMethod *method);
+
+       /*
         * Sentinel string to catch missing methods in class tables.
         */
        const char *sentinel;
@@ -1103,10 +1115,12 @@
                                                                                
                        (customCookie)))
 #define        ILCoderMarkEnd(coder) \
                        ((*((coder)->classInfo->markEnd))((coder)))
-#define        ILCoderRunCCtors(coder) \
-                       ((*((coder)->classInfo->runCCtors))((coder)))
-#define        ILCoderRunCCtor(coder, classInfo) \
-                       ((*((coder)->classInfo->runCCtor))((coder),(classInfo)))
+#define        ILCoderRunCCtors(coder,userData) \
+                       ((*((coder)->classInfo->runCCtors))((coder), 
(userData)))
+#define        ILCoderRunCCtor(coder,classInfo) \
+                       ((*((coder)->classInfo->runCCtor))((coder), 
(classInfo)))
+#define ILCoderHandleLockedMethod(coder,method) \
+                       (*((coder)->classInfo->handleLockedMethod))((coder), 
(method))
 
 #ifdef __cplusplus
 };

Index: include/il_thread.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/include/il_thread.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- include/il_thread.h 10 Oct 2005 20:03:15 -0000      1.27
+++ include/il_thread.h 11 Feb 2007 14:34:32 -0000      1.28
@@ -48,6 +48,7 @@
 typedef struct _tagILThread     ILThread;
 typedef struct _tagILMutex      ILMutex;
 typedef struct _tagILRWLock     ILRWLock;
+typedef struct _tagILSemaphore  ILSemaphore;
 typedef struct _tagILWaitHandle ILWaitHandle;
 
 /*
@@ -399,6 +400,34 @@
 void ILRWLockUnlock(ILRWLock *rwlock);
 
 /*
+ * Create a semaphore. Note: this type of semaphore will not
+ * necessarily update the thread's "wait/sleep/join"
+ * state, so it isn't directly suitable for emulating
+ * Windows-like wait handle semaphores.
+ */
+ILSemaphore *ILSemaphoreCreate(void);
+
+/*
+ * Destroy a semaphore.
+ */
+void ILSemaphoreDestroy(ILSemaphore *sem);
+
+/*
+ * Wait on a semaphore.
+ */
+void ILSemaphoreWait(ILSemaphore *sem);
+
+/*
+ * Increase the semaphore count by 1.
+ */
+void ILSemaphorePost(ILSemaphore *sem);
+
+/*
+ * Increase the semaphore count by count.
+ */
+void ILSemaphorePostMultiple(ILSemaphore *sem, ILUInt32 count);
+
+/*
  * Close a wait handle.  Returns zero if the handle is
  * currently owned by a thread.
  */

Index: support/Makefile.am
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/support/Makefile.am,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -b -r1.55 -r1.56
--- support/Makefile.am 22 Aug 2005 12:39:20 -0000      1.55
+++ support/Makefile.am 11 Feb 2007 14:34:32 -0000      1.56
@@ -59,6 +59,7 @@
                                                 regex.c \
                                                 rem_float.c \
                                                 ripemd160.c \
+                                                semaphore.c \
                                                 serial.c \
                                                 sha1.c \
                                                 sha256.c \

Index: support/no_defs.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/support/no_defs.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- support/no_defs.h   11 May 2004 08:41:19 -0000      1.4
+++ support/no_defs.h   11 Feb 2007 14:34:32 -0000      1.5
@@ -97,6 +97,7 @@
 #define        _ILSemaphoreDestroy(sem)        do { ; } while (0)
 #define        _ILSemaphoreWait(sem)           do { ; } while (0)
 #define        _ILSemaphorePost(sem)           do { ; } while (0)
+#define        _ILSemaphorePostMultiple(sem, count)    do { ; } while (0)
 
 /*
  * Primitive condition variable operations.

Index: support/pt_defs.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/support/pt_defs.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -b -r1.9 -r1.10
--- support/pt_defs.c   4 Sep 2006 18:07:30 -0000       1.9
+++ support/pt_defs.c   11 Feb 2007 14:34:32 -0000      1.10
@@ -286,6 +286,28 @@
        }
 }
 
+/*
+ * Increase the semaphore count by count to release count threads waiting
+ * at the semaphore.
+ */
+int _ILSemaphorePostMultiple(_ILSemaphore *sem, ILUInt32 count)
+{
+       if((count > 0) && (count < IL_MAX_INT32))
+       {
+               ILUInt32 current;
+
+               for(current = 0; current < count; current++)
+               {
+                       if(sem_post(sem))
+                       {
+                               return 0;
+                       }
+               }
+               return 1;
+       }
+       return 0;
+}
+
 #ifdef __cplusplus
 };
 #endif

Index: support/pt_defs.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/support/pt_defs.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- support/pt_defs.h   4 Sep 2006 18:07:30 -0000       1.10
+++ support/pt_defs.h   11 Feb 2007 14:34:32 -0000      1.11
@@ -206,6 +206,7 @@
 #define        _ILSemaphoreDestroy(sem)        (sem_destroy((sem)))
 #define        _ILSemaphoreWait(sem)           (sem_wait((sem)))
 #define        _ILSemaphorePost(sem)           (sem_post((sem)))
+int _ILSemaphorePostMultiple(_ILSemaphore *sem, ILUInt32 count);
 
 /*
  * Primitive condition variable operations.

Index: support/w32_defs.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/support/w32_defs.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- support/w32_defs.h  16 Jun 2004 09:05:06 -0000      1.8
+++ support/w32_defs.h  11 Feb 2007 14:34:32 -0000      1.9
@@ -156,6 +156,10 @@
                        do { \
                                ReleaseSemaphore(*(sem), 1, NULL); \
                        } while (0)
+#define        _ILSemaphorePostMultiple(sem, count)    \
+                       do { \
+                               ReleaseSemaphore(*(sem), (count), NULL); \
+                       } while (0)
 
 /*
  * Primitive condition variable operations.

Index: support/semaphore.c
===================================================================
RCS file: support/semaphore.c
diff -N support/semaphore.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ support/semaphore.c 11 Feb 2007 14:34:32 -0000      1.1
@@ -0,0 +1,68 @@
+/*
+ * semaphore.c - Semaphore management routines.
+ *
+ * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+
+Note: the code in this module is generic to all platforms.  It implements
+the correct CLI locking semantics based on the primitives in "*_defs.h".
+You normally won't need to modify or replace this file when porting.
+
+*/
+
+#include "thr_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ILSemaphore *ILSemaphoreCreate(void)
+{
+       _ILSemaphore *sem;
+       sem = (_ILSemaphore *)ILMalloc(sizeof(_ILSemaphore));
+       if(sem)
+       {
+               _ILSemaphoreCreate(sem);
+       }
+       return (ILSemaphore *)sem;
+}
+
+void ILSemaphoreDestroy(ILSemaphore *sem)
+{
+       _ILSemaphoreDestroy((_ILSemaphore *)sem);
+}
+
+void ILSemaphoreWait(ILSemaphore *sem)
+{
+       _ILSemaphoreWait((_ILSemaphore *)sem);
+}
+
+void ILSemaphorePost(ILSemaphore *sem)
+{
+       _ILSemaphorePost((_ILSemaphore *)sem);
+}
+
+void ILSemaphorePostMultiple(ILSemaphore *sem, ILUInt32 count)
+{
+       _ILSemaphorePostMultiple((_ILSemaphore *)sem, count);
+}
+
+#ifdef __cplusplus
+};
+#endif




reply via email to

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