#include "toolbox/logging.h"
+#include "vm/array.h"
#include "vm/builtin.h"
#include "vm/cycles-stats.h"
#include "vm/exceptions.h"
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;
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;
}
-/* 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;
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;
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)
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
/* 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 */
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 */