*** empty log message ***
[cacao.git] / src / vm / jit / codegen.inc
index dd4943360df976938774378bcca3546ab160bec0..cd7729faec4f93c9f90f02e2ee4ea14d62b8dccf 100644 (file)
@@ -1,10 +1,9 @@
-/* jit/codegen.inc - architecture independent code generator
+/* vm/jit/codegen.inc - architecture independent code generator
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   Institut f. Computersprachen, TU Wien
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
-   S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
-   J. Wenninger
+   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
 
    This file is part of CACAO.
 
@@ -28,8 +27,8 @@
    Authors: Reinhard Grafl
             Andreas  Krall
 
-   Changes: Michael Gschwind
-            Christian Thalinger
+   Changes: Christian Thalinger
+            Joseph Wenninger
 
    All functions assume the following code area / data area layout:
 
    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 1565 2004-11-23 15:56:37Z twisti $
+   $Id: codegen.inc 2220 2005-04-05 15:49:13Z christian $
 
 */
 
+#ifndef _CODEGEN_INC_H_
+#define _CODEGEN_INC_H_
 
 #include <string.h>
-#include "exceptions.h"
-#include "native.h"
-#include "options.h"
-#include "statistics.h"
-#include "jit/codegen.inc.h"
-#include "toolbox/memory.h"
-#include "toolbox/logging.h"
+
+#if !defined(STATIC_CLASSPATH)
+# include <dlfcn.h>
+#endif
+
+#include "mm/memory.h"
 #include "toolbox/avl.h"
-#include "threads/thread.h"
-#ifndef STATIC_CLASSPATH
-#include <dlfcn.h>
+#include "toolbox/logging.h"
+#include "native/native.h"
+
+#if defined(USE_THREADS)
+# if defined(NATIVE_THREADS)
+#  include "threads/native/threads.h"
+# else
+#  include "threads/green/threads.h"
+# endif
 #endif
 
-/* in this tree we store all method addresses */
+#include "vm/exceptions.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
+#include "vm/jit/codegen.inc.h"
+
+
+/* in this tree we store all method addresses *********************************/
 
 #if defined(__I386__) || defined(__X86_64__)
 static struct avl_table *methodtree = NULL;
@@ -302,6 +314,7 @@ static s4 dseg_adds8(codegendata *cd, s8 value)
 #endif
 
 
+#if !defined(__XDSPCORE__)
 static s4 dseg_addfloat_increase(codegendata *cd, float value)
 {
        dseg_increase(cd);
@@ -352,6 +365,7 @@ static s4 dseg_adddouble(codegendata *cd, double value)
 
        return -(cd->dseglen);
 }
+#endif /* !defined(__XDSPCORE__) */
 
 
 static void dseg_addtarget(codegendata *cd, basicblock *target)
