[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] pnet ChangeLog engine/convert.c engine/cvmc.c e...
From: |
Klaus Treichel |
Subject: |
[dotgnu-pnet-commits] pnet ChangeLog engine/convert.c engine/cvmc.c e... |
Date: |
Tue, 16 Jan 2007 06:46:09 +0000 |
CVSROOT: /cvsroot/dotgnu-pnet
Module name: pnet
Changes by: Klaus Treichel <ktreichel> 07/01/16 06:46:08
Modified files:
. : ChangeLog
engine : convert.c cvmc.c cvmc_call.c cvmc_obj.c
cvmc_setup.c engine.h jitc.c jitc_array.c
jitc_call.c jitc_delegate.c jitc_except.c
jitc_obj.c jitc_pinvoke.c jitc_setup.c
lib_helpers.c lookup.c Makefile.am null_coder.c
image : program.h
include : il_coder.h
Added files:
engine : cctormgr.c cctormgr.h
Log message:
Replace emitting calls to the cctors in the code by using a cctor
manager.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pnet/ChangeLog?cvsroot=dotgnu-pnet&r1=1.3401&r2=1.3402
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/convert.c?cvsroot=dotgnu-pnet&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cvmc.c?cvsroot=dotgnu-pnet&r1=1.49&r2=1.50
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cvmc_call.c?cvsroot=dotgnu-pnet&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cvmc_obj.c?cvsroot=dotgnu-pnet&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cvmc_setup.c?cvsroot=dotgnu-pnet&r1=1.43&r2=1.44
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/engine.h?cvsroot=dotgnu-pnet&r1=1.116&r2=1.117
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc.c?cvsroot=dotgnu-pnet&r1=1.63&r2=1.64
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_array.c?cvsroot=dotgnu-pnet&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_call.c?cvsroot=dotgnu-pnet&r1=1.33&r2=1.34
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_delegate.c?cvsroot=dotgnu-pnet&r1=1.8&r2=1.9
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_except.c?cvsroot=dotgnu-pnet&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_obj.c?cvsroot=dotgnu-pnet&r1=1.25&r2=1.26
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_pinvoke.c?cvsroot=dotgnu-pnet&r1=1.6&r2=1.7
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_setup.c?cvsroot=dotgnu-pnet&r1=1.20&r2=1.21
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/lib_helpers.c?cvsroot=dotgnu-pnet&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/lookup.c?cvsroot=dotgnu-pnet&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/Makefile.am?cvsroot=dotgnu-pnet&r1=1.92&r2=1.93
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/null_coder.c?cvsroot=dotgnu-pnet&r1=1.27&r2=1.28
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cctormgr.c?cvsroot=dotgnu-pnet&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/cctormgr.h?cvsroot=dotgnu-pnet&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/pnet/image/program.h?cvsroot=dotgnu-pnet&r1=1.22&r2=1.23
http://cvs.savannah.gnu.org/viewcvs/pnet/include/il_coder.h?cvsroot=dotgnu-pnet&r1=1.52&r2=1.53
Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ChangeLog,v
retrieving revision 1.3401
retrieving revision 1.3402
diff -u -b -r1.3401 -r1.3402
--- ChangeLog 7 Jan 2007 16:28:53 -0000 1.3401
+++ ChangeLog 16 Jan 2007 06:46:08 -0000 1.3402
@@ -1,3 +1,55 @@
+2006-01-16 Klaus Treichel <address@hidden>
+
+ * include/il_coder.h: Add the functions runCCtors to execute the queued
+ cctors during generating the current method and runCCtor to run one
class
+ initializerand the helper macros for the new slots.
+
+ * image/program.h: Add the new system internal attribute
+ IL_META_TYPEDEF_CCTOR_RUNNING to the type attributes to detect is a
cctor
+ is allready executing and to avoid to execute it recursively.
+
+ * engine/cctormgr.c, engine/cctormgr.h: Added new manager functions for
+ running the class initializers. This one makes sure that initializers
are
+ executed only once and methods relying on the execution of a class
+ initializer in a different thread wait for it's completition.
+
+ * engine/convert.c: Acquire the metadata lock during generation of a
method
+ with the jit coder. Call the new coder method RunCCtors after a method
was
+ successfully generated.
+
+ * engine/cvmc.c: Add the cctor manager to the cvm coder class and add
the
+ new coder functions for running the cctors.
+
+ * engine/cvmc_call.c: Replace the inline call to the cctor with queueing
+ the execution of the cctor in the cctor manager.
+
+ * engine/cvmc_obj.c: Replace the inline call to the cctor with queueing
+ the execution of the cctor in the cctor manager.
+
+ * engine/cvmc_setup.c: Remove the cctor once instruction for static
+ constructors.
+
+ * engine/engine.h: Add the decalaration of the new function
_ILLookupClass.
+
+ * engine/lib_helpers.c: Use une new coder function for running the
cctors
+ in _IL_RuntimeHelpers_RunClassConstructor.
+
+ * engine/lookup.c: Add the function _ILLookupClass to find a class by
name
+ without laying out the class and use this function in LookupClass.
+
+ * engine/null_coder.c: Add the stubs Coder_RunCCtors and Coder_RunCCtor
for
+ the new coder functions.
+
+ * engine/jitc.c, engine/jitc_array.c, engine/jitc_call.c,
+ engine/jitc_delegate.c, engine/jitc_except.c, engine/jitc_obj.c,
+ engine/jitc_pinvoke.c,, engine/jitc_setup.c: Add support for the cctor
+ manager. Replace function calls acquiring metadata locks with the non
+ locking ones. (ILSizeOfType -> _ILSizeOfTypeLocked, ...) to avoid
+ deadlocks.
+
+ * engine/Makefile.am: Add the new files cctormgr.c and cctormgr.h to the
+ engine sources.
+
2006-01-07 Klaus Treichel <address@hidden>
* engine/heap.c: Add _ILEngineAllocTyped to allocate memory for objects
Index: engine/convert.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/convert.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- engine/convert.c 20 Oct 2006 19:30:54 -0000 1.27
+++ engine/convert.c 16 Jan 2007 06:46:08 -0000 1.28
@@ -36,7 +36,24 @@
#define IL_CONVERT_TYPE_INIT 5
#define IL_CONVERT_DLL_NOT_FOUND 6
+/*
+ * Acquire and release the metadata lock, while suppressing finalizers
+ * during the execution of "ConvertMethod".
+ */
+#define METADATA_WRLOCK(thread) \
+ do { \
+
IL_METADATA_WRLOCK(_ILExecThreadProcess(thread)); \
+ ILGCDisableFinalizers(0); \
+ } while (0)
+#define METADATA_UNLOCK(thread) \
+ do { \
+ ILGCEnableFinalizers(); \
+
IL_METADATA_UNLOCK(_ILExecThreadProcess(thread)); \
+ ILGCInvokeFinalizers(0); \
+ } while (0)
+
#ifdef IL_USE_JIT
+
/*
* Inner version of "_ILConvertMethod", which detects the type of
* exception to throw, but does not throw it.
@@ -70,17 +87,18 @@
method is written in IL or not */
if(code.code)
{
- /* Disable the finalizers so that the coder will not be called
resursively. */
- ILGCDisableFinalizers(0);
+ /* 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))
{
- ILGCEnableFinalizers();
+ METADATA_UNLOCK(thread);
*errorCode = IL_CONVERT_VERIFY_FAILED;
return 0;
}
- ILGCEnableFinalizers();
+ /* Run the needed cctors and unlock the metadata too */
+ ILCoderRunCCtors(coder);
}
else
{
@@ -148,22 +166,6 @@
#endif /* IL_CONFIG_PINVOKE */
/*
- * Acquire and release the metadata lock, while suppressing finalizers
- * during the execution of "ConvertMethod".
- */
-#define METADATA_WRLOCK(thread) \
- do { \
-
IL_METADATA_WRLOCK(_ILExecThreadProcess(thread)); \
- ILGCDisableFinalizers(0); \
- } while (0)
-#define METADATA_UNLOCK(thread) \
- do { \
- ILGCEnableFinalizers(); \
-
IL_METADATA_UNLOCK(_ILExecThreadProcess(thread)); \
- ILGCInvokeFinalizers(0); \
- } while (0)
-
-/*
* Inner version of "_ILConvertMethod", which detects the type of
* exception to throw, but does not throw it.
*/
@@ -506,7 +508,8 @@
ILThreadAtomicStart();
method->userData = (void *)start;
ILThreadAtomicEnd();
- METADATA_UNLOCK(thread);
+ /* Run the needed cctors and unlock the metadata too */
+ ILCoderRunCCtors(coder);
*errorCode = IL_CONVERT_OK;
return start;
}
Index: engine/cvmc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -b -r1.49 -r1.50
--- engine/cvmc.c 30 Aug 2006 17:33:25 -0000 1.49
+++ engine/cvmc.c 16 Jan 2007 06:46:08 -0000 1.50
@@ -32,6 +32,7 @@
#include "lib_defs.h"
#include "method_cache.h"
#include "cvm_config.h"
+#include "cctormgr.h"
#if defined(HAVE_LIBFFI)
#include "ffi.h"
#endif
@@ -91,6 +92,8 @@
long nativeArgPosn;
long nativeArgHeight;
ILExecProcess *process; /* Backpointer to the owning
process */
+ /* The manager for running the required cctors. */
+ ILCCtorMgr cctorMgr;
};
/*
@@ -160,6 +163,12 @@
ILFree(coder);
return 0;
}
+ if(!ILCCtorMgr_Init(&(coder->cctorMgr), 10))
+ {
+ ILCacheDestroy(coder->cache);
+ ILFree(coder);
+ return 0;
+ }
coder->start = 0;
coder->stackCheck = 0;
coder->needTry = 0;
@@ -230,6 +239,7 @@
{
ILCVMCoder *coder = (ILCVMCoder *)_coder;
ILCacheDestroy(coder->cache);
+ ILCCtorMgr_Destroy(&(coder->cctorMgr));
if(coder->argOffsets)
{
ILFree(coder->argOffsets);
@@ -278,6 +288,24 @@
}
/*
+ * Run the class initializers queued during generation of the last method.
+ */
+static ILInt32 CVMCoder_RunCCtors(ILCoder *_coder)
+{
+ ILCVMCoder *coder = (ILCVMCoder *)_coder;
+ return ILCCtorMgr_RunCCtors(&(coder->cctorMgr));
+}
+
+/*
+ * Run the class initializer for the given class.
+ */
+static ILInt32 CVMCoder_RunCCtor(ILCoder *_coder, ILClass *classInfo)
+{
+ ILCVMCoder *coder = (ILCVMCoder *)_coder;
+ return ILCCtorMgr_RunCCtor(&(coder->cctorMgr), classInfo);
+}
+
+/*
* Get a block of method cache memory for use in code unrolling.
*/
int _ILCVMStartUnrollBlock(ILCoder *_coder, int align, ILCachePosn *posn)
@@ -485,6 +513,8 @@
CVMCoder_CheckNull,
CVMCoder_Convert,
CVMCoder_ConvertCustom,
+ CVMCoder_RunCCtors,
+ CVMCoder_RunCCtor,
"sentinel"
};
Index: engine/cvmc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc_call.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- engine/cvmc_call.c 22 Oct 2006 18:01:08 -0000 1.33
+++ engine/cvmc_call.c 16 Jan 2007 06:46:08 -0000 1.34
@@ -57,52 +57,6 @@
}
/*
- * Call the static constructor for a class if necessary.
- */
-static void CallStaticConstructor(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)
- {
- /* 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 != ((ILCVMCoder *)coder)->currentMethod)
- {
- /* Output a call to the static constructor */
- CVM_OUT_PTR(COP_CALL, cctor);
- }
- }
- 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;
- }
- }
-}
-
-/*
* Adjust the position of the stack for a call.
*/
static void AdjustForCall(ILCoder *coder, ILCoderMethodInfo *info,
@@ -143,7 +97,8 @@
ILEngineStackItem *returnItem,
ILMethod
*methodInfo)
{
- CallStaticConstructor(coder, ILMethod_Owner(methodInfo), 0);
+ /* Queue the cctor to run. */
+ ILCCtorMgr_OnCallMethod(&(((ILCVMCoder *)coder)->cctorMgr), methodInfo);
if(info->tailCall)
{
CVMP_OUT_PTR(COP_PREFIX_TAIL_CALL, methodInfo);
@@ -173,7 +128,8 @@
static void CVMCoder_CallCtor(ILCoder *coder, ILCoderMethodInfo *info,
ILMethod *methodInfo)
{
- CallStaticConstructor(coder, ILMethod_Owner(methodInfo), 1);
+ /* Queue the cctor to run. */
+ ILCCtorMgr_OnCallMethod(&(((ILCVMCoder *)coder)->cctorMgr), methodInfo);
CVM_OUT_PTR(COP_CALL_CTOR, methodInfo);
AdjustForCall(coder, info, 0);
CVM_ADJUST(1);
Index: engine/cvmc_obj.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc_obj.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- engine/cvmc_obj.c 23 Aug 2005 10:45:52 -0000 1.20
+++ engine/cvmc_obj.c 16 Jan 2007 06:46:08 -0000 1.21
@@ -321,10 +321,6 @@
fieldType, field->offset, 1);
}
-/* Forward declaration: defined in "cvmc_call.c" */
-static void CallStaticConstructor(ILCoder *coder, ILClass *classInfo,
- int isCtor);
-
#ifdef IL_CONFIG_PINVOKE
/*
@@ -391,9 +387,10 @@
#endif
if((field->member.attributes & IL_META_FIELDDEF_HAS_FIELD_RVA) == 0)
{
- /* Call the static constructor if necessary */
classInfo = ILField_Owner(field);
- CallStaticConstructor(coder, classInfo, 1);
+
+ /* Queue the cctor to run. */
+ ILCCtorMgr_OnStaticFieldAccess(&(((ILCVMCoder
*)coder)->cctorMgr), field);
/* Regular or thread-static field? */
if(!ILFieldIsThreadStatic(field))
@@ -477,9 +474,10 @@
}
#endif
- /* Call the static constructor if necessary */
classInfo = ILField_Owner(field);
- CallStaticConstructor(coder, classInfo, 1);
+
+ /* Queue the cctor to run. */
+ ILCCtorMgr_OnStaticFieldAccess(&(((ILCVMCoder *)coder)->cctorMgr),
field);
/* Regular or RVA field? */
if((field->member.attributes & IL_META_FIELDDEF_HAS_FIELD_RVA) == 0)
@@ -822,9 +820,10 @@
ILPInvoke *pinvoke;
#endif
- /* Call the static constructor if necessary */
classInfo = ILField_Owner(field);
- CallStaticConstructor(coder, classInfo, 1);
+
+ /* Queue the cctor to run. */
+ ILCCtorMgr_OnStaticFieldAccess(&(((ILCVMCoder *)coder)->cctorMgr),
field);
/* Regular or RVA field? */
#ifdef IL_CONFIG_PINVOKE
Index: engine/cvmc_setup.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/cvmc_setup.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -b -r1.43 -r1.44
--- engine/cvmc_setup.c 30 Aug 2006 17:33:25 -0000 1.43
+++ engine/cvmc_setup.c 16 Jan 2007 06:46:08 -0000 1.44
@@ -279,14 +279,6 @@
/* Set the number of arguments, which initialize's the method's frame */
CVM_OUT_WIDE(COP_SET_NUM_ARGS, ctx->numArgWords);
- /* Is this a static constructor? */
- if(ILMethod_IsStaticConstructor(method))
- {
- /* Output a "cctor_once" instruction to ensure that this
- method's body can only be executed once */
- CVM_OUT_NONE(COP_CCTOR_ONCE);
- }
-
/* If this is a constructor, then back-patch the push down size,
which is one less than the number of argument words */
if(isConstructor)
Index: engine/engine.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/engine.h,v
retrieving revision 1.116
retrieving revision 1.117
diff -u -b -r1.116 -r1.117
--- engine/engine.h 1 Jan 2007 17:09:40 -0000 1.116
+++ engine/engine.h 16 Jan 2007 06:46:08 -0000 1.117
@@ -830,6 +830,13 @@
int _ILGetInternalDelegate(ILMethod *method, int *isCtor, ILInternalInfo
*info);
/*
+ * Look up a class name that is length-specified.
+ */
+ILClass *_ILLookupClass(ILExecProcess *process,
+ const char *className,
+ int classNameLen);
+
+/*
* Look up an interface method. Returns NULL if not found.
*/
ILMethod *_ILLookupInterfaceMethod(ILClassPrivate *objectClassPrivate,
Index: engine/jitc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc.c,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -b -r1.63 -r1.64
--- engine/jitc.c 1 Jan 2007 17:09:40 -0000 1.63
+++ engine/jitc.c 16 Jan 2007 06:46:08 -0000 1.64
@@ -24,6 +24,7 @@
#ifdef IL_USE_JIT
+#include "cctormgr.h"
#include "il_opcodes.h"
#include "il_utils.h"
#ifdef IL_DEBUGGER
@@ -72,6 +73,22 @@
*/
/* #define _IL_JIT_ENABLE_INLINE 1 */
+/*
+ * To enable the cctor manager uncomment define the following define.
+ */
+#define IL_JIT_ENABLE_CCTORMGR
+
+/*
+ * Reenable finalizers, unlock the metadata lock and run finalizers.
+ * Must be kept in sync with convert.c
+ */
+#define METADATA_UNLOCK(thread) \
+ do { \
+ ILGCEnableFinalizers(); \
+
IL_METADATA_UNLOCK(_ILExecThreadProcess(thread)); \
+ ILGCInvokeFinalizers(0); \
+ } while (0)
+
#ifdef _IL_JIT_DUMP_FUNCTION
#ifndef _IL_JIT_ENABLE_DEBUG
#define _IL_JIT_ENABLE_DEBUG 1
@@ -415,6 +432,9 @@
jit_label_t nextBlock;
jit_label_t rethrowBlock;
+ /* The manager for running the required cctors. */
+ ILCCtorMgr cctorMgr;
+
#ifndef IL_JIT_THREAD_IN_SIGNATURE
/* cache for the current thread. */
ILJitValue thread;
@@ -493,18 +513,6 @@
}
/*
- * Acquire and release the metadata lock during layouting a class.
- */
-#define METADATA_WRLOCK(thread) \
- do { \
-
IL_METADATA_WRLOCK(_ILExecThreadProcess(thread)); \
- } while (0)
-#define METADATA_UNLOCK(thread) \
- do { \
-
IL_METADATA_UNLOCK(_ILExecThreadProcess(thread)); \
- } while (0)
-
-/*
* Check if the typeKind is a floating point number.
*/
#define _JIT_TYPEKIND_IS_FLOAT(typeKind) \
@@ -1269,17 +1277,12 @@
*/
static int _LayoutClass(ILExecThread *thread, ILClass *info)
{
- int result = 0;
-
/* Check if the class is allready layouted. */
if((info->userData) && !(((ILClassPrivate
*)(info->userData))->inLayout))
{
return 1;
}
- METADATA_WRLOCK(thread);
- result = _ILLayoutClass(_ILExecThreadProcess(thread), info);
- METADATA_UNLOCK(thread);
- return result;
+ return _ILLayoutClass(_ILExecThreadProcess(thread), info);
}
/*
@@ -1956,6 +1959,7 @@
return((ILUInt32)jit_type_get_size(classPrivate->jitTypes.jitTypeBase));
}
+#ifndef IL_JIT_ENABLE_CCTORMGR
/*
* Call the static constructor for a class if necessary.
*/
@@ -2011,6 +2015,7 @@
}
}
}
+#endif /* !IL_JIT_ENABLE_CCTORMGR */
/*
* The exception handler which converts libjit inbuilt exceptions
@@ -2462,6 +2467,13 @@
/* Init the current jitted function. */
coder->jitFunction = 0;
+ if(!ILCCtorMgr_Init(&(coder->cctorMgr), 10))
+ {
+ ILMemPoolDestroy(&(coder->methodPool));
+ ILFree(coder);
+ return 0;
+ }
+
#ifndef IL_JIT_THREAD_IN_SIGNATURE
coder->thread = 0;
#endif
@@ -2679,6 +2691,8 @@
ILMemPoolDestroy(&(coder->methodPool));
+ ILCCtorMgr_Destroy(&(coder->cctorMgr));
+
ILFree(coder);
}
@@ -2729,6 +2743,33 @@
#endif
}
+/*
+ * Run the class initializers queued during generation of the last method.
+ */
+static ILInt32 JITCoder_RunCCtors(ILCoder *coder)
+{
+#ifdef IL_JIT_ENABLE_CCTORMGR
+ ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
+
+ return ILCCtorMgr_RunCCtors(&(jitCoder->cctorMgr));
+#else /* !IL_JIT_ENABLE_CCTORMGR */
+ ILExecThread *thread = ILExecThreadCurrent();
+
+ METADATA_UNLOCK(thread);
+ return 1;
+#endif /* !IL_JIT_ENABLE_CCTORMGR */
+}
+
+/*
+ * Run the class initializer for the given class.
+ */
+static ILInt32 JITCoder_RunCCtor(ILCoder *coder, ILClass *classInfo)
+{
+ ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
+
+ return ILCCtorMgr_RunCCtor(&(jitCoder->cctorMgr), classInfo);
+}
+
#ifdef IL_CONFIG_PINVOKE
/*
@@ -4507,6 +4548,7 @@
JITCoder_CheckNull,
JITCoder_Convert,
JITCoder_ConvertCustom,
+ JITCoder_RunCCtors,
"sentinel"
};
#ifdef __cplusplus
Index: engine/jitc_array.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_array.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- engine/jitc_array.c 17 Dec 2006 10:31:32 -0000 1.6
+++ engine/jitc_array.c 16 Jan 2007 06:46:08 -0000 1.7
@@ -202,7 +202,7 @@
}
/* Get the size of one array element. */
- elementSize = ILSizeOfType(thread, elementType);
+ elementSize = _ILSizeOfTypeLocked(_ILExecThreadProcess(thread),
elementType);
totalSize = (((ILUInt64)elementSize) * ((ILUInt64)length)) +
_IL_JIT_SARRAY_HEADERSIZE;
if(totalSize > (ILUInt64)IL_MAX_INT32)
@@ -302,7 +302,7 @@
elementType = ILType_ElemType(ILClassGetSynType(arrayClass));
/* Get the size of one array element. */
- elementSize = ILSizeOfType(thread, elementType);
+ elementSize = _ILSizeOfTypeLocked(jitCoder->process,
elementType);
elementClass = ILClassFromType(ILProgramItem_Image(arrayClass),
0,
elementType, 0);
Index: engine/jitc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_call.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -b -r1.33 -r1.34
--- engine/jitc_call.c 1 Jan 2007 17:09:40 -0000 1.33
+++ engine/jitc_call.c 16 Jan 2007 06:46:08 -0000 1.34
@@ -323,7 +323,7 @@
(ILContextNextImage(jitCoder->process->context, 0),
0, paramType, 0);
info = ILClassResolve(info);
- typeSize = ILSizeOfType(_thread, paramType);
+ typeSize = _ILSizeOfTypeLocked(jitCoder->process,
paramType);
boxObject = _ILJitAllocObjectGen(jitCoder->jitFunction,
info);
if(boxValue)
@@ -480,8 +480,13 @@
ILMutexUnlock(globalTraceMutex);
}
#endif
+#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), 0);
+#endif /* !IL_JIT_ENABLE_CCTORMGR */
#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS) &&
defined(_IL_JIT_ENABLE_DEBUG)
methodName = _ILJitFunctionGetMethodName(jitFunction);
@@ -822,8 +827,13 @@
type = ILType_FromClass(classInfo);
synType = ILClassGetSynType(classInfo);
+#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 */
/* Check if the function is implemented in the engine. */
if((internalType = _ILJitFunctionIsInternal(jitCoder, methodInfo,
&fnInfo, 1)))
Index: engine/jitc_delegate.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_delegate.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -b -r1.8 -r1.9
--- engine/jitc_delegate.c 1 Jan 2007 17:09:40 -0000 1.8
+++ engine/jitc_delegate.c 16 Jan 2007 06:46:08 -0000 1.9
@@ -178,7 +178,7 @@
(ILContextNextImage(_thread->process->context, 0),
0, paramType, 0);
info = ILClassResolve(info);
- typeSize = ILSizeOfType(_thread, paramType);
+ typeSize =
_ILSizeOfTypeLocked(_ILExecThreadProcess(_thread), paramType);
boxObject = _ILJitAllocObjectGen(jitFunction, info);
if(boxValue)
@@ -252,7 +252,7 @@
{
ILJitType jitType = _ILJitGetReturnType(paramType,
_ILExecThreadProcess(_thread));
- ILUInt32 typeSize = ILSizeOfType(_thread, paramType);
+ ILUInt32 typeSize =
_ILSizeOfTypeLocked(_ILExecThreadProcess(_thread), paramType);
ILJitValue boxObjectSize =
jit_value_create_nint_constant(jitFunction,
_IL_JIT_TYPE_UINT32,
typeSize);
Index: engine/jitc_except.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_except.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- engine/jitc_except.c 17 Oct 2006 12:24:18 -0000 1.13
+++ engine/jitc_except.c 16 Jan 2007 06:46:08 -0000 1.14
@@ -99,8 +99,9 @@
}
if(exception > 0)
{
- ILClass *classInfo = ILExecThreadLookupClass(_thread,
-
exceptionClasses[exception]);
+ ILClass *classInfo =
_ILLookupClass(_ILExecThreadProcess(_thread),
+
exceptionClasses[exception],
+
strlen(exceptionClasses[exception]));
ILJitValue info;
if(!classInfo)
{
Index: engine/jitc_obj.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_obj.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -b -r1.25 -r1.26
--- engine/jitc_obj.c 1 Jan 2007 17:09:40 -0000 1.25
+++ engine/jitc_obj.c 16 Jan 2007 06:46:08 -0000 1.26
@@ -432,8 +432,13 @@
#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))
@@ -568,8 +573,13 @@
}
#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)
@@ -693,8 +703,13 @@
/* 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_pinvoke.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_pinvoke.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- engine/jitc_pinvoke.c 17 Oct 2006 12:24:18 -0000 1.6
+++ engine/jitc_pinvoke.c 16 Jan 2007 06:46:08 -0000 1.7
@@ -1228,10 +1228,10 @@
thread = ILExecThreadCurrent();
srcElemSize = jit_value_create_nint_constant(function,
_IL_JIT_TYPE_INT32,
-
(jit_nint)(ILSizeOfType(thread, elemType)));
+
(jit_nint)(_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), elemType)));
newElemSize = jit_value_create_nint_constant(function,
_IL_JIT_TYPE_INT32,
-
(jit_nint)(ILSizeOfType(thread, elemType)));
+
(jit_nint)(_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), elemType)));
newArraySize = jit_insn_mul(function, arraySize,
newElemSize);
args[0] = newArraySize;
jit_insn_store(function, newArray,
jit_insn_call_native(function, "ILGCAllocAtomic",
@@ -1290,7 +1290,7 @@
{
ILClass *classInfo =
ILClassResolve(ILType_ToValueType(structureILType));
ILExecThread *thread = ILExecThreadCurrent();
- unsigned int structSize = ILSizeOfType(thread, structureILType);
+ unsigned int structSize =
_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), structureILType);
ILField *field = 0;
ILType *type;
@@ -1650,7 +1650,7 @@
{
ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
ILExecThread *thread = ILExecThreadCurrent();
- unsigned int structSize = ILSizeOfType(thread, structureILType);
+ unsigned int structSize =
_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), structureILType);
ILField *field = 0;
ILJitValue newStruct = 0;
ILType *type;
@@ -1947,10 +1947,10 @@
thread = ILExecThreadCurrent();
srcElemSize =
jit_value_create_nint_constant(function,
_IL_JIT_TYPE_INT32,
-
(jit_nint)(ILSizeOfType(thread, elemType)));
+
(jit_nint)(_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), elemType)));
newElemSize =
jit_value_create_nint_constant(function,
_IL_JIT_TYPE_INT32,
-
(jit_nint)(ILSizeOfType(thread, elemType)));
+
(jit_nint)(_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), elemType)));
newArray = jit_insn_add_relative(function,
outAddressValue, (jit_nint)(sizeof(ILUInt32)));
jit_insn_branch_if(function,
jit_insn_eq(function, arraySize,
@@ -2806,6 +2806,8 @@
if(ILType_IsSimpleArray(type))
{
+ ILExecThread *thread = ILExecThreadCurrent();
+
srcArray = in;
if(addressKind==MARSHAL_ITEM_OF_STRUCTURE ||
addressKind==MARSHAL_ITEM_OF_ARRAY)
srcArray = jit_insn_load_relative(function,
srcArray, offset, _IL_JIT_TYPE_VPTR);
@@ -2818,11 +2820,11 @@
arraySize = jit_insn_load_relative(function,
srcArray, 0, _IL_JIT_TYPE_UINT32);
srcElemSize =
jit_value_create_nint_constant(function,
_IL_JIT_TYPE_INT32,
-
(jit_nint)(ILSizeOfType(ILExecThreadCurrent(),
+
(jit_nint)(_ILSizeOfTypeLocked(_ILExecThreadProcess(thread),
elemType)));
newElemSize =
jit_value_create_nint_constant(function,
_IL_JIT_TYPE_INT32,
-
(jit_nint)(ILSizeOfType(ILExecThreadCurrent(),
+
(jit_nint)(_ILSizeOfTypeLocked(_ILExecThreadProcess(thread),
elemType)));
newArraySize = jit_insn_mul(function, arraySize,
newElemSize);
newArraySize = jit_insn_add_relative(function,
newArraySize, (jit_nint)(sizeof(ILUInt32)));
@@ -2889,8 +2891,9 @@
ILJitValue MarshalDelegateStruct(jit_function_t function, ILJitValue
inAddress, ILType *structureILType,
ILUInt32 marshalType, ILJitValue
outAddress, jit_nint offset, unsigned int addressKind)
{
+ ILExecThread *thread = ILExecThreadCurrent();
ILClass *classInfo = ILClassResolve(ILType_ToValueType(structureILType));
- unsigned int structSize = ILSizeOfType(ILExecThreadCurrent(),
structureILType);
+ unsigned int structSize =
_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), structureILType);
ILField *field = 0;
ILType *type;
ILJitType structType;
@@ -3266,8 +3269,9 @@
ILUInt32 marshalType,
ILJitValue outAddress, jit_nint offset,
unsigned int addressKind)
{
+ ILExecThread *thread = ILExecThreadCurrent();
ILClass *classInfo =
ILClassResolve(ILType_ToValueType(structureILType));
- unsigned int structSize = ILSizeOfType(ILExecThreadCurrent(),
structureILType);
+ unsigned int structSize =
_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), structureILType);
ILField *field = 0;
ILType *type;
@@ -3604,10 +3608,10 @@
arraySize = jit_insn_load_relative(function,
srcArray, 0, _IL_JIT_TYPE_UINT32);
srcElemSize =
jit_value_create_nint_constant(function,
_IL_JIT_TYPE_INT32,
-
(jit_nint)(ILSizeOfType(thread, elemType)));
+
(jit_nint)(_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), elemType)));
newElemSize =
jit_value_create_nint_constant(function,
_IL_JIT_TYPE_INT32,
-
(jit_nint)(ILSizeOfType(thread, elemType)));
+
(jit_nint)(_ILSizeOfTypeLocked(_ILExecThreadProcess(thread), elemType)));
jit_insn_branch_if(function,
jit_insn_eq(function, arraySize,
Index: engine/jitc_setup.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_setup.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -b -r1.20 -r1.21
--- engine/jitc_setup.c 11 Dec 2006 20:40:11 -0000 1.20
+++ engine/jitc_setup.c 16 Jan 2007 06:46:08 -0000 1.21
@@ -67,6 +67,7 @@
}
#endif
+#ifndef IL_JIT_ENABLE_CCTORMGR
if(ILMethod_IsStaticConstructor(method))
{
/* We have to take care that the method is executed only once.
*/
@@ -105,6 +106,7 @@
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_DEBUGGER
/* Check if this method can be debugged */
@@ -233,19 +235,25 @@
ILMutexUnlock(globalTraceMutex);
}
#endif
-#ifdef _IL_JIT_DISASSEMBLE_FUNCTION
- if(jitCoder->flags & IL_CODER_FLAG_STATS)
- {
if(!jit_function_compile(jitCoder->jitFunction))
{
return IL_CODER_END_TOO_BIG;
}
+#ifdef _IL_JIT_DISASSEMBLE_FUNCTION
+ if(jitCoder->flags & IL_CODER_FLAG_STATS)
+ {
ILMutexLock(globalTraceMutex);
jit_dump_function(stdout, jitCoder->jitFunction, methodName);
ILMutexUnlock(globalTraceMutex);
}
#endif
#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/lib_helpers.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/lib_helpers.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- engine/lib_helpers.c 17 Dec 2006 10:31:32 -0000 1.13
+++ engine/lib_helpers.c 16 Jan 2007 06:46:08 -0000 1.14
@@ -270,29 +270,9 @@
#else
ILClass *classInfo = *((ILClass **)type);
#endif
- ILMethod *method;
- if(classInfo)
- {
- /* Locate the static constructor within the class */
- IL_METADATA_RDLOCK(_ILExecThreadProcess(thread));
- method = 0;
- while((method = (ILMethod *)ILClassNextMemberByKind
- (classInfo, (ILMember *)method,
IL_META_MEMBERKIND_METHOD)) != 0)
- {
- if(ILMethod_IsStaticConstructor(method))
- {
- break;
- }
- }
- IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));
+ ILCoder *coder = _ILExecThreadProcess(thread)->coder;
- /* Call the static constructor if we found it. The method
- itself contains instructions that prevent multiple calls */
- if(method)
- {
- ILExecThreadCall(thread, method, (void *)0);
- }
- }
+ ILCoderRunCCtor(coder, classInfo);
}
ILInt32 _IL_RuntimeHelpers_InternalOffsetToStringData(ILExecThread *thread)
Index: engine/lookup.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/lookup.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -b -r1.15 -r1.16
--- engine/lookup.c 23 Aug 2005 10:45:52 -0000 1.15
+++ engine/lookup.c 16 Jan 2007 06:46:08 -0000 1.16
@@ -77,6 +77,33 @@
static ILClass *LookupClass(ILExecThread *thread, const char *className,
int classNameLen)
{
+ ILClass *classInfo = _ILLookupClass(_ILExecThreadProcess(thread),
+
className,
+
classNameLen);
+
+ /* Make sure that the class has been laid out */
+ if(classInfo != 0)
+ {
+ IL_METADATA_WRLOCK(_ILExecThreadProcess(thread));
+ if(!_ILLayoutClass(_ILExecThreadProcess(thread), classInfo))
+ {
+ IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));
+ return 0;
+ }
+ IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));
+ }
+
+ /* Return the final class structure to the caller */
+ return classInfo;
+}
+
+/*
+ * Look up a class name that is length-specified.
+ */
+ILClass *_ILLookupClass(ILExecProcess *process,
+ const char *className,
+ int classNameLen)
+{
int len, dot;
const char *name;
int nameLen;
@@ -119,7 +146,7 @@
{
/* Try looking in the system image first, to prevent the
application from redirecting system types elsewhere */
- image = ILContextGetSystem(thread->process->context);
+ image = ILContextGetSystem(process->context);
if(image)
{
classInfo = ILClassLookupLen(ILClassGlobalScope(image),
@@ -129,7 +156,7 @@
}
if(!classInfo)
{
- classInfo = ILClassLookupGlobalLen(thread->process->context,
+ classInfo = ILClassLookupGlobalLen(process->context,
name, nameLen,
namespace, namespaceLen);
}
@@ -149,18 +176,6 @@
name,
nameLen, 0, 0);
}
- /* Make sure that the class has been laid out */
- if(classInfo != 0)
- {
- IL_METADATA_WRLOCK(_ILExecThreadProcess(thread));
- if(!_ILLayoutClass(_ILExecThreadProcess(thread), classInfo))
- {
- IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));
- return 0;
- }
- IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));
- }
-
/* Return the final class structure to the caller */
return classInfo;
}
Index: engine/Makefile.am
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/Makefile.am,v
retrieving revision 1.92
retrieving revision 1.93
diff -u -b -r1.92 -r1.93
--- engine/Makefile.am 11 Dec 2006 20:40:11 -0000 1.92
+++ engine/Makefile.am 16 Jan 2007 06:46:08 -0000 1.93
@@ -89,7 +89,9 @@
BUILT_SOURCES = gen_marshal.c \
gen_marshal.h
-libILEngine_a_SOURCES = cvm.c \
+libILEngine_a_SOURCES = cctormgr.c \
+ cctormgr.h \
+ cvm.c \
box.c \
call.c \
convert.c \
Index: engine/null_coder.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/null_coder.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -b -r1.27 -r1.28
--- engine/null_coder.c 23 Aug 2005 10:45:52 -0000 1.27
+++ engine/null_coder.c 16 Jan 2007 06:46:08 -0000 1.28
@@ -418,6 +418,14 @@
void *customName, void
*customCookie)
{
}
+static ILInt32 Coder_RunCCtors(ILCoder *coder)
+{
+ return 1;
+}
+static ILInt32 Coder_RunCCtor(ILCoder *coder, ILClass *classInfo)
+{
+ return 1;
+}
/*
* Null coder class and instance.
@@ -528,6 +536,8 @@
Coder_CheckNull,
Coder_Convert,
Coder_ConvertCustom,
+ Coder_RunCCtors,
+ Coder_RunCCtor,
"sentinel"
};
ILCoder _ILNullCoder = {&_ILNullCoderClass};
Index: image/program.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/image/program.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -b -r1.22 -r1.23
--- image/program.h 22 Apr 2005 16:08:05 -0000 1.22
+++ image/program.h 16 Jan 2007 06:46:08 -0000 1.23
@@ -286,10 +286,12 @@
*/
#define IL_META_TYPEDEF_REFERENCE 0x80000000 /* Not
yet really defined */
#define IL_META_TYPEDEF_COMPLETE 0x40000000 /*
Definition is complete */
-#define IL_META_TYPEDEF_CCTOR_ONCE 0x20000000 /*
.cctor already done */
-#define IL_META_TYPEDEF_GENERIC_PARS 0x10000000 /* Has generic
parameters */
-#define IL_META_TYPEDEF_CLASS_EXPANDED 0x08000000 /* Generics
expanded */
-#define IL_META_TYPEDEF_SYSTEM_MASK 0xF8000000 /*
System flags */
+#define IL_META_TYPEDEF_GENERIC_PARS 0x20000000 /* Has generic
parameters */
+#define IL_META_TYPEDEF_CLASS_EXPANDED 0x10000000 /* Generics
expanded */
+#define IL_META_TYPEDEF_CCTOR_RUNNING 0x08000000 /* .cctor is
currenty executed. */
+#define IL_META_TYPEDEF_CCTOR_ONCE 0x04000000 /*
.cctor already done */
+#define IL_META_TYPEDEF_CCTOR_MASK 0x0C000000 /*
.cctor flags */
+#define IL_META_TYPEDEF_SYSTEM_MASK 0xFC000000 /*
System flags */
/*
* Information about an "implements" clause for a class.
Index: include/il_coder.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/include/il_coder.h,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -b -r1.52 -r1.53
--- include/il_coder.h 22 Oct 2006 18:01:09 -0000 1.52
+++ include/il_coder.h 16 Jan 2007 06:46:08 -0000 1.53
@@ -811,6 +811,20 @@
void *customName, void
*customCookie);
/*
+ * Run the cctors collected during code generation.
+ * This function must be called after the method is compiled
successfully
+ * and before the method itself is executed.
+ * The metadata lock must be still accuired and will be released just
+ * before the cctors are executed.
+ */
+ ILInt32 (*runCCtors)(ILCoder *coder);
+
+ /*
+ * Run the class initializer for the given class.
+ */
+ ILInt32 (*runCCtor)(ILCoder *coder, ILClass *classInfo);
+
+ /*
* Sentinel string to catch missing methods in class tables.
*/
const char *sentinel;
@@ -1089,6 +1103,10 @@
(customCookie)))
#define ILCoderMarkEnd(coder) \
((*((coder)->classInfo->markEnd))((coder)))
+#define ILCoderRunCCtors(coder) \
+ ((*((coder)->classInfo->runCCtors))((coder)))
+#define ILCoderRunCCtor(coder, classInfo) \
+ ((*((coder)->classInfo->runCCtor))((coder),(classInfo)))
#ifdef __cplusplus
};
Index: engine/cctormgr.c
===================================================================
RCS file: engine/cctormgr.c
diff -N engine/cctormgr.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ engine/cctormgr.c 16 Jan 2007 06:46:08 -0000 1.1
@@ -0,0 +1,466 @@
+/*
+ * cctormgr.c - Queue and execute class initializers (static constructors).
+ *
+ * Copyright (C) 2001 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
+ */
+
+#include "cctormgr.h"
+#include "lib_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Reenable finalizers, unlock the metadata lock and run finalizers.
+ * Must be kept in sync with convert.c
+ */
+#define METADATA_UNLOCK(thread) \
+ do { \
+ ILGCEnableFinalizers(); \
+
IL_METADATA_UNLOCK(_ILExecThreadProcess(thread)); \
+ ILGCInvokeFinalizers(0); \
+ } while (0)
+/*
+ * Get the number of queued cctors.
+ */
+static ILInt32 _ILCCtorMgr_GetNumQueuedCCtors(ILCCtorMgr *cctorMgr)
+{
+ ILInt32 numQueuedCCtors = 0;
+ ILClassEntry *classEntry = cctorMgr->lastClass;
+
+ while(classEntry)
+ {
+ numQueuedCCtors++;
+ classEntry = classEntry->prevClass;
+ }
+ return numQueuedCCtors;
+}
+
+/*
+ * Execute the cctor of the given class.
+ * This function must be executed with the current thread holding the
+ * cctor manager's lock.
+ */
+static int _ILCCtorMgr_RunCCtor(ILCCtorMgr *cctorMgr,
+ ILExecThread
*thread,
+ ILClass
*classInfo)
+{
+ if((classInfo->attributes &
+ (IL_META_TYPEDEF_CCTOR_RUNNING | IL_META_TYPEDEF_CCTOR_ONCE))
== 0)
+ {
+ /* The cctor was not allready executed and is not currently
running. */
+ /* So find the cctor now. */
+ ILMethod *cctor = 0;
+
+ IL_METADATA_RDLOCK(_ILExecThreadProcess(thread));
+ while((cctor = (ILMethod *)ILClassNextMemberByKind(classInfo,
+
(ILMember *)cctor,
+
IL_META_MEMBERKIND_METHOD)) != 0)
+ {
+ if(ILMethod_IsStaticConstructor(cctor))
+ {
+ break;
+ }
+ }
+ IL_METADATA_UNLOCK(_ILExecThreadProcess(thread));
+ if(cctor)
+ {
+ /* We found the cctor so we can execute it now. */
+ classInfo->attributes |= IL_META_TYPEDEF_CCTOR_RUNNING;
+ if(ILExecThreadCall(thread, cctor, 0))
+ {
+ return 0;
+ }
+ }
+ classInfo->attributes |= IL_META_TYPEDEF_CCTOR_ONCE;
+ }
+ return 1;
+}
+
+/*
+ * Execute the queued cctors.
+ * This function must be executed with the current thread holding the
+ * cctor manager's lock.
+ */
+static int _ILCCtorMgr_RunCCtors(ILCCtorMgr *cctorMgr,
+ ILExecThread
*thread,
+ ILClass
*classes[],
+ ILInt32
numClasses)
+{
+ ILInt32 currentCCtor;
+
+ /* And run the cctors now. */
+ for(currentCCtor = 0; currentCCtor < numClasses; currentCCtor++)
+ {
+ if(!(_ILCCtorMgr_RunCCtor(cctorMgr,
+ thread,
+
classes[currentCCtor])))
+ {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * Lookup the class entry for the given class in the cctor manager and return
+ * the pointer to the class entry or add a new class entry and return the
+ * pointer to the newly created entry.
+ * Returns 0 on out of memory.
+ */
+static ILClassEntry *ILCCtorMgr_FindOrAddClass(ILCCtorMgr *cctorMgr,
+
ILClass *classInfo)
+{
+ ILClassEntry *currentClass = cctorMgr->lastClass;
+
+ while(currentClass)
+ {
+ if(currentClass->classInfo == classInfo)
+ {
+ return currentClass;
+ }
+ currentClass = currentClass->prevClass;
+ }
+
+ /* Add the new class to the queue. */
+ if(!(currentClass = ILMemPoolAlloc(&(cctorMgr->classPool),
+
ILClassEntry)))
+ {
+ return 0;
+ }
+ /* Now fill the class entry with the current class. */
+ currentClass->classInfo = classInfo;
+ currentClass->prevClass = cctorMgr->lastClass;
+ cctorMgr->lastClass = currentClass;
+
+ return currentClass;
+}
+
+/*
+ * Add a class to the queue of the classes which have to be initialized.
+ */
+static int _ILCCtorMgr_QueueClass(ILCCtorMgr *cctorMgr,
+ ILClass *classInfo)
+{
+ ILMethod *cctor = 0;
+ ILClassEntry *currentClass = 0;
+
+ if(!cctorMgr)
+ {
+ return 0;
+ }
+
+ if(!classInfo)
+ {
+ return 0;
+ }
+
+ if((classInfo->attributes & IL_META_TYPEDEF_CCTOR_ONCE) != 0)
+ {
+ /* We already know that the static constructor has been
executed, */
+ return 1;
+ }
+
+ while((cctor = (ILMethod *)ILClassNextMemberByKind(classInfo,
+
(ILMember *)cctor,
+
IL_META_MEMBERKIND_METHOD)) != 0)
+ {
+ if(ILMethod_IsStaticConstructor(cctor))
+ {
+ break;
+ }
+ }
+ if(cctor == 0)
+ {
+ /* We couldn't find a cctor. */
+ /* So we flag the class as if the cctor was executed. */
+ classInfo->attributes |= IL_META_TYPEDEF_CCTOR_ONCE;
+ return 1;
+ }
+
+ /* Check if the class is allready in the queue or add it. */
+ if(!(currentClass = ILCCtorMgr_FindOrAddClass(cctorMgr, classInfo)))
+ {
+ return 0;
+ }
+
+ /* And exit with success. */
+ return 1;
+}
+
+/*
+ * Throw a System.TypeInitializationException.
+ */
+static void _ILCCtorMgr_ThrowTypeInitializationException(ILExecThread *thread)
+{
+ ILObject *exception = ILExecThreadGetException(thread);
+
+ if(exception)
+ {
+ ILObject *typeInitializationException = 0;
+
+ ILExecThreadClearException(thread);
+
+ ILExecThreadThrowSystem(thread,
+
"System.TypeInitializationException",
+ 0);
+
+ typeInitializationException = ILExecThreadGetException(thread);
+ if(typeInitializationException)
+ {
+ /* Set the inner exception thrown by the class
initializer. */
+ ((System_Exception
*)typeInitializationException)->innerException = (System_Exception *)exception;
+ }
+ }
+}
+
+/*
+ * Initialize a cctor manager instance.
+ */
+int ILCCtorMgr_Init(ILCCtorMgr *cctorMgr,
+ ILInt32 numCCtorEntries)
+{
+ if(cctorMgr)
+ {
+ /* Initialize the lock mutex. */
+ if(!(cctorMgr->lock = ILMutexCreate()))
+ {
+ return 0;
+ }
+ cctorMgr->thread = (ILThread *)0;;
+ cctorMgr->currentMethod = (ILMethod *)0;
+ cctorMgr->isStaticConstructor = 0;
+
+ cctorMgr->lastClass = (ILClassEntry *)0;
+
+ /* Intialize the pool for the class infos. */
+ ILMemPoolInit(&(cctorMgr->classPool),
+ sizeof(ILClassEntry),
+ numCCtorEntries);
+
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Destroy a cctor manager instance.
+ */
+void ILCCtorMgr_Destroy(ILCCtorMgr *cctorMgr)
+{
+ if(cctorMgr)
+ {
+ ILMemPoolDestroy(&(cctorMgr->classPool));
+
+ if(cctorMgr->lock)
+ {
+ /* Destroy the lock mutex. */
+ ILMutexDestroy(cctorMgr->lock);
+ }
+ }
+}
+
+/*
+ * Call this method before any non virtual method call is done.
+ * It checks if the static constructor for the method owner has to be invoked
+ * before the call is done.
+ */
+int ILCCtorMgr_OnCallMethod(ILCCtorMgr *cctorMgr,
+ ILMethod *method)
+{
+ ILClass *methodOwner = ILMethod_Owner(method);
+
+ if((methodOwner->attributes & IL_META_TYPEDEF_CCTOR_ONCE) != 0)
+ {
+ /* We already know that the static constructor has been called,
*/
+ return 1;
+ }
+
+ if((methodOwner->attributes & IL_META_TYPEDEF_BEFORE_FIELD_INIT) == 0)
+ {
+ if(ILMethod_IsStatic(method))
+ {
+ /* We have to call the cctor before calling any static
method */
+ /* of this type */
+ return _ILCCtorMgr_QueueClass(cctorMgr, methodOwner);
+
+ }
+ if(ILMethod_IsConstructor(method))
+ {
+ /* We have to call the cctor before calling a
constructor of */
+ /* this type. */
+ return _ILCCtorMgr_QueueClass(cctorMgr, methodOwner);
+ }
+ }
+ return 1;
+}
+
+/*
+ * Call this method before accessing any static field.
+ * It checks if the static constructor for the field's owner has to be invoked
+ * before the field is accessed.
+ */
+int ILCCtorMgr_OnStaticFieldAccess(ILCCtorMgr *cctorMgr,
+ ILField
*field)
+{
+ ILClass *fieldOwner = ILField_Owner(field);
+
+ if((fieldOwner->attributes & IL_META_TYPEDEF_CCTOR_ONCE) != 0)
+ {
+ /* We already know that the static constructor has been called,
*/
+ return 1;
+ }
+
+ if(ILField_IsStatic(field))
+ {
+ /* We have to call the cctor before accessing any static field
*/
+ /* of this type */
+ return _ILCCtorMgr_QueueClass(cctorMgr, fieldOwner);
+ }
+ return 1;
+}
+
+/*
+ * Run the cctor for the given class.
+ */
+int ILCCtorMgr_RunCCtor(ILCCtorMgr *cctorMgr, ILClass *classInfo)
+{
+ if((cctorMgr != 0) && (classInfo != 0))
+ {
+ if((classInfo->attributes & IL_META_TYPEDEF_CCTOR_ONCE) != 0)
+ {
+ /* We already know that the static constructor has been
called, */
+ return 1;
+ }
+ else
+ {
+ ILExecThread *thread = ILExecThreadCurrent();
+ int result;
+
+ if(cctorMgr->thread == thread->supportThread)
+ {
+ /* We allready hold the cctor lock. */
+ result = _ILCCtorMgr_RunCCtor(cctorMgr,
+
thread,
+
classInfo);
+ }
+ else
+ {
+ /* Lock the cctor manager. */
+ ILMutexLock(cctorMgr->lock);
+
+ /* And set the thread holding the lock. */
+ cctorMgr->thread = thread->supportThread;
+
+ result = _ILCCtorMgr_RunCCtor(cctorMgr,
+
thread,
+
classInfo);
+
+ /* reset the thread holding the lock. */
+ cctorMgr->thread = (ILThread *)0;
+ /* and unlock the cctor manager. */
+ ILMutexUnlock(cctorMgr->lock);
+ }
+ if(!result)
+ {
+
_ILCCtorMgr_ThrowTypeInitializationException(thread);
+ }
+ return result;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Run the queued cctors.
+ */
+int ILCCtorMgr_RunCCtors(ILCCtorMgr *cctorMgr)
+{
+ if(cctorMgr)
+ {
+ ILExecThread *thread = ILExecThreadCurrent();
+
+ if(!(cctorMgr->lastClass))
+ {
+ /* There are no cctors queued. */
+ /* So unlock the metadata. */
+ METADATA_UNLOCK(thread);
+ /* and return with success. */
+ return 1;
+ }
+ else
+ {
+ int result;
+ ILInt32 numQueuedCCtors =
_ILCCtorMgr_GetNumQueuedCCtors(cctorMgr);
+ ILClass *classes[numQueuedCCtors];
+ ILClassEntry *classEntry = cctorMgr->lastClass;
+ ILInt32 currentCCtor;
+
+ /* Copy the cctors to execute to the class array. */
+ for(currentCCtor = 0; currentCCtor < numQueuedCCtors;
currentCCtor++)
+ {
+ classes[currentCCtor] = classEntry->classInfo;
+ classEntry = classEntry->prevClass;
+ }
+
+ /* and reset the queue in the cctor manager. */
+ cctorMgr->lastClass = (ILClassEntry *)0;
+ ILMemPoolClear(&(cctorMgr->classPool));
+
+ /* Now unlock the metadata. */
+ METADATA_UNLOCK(thread);
+
+ if(cctorMgr->thread == thread->supportThread)
+ {
+ /* We allready hold the cctor lock. */
+ result = _ILCCtorMgr_RunCCtors(cctorMgr,
+
thread,
+
classes,
+
numQueuedCCtors);
+ }
+ else
+ {
+ /* Lock the cctor manager. */
+ ILMutexLock(cctorMgr->lock);
+
+ /* And set the thread holding the lock. */
+ cctorMgr->thread = thread->supportThread;
+
+ result = _ILCCtorMgr_RunCCtors(cctorMgr,
+
thread,
+
classes,
+
numQueuedCCtors);
+
+ /* reset the thread holding the lock. */
+ cctorMgr->thread = (ILThread *)0;
+ /* and unlock the cctor manager. */
+ ILMutexUnlock(cctorMgr->lock);
+ }
+ if(!result)
+ {
+
_ILCCtorMgr_ThrowTypeInitializationException(thread);
+ }
+ return result;
+ }
+ }
+ return 0;
+}
+
+#ifdef __cplusplus
+};
+#endif
Index: engine/cctormgr.h
===================================================================
RCS file: engine/cctormgr.h
diff -N engine/cctormgr.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ engine/cctormgr.h 16 Jan 2007 06:46:08 -0000 1.1
@@ -0,0 +1,98 @@
+/*
+ * cctormgr.h - Header file for the cctor manager.
+ *
+ * Copyright (C) 2001 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
+ */
+
+#ifndef _ENGINE_CCTORMGR_H
+#define _ENGINE_CCTORMGR_H
+
+#include "engine_private.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward declarations. */
+typedef struct _tagILClassEntry ILClassEntry;
+typedef struct _tagILCCtorMgr ILCCtorMgr;
+
+struct _tagILClassEntry
+{
+ ILClass *classInfo; /* The class for which the cctor has to
be executed. */
+ ILClassEntry *prevClass; /* The previous class entry. */
+};
+
+struct _tagILCCtorMgr
+{
+ /* Mutex to synchronize the cctor execution. */
+ ILMutex *lock;
+
+ /* The thread holding the lock. */
+ ILThread *thread;
+
+ /* The currently compiled method. */
+ ILMethod *currentMethod;
+ /* Flag if the current method is a cctor. */
+ ILInt32 isStaticConstructor;
+
+ /* Pool for the class entries. */
+ ILMemPool classPool;
+ /* The last classentry in the memory pool. */
+ ILClassEntry *lastClass;
+
+};
+
+int ILCCtorMgr_Init(ILCCtorMgr *cctorMgr,
+ ILInt32 numCCtorEntries);
+
+void ILCCtorMgr_Destroy(ILCCtorMgr *cctorMgr);
+
+/*
+ * Call this method before any non virtual method call is done.
+ * It checks if the static constructor for the method owner has to be invoked
+ * before the call is done.
+ */
+int ILCCtorMgr_OnCallMethod(ILCCtorMgr *cctorMgr,
+ ILMethod *method);
+/*
+ * Call this method before accessing any static field.
+ * It checks if the static constructor for the field's owner has to be invoked
+ * before the field is accessed.
+ */
+int ILCCtorMgr_OnStaticFieldAccess(ILCCtorMgr *cctorMgr,
+ ILField
*field);
+
+/*
+ * Run the cctor for the given class.
+ * Returns != 0 on success or 0 if an exception was thrown.
+ */
+int ILCCtorMgr_RunCCtor(ILCCtorMgr *cctorMgr, ILClass *classInfo);
+
+/*
+ * Run the queued cctors.
+ * Returns != 0 on success or 0 if an exception was thrown.
+ */
+int ILCCtorMgr_RunCCtors(ILCCtorMgr *cctorMgr);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* !_ENGINE_CCTORMGR_H */
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] pnet ChangeLog engine/convert.c engine/cvmc.c e...,
Klaus Treichel <=