* Removed all Id tags.
[cacao.git] / src / vm / jit / intrp / dynamic-super.c
index 5cd0667c8f5d1d37299c7637142f2e2e8d17ee37..923a9f510a7f2339d4a6dfe21e0f6811824ddae5 100644 (file)
@@ -3,10 +3,10 @@
    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
 };
 
@@ -110,7 +104,7 @@ typedef struct superstart {
 static hashtable hashtable_patchersupers;
 #define HASHTABLE_PATCHERSUPERS_BITS 14
 
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
 static java_objectheader *lock_hashtable_patchersupers;
 #endif
 
@@ -124,7 +118,7 @@ typedef struct superreuse {
 static hashtable hashtable_superreuse;
 #define HASHTABLE_SUPERREUSE_BITS 14
 
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
 static java_objectheader *lock_hashtable_superreuse;
 #endif
 
@@ -318,13 +312,13 @@ static void check_prims(Label symbols1[])
 #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]);
@@ -355,11 +349,12 @@ static void init_dynamic_super(codegendata *cd)
    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);
@@ -372,14 +367,14 @@ static void superreuse_insert(u1 *code, u4 length)
   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++;
 }
 
@@ -410,9 +405,9 @@ void patchersuper_rewrite(Inst *p)
   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;
@@ -429,9 +424,8 @@ void patchersuper_rewrite(Inst *p)
       break;
     }
   }
-#if defined(USE_THREADS)
-  builtin_monitorexit(lock_hashtable_patchersupers);
-#endif
+
+  LOCK_MONITOR_EXIT(lock_hashtable_patchersupers);
 }
 
 static void hashtable_patchersupers_insert(superstart *ss)
@@ -440,14 +434,14 @@ 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++;
 }
 
@@ -537,7 +531,7 @@ void append_dispatch(codegendata *cd)
   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)
@@ -558,7 +552,7 @@ static void compile_prim_dyn(codegendata *cd, u4 p)
   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) {
@@ -569,7 +563,7 @@ static void replace_patcher(codegendata *cd, u4 p)
   }
 }
 
-void gen_inst1(codegendata *cd, u4 instr)
+void gen_inst1(codegendata *cd, ptrint instr)
 {
   /* actually generate the threaded code instruction */
 
@@ -598,7 +592,7 @@ void gen_inst1(codegendata *cd, u4 instr)
   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);
@@ -617,14 +611,14 @@ void finish_ss(codegendata *cd)
 {
 #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);
@@ -632,17 +626,18 @@ void gen_inst(codegendata *cd, u4 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);
 
@@ -655,13 +650,14 @@ void gen_inst(codegendata *cd, u4 instr)
 
   /* 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 );
@@ -680,22 +676,42 @@ void print_dynamic_super_statistics()
   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
 }