Merged?
[cacao.git] / src / vm / jit / stacktrace.c
index e13c47d0844b9ef486cd6fa52937aac7d59a7f1b..8a58dce8c98c537a87b303d0bf8254bbae06b7ed 100644 (file)
@@ -56,6 +56,7 @@
 
 #include "toolbox/logging.h"
 
+#include "vm/array.h"
 #include "vm/builtin.h"
 #include "vm/cycles-stats.h"
 #include "vm/exceptions.h"
@@ -83,76 +84,14 @@ CYCLES_STATS_DECLARE(stacktrace_getCurrentClass ,40,5000)
 CYCLES_STATS_DECLARE(stacktrace_getStack        ,40,10000)
 
 
-/* stacktrace_create_stackframeinfo ********************************************
+/* stacktrace_stackframeinfo_add ***********************************************
 
-   Creates an stackframe info structure for inline code in the
-   interpreter.
+   Fills a stackframe info structure with the given or calculated
+   values and adds it to the chain.
 
 *******************************************************************************/
 
-#if defined(ENABLE_INTRP)
-void stacktrace_create_stackframeinfo(stackframeinfo *sfi, u1 *pv, u1 *sp,
-                                                                         u1 *ra)
-{
-       stackframeinfo **psfi;
-       methodinfo      *m;
-       codeinfo        *code;
-
-       /* get current stackframe info pointer */
-
-       psfi = &STACKFRAMEINFO;
-
-       /* if we don't have pv handy */
-
-       if (pv == NULL) {
-#if defined(ENABLE_INTRP)
-               if (opt_intrp)
-                       pv = codegen_get_pv_from_pc(ra);
-               else
-#endif
-                       {
-#if defined(ENABLE_JIT)
-                               pv = md_codegen_get_pv_from_pc(ra);
-#endif
-                       }
-       }
-
-       /* get codeinfo pointer from data segment */
-
-       code = *((codeinfo **) (pv + CodeinfoPointer));
-
-       /* For asm_vm_call_method the codeinfo pointer is NULL. */
-
-       m = (code == NULL) ? NULL : code->m;
-
-       /* fill new stackframe info structure */
-
-       sfi->prev   = *psfi;
-       sfi->method = m;
-       sfi->pv     = pv;
-       sfi->sp     = sp;
-       sfi->ra     = ra;
-
-       /* xpc is the same as ra, but is required in stacktrace_create */
-
-       sfi->xpc    = ra;
-
-       /* store new stackframe info pointer */
-
-       *psfi = sfi;
-}
-#endif /* defined(ENABLE_INTRP) */
-
-
-/* stacktrace_create_extern_stackframeinfo *************************************
-
-   Creates an stackframe info structure for an extern exception
-   (hardware or assembler).
-
-*******************************************************************************/
-
-void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
-                                                                                        u1 *sp, u1 *ra, u1 *xpc)
+void stacktrace_stackframeinfo_add(stackframeinfo *sfi, u1 *pv, u1 *sp, u1 *ra, u1 *xpc)
 {
        stackframeinfo **psfi;
        methodinfo      *m;
@@ -247,6 +186,17 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
        sfi->ra     = ra;
        sfi->xpc    = xpc;
 
+#if !defined(NDEBUG)
+       if (opt_DebugStackFrameInfo) {
+               log_start();
+               log_print("[stackframeinfo add   : sfi=%p, method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=",
+                                 sfi, sfi->method, sfi->pv, sfi->sp, sfi->ra, sfi->xpc);
+               method_print(sfi->method);
+               log_print("]");
+               log_finish();
+       }
+#endif
+
        /* Store new stackframeinfo pointer. */
 
        *psfi = sfi;
@@ -259,13 +209,14 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 }
 
 
-/* stacktrace_remove_stackframeinfo ********************************************
+/* stacktrace_stackframeinfo_remove ********************************************
 
-   Remove the topmost stackframeinfo in the current thread.
+   Remove the given stackframeinfo from the chain in the current
+   thread.
 
 *******************************************************************************/
 
-void stacktrace_remove_stackframeinfo(stackframeinfo *sfi)
+void stacktrace_stackframeinfo_remove(stackframeinfo *sfi)
 {
        stackframeinfo **psfi;
 
@@ -278,6 +229,17 @@ void stacktrace_remove_stackframeinfo(stackframeinfo *sfi)
 
        psfi = &STACKFRAMEINFO;
 
+#if !defined(NDEBUG)
+       if (opt_DebugStackFrameInfo) {
+               log_start();
+               log_print("[stackframeinfo remove: sfi=%p, method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=",
+                                 sfi, sfi->method, sfi->pv, sfi->sp, sfi->ra, sfi->xpc);
+               method_print(sfi->method);
+               log_print("]");
+               log_finish();
+       }
+#endif
+
        /* restore the old pointer */
 
        *psfi = sfi->prev;
@@ -409,7 +371,9 @@ static inline void stacktrace_stack_walk(stackframeinfo *sfi)
        framesize = *((uint32_t *) (((intptr_t) pv) + FrameSize));
 
        /* Get the RA of the current stack frame (RA to the parent Java
-          method). */
+          method) if the current method is a non-leaf method.  Otherwise
+          the value in the stackframeinfo is correct (from the signal
+          handler). */
 
 #if defined(ENABLE_JIT)
 # if defined(ENABLE_INTRP)
@@ -417,7 +381,16 @@ static inline void stacktrace_stack_walk(stackframeinfo *sfi)
                ra = intrp_md_stacktrace_get_returnaddress(sp, framesize);
        else
 # endif
-               ra = md_stacktrace_get_returnaddress(sp, framesize);
+               {
+                       /* TODO Remove jd->isleafmethod and use the flags in
+                          codeinfo. */
+
+/*                     if (!CODE_IS_LEAFMETHOD(m->code)) { */
+                       int32_t isleafmethod = *((int32_t *) (((intptr_t) pv) + IsLeaf));
+                       if (!isleafmethod) {
+                               ra = md_stacktrace_get_returnaddress(sp, framesize);
+                       }
+               }
 #else
        ra = intrp_md_stacktrace_get_returnaddress(sp, framesize);
 #endif
@@ -860,8 +833,8 @@ java_handle_objectarray_t *stacktrace_getStack(void)
 
        /* set up the 2-dimensional array */
 
-       LLNI_objectarray_element_set(oa, 0, classes);
-       LLNI_objectarray_element_set(oa, 1, methodnames);
+       array_objectarray_element_set(oa, 0, (java_handle_t *) classes);
+       array_objectarray_element_set(oa, 1, (java_handle_t *) methodnames);
 
        /* iterate over all stacktrace entries */
 
@@ -875,7 +848,7 @@ java_handle_objectarray_t *stacktrace_getStack(void)
                if (string == NULL)
                        goto return_NULL;
 
-               LLNI_objectarray_element_set(methodnames, i, string);
+               array_objectarray_element_set(methodnames, i, string);
        }
 
        /* return the 2-dimensional array */