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 592 2003-11-09 19:46:15Z 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 */
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.
Authors: Andreas Krall
Christian Thalinger
- $Id: codegen.c 862 2004-01-06 23:42:01Z stefan $
+ $Id: codegen.c 883 2004-01-14 12:42:52Z stefan $
*/
void catch_NullPointerException(int sig)
{
sigset_t nsig;
- int instr;
/* long faultaddr; */
void **_p = (void **) &sig;
i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ codegen_threadcritstart(mcodeptr - mcodebase);
+#endif
if (d != REG_ITMP3) {
i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ codegen_threadcritstop(mcodeptr - mcodebase);
+#endif
i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
} else {
i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ codegen_threadcritstop(mcodeptr - mcodebase);
+#endif
}
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
#include "asmpart.h"
#include "toolbox/loging.h"
#include "toolbox/memory.h"
+#include "toolbox/avl.h"
#if defined(NATIVE_THREADS)
+
+static struct avl_table *criticaltree;
+
+static int criticalcompare(const void *pa, const void *pb, void *param)
+{
+ const threadcritnode *na = pa;
+ const threadcritnode *nb = pb;
+
+ if (na->mcodebegin < nb->mcodebegin)
+ return -1;
+ if (na->mcodebegin > nb->mcodebegin)
+ return 1;
+ return 0;
+}
+
+static const threadcritnode *findcritical(u1 *mcodeptr)
+{
+ struct avl_node *n = criticaltree->avl_root;
+ const threadcritnode *m = NULL;
+ if (!n)
+ return NULL;
+ for (;;)
+ {
+ const threadcritnode *d = n->avl_data;
+ if (mcodeptr == d->mcodebegin)
+ return d;
+ if (mcodeptr < d->mcodebegin) {
+ if (n->avl_link[0])
+ n = n->avl_link[0];
+ else
+ return m;
+ } else {
+ if (n->avl_link[1]) {
+ m = n->avl_data;
+ n = n->avl_link[1];
+ } else
+ return n->avl_data;
+ }
+ }
+}
+
+void thread_registercritical(threadcritnode *n)
+{
+ avl_insert(criticaltree, n);
+}
+
+static int thread_checkcritical(u1 *mcodeptr)
+{
+ const threadcritnode *n = findcritical(mcodeptr);
+ if (!n)
+ return 0;
+ return (mcodeptr < n->mcodeend);
+}
+
pthread_mutex_t cast_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t compiler_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
void
initThreads(u1 *stackbottom)
{
-#if defined(NATIVE_THREADS) && !defined(HAVE___THREAD)
+#if defined(NATIVE_THREADS)
+#if !defined(HAVE___THREAD)
pthread_key_create(&tkey_threadinfo, NULL);
+#endif
+
+ criticaltree = avl_create(criticalcompare, NULL, NULL);
+
#endif
thread *the_main_thread;
java_objectheader *_exceptionptr;
} nativethread;
-#if defined(NATIVE_THREADS) && !defined(HAVE___THREAD)
+#if defined(NATIVE_THREADS)
+
+#if !defined(HAVE___THREAD)
extern pthread_key_t tkey_threadinfo;
#endif
+typedef struct {
+ u1 *mcodebegin, *mcodeend;
+} threadcritnode;
+
+void thread_registercritical(threadcritnode *);
+
+#endif
+
#else
#define intsDisable()
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 592 2003-11-09 19:46:15Z 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 */
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.
Authors: Andreas Krall
Christian Thalinger
- $Id: codegen.c 862 2004-01-06 23:42:01Z stefan $
+ $Id: codegen.c 883 2004-01-14 12:42:52Z stefan $
*/
void catch_NullPointerException(int sig)
{
sigset_t nsig;
- int instr;
/* long faultaddr; */
void **_p = (void **) &sig;
i386_mov_membase_reg(s1, OFFSET(java_objectheader, vftbl), REG_ITMP1);
i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
i386_mov_membase_reg(REG_ITMP1, OFFSET(vftbl, baseval), REG_ITMP1);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ codegen_threadcritstart(mcodeptr - mcodebase);
+#endif
if (d != REG_ITMP3) {
i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, baseval), REG_ITMP3);
i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ codegen_threadcritstop(mcodeptr - mcodebase);
+#endif
i386_alu_reg_reg(I386_SUB, REG_ITMP3, REG_ITMP1);
} else {
i386_alu_reg_reg(I386_SUB, REG_ITMP2, REG_ITMP1);
i386_mov_imm_reg((s4) super->vftbl, REG_ITMP2);
i386_mov_membase_reg(REG_ITMP2, OFFSET(vftbl, diffval), REG_ITMP2);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+ codegen_threadcritstop(mcodeptr - mcodebase);
+#endif
}
#if defined(USE_THREADS) && defined(NATIVE_THREADS)
#include "asmpart.h"
#include "toolbox/loging.h"
#include "toolbox/memory.h"
+#include "toolbox/avl.h"
#if defined(NATIVE_THREADS)
+
+static struct avl_table *criticaltree;
+
+static int criticalcompare(const void *pa, const void *pb, void *param)
+{
+ const threadcritnode *na = pa;
+ const threadcritnode *nb = pb;
+
+ if (na->mcodebegin < nb->mcodebegin)
+ return -1;
+ if (na->mcodebegin > nb->mcodebegin)
+ return 1;
+ return 0;
+}
+
+static const threadcritnode *findcritical(u1 *mcodeptr)
+{
+ struct avl_node *n = criticaltree->avl_root;
+ const threadcritnode *m = NULL;
+ if (!n)
+ return NULL;
+ for (;;)
+ {
+ const threadcritnode *d = n->avl_data;
+ if (mcodeptr == d->mcodebegin)
+ return d;
+ if (mcodeptr < d->mcodebegin) {
+ if (n->avl_link[0])
+ n = n->avl_link[0];
+ else
+ return m;
+ } else {
+ if (n->avl_link[1]) {
+ m = n->avl_data;
+ n = n->avl_link[1];
+ } else
+ return n->avl_data;
+ }
+ }
+}
+
+void thread_registercritical(threadcritnode *n)
+{
+ avl_insert(criticaltree, n);
+}
+
+static int thread_checkcritical(u1 *mcodeptr)
+{
+ const threadcritnode *n = findcritical(mcodeptr);
+ if (!n)
+ return 0;
+ return (mcodeptr < n->mcodeend);
+}
+
pthread_mutex_t cast_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t compiler_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
void
initThreads(u1 *stackbottom)
{
-#if defined(NATIVE_THREADS) && !defined(HAVE___THREAD)
+#if defined(NATIVE_THREADS)
+#if !defined(HAVE___THREAD)
pthread_key_create(&tkey_threadinfo, NULL);
+#endif
+
+ criticaltree = avl_create(criticalcompare, NULL, NULL);
+
#endif
thread *the_main_thread;
java_objectheader *_exceptionptr;
} nativethread;
-#if defined(NATIVE_THREADS) && !defined(HAVE___THREAD)
+#if defined(NATIVE_THREADS)
+
+#if !defined(HAVE___THREAD)
extern pthread_key_t tkey_threadinfo;
#endif
+typedef struct {
+ u1 *mcodebegin, *mcodeend;
+} threadcritnode;
+
+void thread_registercritical(threadcritnode *);
+
+#endif
+
#else
#define intsDisable()