[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[dotgnu-pnet-commits] pnet ChangeLog engine/jitc.c engine/jitc_branch...
From: |
Klaus Treichel |
Subject: |
[dotgnu-pnet-commits] pnet ChangeLog engine/jitc.c engine/jitc_branch... |
Date: |
Mon, 11 Dec 2006 20:40:11 +0000 |
CVSROOT: /cvsroot/dotgnu-pnet
Module name: pnet
Changes by: Klaus Treichel <ktreichel> 06/12/11 20:40:11
Modified files:
. : ChangeLog
engine : jitc.c jitc_branch.c jitc_call.c jitc_labels.c
jitc_locals.c jitc_setup.c jitc_stack.c
Makefile.am
Added files:
engine : jitc_inline.c
Log message:
2006-12-11 Klaus Treichel <address@hidden>
* engine/Makefile.am: Add jitc_inline.c to the jit coder
sources.
* engine/jitc.c: Add method implementation flags needed for
inlining and
include jitc_inline.c where needed.
* engine/jitc_branch.c: Remove the #ifdef
_IL_JIT_OPTIMIZE_NULLCHECK and
#endif around the _ILJitValuesResetNullChecked in
JITCoder_Label because
the macro is defined now how it's needed for the configuration.
* engine/jitc_call.c: Add support for inlining methods in
JITCoder_CallMethod. Store the value to return in the inline
context and
jump to the end of the inlined function if returning from an
inlined method
in JITCoder_ReturnInsn.
* engine/jitc_labels.c: Add support for labels in inlined
methods.
* engine/jitc_locals.c: Add support for locals and args in
inlined methods.
* engine/jitc_setup.c: Add support for inlined methods in the
setup and
finish functions of the jit coder.
*engine/jitc_stack.c: Add support for inlining methods.
*engine/jitc_inline.c: Added
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/pnet/ChangeLog?cvsroot=dotgnu-pnet&r1=1.3395&r2=1.3396
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc.c?cvsroot=dotgnu-pnet&r1=1.61&r2=1.62
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_branch.c?cvsroot=dotgnu-pnet&r1=1.13&r2=1.14
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_call.c?cvsroot=dotgnu-pnet&r1=1.31&r2=1.32
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_labels.c?cvsroot=dotgnu-pnet&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_locals.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.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_stack.c?cvsroot=dotgnu-pnet&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/Makefile.am?cvsroot=dotgnu-pnet&r1=1.91&r2=1.92
http://cvs.savannah.gnu.org/viewcvs/pnet/engine/jitc_inline.c?cvsroot=dotgnu-pnet&rev=1.1
Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/ChangeLog,v
retrieving revision 1.3395
retrieving revision 1.3396
diff -u -b -r1.3395 -r1.3396
--- ChangeLog 30 Nov 2006 20:12:59 -0000 1.3395
+++ ChangeLog 11 Dec 2006 20:40:11 -0000 1.3396
@@ -1,3 +1,30 @@
+2006-12-11 Klaus Treichel <address@hidden>
+
+ * engine/Makefile.am: Add jitc_inline.c to the jit coder sources.
+
+ * engine/jitc.c: Add method implementation flags needed for inlining and
+ include jitc_inline.c where needed.
+
+ * engine/jitc_branch.c: Remove the #ifdef _IL_JIT_OPTIMIZE_NULLCHECK and
+ #endif around the _ILJitValuesResetNullChecked in JITCoder_Label because
+ the macro is defined now how it's needed for the configuration.
+
+ * engine/jitc_call.c: Add support for inlining methods in
+ JITCoder_CallMethod. Store the value to return in the inline context and
+ jump to the end of the inlined function if returning from an inlined
method
+ in JITCoder_ReturnInsn.
+
+ * engine/jitc_labels.c: Add support for labels in inlined methods.
+
+ * engine/jitc_locals.c: Add support for locals and args in inlined
methods.
+
+ * engine/jitc_setup.c: Add support for inlined methods in the setup and
+ finish functions of the jit coder.
+
+ *engine/jitc_stack.c: Add support for inlining methods.
+
+ *engine/jitc_inline.c: Added
+
2006-11-30 Klaus Treichel <address@hidden>
* Makefile.am: Set DIST_SUBDIRS to SUBDIRS to fix make distclean if pnet
Index: engine/jitc.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -b -r1.61 -r1.62
--- engine/jitc.c 29 Nov 2006 19:49:17 -0000 1.61
+++ engine/jitc.c 11 Dec 2006 20:40:11 -0000 1.62
@@ -63,14 +63,14 @@
/* #define _IL_JIT_OPTIMIZE_LOCALS 1 */
/*
- * To enable null check optimizations uncomment the following define.
+ * To defer the initialization of the locals uncomment the following define.
*/
-/* #define _IL_JIT_OPTIMIZE_NULLCHECKS 1 */
+/* #define _IL_JIT_OPTIMIZE_INIT_LOCALS 1 */
/*
- * To defer the initialization of the locals uncomment the following define.
+ * To enable method inlining uncomment the following define.
*/
-/* #define _IL_JIT_OPTIMIZE_INIT_LOCALS 1 */
+/* #define _IL_JIT_ENABLE_INLINE 1 */
#ifdef _IL_JIT_DUMP_FUNCTION
#ifndef _IL_JIT_ENABLE_DEBUG
@@ -306,6 +306,7 @@
#include "jitc_locals.c"
#include "jitc_stack.c"
#include "jitc_labels.c"
+#include "jitc_inline.c"
#include "jitc_except.c"
#include "jitc_alloc.c"
#include "jitc_array.c"
@@ -346,11 +347,15 @@
ILJitInlineFunc inlineFunc; /* Function for inlining. */
};
-#define _IL_JIT_IMPL_DEFAULT 0x0
-#define _IL_JIT_IMPL_INTERNAL 0x1
-#define _IL_JIT_IMPL_INTERNALALLOC 0x2
-#define _IL_JIT_IMPL_INTERNALMASK 0x3
-#define _IL_JIT_IMPL_PINVOKE 0x4
+#define _IL_JIT_IMPL_DEFAULT 0x000
+#define _IL_JIT_IMPL_INTERNAL 0x001
+#define _IL_JIT_IMPL_INTERNALALLOC 0x002
+#define _IL_JIT_IMPL_INTERNALMASK 0x003
+#define _IL_JIT_IMPL_PINVOKE 0x004
+#define _IL_JIT_IMPL_MASK 0x0FF
+#define _IL_JIT_IMPL_NOINLINE 0x100
+#define _IL_JIT_IMPL_INLINE 0x200
+#define _IL_JIT_IMPL_INLINE_MASK 0x300
/* Error codes stored in fnInfo.func in case a library or method was not */
/* found */
@@ -382,6 +387,7 @@
ILMemPool methodPool;
#define IL_JITC_CODER_INSTANCE
+#include "jitc_inline.c"
#include "jitc_locals.c"
#include "jitc_stack.c"
#include "jitc_labels.c"
@@ -2437,6 +2443,7 @@
#endif
#define IL_JITC_CODER_INIT
+ #include "jitc_inline.c"
#include "jitc_locals.c"
#include "jitc_stack.c"
#include "jitc_labels.c"
@@ -2634,6 +2641,7 @@
ILJITCoder *coder = _ILCoderToILJITCoder(_coder);
#define IL_JITC_CODER_DESTROY
+#include "jitc_inline.c"
#include "jitc_locals.c"
#include "jitc_stack.c"
#include "jitc_labels.c"
@@ -4337,6 +4345,7 @@
#include "jitc_locals.c"
#include "jitc_stack.c"
#include "jitc_labels.c"
+#include "jitc_inline.c"
#include "jitc_alloc.c"
#include "jitc_array.c"
#include "jitc_except.c"
Index: engine/jitc_branch.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_branch.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -b -r1.13 -r1.14
--- engine/jitc_branch.c 10 Oct 2006 17:10:45 -0000 1.13
+++ engine/jitc_branch.c 11 Dec 2006 20:40:11 -0000 1.14
@@ -30,9 +30,7 @@
if(label)
{
- #ifdef _IL_JIT_OPTIMIZE_NULLCHECKS
_ILJitValuesResetNullChecked(jitCoder);
- #endif
if(label->labelType == _IL_JIT_LABEL_STARTFINALLY)
{
#if !defined(IL_CONFIG_REDUCE_CODE) &&
!defined(IL_WITHOUT_TOOLS)
Index: engine/jitc_call.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_call.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -b -r1.31 -r1.32
--- engine/jitc_call.c 28 Nov 2006 19:15:23 -0000 1.31
+++ engine/jitc_call.c 11 Dec 2006 20:40:11 -0000 1.32
@@ -596,6 +596,38 @@
else
#endif
{
+ #ifdef _IL_JIT_ENABLE_INLINE
+ if(_ILJitMethodIsInlineable(jitCoder, methodInfo))
+ {
+ /* Get the pointer to the args on the stack. */
+ ILJitStackItem *args =
_ILJitStackItemGetTop(jitCoder, -1);
+
+ #if !defined(IL_CONFIG_REDUCE_CODE) &&
!defined(IL_WITHOUT_TOOLS)
+ if (jitCoder->flags & IL_CODER_FLAG_STATS)
+ {
+ ILMutexLock(globalTraceMutex);
+ fprintf(stdout,
+ "Inline Method:
%s.%s\n",
+
ILClass_Name(ILMethod_Owner(methodInfo)),
+
ILMethod_Name(methodInfo));
+ ILMutexUnlock(globalTraceMutex);
+ }
+ #endif
+ if(!_ILJitCoderInlineMethod(jitCoder,
+
methodInfo,
+
0,
+
args,
+
argCount))
+ {
+ printf("Inlining failed!\n");
+ }
+ if(destroyCallSignature && callSignature)
+ {
+ jit_type_free(callSignature);
+ }
+ return;
+ }
+ #endif /* _IL_JIT_ENABLE_INLINE */
#ifdef IL_JIT_THREAD_IN_SIGNATURE
returnValue = jit_insn_call(jitCoder->jitFunction,
methodName,
jitFunction, 0,
@@ -1670,6 +1702,31 @@
}
#endif
+#ifdef _IL_JIT_ENABLE_INLINE
+ if(jitCoder->currentInlineContext)
+ {
+ if(jitCoder->currentInlineContext->returnValue)
+ {
+ /* Pop the return value ans store it in the returnvalue
for the */
+ /* inlined function. */
+ ILJitType returnType =
jit_value_get_type(jitCoder->currentInlineContext->returnValue);
+ _ILJitStackItemNew(value);
+
+ _ILJitStackPop(jitCoder, value);
+ jit_insn_store(jitCoder->jitFunction,
+
jitCoder->currentInlineContext->returnValue,
+
_ILJitValueConvertImplicit(jitCoder->jitFunction,
+
_ILJitStackItemValue(value),
+
returnType));
+ }
+ /* And jump to the end of the inlined function. */
+ jit_insn_branch(jitCoder->jitFunction,
+
&(jitCoder->currentInlineContext->returnLabel));
+
+ return;
+ }
+#endif /* _IL_JIT_ENABLE_INLINE */
+
if(engineType == ILEngineType_Invalid)
{
jit_insn_return(jitCoder->jitFunction, 0);
Index: engine/jitc_labels.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_labels.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- engine/jitc_labels.c 10 Oct 2006 17:10:45 -0000 1.4
+++ engine/jitc_labels.c 11 Dec 2006 20:40:11 -0000 1.5
@@ -87,6 +87,21 @@
static int _ILJitLabelSaveStack(ILJITCoder *coder, ILJITLabel *label)
{
int coderStackHeight = _ILJitStackHeight(coder);
+#ifdef _IL_JIT_ENABLE_INLINE
+ int coderStackBase;
+
+ if(coder->currentInlineContext)
+ {
+ coderStackBase = coder->currentInlineContext->stackBase;
+ coderStackHeight -= coderStackBase;
+ }
+ else
+ {
+ coderStackBase = 0;
+ }
+#else /* !_IL_JIT_ENABLE_INLINE */
+ int coderStackBase = 0;
+#endif /* !_IL_JIT_ENABLE_INLINE */
if(((label->labelType & (_IL_JIT_LABEL_NORMAL |
_IL_JIT_LABEL_STARTCATCH)) != 0) &&
@@ -102,7 +117,7 @@
/* Now save the current stack state. */
for(current = 0; current < coderStackHeight; current++)
{
- ILJitStackItem *stackItem = _ILJitStackItemGet(coder,
current);
+ ILJitStackItem *stackItem = _ILJitStackItemGet(coder,
coderStackBase + current);
stack[current] = _ILJitStackItemValue(*stackItem);
if(jit_value_is_constant(_ILJitStackItemValue(*stackItem)))
@@ -115,12 +130,14 @@
jit_insn_store(coder->jitFunction, temp,
_ILJitStackItemValue(*stackItem));
/* Now replace the constant with the new
temporary. */
stack[current] = temp;
+ _ILJitStackItemSetValue(*stackItem, temp);
}
else if(_ILJitStackItemNeedsDupOnLabel(*stackItem))
{
ILJitValue temp =
jit_insn_dup(coder->jitFunction,
_ILJitStackItemValue(*stackItem));
stack[current] = temp;
+ _ILJitStackItemSetValue(*stackItem, temp);
}
}
label->jitStack = stack;
@@ -135,6 +152,21 @@
static int _ILJitLabelMergeStack(ILJITCoder *coder, ILJITLabel *label)
{
int coderStackHeight = _ILJitStackHeight(coder);
+#ifdef _IL_JIT_ENABLE_INLINE
+ int coderStackBase;
+
+ if(coder->currentInlineContext)
+ {
+ coderStackBase = coder->currentInlineContext->stackBase;
+ coderStackHeight -= coderStackBase;
+ }
+ else
+ {
+ coderStackBase = 0;
+ }
+#else /* !_IL_JIT_ENABLE_INLINE */
+ int coderStackBase = 0;
+#endif /* !_IL_JIT_ENABLE_INLINE */
if(label->labelType & (_IL_JIT_LABEL_NORMAL | _IL_JIT_LABEL_STARTCATCH))
{
@@ -151,7 +183,7 @@
/* Now save the current stack state. */
for(current = 0; current < coderStackHeight; current++)
{
- ILJitStackItem *stackItem =
_ILJitStackItemGet(coder, current);
+ ILJitStackItem *stackItem =
_ILJitStackItemGet(coder, coderStackBase + current);
if(_ILJitStackItemValue(*stackItem) !=
label->jitStack[current])
{
@@ -172,6 +204,21 @@
static void _ILJitLabelRestoreStack(ILJITCoder *coder, ILJITLabel *label)
{
int coderStackHeight = _ILJitStackHeight(coder);
+#ifdef _IL_JIT_ENABLE_INLINE
+ int coderStackBase;
+
+ if(coder->currentInlineContext)
+ {
+ coderStackBase = coder->currentInlineContext->stackBase;
+ coderStackHeight -= coderStackBase;
+ }
+ else
+ {
+ coderStackBase = 0;
+ }
+#else /* !_IL_JIT_ENABLE_INLINE */
+ int coderStackBase = 0;
+#endif /* !_IL_JIT_ENABLE_INLINE */
/* Verify that the stack sizes match. */
if(coderStackHeight != label->stackSize)
@@ -186,12 +233,12 @@
/* Now restore the stack state. */
for(current = 0; current < coderStackHeight; current++)
{
- ILJitStackItem *stackItem = _ILJitStackItemGet(coder,
current);
+ ILJitStackItem *stackItem = _ILJitStackItemGet(coder,
coderStackBase + current);
_ILJitStackItemInitWithValue(*stackItem,
label->jitStack[current]);
}
}
- coder->stackTop = label->stackSize;
+ coder->stackTop = coderStackBase + label->stackSize;
}
/*
@@ -200,8 +247,21 @@
*/
static ILJITLabel *_ILJitLabelFind(ILJITCoder *coder, ILUInt32 address)
{
+#ifdef _IL_JIT_ENABLE_INLINE
ILJITLabel *label = coder->labelList;
+ if(coder->currentInlineContext)
+ {
+ label = coder->currentInlineContext->labelList;
+ }
+ else
+ {
+ label = coder->labelList;
+ }
+#else /* !_IL_JIT_ENABLE_INLINE */
+ ILJITLabel *label = coder->labelList;
+#endif /* !_IL_JIT_ENABLE_INLINE */
+
while(label != 0)
{
if(label->address == address)
@@ -225,7 +285,18 @@
;
if(!label)
{
+ #ifdef _IL_JIT_ENABLE_INLINE
+ if(coder->currentInlineContext)
+ {
+ label =
ILMemPoolAlloc(&(coder->currentInlineContext->labelPool), ILJITLabel);
+ }
+ else
+ {
+ label = ILMemPoolAlloc(&(coder->labelPool), ILJITLabel);
+ }
+ #else /* !_IL_JIT_ENABLE_INLINE */
label = ILMemPoolAlloc(&(coder->labelPool), ILJITLabel);
+ #endif /* !_IL_JIT_ENABLE_INLINE */
if(label)
{
label->stackSize = 0;
@@ -238,8 +309,23 @@
coder->labelOutOfMemory = 1;
return 0;
}
+ #ifdef _IL_JIT_ENABLE_INLINE
+ if(coder->currentInlineContext)
+ {
+ label->next =
coder->currentInlineContext->labelList;
+ coder->currentInlineContext->labelList = label;
+ _ILJitLocalSlotsHandleProtectedValues(coder,
+
coder->currentInlineContext);
+ }
+ else
+ {
label->next = coder->labelList;
coder->labelList = label;
+ }
+ #else /* !_IL_JIT_ENABLE_INLINE */
+ label->next = coder->labelList;
+ coder->labelList = label;
+ #endif /* !_IL_JIT_ENABLE_INLINE */
#ifdef _IL_JIT_OPTIMIZE_INIT_LOCALS
if((coder->localsInitialized == 0) && (address != 0))
{
@@ -271,3 +357,25 @@
#endif /* IL_JITC_FUNCTIONS */
+#ifdef IL_JITC_INLINE_CONTEXT_INSTANCE
+
+ /* Handle the labels. */
+ ILMemPool labelPool;
+ ILJITLabel *labelList;
+
+#endif /* IL_JITC_INLINE_CONTEXT_INSTANCE */
+
+#ifdef IL_JITC_INLINE_CONTEXT_INIT
+
+ /* Init the label stuff. */
+ ILMemPoolInit(&(inlineContext->labelPool), sizeof(ILJITLabel), 8);
+ inlineContext->labelList = 0;
+
+#endif /* IL_JITC_INLINE_CONTEXT_INIT */
+
+#ifdef IL_JITC_INLINE_CONTEXT_DESTROY
+
+ ILMemPoolDestroy(&(inlineContext->labelPool));
+
+#endif /* IL_JITC_INLINE_CONTEXT_DESTROY */
+
Index: engine/jitc_locals.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_locals.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -b -r1.6 -r1.7
--- engine/jitc_locals.c 10 Oct 2006 17:10:45 -0000 1.6
+++ engine/jitc_locals.c 11 Dec 2006 20:40:11 -0000 1.7
@@ -44,6 +44,13 @@
int maxSlots; /* Number of allocated
slots. */
};
+/*
+ * Initialize all not yet initialized values in the local slots to 0.
+ * Returns 0 on failure.
+ */
+static int _ILJitLocalSlotsInitLocals(ILJITCoder *jitCoder,
+
ILJitLocalSlots *localSlots);
+
#define _ILJitLocalSlotsInit(s) \
do { \
(s).slots = 0; \
@@ -67,6 +74,8 @@
*/
#define _IL_JIT_VALUE_NULLCHECKED 0x00000001
#define _IL_JIT_VALUE_INITIALIZED 0x00000002
+#define _IL_JIT_VALUE_PROTECT 0x00000004
+#define _IL_JIT_VALUE_LOCAL_MASK 0x000000FF
/*
* additional flags used on the evaluation stack.
@@ -75,6 +84,96 @@
#define _IL_JIT_VALUE_POINTER_TO 0x00000200 /* pointer to the
local/arg value */
/*
+ * Set flags for the given local slot.
+ */
+#define _ILJitLocalSlotSetFlags(s, f) ((s).flags |= (f))
+
+/*
+ * Reset flags for the given local slot.
+ */
+#define _ILJitLocalSlotResetFlags(s, f) ((s).flags &= ~(f))
+
+/*
+ * Get a specific slot from a ILJitLocalSlots structure.
+ */
+#define _ILJitLocalSlotFromSlots(localSlots, n)
((localSlots).slots[(n)])
+
+/*
+ * Set flags for all values in the given local slots.
+ */
+#define _ILJitLocalSlotsSetFlags(s, f) \
+ do { \
+ ILInt32 __current; \
+ for(__current = 0; __current < (s).numSlots; __current++) \
+ { \
+ _ILJitLocalSlotSetFlags(_ILJitLocalSlotFromSlots(s,
__current), f); \
+ } \
+ } while (0)
+
+/*
+ * Reset flags for all values in the given local slots.
+ */
+#define _ILJitLocalSlotsResetFlags(s, f) \
+ do { \
+ ILInt32 __current; \
+ for(__current = 0; __current < (s).numSlots; __current++) \
+ { \
+ _ILJitLocalSlotResetFlags(_ILJitLocalSlotFromSlots(s,
__current), f); \
+ } \
+ } while (0)
+
+/*
+ * Set flags for all argument / local values in the jit coder.
+ */
+#define _ILJitCoderLocalsSetFlags(c, f) \
+ do { \
+ _ILJitLocalSlotsSetFlags((c)->jitParams, f); \
+ _ILJitLocalSlotsSetFlags((c)->jitLocals, f); \
+ } while (0)
+
+/*
+ * Reset flags for all argument / local values in the jit coder.
+ */
+#define _ILJitCoderLocalsResetFlags(c, f) \
+ do { \
+ _ILJitLocalSlotsResetFlags((c)->jitParams, f); \
+ _ILJitLocalSlotsResetFlags((c)->jitLocals, f); \
+ } while (0)
+
+#ifdef _IL_JIT_OPTIMIZE_LOCALS
+
+#define _ILJitValuesResetNullChecked(c) \
+ _ILJitCoderLocalsResetFlags(c, _IL_JIT_VALUE_NULLCHECKED)
+
+#else
+
+#define _ILJitValuesResetNullChecked(c)
+
+#endif /* _IL_JIT_OPTIMIZE_LOCALS */
+
+#ifdef _IL_JIT_ENABLE_INLINE
+
+/*
+ * Set flags for all argument / local values in the inline context.
+ */
+#define _ILJitInlineContextLocalsSetFlags(c, f) \
+ do { \
+ _ILJitLocalSlotsSetFlags((c)->jitParams, f); \
+ _ILJitLocalSlotsSetFlags((c)->jitLocals, f); \
+ } while (0)
+
+/*
+ * Reset flags for all argument / local values in the inline context.
+ */
+#define _ILJitInlineContextLocalsResetFlags(c, f) \
+ do { \
+ _ILJitLocalSlotsResetFlags((c)->jitParams, f); \
+ _ILJitLocalSlotsResetFlags((c)->jitLocals, f); \
+ } while (0)
+
+#endif /* _IL_JIT_ENABLE_INLINE */
+
+/*
* Allocate enough space for "n" slots.
*/
#define _ILJitLocalsAlloc(s, n) \
@@ -97,42 +196,97 @@
/*
* Get the slot for a local value.
*/
-#define _ILJitLocalGet(coder, n) ((coder)->jitLocals.slots[(n)])
+#ifdef _IL_JIT_ENABLE_INLINE
+#define _ILJitLocalGet(coder, n) \
+ ({ \
+ ILJitLocalSlot *localSlot; \
+ if((coder)->currentInlineContext) \
+ { \
+ localSlot =
&_ILJitLocalSlotFromSlots((coder)->currentInlineContext->jitLocals, (n)); \
+ } \
+ else \
+ { \
+ localSlot =
&_ILJitLocalSlotFromSlots((coder)->jitLocals, (n)); \
+ } \
+ localSlot; \
+ })
+
+#else
+#define _ILJitLocalGet(coder, n)
(&_ILJitLocalSlotFromSlots((coder)->jitLocals, (n)))
+#endif
/*
* Access the flags member of a local slot.
*/
-#define _ILJitLocalFlags(coder, n) _ILJitLocalGet((coder), (n)).flags
+#define _ILJitLocalFlags(coder, n) _ILJitLocalGet((coder), (n))->flags
/*
* Access the ptrToValue member of a locals slot.
*/
-#define _ILJitLocalPointer(coder, n) _ILJitLocalGet((coder), (n)).refValue
+#define _ILJitLocalPointer(coder, n) _ILJitLocalGet((coder), (n))->refValue
/*
* Access the value member of a locals slot.
*/
-#define _ILJitLocalValue(coder, n) _ILJitLocalGet((coder), (n)).value
+#define _ILJitLocalValue(coder, n) _ILJitLocalGet((coder), (n))->value
/*
* Get the slot for a param value.
*/
-#define _ILJitParamGet(coder, n) ((coder)->jitParams.slots[(n)])
+#ifdef _IL_JIT_ENABLE_INLINE
+#define _ILJitParamGet(coder, n) \
+ ({ \
+ ILJitLocalSlot *localSlot; \
+ if((coder)->currentInlineContext) \
+ { \
+ localSlot =
&_ILJitLocalSlotFromSlots((coder)->currentInlineContext->jitParams, (n)); \
+ } \
+ else \
+ { \
+ localSlot =
&_ILJitLocalSlotFromSlots((coder)->jitParams, (n)); \
+ } \
+ localSlot; \
+ })
+
+#else
+#define _ILJitParamGet(coder, n)
(&_ILJitLocalSlotFromSlots((coder)->jitParams, (n)))
+#endif
/*
* Access the flags member of a local slot.
*/
-#define _ILJitParamFlags(coder, n) _ILJitParamGet((coder), (n)).flags
+#define _ILJitParamFlags(coder, n) _ILJitParamGet((coder), (n))->flags
/*
* Access the ptrToValue member of a locals slot.
*/
-#define _ILJitParamPointer(coder, n) _ILJitParamGet((coder), (n)).refValue
+#define _ILJitParamPointer(coder, n) _ILJitParamGet((coder), (n))->refValue
/*
* Access the value member of a locals slot.
*/
-#define _ILJitParamValue(coder, n) _ILJitParamGet((coder), (n)).value
+#define _ILJitParamValue(coder, n) _ILJitParamGet((coder), (n))->value
+
+#ifdef _IL_JIT_ENABLE_INLINE
+
+/*
+ * Create a new jit_value_t with the type of the existing jit_value_t in the
+ * local slot and replace the existing one with the new one.
+ * Clear the protect flag afterwards.
+ */
+static int _ILJitLocalSlotNewValue(ILJITCoder *jitCoder,
+ ILJitLocalSlot *localSlot);
+
+/*
+ * Duplicate the jit_value_t in a local slot and clear the protect flag.
+ */
+static int _ILJitLocalSlotDupValue(ILJITCoder *jitCoder,
+ ILJitLocalSlot *localSlot);
+
+#define _ILJitLocalsInitInlineContext(coder, inlineContext) \
+ _ILJitLocalSlotsInitLocals((coder),
&((inlineContext)->jitLocals))
+
+#endif /* _IL_JIT_ENABLE_INLINE */
#endif /* IL_JITC_DECLARATIONS */
@@ -161,9 +315,9 @@
#ifdef IL_JITC_CODER_DESTROY
- _ILJitLocalSlotsDestroy(coder->jitLocals)
+ _ILJitLocalSlotsDestroy(coder->jitLocals);
- _ILJitLocalSlotsDestroy(coder->jitParams)
+ _ILJitLocalSlotsDestroy(coder->jitParams);
#endif /* IL_JITC_CODER_DESTROY */
@@ -176,7 +330,7 @@
static ILJitValue _ILJitLocalGetPointerTo(ILJITCoder *coder,
ILUInt32 localNum)
{
- ILJitLocalSlot *slot = &_ILJitLocalGet(coder, localNum);
+ ILJitLocalSlot *slot = _ILJitLocalGet(coder, localNum);
/*
if(!slot->refValue)
@@ -195,8 +349,17 @@
static ILJitValue _ILJitParamGetPointerTo(ILJITCoder *coder,
ILUInt32 paramNum)
{
- ILJitLocalSlot *slot = &_ILJitParamGet(coder, paramNum);
+ ILJitLocalSlot *slot = _ILJitParamGet(coder, paramNum);
+#ifdef _IL_JIT_ENABLE_INLINE
+ if(slot->flags & _IL_JIT_VALUE_PROTECT)
+ {
+ if(!(_ILJitLocalSlotDupValue(coder, slot)))
+ {
+ return 0;
+ }
+ }
+#endif
/*
if(!slot->refValue)
{
@@ -259,34 +422,54 @@
}
/*
+ * Initialize all not yet initialized values in the local slots to 0.
+ * Returns 0 on failure.
+ */
+static int _ILJitLocalSlotsInitLocals(ILJITCoder *jitCoder,
+
ILJitLocalSlots *localSlots)
+{
+ ILUInt32 num = localSlots->numSlots;
+
+ if(num > 0)
+ {
+ ILUInt32 current;
+ ILJitLocalSlot *slot;
+
+ for(current = 0; current < num; ++current)
+ {
+ slot = &_ILJitLocalSlotFromSlots(*localSlots, current);
+
+ if(!_ILJitLocalInit(jitCoder, slot))
+ {
+ return 0;
+ }
+ }
+ }
+ return 1;
+}
+
+/*
* Initialize the not yet initialized local values to 0 and move the
* initialization sequence to the start of the function.
*/
static int _ILJitLocalsInit(ILJITCoder *coder)
{
ILUInt32 num = coder->jitLocals.numSlots;
- ILUInt32 current;
if(num > 0)
{
jit_label_t startLabel = jit_label_undefined;
jit_label_t endLabel = jit_label_undefined;
- ILJitLocalSlot *slot;
if(!jit_insn_label(coder->jitFunction, &startLabel))
{
return 0;
}
- for(current = 0; current < num; ++current)
- {
- slot = &_ILJitLocalGet(coder, current);
-
- if(!_ILJitLocalInit(coder, slot))
+ if(!_ILJitLocalSlotsInitLocals(coder, &(coder->jitLocals)))
{
return 0;
}
- }
if(!jit_insn_label(coder->jitFunction, &endLabel))
{
@@ -305,48 +488,83 @@
* Create the slots for the declared local variables.
* Returns zero if out of memory.
*/
-static int _ILJitLocalsCreate(ILJITCoder *coder, ILStandAloneSig *localVarSig)
+static int _ILJitLocalSlotsCreateLocals(ILJITCoder *jitCoder,
+
ILJitLocalSlots *localSlots,
+
ILStandAloneSig *localVarSig)
{
+ if(localVarSig)
+ {
ILType *signature;
ILType *type;
ILJitType jitType;
ILUInt32 num;
ILUInt32 current;
-#ifdef IL_DEBUGGER
- jit_value_t data1;
- jit_value_t data2;
-#endif
- if(localVarSig)
- {
/* Determine the number of locals to allocate */
- signature = ILStandAloneSigGetType(localVarSig);
+ if(!(signature = ILStandAloneSigGetType(localVarSig)))
+ {
+ return 0;
+ }
num = ILTypeNumLocals(signature);
/* Allocate the "jitLocals" array for the variables */
- _ILJitLocalsAlloc(coder->jitLocals, num);
+ _ILJitLocalsAlloc(*localSlots, num);
- /* Set the offsets for each of the local variables */
+ /* Create the jit values for the local variables */
for(current = 0; current < num; ++current)
{
- ILJitLocalSlot *local = &_ILJitLocalGet(coder, current);
-
- type = ILTypeGetLocal(signature, current);
+ ILJitLocalSlot *local =
&_ILJitLocalSlotFromSlots(*localSlots, current);
- if(!(jitType = _ILJitGetLocalsType(type,
coder->process)))
+ if(!(type = ILTypeGetLocal(signature, current)))
{
return 0;
}
- if(!(local->value =
jit_value_create(coder->jitFunction, jitType)))
+ if(!(jitType = _ILJitGetLocalsType(type,
jitCoder->process)))
{
return 0;
}
+ if(!(local->value =
jit_value_create(jitCoder->jitFunction, jitType)))
+ {
+ return 0;
+ }
+ local->flags = 0;
local->refValue = 0;
+ }
+ /* Record the number of used locals in the local slots. */
+ localSlots->numSlots = num;
+ }
+ else
+ {
+ /* Set the number of used locals to 0. */
+ localSlots->numSlots = 0;
+ }
+ return 1;
+}
+
+/*
+ * Create the slots for the declared local variables.
+ * Returns zero if out of memory.
+ */
+static int _ILJitLocalsCreate(ILJITCoder *coder, ILStandAloneSig *localVarSig)
+{
+ if(!_ILJitLocalSlotsCreateLocals(coder, &(coder->jitLocals),
localVarSig))
+ {
+ return 0;
+ }
#ifdef IL_DEBUGGER
- /* Notify debugger about address of local variable */
if(coder->markBreakpoints)
{
+ ILUInt32 current;
+ jit_value_t data1;
+ jit_value_t data2;
+
+ /* Set the offsets for each of the local variables */
+ for(current = 0; current < coder->jitLocals.numSlots; ++current)
+ {
+ ILJitLocalSlot *local =
&_ILJitLocalSlotFromSlots(coder->jitLocals, current);
+
+ /* Notify debugger about address of local variable */
/* Make the variable accessible for debugger */
jit_value_set_volatile(local->value);
jit_value_set_addressable(local->value);
@@ -357,15 +575,10 @@
JIT_DEBUGGER_DATA1_LOCAL_VAR_ADDR);
data2 = jit_insn_address_of(coder->jitFunction,
local->value);
- jit_insn_mark_breakpoint_variable
-
(coder->jitFunction, data1, data2);
+ jit_insn_mark_breakpoint_variable(coder->jitFunction,
data1, data2);
}
-#endif
-
- local->flags = 0;
}
- /* Record the number of used locals in the coder. */
- coder->jitLocals.numSlots = num;
+#endif
#ifndef _IL_JIT_OPTIMIZE_INIT_LOCALS
/* Initialize the locals. */
@@ -374,12 +587,6 @@
return 0;
}
#endif
- }
- else
- {
- /* Set the number of used locals to 0. */
- coder->jitLocals.numSlots = 0;
- }
return 1;
}
@@ -408,7 +615,7 @@
for(current = 1; current < numParams; ++current)
{
- param = &_ILJitParamGet(coder, current - 1);
+ param = _ILJitParamGet(coder, current - 1);
param->value =
jit_value_get_param(coder->jitFunction, current);
param->flags = 0;
@@ -450,7 +657,7 @@
*/
static ILJitValue _ILJitLocalGetValue(ILJITCoder *coder, ILUInt32 localNum)
{
- ILJitLocalSlot *slot = &_ILJitLocalGet(coder, localNum);
+ ILJitLocalSlot *slot = _ILJitLocalGet(coder, localNum);
if((slot->flags & _IL_JIT_VALUE_INITIALIZED) == 0)
{
@@ -468,7 +675,7 @@
static void _ILJitLocalStoreValue(ILJITCoder *coder, ILUInt32 localNum,
ILJitValue value)
{
- ILJitLocalSlot *slot = &_ILJitLocalGet(coder, localNum);
+ ILJitLocalSlot *slot = _ILJitLocalGet(coder, localNum);
jit_insn_store(coder->jitFunction, slot->value,
_ILJitValueConvertImplicit(coder->jitFunction,
@@ -488,7 +695,7 @@
ILUInt32 paramNum,
ILJitValue value)
{
- ILJitLocalSlot *slot = &_ILJitLocalGet(coder, paramNum);
+ ILJitLocalSlot *slot = _ILJitLocalGet(coder, paramNum);
jit_insn_store(coder->jitFunction, slot->value,
_ILJitValueConvertImplicit(coder->jitFunction,
@@ -505,7 +712,7 @@
*/
static ILJitValue _ILJitParamGetValue(ILJITCoder *coder, ILUInt32 paramNum)
{
- ILJitLocalSlot *slot = &_ILJitParamGet(coder, paramNum);
+ ILJitLocalSlot *slot = _ILJitParamGet(coder, paramNum);
return slot->value;
}
@@ -516,8 +723,17 @@
static void _ILJitParamStoreValue(ILJITCoder *coder, ILUInt32 paramNum,
ILJitValue value)
{
- ILJitLocalSlot *slot = &_ILJitParamGet(coder, paramNum);
+ ILJitLocalSlot *slot = _ILJitParamGet(coder, paramNum);
+#ifdef _IL_JIT_ENABLE_INLINE
+ if(slot->flags & _IL_JIT_VALUE_PROTECT)
+ {
+ if(!(_ILJitLocalSlotNewValue(coder, slot)))
+ {
+ return;
+ }
+ }
+#endif
jit_insn_store(coder->jitFunction, slot->value,
_ILJitValueConvertImplicit(coder->jitFunction,
value,
@@ -535,8 +751,17 @@
ILUInt32 paramNum,
ILJitValue value)
{
- ILJitLocalSlot *slot = &_ILJitParamGet(coder, paramNum);
+ ILJitLocalSlot *slot = _ILJitParamGet(coder, paramNum);
+#ifdef _IL_JIT_ENABLE_INLINE
+ if(slot->flags & _IL_JIT_VALUE_PROTECT)
+ {
+ if(!(_ILJitLocalSlotNewValue(coder, slot)))
+ {
+ return;
+ }
+ }
+#endif /* _IL_JIT_ENABLE_INLINE */
jit_insn_store(coder->jitFunction, slot->value,
_ILJitValueConvertImplicit(coder->jitFunction,
value,
@@ -545,151 +770,186 @@
slot->flags |= _IL_JIT_VALUE_NULLCHECKED;
}
-#endif
+#endif /* _IL_JIT_OPTIMIZE_LOCALS */
+
+#ifdef _IL_JIT_ENABLE_INLINE
/*
- * Check if the given value is a parameter or local.
- * Returns 1 if the value is either a param or local value or pointer to
- * a param or local otherwise 0.
+ * Create a new jit_value_t with the type of the existing jit_value_t in the
+ * local slot and replace the existing one with the new one.
+ * Clear the protect flag afterwards.
*/
-static ILInt32 _ILJitValueIsArgOrLocal(ILJITCoder *coder, ILJitValue value)
+static int _ILJitLocalSlotNewValue(ILJITCoder *jitCoder,
+ ILJitLocalSlot *localSlot)
{
- ILInt32 current;
- ILJitLocalSlot *slot = 0;
-
- for(current = 0; current < coder->jitLocals.numSlots; ++current)
- {
- slot = &_ILJitLocalGet(coder, current);
+ ILJitType type;
+ ILJitValue value;
- if(slot->value == value)
+ if(!(type = jit_value_get_type(localSlot->value)))
{
- return 1;
+ return 0;
}
+ if(!(value = jit_value_create(jitCoder->jitFunction, type)))
+ {
+ return 0;
}
+ localSlot->value = value;
+ localSlot->refValue = 0;
+ localSlot->flags &= ~_IL_JIT_VALUE_PROTECT;
+ return 1;
+}
- for(current = 0; current < coder->jitParams.numSlots; ++current)
- {
- slot = &_ILJitParamGet(coder, current);
+/*
+ * Duplicate the jit_value_t in a local slot and clear the protect flag.
+ */
+static int _ILJitLocalSlotDupValue(ILJITCoder *jitCoder,
+ ILJitLocalSlot *localSlot)
+{
+ ILJitType type;
+ ILJitValue value;
- if(slot->value == value)
+ if(!(type = jit_value_get_type(localSlot->value)))
{
- return 1;
+ return 0;
}
+ if(!(value = jit_value_create(jitCoder->jitFunction, type)))
+ {
+ return 0;
}
-
+ if(!(jit_insn_store(jitCoder->jitFunction, value, localSlot->value)))
+ {
return 0;
+ }
+ localSlot->value = value;
+ localSlot->refValue = 0;
+ localSlot->flags &= ~_IL_JIT_VALUE_PROTECT;
+ return 1;
}
-#ifdef _IL_JIT_OPTIMIZE_NULLCHECKS
-
-#define _ILJitValuesResetNullChecked(coder) \
- _ILJitValuesSetFlags((coder), 0, _IL_JIT_VALUE_NULLCHECKED)
-#endif
-
/*
- * Find the slot for the given value.
- * Returns the slot with the value when found otherwise 0.
+ * Duplicate all values in an inline context that are marked to protect.
+ * This has to be done for example before if branch or a branch target is
+ * emitted.
*/
-static ILJitLocalSlot *_ILJitValueFindSlot(ILJITCoder *coder, ILJitValue value)
+static int _ILJitLocalSlotsHandleProtectedValues(ILJITCoder *jitCoder,
+
ILJITCoderInlineContext *inlineContext)
{
+ ILJitLocalSlot *slot;
ILInt32 current;
- ILJitLocalSlot *slot = 0;
- for(current = 0; current < coder->jitLocals.numSlots; ++current)
+ for(current = 0; current < inlineContext->jitParams.numSlots; current++)
{
- slot = &_ILJitLocalGet(coder, current);
+ slot = &_ILJitLocalSlotFromSlots(inlineContext->jitParams,
current);
- if(slot->value == value)
+ if(slot->flags & _IL_JIT_VALUE_PROTECT)
{
- return slot;
- }
- }
-
- for(current = 0; current < coder->jitParams.numSlots; ++current)
- {
- slot = &_ILJitParamGet(coder, current);
-
- if(slot->value == value)
+ if(!(_ILJitLocalSlotDupValue(jitCoder, slot)))
{
- return slot;
+ return 0;
}
}
- return 0;
+ }
+ return 1;
}
/*
- * Set or reset flags for the given value.
+ * Setup the arguments for an inlined function.
*/
-static void _ILJitValueSetFlags(ILJITCoder *coder, ILJitValue value,
- ILUInt32
setFlags, ILUInt32 resetFlags)
+static int _ILJitLocalSlotsSetupInlineArgs(ILJITCoder *jitCoder,
+
ILJITCoderInlineContext *inlineContext,
+
ILJitValue this,
+
ILJitStackItem *args,
+
ILInt32 numArgs)
{
- ILJitLocalSlot *slot = _ILJitValueFindSlot(coder, value);
+ ILInt32 current;
+ ILInt32 currentArg;
- if(slot)
+ if(this)
{
- slot->flags |= setFlags;
- slot->flags &= ~resetFlags;
- }
-}
+ ILJitLocalSlot *arg;
-/*
- * Set or reset flags for all locals / parameters.
- */
-static void _ILJitValuesSetFlags(ILJITCoder *coder,
- ILUInt32
setFlags, ILUInt32 resetFlags)
-{
+ _ILJitLocalsAlloc(inlineContext->jitParams, numArgs + 1);
- ILInt32 current;
- ILJitLocalSlot *slot = 0;
+ arg = &_ILJitLocalSlotFromSlots(inlineContext->jitParams, 0);
- for(current = 0; current < coder->jitLocals.numSlots; ++current)
- {
- slot = &_ILJitLocalGet(coder, current);
+ arg->value = this;
+ arg->refValue = 0;
+ arg->flags = _IL_JIT_VALUE_NULLCHECKED;
- slot->flags |= setFlags;
- slot->flags &= ~resetFlags;
+ current = 1;
}
-
- for(current = 0; current < coder->jitParams.numSlots; ++current)
+ else
{
- slot = &_ILJitParamGet(coder, current);
-
- slot->flags |= setFlags;
- slot->flags &= ~resetFlags;
+ _ILJitLocalsAlloc(inlineContext->jitParams, numArgs);
+ current = 0;
}
-}
-
-/*
- * Throw a NullReferenceException if address.is 0.
- */
-static void _ILJitCheckNull(ILJITCoder *coder, ILJitValue address)
-{
-#ifdef _IL_JIT_OPTIMIZE_NULLCHECKS
- ILJitLocalSlot *slot = 0;
-#endif
- if(jit_value_is_constant(address))
+ for(currentArg = 0; currentArg < numArgs; currentArg++)
{
- /* We assume that the type of the constant is a pointer type. */
- if(jit_value_get_nint_constant(address) != 0)
+ ILJitLocalSlot *arg =
&_ILJitLocalSlotFromSlots(inlineContext->jitParams,
+
currentArg);
+
+ arg->value = _ILJitStackItemValue(args[currentArg]);
+ arg->refValue = 0;
+#ifdef _IL_JIT_OPTIMIZE_LOCALS
+ if(jit_value_is_constant(arg->value))
{
- /* We don't have to do a null check for a non null
constant. */
- return;
+ arg->flags = ((args[currentArg].flags &
_IL_JIT_VALUE_LOCAL_MASK) | _IL_JIT_VALUE_PROTECT);
}
+ else if(args[currentArg].flags & _IL_JIT_VALUE_COPYOF)
+ {
+ arg->flags = ((args[currentArg].flags &
_IL_JIT_VALUE_LOCAL_MASK) | _IL_JIT_VALUE_PROTECT);
}
-#ifdef _IL_JIT_OPTIMIZE_NULLCHECKS
- if((slot = _ILJitValueFindSlot(coder, address)))
+ else
{
- if((slot->flags & _IL_JIT_VALUE_NULLCHECKED) == 0)
+ arg->flags = (args[currentArg].flags &
_IL_JIT_VALUE_LOCAL_MASK);
+ }
+#else
+ if(jit_value_is_constant(arg->value))
{
- jit_insn_check_null(coder->jitFunction, address);
- slot->flags |= _IL_JIT_VALUE_NULLCHECKED;
+ arg->flags = _IL_JIT_VALUE_PROTECT;
}
- return;
+ else
+ {
+ arg->flags = 0;
}
#endif
- jit_insn_check_null(coder->jitFunction, address);
+ /* TODO: look at the bug that happens without this. */
+ _ILJitLocalSlotDupValue(jitCoder, arg);
+ current++;
+ }
+ return 1;
}
+#endif /* _IL_JIT_ENABLE_INLINE */
+
#endif /* IL_JITC_FUNCTIONS */
+#ifdef IL_JITC_INLINE_CONTEXT_INSTANCE
+
+ /* Members to manage the fixed arguments. */
+ ILJitLocalSlots jitParams;
+
+ /* Members to manage the local variables. */
+ ILJitLocalSlots jitLocals;
+
+#endif /* IL_JITC_INLINE_CONTEXT_INSTANCE */
+
+#ifdef IL_JITC_INLINE_CONTEXT_INIT
+
+ /* Initialize the parameter management. */
+ _ILJitLocalSlotsInit(inlineContext->jitParams)
+
+ /* Initialize the locals management. */
+ _ILJitLocalSlotsInit(inlineContext->jitLocals)
+
+#endif /* IL_JITC_INLINE_CONTEXT_INIT */
+
+#ifdef IL_JITC_INLINE_CONTEXT_DESTROY
+
+ _ILJitLocalSlotsDestroy(inlineContext->jitLocals)
+
+ _ILJitLocalSlotsDestroy(inlineContext->jitParams)
+
+#endif /* IL_JITC_INLINE_CONTEXT_DESTROY */
+
Index: engine/jitc_setup.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_setup.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- engine/jitc_setup.c 1 Oct 2006 17:11:24 -0000 1.19
+++ engine/jitc_setup.c 11 Dec 2006 20:40:11 -0000 1.20
@@ -32,6 +32,16 @@
ILDebugger *debugger;
#endif
+#ifdef _IL_JIT_ENABLE_INLINE
+ if(coder->currentInlineContext)
+ {
+ int neededStackHeight = coder->currentInlineContext->stackBase
+ code->maxStack + 2;
+
+ ALLOC_STACK(coder, neededStackHeight);
+ return 1;
+ }
+#endif /* _IL_JIT_ENABLE_INLINE */
+
/* Record the current jitted function. */
coder->jitFunction = ILJitFunctionFromILMethod(method);
/* Record the current method. */
@@ -192,6 +202,13 @@
char *methodName = _ILJitFunctionGetMethodName(jitCoder->jitFunction);
#endif
+#ifdef _IL_JIT_ENABLE_INLINE
+ if(jitCoder->currentInlineContext)
+ {
+ return IL_CODER_END_OK;
+ }
+#endif /* _IL_JIT_ENABLE_INLINE */
+
/* Destroy the mem stack for the label stackstates. */
ILMemStackDestroy(&(jitCoder->stackStates));
Index: engine/jitc_stack.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/jitc_stack.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- engine/jitc_stack.c 13 Oct 2006 15:04:03 -0000 1.11
+++ engine/jitc_stack.c 11 Dec 2006 20:40:11 -0000 1.12
@@ -255,7 +255,7 @@
do { \
(s).flags = (_ILJitParamFlags(coder, n) |
_IL_JIT_VALUE_COPYOF); \
(s).value = _ILJitParamValue(coder, n); \
- (s).refValue = &(_ILJitParamGet(coder, n)); \
+ (s).refValue = (_ILJitParamGet(coder, n)); \
} while(0)
/*
@@ -407,7 +407,7 @@
ILJitStackItem *__stackValue = _ILJitStackItemGetTop(coder,
-1); \
__stackValue->flags = (_ILJitParamFlags(coder, n) |
_IL_JIT_VALUE_COPYOF); \
__stackValue->value = _ILJitParamValue(coder, n); \
- __stackValue->refValue = &(_ILJitParamGet(coder, n)); \
+ __stackValue->refValue = (_ILJitParamGet(coder, n)); \
JITC_ADJUST((coder), 1); \
} while(0)
@@ -419,7 +419,7 @@
ILJitStackItem *__stackValue = _ILJitStackItemGetTop(coder,
-1); \
__stackValue->flags = (_IL_JIT_VALUE_NULLCHECKED |
_IL_JIT_VALUE_POINTER_TO); \
__stackValue->value = _ILJitParamGetPointerTo(coder, n); \
- __stackValue->refValue = &(_ILJitParamGet(coder, n)); \
+ __stackValue->refValue = (_ILJitParamGet(coder, n)); \
JITC_ADJUST((coder), 1); \
} while(0)
@@ -431,7 +431,7 @@
_ILJitStackItemNew(__value) ; \
ILJitLocalSlot *__refValue; \
_ILJitStackPop(coder, __value); \
- __refValue = &(_ILJitParamGet(coder, n)); \
+ __refValue = (_ILJitParamGet(coder, n)); \
_ILJitStackDupLocal(coder, __refValue); \
if(__value.flags & _IL_JIT_VALUE_NULLCHECKED) \
{ \
@@ -451,7 +451,7 @@
ILJitStackItem *__stackValue = _ILJitStackItemGetTop(coder,
-1); \
__stackValue->flags = (_ILJitLocalFlags(coder, n) |
_IL_JIT_VALUE_COPYOF); \
__stackValue->value = _ILJitLocalValue(coder, n); \
- __stackValue->refValue = &(_ILJitLocalGet(coder, n)); \
+ __stackValue->refValue = (_ILJitLocalGet(coder, n)); \
JITC_ADJUST((coder), 1); \
} while(0)
@@ -463,7 +463,7 @@
ILJitStackItem *__stackValue = _ILJitStackItemGetTop(coder,
-1); \
__stackValue->flags = (_IL_JIT_VALUE_NULLCHECKED |
_IL_JIT_VALUE_POINTER_TO); \
__stackValue->value = _ILJitLocalGetPointerTo(coder, n); \
- __stackValue->refValue = &(_ILJitLocalGet(coder, n)); \
+ __stackValue->refValue = (_ILJitLocalGet(coder, n)); \
JITC_ADJUST((coder), 1); \
} while(0)
@@ -476,7 +476,7 @@
_ILJitStackItemNew(__value); \
ILJitLocalSlot *__refValue; \
_ILJitStackPop(coder, __value); \
- __refValue = &(_ILJitLocalGet(coder, n)); \
+ __refValue = (_ILJitLocalGet(coder, n)); \
__refValue->flags |= _IL_JIT_VALUE_INITIALIZED; \
_ILJitStackDupLocal(coder, __refValue); \
if(__value.flags & _IL_JIT_VALUE_NULLCHECKED) \
@@ -756,6 +756,12 @@
{
ILJITCoder *jitCoder = _ILCoderToILJITCoder(coder);
+#ifdef _IL_JIT_ENABLE_INLINE
+ if(jitCoder->currentInlineContext)
+ {
+ stackSize += jitCoder->currentInlineContext->stackBase;
+ }
+#endif /* _IL_JIT_ENABLE_INLINE */
#if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
if (jitCoder->flags & IL_CODER_FLAG_STATS)
{
Index: engine/Makefile.am
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/Makefile.am,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -b -r1.91 -r1.92
--- engine/Makefile.am 29 Nov 2006 19:49:17 -0000 1.91
+++ engine/Makefile.am 11 Dec 2006 20:40:11 -0000 1.92
@@ -24,6 +24,7 @@
jitc_delegate.c \
jitc_diag.c \
jitc_except.c \
+ jitc_inline.c \
jitc_labels.c \
jitc_locals.c \
jitc_math.c \
Index: engine/jitc_inline.c
===================================================================
RCS file: engine/jitc_inline.c
diff -N engine/jitc_inline.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ engine/jitc_inline.c 11 Dec 2006 20:40:11 -0000 1.1
@@ -0,0 +1,477 @@
+/*
+ * jitc_inline.c - JIT Coder support for inlining IL methods.
+ *
+ * Copyright (C) 2006 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
+ */
+
+#ifdef _IL_JIT_ENABLE_INLINE
+
+/*
+ * Maximum method code size to inline.
+ */
+#define _IL_JIT_MAX_INLINE_CODELEN 32
+
+#ifdef IL_JITC_DECLARATIONS
+
+/*
+ * Forward declaration of the inline context.
+ */
+typedef struct _tagILJitCoderInlineContext ILJITCoderInlineContext;
+
+/*
+ * Structure to hold the information for inlining an IL method.
+ */
+struct _tagILJitCoderInlineContext
+{
+ /* The previous context level. */
+ ILJITCoderInlineContext *prevContext;
+
+ /* The method inlined. */
+ ILMethod *inlineMethod;
+
+ /* The return value for the inlined method. */
+ ILJitValue returnValue;
+
+ /* The stack base on entry of the method. */
+ ILInt32 stackBase;
+
+ /* The label to jump to on return. */
+ jit_label_t returnLabel;
+
+#undef IL_JITC_DECLARATIONS
+#define IL_JITC_INLINE_CONTEXT_INSTANCE
+#include "jitc_labels.c"
+#include "jitc_locals.c"
+#undef IL_JITC_INLINE_CONTEXT_INSTANCE
+#define IL_JITC_DECLARATIONS
+};
+
+/*
+ * Initialize a new inline context.
+ */
+static void _ILJitCoderInlineContextInit(ILJITCoderInlineContext
*inlineContext);
+
+/*
+ * Destroy an inline context.
+ */
+static void _ILJitCoderInlineContextDestroy(ILJITCoderInlineContext
*inlineContext);
+
+/*
+ * Get a new inline context and make it the current inline context for the
+ * coder instance..
+ */
+static ILJITCoderInlineContext *_ILJitCoderInlineContextPush(ILJITCoder
*coder);
+
+/*
+ * Pop the current inline context of the context stack and make the previous
+ * context the current again.
+ */
+static ILInt32 _ILJitCoderInlineContextPop(ILJITCoder *coder);
+
+/*
+ * Check If a method is inlineable by the jit coder.
+ */
+static int _ILJitMethodIsInlineable(ILJITCoder *jitCoder, ILMethod *method);
+
+/*
+ * Inline the IL method.
+ */
+static int _ILJitCoderInlineMethod(ILJITCoder *jitCoder,
+ ILMethod
*method,
+ ILJitValue
this,
+
ILJitStackItem *args,
+ ILInt32
numArgs);
+
+#endif /* IL_JITC_DECLARATIONS */
+
+#ifdef IL_JITC_CODER_INSTANCE
+
+ /* Handle the inline contexts. */
+ ILMemPool inlineContextPool;
+ ILJITCoderInlineContext *freeInlineContext;
+
+ /* The current context if inlining a method otherwise 0. */
+ ILJITCoderInlineContext *currentInlineContext;
+
+#endif /* IL_JITC_CODER_INSTANCE */
+
+#ifdef IL_JITC_CODER_INIT
+
+ /* Init the inline context stuff. */
+ ILMemPoolInit(&(coder->inlineContextPool),
sizeof(ILJITCoderInlineContext), 8);
+ coder->freeInlineContext = 0;
+ coder->currentInlineContext = 0;
+
+#endif /* IL_JITC_CODER_INIT */
+
+#ifdef IL_JITC_CODER_DESTROY
+
+ while(coder->freeInlineContext)
+ {
+ ILJITCoderInlineContext *inlineContext =
coder->freeInlineContext;
+
+ coder->freeInlineContext = inlineContext->prevContext;
+ _ILJitCoderInlineContextDestroy(inlineContext);
+
+ }
+ ILMemPoolDestroy(&(coder->inlineContextPool));
+
+#endif /* IL_JITC_CODER_DESTROY */
+
+#ifdef IL_JITC_FUNCTIONS
+
+/*
+ * Initialize a new inline context.
+ */
+static void _ILJitCoderInlineContextInit(ILJITCoderInlineContext
*inlineContext)
+{
+ inlineContext->prevContext = 0;
+ inlineContext->inlineMethod = 0;
+ inlineContext->returnValue = 0;
+ inlineContext->stackBase = 0;
+
+#undef IL_JITC_FUNCTIONS
+#define IL_JITC_INLINE_CONTEXT_INIT
+#include "jitc_labels.c"
+#include "jitc_locals.c"
+#undef IL_JITC_INLINE_CONTEXT_INIT
+#define IL_JITC_FUNCTIONS
+}
+
+/*
+ * Destroy an inline context.
+ */
+static void _ILJitCoderInlineContextDestroy(ILJITCoderInlineContext
*inlineContext)
+{
+#undef IL_JITC_FUNCTIONS
+#define IL_JITC_INLINE_CONTEXT_DESTROY
+#include "jitc_labels.c"
+#include "jitc_locals.c"
+#undef IL_JITC_INLINE_CONTEXT_DESTROY
+#define IL_JITC_FUNCTIONS
+}
+
+/*
+ * Check If a method is inlineable by the jit coder.
+ */
+static int _ILJitMethodIsInlineable(ILJITCoder *jitCoder, ILMethod *method)
+{
+ /* Check if we are in debugging mode. */
+ if(jitCoder->debugEnabled)
+ {
+ /* Don't inline anything while in debugging mode. */
+ return 0;
+ }
+
+ if(method)
+ {
+ ILJitMethodInfo *jitMethodInfo = (ILJitMethodInfo
*)method->userData;
+ ILJITCoderInlineContext *inlineContext;
+
+ if(!(jitMethodInfo->implementationType &
_IL_JIT_IMPL_INLINE_MASK))
+ {
+ ILMethodCode code;
+ ILException *exceptions;
+
+ /* Check if the method is syncronized. */
+ if(ILMethod_IsSynchronized(method))
+ {
+ /* We don't inline syncronized methods. */
+ jitMethodInfo->implementationType |=
_IL_JIT_IMPL_NOINLINE;
+ return 0;
+ }
+
+ /* Get the method code */
+ if(!ILMethodGetCode(method, &code))
+ {
+ jitMethodInfo->implementationType |=
_IL_JIT_IMPL_NOINLINE;
+ return 0;
+ }
+
+ if((code.codeLen == 0) || (code.codeLen >
_IL_JIT_MAX_INLINE_CODELEN))
+ {
+ jitMethodInfo->implementationType |=
_IL_JIT_IMPL_NOINLINE;
+ return 0;
+ }
+
+ /* Get the exception list */
+ if(!ILMethodGetExceptions(method, &code, &exceptions))
+ {
+ jitMethodInfo->implementationType |=
_IL_JIT_IMPL_NOINLINE;
+ return 0;
+ }
+
+ /* Now Check if the method has any catch or finally
blocks. */
+ if(exceptions)
+ {
+ /* We don't inline methods with catch or
finally blocks. */
+ jitMethodInfo->implementationType |=
_IL_JIT_IMPL_NOINLINE;
+ return 0;
+ }
+ /* Flag the method inlineable. */
+ jitMethodInfo->implementationType |=
_IL_JIT_IMPL_INLINE;
+ }
+
+ if((jitMethodInfo->implementationType &
_IL_JIT_IMPL_INLINE_MASK) == _IL_JIT_IMPL_NOINLINE)
+ {
+ return 0;
+ }
+
+ /* Now check if the method is allready somewhere in the
currently */
+ /* inlined methods to avoid an endless recursion. */
+ if(method == jitCoder->currentMethod)
+ {
+ return 0;
+ }
+
+ inlineContext = jitCoder->currentInlineContext;
+ while(inlineContext)
+ {
+ if(method == inlineContext->inlineMethod)
+ {
+ return 0;
+ }
+ inlineContext = inlineContext->prevContext;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Setup the inline context in the coder to inline the given method.
+ */
+static int _ILJitCoderInlineContextSetup(ILJITCoder *jitCoder,
+
ILMethod *method,
+
ILJitValue this,
+
ILJitStackItem *args,
+
ILInt32 numArgs)
+{
+ if(method)
+ {
+ ILJitMethodInfo *jitMethodInfo = (ILJitMethodInfo
*)method->userData;
+ ILJitType signature;
+ ILJitType returnType;
+ ILMethodCode code;
+ ILJITCoderInlineContext *inlineContext;
+
+ /* Get the method code */
+ if(!ILMethodGetCode(method, &code))
+ {
+ return 0;
+ }
+
+ /* Get a new inline context. */
+ if(!(inlineContext = _ILJitCoderInlineContextPush(jitCoder)))
+ {
+ return 0;
+ }
+
+ /* Setup the return value for the inlined function. */
+ if(!(signature =
jit_function_get_signature(jitMethodInfo->jitFunction)))
+ {
+ /* Pop the new created inline context. */
+ _ILJitCoderInlineContextPop(jitCoder);
+ return 0;
+ }
+
+ if(!(returnType = jit_type_get_return(signature)))
+ {
+ /* Pop the new created inline context. */
+ _ILJitCoderInlineContextPop(jitCoder);
+ return 0;
+ }
+
+ if(returnType == _IL_JIT_TYPE_VOID)
+ {
+ inlineContext->returnValue = 0;
+ }
+ else
+ {
+ if(!(inlineContext->returnValue =
jit_value_create(jitCoder->jitFunction,
+
returnType)))
+ {
+ /* Pop the new created inline context. */
+ _ILJitCoderInlineContextPop(jitCoder);
+ return 0;
+ }
+ }
+ /* Setup the locals for the inlined function. */
+ if(!_ILJitLocalSlotsCreateLocals(jitCoder,
+
&(inlineContext->jitLocals),
+
code.localVarSig))
+ {
+ /* Pop the new created inline context. */
+ _ILJitCoderInlineContextPop(jitCoder);
+ return 0;
+ }
+
+ if(!_ILJitLocalSlotsSetupInlineArgs(jitCoder,
+
inlineContext,
+
this,
+
args,
+
numArgs))
+ {
+ /* Pop the new created inline context. */
+ _ILJitCoderInlineContextPop(jitCoder);
+ return 0;
+ }
+
+ if(!_ILJitLocalsInitInlineContext(jitCoder, inlineContext))
+ {
+ /* Pop the new created inline context. */
+ _ILJitCoderInlineContextPop(jitCoder);
+ return 0;
+ }
+
+ ILMemPoolClear(&(inlineContext->labelPool));
+ inlineContext->labelList = 0;
+ inlineContext->inlineMethod = method;
+ inlineContext->stackBase = jitCoder->stackTop;
+ inlineContext->returnLabel = jit_label_undefined;
+
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Inline the IL method.
+ */
+static int _ILJitCoderInlineMethod(ILJITCoder *jitCoder,
+ ILMethod
*method,
+ ILJitValue
this,
+
ILJitStackItem *args,
+ ILInt32
numArgs)
+{
+ if(_ILJitCoderInlineContextSetup(jitCoder,
+ method,
+ this,
+ args,
+
numArgs))
+ {
+ ILJITCoderInlineContext *inlineContext;
+ ILMethodCode code;
+ unsigned char *start;
+
+ inlineContext = jitCoder->currentInlineContext;
+ if(!inlineContext)
+ {
+ return 0;
+ }
+
+ /* Get the method code */
+ if(!ILMethodGetCode(method, &code))
+ {
+ return 0;
+ }
+
+ if(!_ILVerify((ILCoder *)jitCoder,
+ &start,
+ method,
+ &code,
+
ILImageIsSecure(ILProgramItem_Image(method)),
+ ILExecThreadCurrent()))
+ {
+ return 0;
+ }
+
+ if(inlineContext != jitCoder->currentInlineContext)
+ {
+ printf("Inline contexts on start and end don't
match!\n");
+ }
+
+ if(jitCoder->stackTop != inlineContext->stackBase)
+ {
+ printf("Stack height on start and end doesn't match!
start: %i end: %i\n",
+ inlineContext->stackBase,
jitCoder->stackTop);
+
+ jitCoder->stackTop = inlineContext->stackBase;
+ }
+
+ /* Set the end label for the inlined method. */
+ if(inlineContext->returnLabel != jit_label_undefined)
+ {
+ jit_insn_label(jitCoder->jitFunction,
+
&(inlineContext->returnLabel));
+ }
+
+ /* And push the return value on the stack. */
+ if(inlineContext->returnValue)
+ {
+ _ILJitStackPushValue(jitCoder,
inlineContext->returnValue);
+ }
+
+ /* Pop the inline context. */
+ _ILJitCoderInlineContextPop(jitCoder);
+
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Pop the current inline context of the context stack and make the previous
+ * context the current again.
+ */
+static ILInt32 _ILJitCoderInlineContextPop(ILJITCoder *coder)
+{
+ if(coder->currentInlineContext)
+ {
+ /* Save the current inline context in the freelist.*/
+ ILJITCoderInlineContext *inlineContext =
coder->currentInlineContext->prevContext;
+
+ coder->currentInlineContext->prevContext =
coder->freeInlineContext;
+ coder->freeInlineContext = coder->currentInlineContext;
+ coder->currentInlineContext = inlineContext;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Get a new inline context and make it the current inline context for the
+ * coder instance..
+ */
+static ILJITCoderInlineContext *_ILJitCoderInlineContextPush(ILJITCoder *coder)
+{
+ ILJITCoderInlineContext *inlineContext = 0;
+
+ if((inlineContext = coder->freeInlineContext) == 0)
+ {
+ if(!(inlineContext = (ILJITCoderInlineContext
*)ILMemPoolAllocItem(&(coder->inlineContextPool))))
+ {
+ return 0;
+ }
+ /* Now initialize the new allocated inline context. */
+ _ILJitCoderInlineContextInit(inlineContext);
+ }
+ else
+ {
+ /* Take the inline context from the freelist. */
+ coder->freeInlineContext = inlineContext->prevContext;
+ }
+ /* Make the new inline context the current one. */
+ inlineContext->prevContext = coder->currentInlineContext;
+ coder->currentInlineContext = inlineContext;
+ return inlineContext;
+}
+
+#endif /* IL_JITC_FUNCTIONS */
+
+#endif /* _IL_JIT_ENABLE_INLINE */
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [dotgnu-pnet-commits] pnet ChangeLog engine/jitc.c engine/jitc_branch...,
Klaus Treichel <=