Copyright (C) 1995,1996,1997,1998,2000,2003,2004 Free Software Foundation, Inc.
Taken from Gforth.
- Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
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.
-
- Contact: cacao@complang.tuwien.ac.at
-
- Authors: Christian Thalinger
- Anton Ertl
-
- Changes:
-
- $Id: dynamic-super.c 3979 2005-12-21 16:39:52Z anton $
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
*/
#include <stdlib.h>
#include <assert.h>
+#include "vm/types.h"
+
#include "mm/memory.h"
-#if defined(USE_THREADS)
-# if defined(NATIVE_THREADS)
-# include "threads/native/threads.h"
-# else
-# include "threads/green/threads.h"
-# endif
+#if defined(ENABLE_THREADS)
+# include "threads/native/lock.h"
+#else
+# include "threads/none/lock.h"
#endif
-#include "vm/hashtable.h"
-#include "vm/options.h"
-#include "vm/types.h"
-#include "vm/jit/intrp/intrp.h"
+#include "toolbox/hashtable.h"
#include "toolbox/logging.h"
+#include "vm/jit/disass.h"
+#include "vm/jit/intrp/intrp.h"
+
+#include "vmcore/options.h"
+
+
s4 no_super=0; /* option: just use replication, but no dynamic superinsts */
static char MAYBE_UNUSED superend[]={
-#include "java-superend.i"
+#include <java-superend.i>
};
const char * const prim_names[]={
-#include "java-names.i"
+#include <java-names.i>
};
enum {
#define INST_ADDR(_inst) N_##_inst
-#include "java-labels.i"
+#include <java-labels.i>
#undef INST_ADDR
};
static hashtable hashtable_patchersupers;
#define HASHTABLE_PATCHERSUPERS_BITS 14
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
static java_objectheader *lock_hashtable_patchersupers;
#endif
static hashtable hashtable_superreuse;
#define HASHTABLE_SUPERREUSE_BITS 14
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
static java_objectheader *lock_hashtable_superreuse;
#endif
#endif
}
-static bool is_relocatable(u4 p)
+static bool is_relocatable(ptrint p)
{
return !opt_no_dynamic && priminfos[p].start != NULL;
}
static
-void append_prim(codegendata *cd, u4 p)
+void append_prim(codegendata *cd, ptrint p)
{
PrimInfo *pi = &priminfos[p];
debugp1(stderr,"append_prim %p %s\n",cd->lastmcodeptr, prim_names[p]);
more locking. */
static u4 hash_superreuse(u1 *code, u4 length)
+ /* calculates a hash value for given code length */
{
u4 r=0;
u4 i;
- for (i=0; i<length; i+=sizeof(u4)) {
+ for (i=0; i<(length&(~3)); i+=sizeof(u4)) {
r += *(s4 *)(code+i); /* !! align each superinstruction */
}
return (r+(r>>HASHTABLE_SUPERREUSE_BITS))&((1<<HASHTABLE_SUPERREUSE_BITS)-1);
superreuse *sr = NEW(superreuse);
sr->code = code;
sr->length = length;
-#if defined(USE_THREADS)
- builtin_monitorenter(lock_hashtable_superreuse);
-#endif
+
+ LOCK_MONITOR_ENTER(lock_hashtable_superreuse);
+
sr->next = *listp;
*listp = sr;
-#if defined(USE_THREADS)
- builtin_monitorexit(lock_hashtable_superreuse);
-#endif
+
+ LOCK_MONITOR_EXIT(lock_hashtable_superreuse);
+
count_supers_unique++;
}
superstart **listp = (superstart **)&hashtable_patchersupers.ptr[slot];
superstart *ss;
count_patchers_exec++;
-#if defined(USE_THREADS)
- builtin_monitorenter(lock_hashtable_patchersupers);
-#endif
+
+ LOCK_MONITOR_ENTER(lock_hashtable_patchersupers);
+
for (; ss=*listp, ss!=NULL; listp = &(ss->next)) {
if (p == ((Inst *)(ss->mcodebase + ss->patcherm))) {
Inst target;
break;
}
}
-#if defined(USE_THREADS)
- builtin_monitorexit(lock_hashtable_patchersupers);
-#endif
+
+ LOCK_MONITOR_EXIT(lock_hashtable_patchersupers);
}
static void hashtable_patchersupers_insert(superstart *ss)
u4 slot = ((key + (key>>HASHTABLE_PATCHERSUPERS_BITS)) &
((1<<HASHTABLE_PATCHERSUPERS_BITS)-1));
void **listp = &hashtable_patchersupers.ptr[slot];
-#if defined(USE_THREADS)
- builtin_monitorenter(lock_hashtable_patchersupers);
-#endif
+
+ LOCK_MONITOR_ENTER(lock_hashtable_patchersupers);
+
ss->next = (superstart *)*listp;
*listp = (void *)ss;
-#if defined(USE_THREADS)
- builtin_monitorexit(lock_hashtable_patchersupers);
-#endif
+
+ LOCK_MONITOR_EXIT(lock_hashtable_patchersupers);
+
count_patchers_ins++;
}
init_dynamic_super(cd);
}
-static void compile_prim_dyn(codegendata *cd, u4 p)
+static void compile_prim_dyn(codegendata *cd, ptrint p)
/* compile prim #p dynamically (mod flags etc.) */
{
if (opt_no_dynamic)
return;
}
-static void replace_patcher(codegendata *cd, u4 p)
+static void replace_patcher(codegendata *cd, ptrint p)
/* compile p dynamically, and note that there is a patcher here */
{
if (opt_no_quicksuper) {
}
}
-void gen_inst1(codegendata *cd, u4 instr)
+void gen_inst1(codegendata *cd, ptrint instr)
{
/* actually generate the threaded code instruction */
case N_PATCHER_CHECKCAST: replace_patcher(cd, N_CHECKCAST); break;
case N_PATCHER_INSTANCEOF: replace_patcher(cd, N_INSTANCEOF); break;
case N_PATCHER_NATIVECALL:
- if (runverbose)
+ if (opt_verbosecall)
replace_patcher(cd, N_TRACENATIVECALL);
else
replace_patcher(cd, N_NATIVECALL);
{
#if 1
if (cd->lastmcodeptr != NULL) {
- gen_inst1(cd, *(s4 *)(cd->lastmcodeptr));
+ gen_inst1(cd, *(ptrint *)(cd->lastmcodeptr));
cd->lastmcodeptr = NULL;
}
#endif
}
#if 0
-void gen_inst(codegendata *cd, u4 instr)
+void gen_inst(codegendata *cd, ptrint instr)
{
cd->lastmcodeptr = cd->mcodeptr;
gen_inst1(cd, instr);
cd->lastmcodeptr = NULL;
}
#else
-void gen_inst(codegendata *cd, u4 instr)
+void gen_inst(codegendata *cd, ptrint instr)
{
/* vmgen-0.6.2 generates gen_... calls with Inst ** as first
parameter, but we need to pass in cd to make lastmcodeptr
thread-safe */
- u4 *lastmcodeptr = (u4 *)cd->lastmcodeptr;
+ ptrint *lastmcodeptr = (ptrint *)cd->lastmcodeptr;
if (lastmcodeptr != NULL) {
- s4 combo;
+ ptrint combo;
- assert(lastmcodeptr < cd->mcodeptr && cd->mcodeptr < lastmcodeptr+40);
+ assert((u1 *) lastmcodeptr < cd->mcodeptr &&
+ cd->mcodeptr < (u1 *) (lastmcodeptr + 40));
combo = peephole_opt(*lastmcodeptr, instr, peeptable);
/* actually generate the threaded code instruction */
- *((Inst *) cd->mcodeptr) = instr;
+ *((Inst *) cd->mcodeptr) = (Inst) instr;
+
cd->lastmcodeptr = cd->mcodeptr;
cd->mcodeptr += sizeof(Inst);
}
#endif
-void print_dynamic_super_statistics()
+void print_dynamic_super_statistics(void)
{
dolog("count_supers = %d", count_supers );
dolog("count_supers_unique = %d", count_supers_unique );
dolog("count_native_saved = %d", count_native_saved );
}
+#if defined(ENABLE_DISASSEMBLER)
+void disassemble_prim(int n)
+{
+ PrimInfo *p = &(priminfos[n]);
+ u1 *start = vm_prim[n];
+
+#if defined(ENABLE_JIT)
+ printf("%s (len=%d, restlen=%d):\n",prim_names[n],p->length, p->restlength);
+ disassemble(start, start + p->length + p->restlength);
+#endif
+}
+#endif /* defined(ENABLE_DISASSEMBLER) */
+
void dynamic_super_init(void)
{
check_prims(vm_prim);
+
+#if defined(ENABLE_DISASSEMBLER)
+ if (opt_verbose) {
+ disassemble_prim(N_IADD);
+ disassemble_prim(N_ILOAD);
+ disassemble_prim(N_GETFIELD_INT);
+ }
+#endif
+
hashtable_create(&hashtable_patchersupers, 1<<HASHTABLE_PATCHERSUPERS_BITS);
if (opt_no_replication)
hashtable_create(&hashtable_superreuse, 1<<HASHTABLE_SUPERREUSE_BITS);
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
/* create patchersupers hashtable lock object */
lock_hashtable_patchersupers = NEW(java_objectheader);
lock_hashtable_superreuse = NEW(java_objectheader);
-# if defined(NATIVE_THREADS)
- initObjectLock(lock_hashtable_patchersupers);
- initObjectLock(lock_hashtable_superreuse);
-# endif
+ lock_init_object_lock(lock_hashtable_patchersupers);
+ lock_init_object_lock(lock_hashtable_superreuse);
#endif
}