* src/vm/jit/arm/codegen.h (SPLIT_LOAD): Removed.
[cacao.git] / src / vm / jit / trace.c
index 5bc9e434970e2c08c95afe7edf089189a14c646f..6d036b08cb128530d9ca99dca5bbe3287d72f6d9 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/trace.c - Functions for tracing from java code.
 
-   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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Throwable.h"
 
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
 #include "toolbox/logging.h"
 
 #include "vm/global.h"
 #include "vm/stringlocal.h"
+#include "vm/jit/argument.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/trace.h"
 #include "vm/jit/show.h"
@@ -64,112 +63,18 @@ u4 _no_threads_tracejavacallcount= 0;
 #endif
 
 
-/* _array_load_param **********************************************************
-   Returns the argument specified by pd and td from one of the passed arrays
-   and returns it.
-
-*******************************************************************************/
-
-static imm_union _array_load_param(paramdesc *pd, typedesc *td, uint64_t *arg_regs, uint64_t *stack)
-{
-       imm_union ret;
-
-       switch (td->type) {
-               case TYPE_INT:
-               case TYPE_ADR:
-                       if (pd->inmemory) {
-#if (SIZEOF_VOID_P == 8)
-                               ret.l = (int64_t)stack[pd->index];
-#else
-                               ret.l = *(int32_t *)(stack + pd->index);
-#endif
-                       } else {
-                               ret.l = arg_regs[pd->index];
-                       }
-                       break;
-               case TYPE_LNG:
-                       if (pd->inmemory) {
-                               ret.l = (int64_t)stack[pd->index];
-                       } else {
-#if (SIZEOF_VOID_P == 8)
-                               ret.l = (int64_t)arg_regs[pd->index];
-#else
-                               ret.l = (int64_t)(
-                                       (arg_regs[GET_HIGH_REG(pd->index)] << 32) |
-                                       (arg_regs[GET_LOW_REG(pd->index)] & 0xFFFFFFFF)
-                               );
-#endif
-                       }
-                       break;
-               case TYPE_FLT:
-                       if (pd->inmemory) {
-                               ret.l = (int64_t)stack[pd->index];
-                       } else {
-                               ret.l = (int64_t)arg_regs[pd->index + INT_ARG_CNT];
-                       }
-                       break;
-               case TYPE_DBL:
-                       if (pd->inmemory) {
-                               ret.l = (int64_t)stack[pd->index];
-                       } else {
-                               ret.l = (int64_t)arg_regs[pd->index + INT_ARG_CNT];
-                       }
-                       break;
-       }
-
-       return ret;
-}
-
-/* _array_load_return_value ***************************************************
-
-   Loads the proper return value form the return registers array and returns it.
-
-*******************************************************************************/
-
-static imm_union _array_load_return_value(typedesc *td, uint64_t *return_regs)
-{
-       imm_union ret;
-
-       switch (td->type) {
-               case TYPE_INT:
-               case TYPE_ADR:
-                       ret.l = return_regs[0];
-                       break;
-               case TYPE_LNG:
-#if (SIZEOF_VOID_P == 8)
-                       ret.l = (int64_t)return_regs[0];
-#else
-                       ret.l = (int64_t)(
-                               (return_regs[0] << 32) | (return_regs[1] & 0xFFFFFFFF)
-                       );
-#endif
-                       break;
-               case TYPE_FLT:
-                       ret.l = (int64_t)return_regs[2];
-                       break;
-               case TYPE_DBL:
-                       ret.l = (int64_t)return_regs[2];
-                       break;
-       }
-
-       return ret;
-}
-
-
 /* trace_java_call_print_argument **********************************************
 
    XXX: Document me!
 
 *******************************************************************************/
 
