* src/vm/jit/md.h: Removed.
[cacao.git] / src / vm / jit / jit.c
index 3d2ce2f32dd8c6044ece75645f5c7c295d1a04b4..488103b81a61cd416cb1b26687df5944538065c2 100644 (file)
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 
 #include "vm/types.h"
 
+#include "md.h"
+
 #include "mm/memory.h"
 
 #include "native/native.h"
@@ -51,7 +54,6 @@
 #include "vm/jit/disass.h"
 #include "vm/jit/dseg.h"
 #include "vm/jit/jit.h"
-#include "vm/jit/md.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/reg.h"
 
 /* debug macros ***************************************************************/
 
 #if !defined(NDEBUG)
-#define DEBUG_JIT_COMPILEVERBOSE(x) \
-    do { \
-        if (compileverbose) { \
-            log_message_method(x, m); \
-        } \
+#define DEBUG_JIT_COMPILEVERBOSE(x)                            \
+    do {                                                                               \
+        if (compileverbose) {                                  \
+            log_message_method(x, m);                  \
+        }                                                                              \
     } while (0)
 #else
 #define DEBUG_JIT_COMPILEVERBOSE(x)    /* nothing */
 #endif
 
+#if !defined(NDEBUG)
+# define TRACECOMPILERCALLS()                                                          \
+       do {                                                                                                    \
+               if (opt_TraceCompilerCalls) {                                           \
+                       log_start();                                                                    \
+                       log_print("[JIT compiler started: method=");    \
+                       method_print(m);                                                                \
+                       log_print("]");                                                                 \
+                       log_finish();                                                                   \
+               }                                                                                                       \
+       } while (0)
+#else
+# define TRACECOMPILERCALLS()
+#endif
+
+
 /* the ICMD table ************************************************************/
 
 #if !defined(NDEBUG)
@@ -904,6 +921,19 @@ void jit_init(void)
        /* initialize code subsystem */
 
        (void) code_init();
+
+       /* Machine dependent initialization. */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (opt_intrp)
+               intrp_md_init();
+       else
+# endif
+               md_init();
+#else
+       intrp_md_init();
+#endif
 }
 
 
@@ -935,7 +965,8 @@ static u1 *do_nothing_function(void)
 
 jitdata *jit_jitdata_new(methodinfo *m)
 {
-       jitdata *jd;
+       jitdata  *jd;
+       codeinfo *code;
 
        /* allocate jitdata structure and fill it */
 
@@ -950,10 +981,23 @@ jitdata *jit_jitdata_new(methodinfo *m)
 
        /* Allocate codeinfo memory from the heap as we need to keep them. */
 
-       jd->code  = code_codeinfo_new(m);
+       code = code_codeinfo_new(m);
+
+       /* Set codeinfo flags. */
+
+#if defined(ENABLE_THREADS)
+       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               code_flag_synchronized(code);
+
+       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+               code_unflag_leafmethod(code);
+       else
+#endif
+               code_flag_leafmethod(code);
 
        /* initialize variables */
 
+       jd->code                 = code;
        jd->flags                = 0;
        jd->exceptiontable       = NULL;
        jd->exceptiontablelength = 0;
@@ -964,13 +1008,6 @@ jitdata *jit_jitdata_new(methodinfo *m)
        jd->returnblock          = NULL;
        jd->maxlocals            = m->maxlocals;
 
-#if defined(ENABLE_THREADS)
-       if (checksync && (m->flags & ACC_SYNCHRONIZED))
-               jd->isleafmethod = false;
-       else
-#endif
-               jd->isleafmethod = true;
-
        return jd;
 }
 
@@ -1025,6 +1062,8 @@ u1 *jit_compile(methodinfo *m)
                return m->code->entrypoint;
        }
 
+       TRACECOMPILERCALLS();
+
        STATISTICS(count_methods++);
 
 #if defined(ENABLE_STATISTICS)
@@ -1277,10 +1316,6 @@ static u1 *jit_compile_intern(jitdata *jd)
        code = jd->code;
        cd   = jd->cd;
        
-       /* print log message for compiled method */
-
-       DEBUG_JIT_COMPILEVERBOSE("Compiling: ");
-
 #if defined(ENABLE_DEBUG_FILTER)
        show_filters_apply(jd->m);
 #endif
