memory. All functions writing values into the data area return the offset
relative the begin of the code area (start of procedure).
- $Id: codegen.inc 557 2003-11-02 22:51:59Z twisti $
+ $Id: codegen.inc 883 2004-01-14 12:42:52Z stefan $
*/
+#include <string.h>
#include "toolbox/memory.h"
#include "toolbox/loging.h"
+#include "threads/thread.h"
+/************************* critical sections *********************************/
+
+struct threadcritnodetemp {
+ struct threadcritnodetemp *next;
+ int mcodebegin, mcodeend;
+};
+
#define MCODEINITSIZE (1<<15) /* 32 Kbyte code area initialization size */
#define DSEGINITSIZE (1<<12) /* 4 Kbyte data area initialization size */
static branchref *xcastrefs; /* list of cast check branches */
static branchref *xdivrefs; /* list of divide by zero branches */
+static struct threadcritnodetemp *threadcrit;
+ /* List of critical code regions */
+static struct threadcritnodetemp threadcritcurrent;
+static int threadcritcount; /* Number of critical regions */
+
+int parentargs_base; /* offset in stackframe for the parameter from the caller*/
+
void codegen_init(); /* allocates code and data area */
void codegen_close(); /* releases temporary storage */
static void codegen_finish(); /* makes code and data area permanent and */
static void codegen_addxnullrefs(void *branchptr);
static void codegen_addxcastrefs(void *branchptr);
static void codegen_addxdivrefs(void *branchptr);
+static void codegen_threadcritstart(int offset);
+static void codegen_threadcritstop(int offset);
void dseg_display(s4 *s4ptr);
xnullrefs = NULL;
xcastrefs = NULL;
xdivrefs = NULL;
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ threadcritcurrent.next = NULL;
+ threadcritcount = 0;
+#endif
}
jumpref *jr;
u1 *epoint;
+ int extralen = 0;
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ extralen += sizeof(threadcritnode) * threadcritcount;
+#endif
+
count_code_len += mcodelen;
count_data_len += dseglen;
dseglen = ALIGN(dseglen, MAX_ALIGN);
method -> mcodelength = mcodelen + dseglen;
- method -> mcode = CNEW(u1, mcodelen + dseglen);
+ method -> mcode = CNEW(u1, mcodelen + dseglen + extralen);
memcpy ( method->mcode, dsegtop - dseglen, dseglen);
memcpy ( method->mcode + dseglen, mcodebase, mcodelen);
}
}
#endif
+
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ {
+ threadcritnode *n = (threadcritnode*) (method->mcode + mcodelen + dseglen);
+ int i;
+ struct threadcritnodetemp *nt = threadcrit;
+
+ for (i=0; i<threadcritcount; i++)
+ {
+ n->mcodebegin = method->mcode + nt->mcodebegin;
+ n->mcodeend = method->mcode + nt->mcodeend;
+ thread_registercritical(n);
+ n++;
+ nt = nt->next;
+ }
+ }
+#endif
}
printf(" --- begin of data segment: %p\n", s4ptr);
}
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+void codegen_threadcritstart(int offset)
+{
+ threadcritcurrent.mcodebegin = offset;
+}
+
+void codegen_threadcritstop(int offset)
+{
+ threadcritcurrent.next = threadcrit;
+ threadcritcurrent.mcodeend = offset;
+ threadcrit = DNEW(struct threadcritnodetemp);
+ *threadcrit = threadcritcurrent;
+ threadcritcount++;
+}
+#endif
/*
* These are local overrides for various environment variables in Emacs.