-static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
-                                                                                       typedesc *paramtype, imm_union imu)
+static char *trace_java_call_print_argument(methodinfo *m, char *logtext, s4 *logtextlen, typedesc *paramtype, imm_union imu)
 {
-       java_object_t     *o;
-       classinfo         *c;
-       utf               *u;
-       u4                 len;
+       java_object_t *o;
+       classinfo     *c;
+       utf           *u;
+       u4             len;
 
        switch (paramtype->type) {
        case TYPE_INT:
@@ -203,14 +108,23 @@ static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
                sprintf(logtext + strlen(logtext), "0x%016lx", (ptrint) imu.l);
 #endif
 
-               /* cast to java.lang.Object */
+               /* Workaround for sun.misc.Unsafe methods.  In the future
+                  (exact GC) we should check if the address is on the GC
+                  heap. */
+
+               if ((m->clazz       != NULL) &&
+                       (m->clazz->name == utf_new_char("sun/misc/Unsafe")))
+                       break;
+
+               /* Cast to java.lang.Object. */
 
                o = (java_object_t *) (ptrint) imu.l;
 
-               /* check return argument for java.lang.Class or java.lang.String */
+               /* Check return argument for java.lang.Class or
+                  java.lang.String. */
 
                if (o != NULL) {
-                       if (o->vftbl->class == class_java_lang_String) {
+                       if (o->vftbl->clazz == class_java_lang_String) {
                                /* get java.lang.String object and the length of the
                                   string */
 
@@ -230,7 +144,7 @@ static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
                                strcat(logtext, "\")");
                        }
                        else {
-                               if (o->vftbl->class == class_java_lang_Class) {
+                               if (o->vftbl->clazz == class_java_lang_Class) {
                                        /* if the object returned is a java.lang.Class
                                           cast it to classinfo structure and get the name
                                           of the class */
@@ -243,7 +157,7 @@ static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
                                        /* if the object returned is not a java.lang.String or
                                           a java.lang.Class just print the name of the class */
 
-                                       u = o->vftbl->class->name;
+                                       u = o->vftbl->clazz->name;
                                }
 
                                len = strlen(" (Class = \"") + utf_bytes(u) + strlen("\")");
@@ -269,8 +183,8 @@ static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
  
    Traces an entry into a java method.
 
-   arg_regs: Array of size ARG_CNT containing all argument registers in
-   the same format as in asm_vm_call_method. The array is usually allocated
+   arg_regs: Array containing all argument registers as int64_t values in
+   the same order as listed in m->methoddesc. The array is usually allocated
    on the stack and used for restoring the argument registers later.
 
    stack: Pointer to first on stack argument in the same format passed to 
@@ -281,17 +195,16 @@ static char *trace_java_call_print_argument(char *logtext, s4 *logtextlen,
 void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
 {
        methoddesc *md;
-       paramdesc *pd;
-       typedesc *td;
-       imm_union arg;
+       imm_union   arg;
        char       *logtext;
        s4          logtextlen;
-       s4          dumpsize;
        s4          i;
        s4          pos;
+       int32_t     dumpmarker;
 
 #if defined(ENABLE_DEBUG_FILTER)
-       if (! show_filters_test_verbosecall_enter(m)) return;
+       if (!show_filters_test_verbosecall_enter(m))
+               return;
 #endif
 
 #if defined(ENABLE_VMLOG)
@@ -308,7 +221,7 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
                strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
                TRACEJAVACALLINDENT +
                strlen("called: ") +
-               utf_bytes(m->class->name) +
+               ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
                strlen(".") +
                utf_bytes(m->name) +
                utf_bytes(m->descriptor);
@@ -327,7 +240,8 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
                strlen(" TRANSIENT") +
                strlen(" NATIVE") +
                strlen(" INTERFACE") +
-               strlen(" ABSTRACT");
+               strlen(" ABSTRACT") +
+               strlen(" METHOD_BUILTIN");
 
        /* add maximal argument length */
 
@@ -339,7 +253,7 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
 
        /* allocate memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        logtext = DMNEW(char, logtextlen);
 
@@ -355,32 +269,33 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
 
        strcpy(logtext + pos, "called: ");
 
-       utf_cat_classname(logtext, m->class->name);
+       if (m->clazz != NULL)
+               utf_cat_classname(logtext, m->clazz->name);
+       else
+               strcat(logtext, "NULL");
        strcat(logtext, ".");
        utf_cat(logtext, m->name);
        utf_cat(logtext, m->descriptor);
 
-       if (m->flags & ACC_PUBLIC)       strcat(logtext, " PUBLIC");
-       if (m->flags & ACC_PRIVATE)      strcat(logtext, " PRIVATE");
-       if (m->flags & ACC_PROTECTED)    strcat(logtext, " PROTECTED");
-       if (m->flags & ACC_STATIC)       strcat(logtext, " STATIC");
-       if (m->flags & ACC_FINAL)        strcat(logtext, " FINAL");
-       if (m->flags & ACC_SYNCHRONIZED) strcat(logtext, " SYNCHRONIZED");
-       if (m->flags & ACC_VOLATILE)     strcat(logtext, " VOLATILE");
-       if (m->flags & ACC_TRANSIENT)    strcat(logtext, " TRANSIENT");
-       if (m->flags & ACC_NATIVE)       strcat(logtext, " NATIVE");
-       if (m->flags & ACC_INTERFACE)    strcat(logtext, " INTERFACE");
-       if (m->flags & ACC_ABSTRACT)     strcat(logtext, " ABSTRACT");
+       if (m->flags & ACC_PUBLIC)         strcat(logtext, " PUBLIC");
+       if (m->flags & ACC_PRIVATE)        strcat(logtext, " PRIVATE");
+       if (m->flags & ACC_PROTECTED)      strcat(logtext, " PROTECTED");
+       if (m->flags & ACC_STATIC)         strcat(logtext, " STATIC");
+       if (m->flags & ACC_FINAL)          strcat(logtext, " FINAL");
+       if (m->flags & ACC_SYNCHRONIZED)   strcat(logtext, " SYNCHRONIZED");
+       if (m->flags & ACC_VOLATILE)       strcat(logtext, " VOLATILE");
+       if (m->flags & ACC_TRANSIENT)      strcat(logtext, " TRANSIENT");
+       if (m->flags & ACC_NATIVE)         strcat(logtext, " NATIVE");
+       if (m->flags & ACC_INTERFACE)      strcat(logtext, " INTERFACE");
+       if (m->flags & ACC_ABSTRACT)       strcat(logtext, " ABSTRACT");
+       if (m->flags & ACC_METHOD_BUILTIN) strcat(logtext, " METHOD_BUILTIN");
 
        strcat(logtext, "(");
 
        for (i = 0; i < md->paramcount; ++i) {
-               pd = &md->params[i];
-               td = &md->paramtypes[i];
-               arg = _array_load_param(pd, td, arg_regs, stack);
-               logtext = trace_java_call_print_argument(
-                       logtext, &logtextlen, td, arg
-               );
+               arg = argument_jitarray_load(md, i, arg_regs, stack);
+               logtext = trace_java_call_print_argument(m, logtext, &logtextlen,
+                                                                                                &md->paramtypes[i], arg);
                if (i != (md->paramcount - 1)) {
                        strcat(logtext, ", ");
                }
@@ -392,7 +307,7 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 
        TRACEJAVACALLINDENT++;
 
@@ -402,13 +317,9 @@ void trace_java_call_enter(methodinfo *m, uint64_t *arg_regs, uint64_t *stack)
 
    Traces an exit form a java method.
 
-   return_regs: Array of size 3 containing return registers:
-     [0] : REG_RESULT
-     [1] : REG_RESULT2 (if available on architecture)
-     [2] : REG_FRESULT
+   return_regs: Array of size 1 containing return register.
    The array is usually allocated on the stack and used for restoring the
-   registers later. The format of the array is the same as the format of 
-   register arguments passed to asm_vm_call_method.
+   registers later.
 
 *******************************************************************************/
 
@@ -417,10 +328,10 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
        methoddesc *md;
        char       *logtext;
        s4          logtextlen;
-       s4          dumpsize;
        s4          i;
        s4          pos;
        imm_union   val;
+       int32_t     dumpmarker;
 
 #if defined(ENABLE_DEBUG_FILTER)
        if (!show_filters_test_verbosecall_exit(m))
@@ -448,7 +359,7 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
                strlen("-2147483647-") +        /* INT_MAX should be sufficient       */
                TRACEJAVACALLINDENT +
                strlen("finished: ") +
-               utf_bytes(m->class->name) +
+               ((m->clazz == NULL) ? strlen("NULL") : utf_bytes(m->clazz->name)) +
                strlen(".") +
                utf_bytes(m->name) +
                utf_bytes(m->descriptor) +
@@ -460,7 +371,7 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
 
        /* allocate memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        logtext = DMNEW(char, logtextlen);
 
@@ -475,25 +386,28 @@ void trace_java_call_exit(methodinfo *m, uint64_t *return_regs)
                logtext[pos++] = '\t';
 
        strcpy(logtext + pos, "finished: ");
-       utf_cat_classname(logtext, m->class->name);
+       if (m->clazz != NULL)
+               utf_cat_classname(logtext, m->clazz->name);
+       else
+               strcat(logtext, "NULL");
        strcat(logtext, ".");
        utf_cat(logtext, m->name);
        utf_cat(logtext, m->descriptor);
 
        if (!IS_VOID_TYPE(md->returntype.type)) {
                strcat(logtext, "->");
-               val = _array_load_return_value(&md->returntype, return_regs);
+               val = argument_jitreturn_load(md, return_regs);
 
                logtext =
-                       trace_java_call_print_argument(logtext, &logtextlen, &md->returntype, val);
+                       trace_java_call_print_argument(m, logtext, &logtextlen,
+                                                                                  &md->returntype, val);
        }
 
        log_text(logtext);
 
        /* release memory */
 
-       dump_release(dumpsize);
-
+       DRELEASE;
 }
 
 
@@ -507,14 +421,14 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
 {
        char *logtext;
        s4    logtextlen;
-       s4    dumpsize;
        codeinfo *code;
+       int32_t   dumpmarker;
 
        /* calculate message length */
 
        if (xptr) {
                logtextlen =
-                       strlen("Exception ") + utf_bytes(xptr->vftbl->class->name);
+                       strlen("Exception ") + utf_bytes(xptr->vftbl->clazz->name);
        } 
        else {
                logtextlen = strlen("Some Throwable");
@@ -524,7 +438,7 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
 
        if (m) {
                logtextlen +=
-                       utf_bytes(m->class->name) +
+                       utf_bytes(m->clazz->name) +
                        strlen(".") +
                        utf_bytes(m->name) +
                        utf_bytes(m->descriptor) +
@@ -537,10 +451,10 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
                logtextlen += strlen(")(0x12345678) at position 0x12345678 (");
 #endif
 
-               if (m->class->sourcefile == NULL)
+               if (m->clazz->sourcefile == NULL)
                        logtextlen += strlen("<NO CLASSFILE INFORMATION>");
                else
-                       logtextlen += utf_bytes(m->class->sourcefile);
+                       logtextlen += utf_bytes(m->clazz->sourcefile);
 
                logtextlen += strlen(":65536)");
 
@@ -553,13 +467,13 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
 
        /* allocate memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        logtext = DMNEW(char, logtextlen);
 
        if (xptr) {
                strcpy(logtext, "Exception ");
-               utf_cat_classname(logtext, xptr->vftbl->class->name);
+               utf_cat_classname(logtext, xptr->vftbl->clazz->name);
 
        } else {
                strcpy(logtext, "Some Throwable");
@@ -568,7 +482,7 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
        strcat(logtext, " thrown in ");
 
        if (m) {
-               utf_cat_classname(logtext, m->class->name);
+               utf_cat_classname(logtext, m->clazz->name);
                strcat(logtext, ".");
                utf_cat(logtext, m->name);
                utf_cat(logtext, m->descriptor);
@@ -609,10 +523,10 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
                                        (ptrint) code->entrypoint, (ptrint) pos);
 #endif
 
-                       if (m->class->sourcefile == NULL)
+                       if (m->clazz->sourcefile == NULL)
                                strcat(logtext, "<NO CLASSFILE INFORMATION>");
                        else
-                               utf_cat(logtext, m->class->sourcefile);
+                               utf_cat(logtext, m->clazz->sourcefile);
 
                        sprintf(logtext + strlen(logtext), ":%d)", 0);
                }
@@ -624,7 +538,7 @@ void trace_exception(java_object_t *xptr, methodinfo *m, void *pos)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 }
 
 
@@ -640,7 +554,7 @@ void trace_exception_builtin(java_object_t *xptr)
        java_lang_String    *s;
        char                *logtext;
        s4                   logtextlen;
-       s4                   dumpsize;
+       int32_t              dumpmarker;
 
        t = (java_lang_Throwable *) xptr;
 
@@ -654,7 +568,7 @@ void trace_exception_builtin(java_object_t *xptr)
 
        if (t) {
                logtextlen +=
-                       utf_bytes(xptr->vftbl->class->name);
+                       utf_bytes(xptr->vftbl->clazz->name);
                if (s) {
                        logtextlen += strlen(": ") +
                                u2_utflength(LLNI_field_direct(s, value)->data 
@@ -668,14 +582,14 @@ void trace_exception_builtin(java_object_t *xptr)
 
        /* allocate memory */
 
-       dumpsize = dump_size();
+       DMARKER;
 
        logtext = DMNEW(char, logtextlen);
 
        strcpy(logtext, "Builtin exception thrown: ");
 
        if (t) {
-               utf_cat_classname(logtext, xptr->vftbl->class->name);
+               utf_cat_classname(logtext, xptr->vftbl->clazz->name);
 
                if (s) {
                        char *buf;
@@ -694,7 +608,7 @@ void trace_exception_builtin(java_object_t *xptr)
 
        /* release memory */
 
-       dump_release(dumpsize);
+       DRELEASE;
 }