@@ -538,7 +552,7 @@ static void codegen_addclinitref(codegendata *cd,
 
 static void codegen_createlinenumbertable(codegendata *cd)
 {
-#ifdef __I386__
+#if defined(__I386__) || defined(__ALPHA__)
        linenumberref *lr;
 
        for (lr = cd->linenumberreferences; lr != NULL; lr = lr->next) {
@@ -668,6 +682,46 @@ functionptr codegen_findmethod(functionptr pc)
 }
 #endif
 
+#if defined(__ALPHA__)
+/*perhaps in the end I'll have to go for the tree version on alpha too, since this is insecure for eg segfault signals in native code,
+since it will still return an adress of a datasegment, but which will not be a valid one of a java method. This version is faster though (jowenn)*/
+void *codegen_findmethod(void *returnAdress)
+ {
+        void *result;
+        s8 d;
+        void *dataseg;
+        d=*((s4*)returnAdress);
+        d=d<<48;
+        d=d>>48;
+        dataseg=returnAdress+d;
+        d=*(((s4*)returnAdress)+1);
+        d=d>>16;
+        d=d-0x177b;
+        if (d==0) {
+                d=*(((s4*)returnAdress)+1);
+                d=d<<16;
+                dataseg=dataseg+d;
+        }
+        return dataseg;
+#if 0
+        ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
+        sll     t0,48,t0
+        sra     t0,48,t0              /* isolate offset                           */
+        addq    t0,ra,pv              /* compute update address                   */
+        ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
+        srl     t0,16,t0              /* isolate instruction code                 */
+        lda     t0,-0x177b(t0)        /* test for LDAH                            */
+        bne     t0,ex_stack_loop
+        ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(RA)         */
+        sll     t0,16,t0              /* compute high offset                      */
+        addl    t0,0,t0               /* sign extend high offset                  */
+        addq    t0,pv,pv              /* compute update address                   */
+        br      ex_stack_loop
+#endif
+}
+
+#endif
+
 
 static void codegen_finish(methodinfo *m, codegendata *cd, s4 mcodelen)
 {
@@ -708,7 +762,7 @@ static void codegen_finish(methodinfo *m, codegendata *cd, s4 mcodelen)
                jr = jr->next;
        }
 
-#ifdef __I386__
+#if defined(__I386__) || defined(__ALPHA__)
        /* line number table resolving */
        {
                linenumberref *lr;
@@ -804,43 +858,30 @@ static int reg_of_var(registerdata *rd, stackptr v, int tempregnum)
                if (!(v->flags & INMEMORY))
                        return(v->regoff);
                break;
+
        case STACKVAR:
                var = &(rd->interfaces[v->varnum][v->type]);
                v->regoff = var->regoff;
                if (!(var->flags & INMEMORY))
                        return(var->regoff);
                break;
+
        case LOCALVAR:
                var = &(rd->locals[v->varnum][v->type]);
                v->regoff = var->regoff;
                if (!(var->flags & INMEMORY))
                        return(var->regoff);
                break;
+
        case ARGVAR:
-               v->regoff = v->varnum;
-               if (IS_FLT_DBL_TYPE(v->type)) {
-                       if (v->varnum < rd->fltreg_argnum) {
-                               v->regoff = rd->argfltregs[v->varnum];
-                               return(rd->argfltregs[v->varnum]);
-                       }
-
-               } else {
-#if defined(__POWERPC__)
-                       if (v->varnum < rd->intreg_argnum - (IS_2_WORD_TYPE(v->type) != 0)) {
-#else
-                       if (v->varnum < rd->intreg_argnum) {
-#endif
-                               v->regoff = rd->argintregs[v->varnum];
-                               return (rd->argintregs[v->varnum]);
-                       }
-               }
-#if defined(__POWERPC__)
-               v->regoff += 6;
-#else
-               v->regoff -= rd->intreg_argnum;
-#endif
+               if (!(v->flags & INMEMORY))
+                       return(v->regoff);
                break;
        }
+#ifdef STATISTICS
+       if (opt_stat)
+               count_spills_read++;
+#endif
        v->flags |= INMEMORY;
        return tempregnum;
 }
@@ -954,17 +995,28 @@ static void codegen_resolve_native(methodinfo *m,void **insertionPoint,void *jmp
        void *lib;
        void *sym;
 
+#if defined(USE_THREADS)
   builtin_monitorenter((java_objectheader*) m);
+#endif
+
+#if defined(__X86_64__)
+  if ((*((s4*)jmpPatchTarget))==((s4)jmpTarget)) {
+#else
   if ((*jmpPatchTarget)==jmpTarget) {
+#endif
+
+#if defined(USE_THREADS)
     builtin_monitorexit((java_objectheader*) m);
+#endif
+
     return;
   }
-  log_text("trying to resolve a native method");
+  /*log_text("trying to resolve a native method");
   utf_display(m->class->name);
-  utf_display(m->name);
+  utf_display(m->name);*/
   
-  lib=dlopen(0,RTLD_NOW | RTLD_GLOBAL);
-  if (lib) {
+  lib=dlopen(0,RTLD_NOW | RTLD_GLOBAL); /* open the application execution image */
+  if (lib) { /* it did work -> good, otherwise fail with error*/
     int ok=0;
     /*generate the name of the native function in the form Java_package1_package2...._classname_methodname*/
     nativeLen=/*Java_*/5+strlen(m->class->name->text)+/*_*/1+strlen(m->name->text)+/*\0*/1;
@@ -989,38 +1041,51 @@ static void codegen_resolve_native(methodinfo *m,void **insertionPoint,void *jmp
 
 /*     printf("nativename: %s\n",nativeName); */
 
+    /*try to find the symbal fo the function */
     sym=dlsym(lib,nativeName);
     if (sym) {
-      ok=1;
-      log_text("resolved");
+      ok=1; /* it worked, everything fine */
+      /*log_text("resolved");*/
       MFREE(nativeName,char,nativeLen);
-    } else {
+    } else { /* we didn't find the symbol yet, try to resolve an overlaoded function (having the types in it's name*/
       size_t overloadedNativeLen=nativeLen+codegen_overloadPartLen(m->descriptor);
       char *overloadedNative=MNEW(char,overloadedNativeLen);
       sprintf(overloadedNative,"%s",nativeName);
       MFREE(nativeName,char,nativeLen);
       codegen_fillInOverloadPart(overloadedNative,m->descriptor);
-      log_text("symbol not found,trying harder (overloaded member ?)");
+      /*log_text("symbol not found,trying harder (overloaded member ?)");*/
       sym=dlsym(lib,overloadedNative);
       if (sym) {
         MFREE(overloadedNative,char,overloadedNativeLen);
-        ok=1;
-        log_text("resolved");
+        ok=1; /* we eventually found the native function -> everything ok*/
+        /*log_text("resolved");*/
       } else { 
+         /* we failed to find the native function within the execution image (app + loaded libraries) -> will cause an exit*/
+                dolog("\nnative function not found: %s",overloadedNative);
          MFREE(overloadedNative,char,overloadedNativeLen);
          log_text("It was not possible to find the native function implementation. Not even in overloading case");
       }
    }
+    /* patch the address of the native function into the stub and make the stub jump over this function call in the future */
     if (ok) {
       (*insertionPoint)=sym;
+#if defined(__X86_64__)
+      (*((s4*)jmpPatchTarget))=(s4)jmpTarget;
+#else
       (*jmpPatchTarget)=jmpTarget;
+#endif
+
+#if defined(USE_THREADS)
       builtin_monitorexit((java_objectheader *) m );
+#endif
+
       return;
     }
 
   } else log_text("library not found");
   
-
+  /* There was an error, either the app image could not be opened or the native does not exist in the application and the
+     loaded libraries. Show an additional error and exit the vm*/
   {
     char *info;
     size_t slen;
@@ -1028,7 +1093,10 @@ static void codegen_resolve_native(methodinfo *m,void **insertionPoint,void *jmp
     info=(char*)MNEW(char,slen);
     sprintf(info,"%s.%s%s",m->class->name->text,m->name->text,m->descriptor->text);
     
+#if defined(USE_THREADS)
     builtin_monitorexit((java_objectheader *) m );
+#endif
+
     throw_cacao_exception_exit(string_java_lang_LinkageError,
                                                        info);
   }
@@ -1037,6 +1105,8 @@ static void codegen_resolve_native(methodinfo *m,void **insertionPoint,void *jmp
 #endif
 
 
+#endif
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where