@@ -1290,11 +1325,17 @@ static u1 *jit_compile_intern(jitdata *jd)
        if (m->flags & ACC_NATIVE) {
                functionptr f;
 
-               f = NULL;
+               f = native_method_resolve(m);
+
+               if (f == NULL)
+                       return NULL;
 
                code = codegen_generate_stub_native(m, f);
 
-               assert(!m->code); /* native methods are never recompiled */
+               /* Native methods are never recompiled. */
+               
+               assert(!m->code);
+
                m->code = code;
                
                return code->entrypoint;
@@ -1321,6 +1362,18 @@ static u1 *jit_compile_intern(jitdata *jd)
 
        RT_TIMING_GET_TIME(time_checks);
 
+#if defined(WITH_CLASSPATH_SUN)
+       /* Code for Sun's OpenJDK (see
+          hotspot/src/share/vm/classfile/verifier.cpp
+          (Verifier::is_eligible_for_verification)): Don't verify
+          dynamically-generated bytecodes. */
+
+# if defined(ENABLE_VERIFIER)
+       if (class_issubclass(m->class, class_sun_reflect_MagicAccessorImpl))
+               jd->flags &= ~JITDATA_FLAG_VERIFY;
+# endif
+#endif
+
        /* call the compiler passes ***********************************************/
 
        DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
@@ -1503,6 +1556,13 @@ static u1 *jit_compile_intern(jitdata *jd)
 
        DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
 
+#if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
+       /* activate replacement points inside newly created code */
+
+       if (opt_TestReplacement)
+               replace_activate_replacement_points(code, false);
+#endif
+
 #if !defined(NDEBUG)
 #if defined(ENABLE_DEBUG_FILTER)
        if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
@@ -1525,8 +1585,6 @@ static u1 *jit_compile_intern(jitdata *jd)
        }
 #endif
 
-       DEBUG_JIT_COMPILEVERBOSE("Compiling done: ");
-
        /* switch to the newly generated code */
 
        assert(code);
@@ -1566,10 +1624,11 @@ void jit_invalidate_code(methodinfo *m)
        codeinfo *code;
 
        code = m->code;
-       if (code == NULL || CODE_IS_INVALID(code))
+
+       if (code == NULL || code_is_invalid(code))
                return;
 
-       CODE_SETFLAG_INVALID(code);
+       code_flag_invalid(code);
 
        /* activate mappable replacement points */
 
@@ -1624,7 +1683,7 @@ codeinfo *jit_get_current_code(methodinfo *m)
 
        /* if we have valid code, return it */
 
-       if (m->code && CODE_IS_VALID(m->code))
+       if (m->code && !code_is_invalid(m->code))
                return m->code;
 
        /* otherwise: recompile */
@@ -1651,17 +1710,18 @@ codeinfo *jit_get_current_code(methodinfo *m)
 *******************************************************************************/
 
 #if defined(ENABLE_JIT)
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
 {
-       stackframeinfo  sfi;
-       u1             *entrypoint;
-       u1             *pa;
-       ptrint         *p;
+       stackframeinfo_t  sfi;
+       u1               *entrypoint;
+       u1               *pa;
+       ptrint           *p;
 
        /* create the stackframeinfo (subtract 1 from RA as it points to the */
        /* instruction after the call)                                       */
 
-       stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra-1);
+       stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
 
        /* actually compile the method */
 
@@ -1669,7 +1729,7 @@ u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
 
        /* remove the stackframeinfo */
 
-       stacktrace_remove_stackframeinfo(&sfi);
+       stacktrace_stackframeinfo_remove(&sfi);
 
        /* there was a problem during compilation */
 
@@ -1678,7 +1738,7 @@ u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
 
        /* get the method patch address */
 
-       pa = md_get_method_patch_address(ra, &sfi, mptr);
+       pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
 
        /* patch the method entry point */
 
@@ -1692,6 +1752,51 @@ u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
 
        return entrypoint;
 }
+#endif
+
+/* jit_compile_handle **********************************************************
+
+   This method is called from the appropriate signal handler which
+   handles compiler-traps and does the following:
+
+     - compile the method
+     - patch the entrypoint of the method into the calculated address in
+       the JIT code
+     - flush the instruction cache
+
+*******************************************************************************/
+
+void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
+{
+       void      *newpv;                               /* new compiled method PV */
+       void      *pa;                                           /* patch address */
+       uintptr_t *p;                                      /* convenience pointer */
+
+       /* Compile the method. */
+
+       newpv = jit_compile(m);
+
+       /* There was a problem during compilation. */
+
+       if (newpv == NULL)
+               return NULL;
+
+       /* Get the method patch address. */
+
+       pa = md_jit_method_patch_address(pv, ra, mptr);
+
+       /* Patch the method entry point. */
+
+       p = (uintptr_t *) pa;
+
+       *p = (uintptr_t) newpv;
+
+       /* Flush both caches. */
+
+       md_cacheflush(pa, SIZEOF_VOID_P);
+
+       return newpv;
+}
 #endif /* defined(ENABLE_JIT) */