Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: stacktrace.c 7323 2007-02-11 17:52:12Z pm $
-
*/
#include "mm/gc-common.h"
#include "mm/memory.h"
+#include "vm/jit/stacktrace.h"
+
#include "vm/global.h" /* required here for native includes */
#include "native/jni.h"
+#include "native/llni.h"
#include "native/include/java_lang_Throwable.h"
#if defined(WITH_CLASSPATH_GNU)
/* global variables ***********************************************************/
-
#if !defined(ENABLE_THREADS)
stackframeinfo *_no_threads_stackframeinfo = NULL;
#endif
/* get current stackframe info pointer */
- psfi = STACKFRAMEINFO;
+ psfi = &STACKFRAMEINFO;
/* if we don't have pv handy */
#endif /* defined(ENABLE_INTRP) */
-/* stacktrace_create_inline_stackframeinfo *************************************
-
- Creates an stackframe info structure for an inline exception stub.
-
-*******************************************************************************/
-
-void stacktrace_create_inline_stackframeinfo(stackframeinfo *sfi, u1 *pv,
- u1 *sp, u1 *ra, u1 *xpc)
-{
- stackframeinfo **psfi;
-
- /* get current stackframe info pointer */
-
- psfi = STACKFRAMEINFO;
-
-#if defined(ENABLE_INTRP)
- if (opt_intrp) {
- /* if we don't have pv handy */
-
- if (pv == NULL)
- pv = codegen_get_pv_from_pc(ra);
-
- }
-#endif
-
- /* fill new stackframe info structure */
-
- sfi->prev = *psfi;
- sfi->method = NULL;
- sfi->pv = pv;
- sfi->sp = sp;
- sfi->ra = ra;
- sfi->xpc = xpc;
-
- /* store new stackframe info pointer */
-
- *psfi = sfi;
-}
-
-
/* stacktrace_create_extern_stackframeinfo *************************************
Creates an stackframe info structure for an extern exception
u1 *sp, u1 *ra, u1 *xpc)
{
stackframeinfo **psfi;
-#if !defined(__I386__) && !defined(__X86_64__) && !defined(__S390__)
+#if !defined(__I386__) && !defined(__X86_64__) && !defined(__S390__) && !defined(__M68K__)
bool isleafmethod;
#endif
#if defined(ENABLE_JIT)
/* get current stackframe info pointer */
- psfi = STACKFRAMEINFO;
+ psfi = &STACKFRAMEINFO;
/* sometimes we don't have pv handy (e.g. in asmpart.S:
L_asm_call_jit_compiler_exception or in the interpreter). */
#endif
{
#if defined(ENABLE_JIT)
+# if defined(__SPARC_64__)
+ pv = md_get_pv_from_stackframe(sp);
+# else
pv = md_codegen_get_pv_from_pc(ra);
+# endif
#endif
}
}
if (!opt_intrp) {
# endif
-# if defined(__I386__) || defined(__X86_64__) || defined(__S390__)
+# if defined(__I386__) || defined(__X86_64__) || defined(__S390__) || defined(__M68K__)
/* On i386 and x86_64 we always have to get the return address
from the stack. */
+ /* m68k has return address on stack always */
/* On S390 we use REG_RA as REG_ITMP3, so we have always to get
the RA from stack. */
/* get current stackframe info pointer */
- psfi = STACKFRAMEINFO;
+ psfi = &STACKFRAMEINFO;
/* fill new stackframe info structure */
/* get current stackframe info pointer */
- psfi = STACKFRAMEINFO;
+ psfi = &STACKFRAMEINFO;
/* restore the old pointer */
}
-/* stacktrace_inline_arithmeticexception ***************************************
-
- Creates an ArithemticException for inline stub.
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_inline_arithmeticexception(u1 *pv, u1 *sp,
- u1 *ra, u1 *xpc)
-{
- stackframeinfo sfi;
- java_objectheader *o;
-
- /* create stackframeinfo */
-
- stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
- /* create exception */
-
- o = exceptions_new_arithmeticexception();
-
- /* remove stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- return o;
-}
-
-
-/* stacktrace_inline_arrayindexoutofboundsexception ****************************
-
- Creates an ArrayIndexOutOfBoundsException for inline stub.
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_inline_arrayindexoutofboundsexception(u1 *pv,
- u1 *sp,
- u1 *ra,
- u1 *xpc,
- s4 index)
-{
- stackframeinfo sfi;
- java_objectheader *o;
-
- /* create stackframeinfo */
-
- stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
- /* create exception */
-
- o = exceptions_new_arrayindexoutofboundsexception(index);
-
- /* remove stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- return o;
-}
-
-
-/* stacktrace_inline_arraystoreexception ***************************************
-
- Creates an ArrayStoreException for inline stub.
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_inline_arraystoreexception(u1 *pv, u1 *sp, u1 *ra,
- u1 *xpc)
-{
- stackframeinfo sfi;
- java_objectheader *o;
-
- /* create stackframeinfo */
-
- stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
- /* create exception */
-
- o = exceptions_new_arraystoreexception();
-
- /* remove stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- return o;
-}
-
-
-/* stacktrace_inline_classcastexception ****************************************
-
- Creates an ClassCastException for inline stub.
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_inline_classcastexception(u1 *pv, u1 *sp, u1 *ra,
- u1 *xpc,
- java_objectheader *o)
-{
- stackframeinfo sfi;
- java_objectheader *e;
-
- /* create stackframeinfo */
-
- stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
- /* create exception */
-
- e = exceptions_new_classcastexception(o);
-
- /* remove stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- return e;
-}
-
-
-/* stacktrace_inline_nullpointerexception **************************************
-
- Creates an NullPointerException for inline stub.
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_inline_nullpointerexception(u1 *pv, u1 *sp,
- u1 *ra, u1 *xpc)
-{
- stackframeinfo sfi;
- java_objectheader *o;
-
- /* create stackframeinfo */
-
- stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
- /* create exception */
-
- o = exceptions_new_nullpointerexception();
-
- /* remove stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- return o;
-}
-
-
-/* stacktrace_inline_fillInStackTrace ******************************************
-
- Fills in the correct stacktrace into an existing exception object
- (this one is for inline exception stubs).
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_inline_fillInStackTrace(u1 *pv, u1 *sp, u1 *ra,
- u1 *xpc)
-{
- stackframeinfo sfi;
- java_objectheader *o;
- methodinfo *m;
-
- /* create stackframeinfo */
-
- stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
- /* get exception */
-
- o = *exceptionptr;
- assert(o);
-
- /* clear exception */
-
- *exceptionptr = NULL;
-
- /* resolve methodinfo pointer from exception object */
-
-#if defined(ENABLE_JAVASE)
- m = class_resolvemethod(o->vftbl->class,
- utf_fillInStackTrace,
- utf_void__java_lang_Throwable);
-#elif defined(ENABLE_JAVAME_CLDC1_1)
- m = class_resolvemethod(o->vftbl->class,
- utf_fillInStackTrace,
- utf_void__void);
-#else
-#error IMPLEMENT ME!
-#endif
-
- /* call function */
-
- (void) vm_call_method(m, o);
-
- /* remove stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- return o;
-}
-
-
-/* stacktrace_hardware_arithmeticexception *************************************
-
- Creates an ArithemticException for inline stub.
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_hardware_arithmeticexception(u1 *pv, u1 *sp,
- u1 *ra, u1 *xpc)
-{
- stackframeinfo sfi;
- java_objectheader *o;
-
- /* create stackframeinfo */
-
- stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
- /* create exception */
-
- o = exceptions_new_arithmeticexception();
-
- /* remove stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- return o;
-}
-
-
-/* stacktrace_hardware_nullpointerexception ************************************
-
- Creates an NullPointerException for the SIGSEGV signal handler.
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_hardware_nullpointerexception(u1 *pv, u1 *sp,
- u1 *ra, u1 *xpc)
-{
- stackframeinfo sfi;
- java_objectheader *o;
-
- /* create stackframeinfo */
-
- stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
- /* create exception */
-
- o = exceptions_new_nullpointerexception();
-
- /* remove stackframeinfo */
-
- stacktrace_remove_stackframeinfo(&sfi);
-
- return o;
-}
-
-
/* stacktrace_add_entry ********************************************************
Adds a new entry to the stacktrace buffer.
/* stacktrace_create ***********************************************************
Generates a stacktrace from the thread passed into a
- stacktracebuffer. The stacktracebuffer is allocated on the GC
- heap.
+ stacktracebuffer. The stacktracebuffer is allocated on the
+ dump memory.
+
+ NOTE: The first element in the stackframe chain must always be a
+ native stackframeinfo (e.g. VMThrowable.fillInStackTrace() is
+ a native function).
RETURN VALUE:
pointer to the stacktracebuffer, or
- NULL if an exception has been thrown
+ NULL if there is no stacktrace available for the
+ given thread.
*******************************************************************************/
-stacktracebuffer *stacktrace_create(threadobject* thread)
+stacktracebuffer *stacktrace_create(stackframeinfo *sfi)
{
stacktracebuffer *stb;
- stackframeinfo *sfi;
methodinfo *m;
codeinfo *code;
u1 *pv;
stb->used = 0;
stb->entries = DMNEW(stacktrace_entry, STACKTRACE_CAPACITY_DEFAULT);
- /* The first element in the stackframe chain must always be a
- native stackframeinfo (VMThrowable.fillInStackTrace is a native
- function). */
-
- /* We don't use the STACKFRAMEINFO macro here, as we have to use
- the passed thread. */
-
-#if defined(ENABLE_THREADS)
- sfi = thread->_stackframeinfo;
-#else
- sfi = _no_threads_stackframeinfo;
-#endif
-
#define PRINTMETHODS 0
#if PRINTMETHODS
/* Set stack pointer to stackframe of parent Java
function of the current Java function. */
-#if defined(__I386__) || defined (__X86_64__)
+#if defined(__I386__) || defined (__X86_64__) || defined (__M68K__)
sp += framesize + SIZEOF_VOID_P;
+#elif defined(__SPARC_64__)
+ sp = md_get_framepointer(sp);
#else
sp += framesize;
#endif
#endif
{
#if defined(ENABLE_JIT)
+# if defined(__SPARC_64__)
+ sp = md_get_framepointer(sp);
+ pv = md_get_pv_from_stackframe(sp);
+# else
pv = md_codegen_get_pv_from_pc(ra);
+# endif
#endif
}
else
#endif
{
-#if defined(__I386__) || defined (__X86_64__)
+#if defined(__I386__) || defined (__X86_64__) || defined (__M68K__)
sp += framesize + SIZEOF_VOID_P;
+#elif defined(__SPARC_64__)
+ /* already has the new sp */
#else
sp += framesize;
#endif
/* return the stacktracebuffer */
- return stb;
+ if (stb->used == 0)
+ return NULL;
+ else
+ return stb;
}
/* create a stacktrace from the current thread */
- stb = stacktrace_create(THREADOBJECT);
- if (!stb)
+ stb = stacktrace_create(STACKFRAMEINFO);
+
+ if (stb == NULL)
goto return_NULL;
/* allocate memory from the GC heap and copy the stacktrace buffer */
*******************************************************************************/
-java_objectarray *stacktrace_getClassContext(void)
+java_handle_objectarray_t *stacktrace_getClassContext(void)
{
- stacktracebuffer *stb;
- stacktrace_entry *ste;
- java_objectarray *oa;
- s4 oalength;
- s4 i;
- s4 dumpsize;
+ stacktracebuffer *stb;
+ stacktrace_entry *ste;
+ java_handle_objectarray_t *oa;
+ s4 oalength;
+ s4 i;
+ s4 dumpsize;
CYCLES_STATS_DECLARE_AND_START
/* mark start of dump memory area */
/* create a stacktrace for the current thread */
- stb = stacktrace_create(THREADOBJECT);
- if (!stb)
+ stb = stacktrace_create(STACKFRAMEINFO);
+
+ if (stb == NULL)
goto return_NULL;
/* calculate the size of the Class array */
continue;
}
- oa->data[i] = (java_objectheader *) ste->method->class;
+ oa->data[i] = (java_object_t *) ste->method->class;
}
/* release dump memory */
/* create a stacktrace for the current thread */
- stb = stacktrace_create(THREADOBJECT);
- if (!stb)
+ stb = stacktrace_create(STACKFRAMEINFO);
+
+ if (stb == NULL)
goto return_NULL; /* XXX exception: how to distinguish from normal NULL return? */
/* iterate over all stacktrace entries and find the first suitable
*******************************************************************************/
#if defined(ENABLE_JAVASE)
-java_objectarray *stacktrace_getStack(void)
+java_handle_objectarray_t *stacktrace_getStack(void)
{
- stacktracebuffer *stb;
- stacktrace_entry *ste;
- java_objectarray *oa;
- java_objectarray *classes;
- java_objectarray *methodnames;
- classinfo *c;
- java_objectheader *string;
- s4 i;
- s4 dumpsize;
+ stacktracebuffer *stb;
+ stacktrace_entry *ste;
+ java_handle_objectarray_t *oa;
+ java_handle_objectarray_t *classes;
+ java_handle_objectarray_t *methodnames;
+ classinfo *c;
+ java_handle_t *string;
+ s4 i;
+ s4 dumpsize;
CYCLES_STATS_DECLARE_AND_START
/* mark start of dump memory area */
/* create a stacktrace for the current thread */
- stb = stacktrace_create(THREADOBJECT);
+ stb = stacktrace_create(STACKFRAMEINFO);
if (stb == NULL)
goto return_NULL;
/* set up the 2-dimensional array */
- oa->data[0] = (java_objectheader *) classes;
- oa->data[1] = (java_objectheader *) methodnames;
+ oa->data[0] = (java_object_t *) classes;
+ oa->data[1] = (java_object_t *) methodnames;
/* iterate over all stacktrace entries */
for (i = 0, ste = &(stb->entries[0]); i < stb->used; i++, ste++) {
c = ste->method->class;
- classes->data[i] = (java_objectheader *) c;
+ classes->data[i] = (java_object_t *) c;
string = javastring_new(ste->method->name);
}
-/* stacktrace_dump_trace *******************************************************
-
- This method is call from signal_handler_sigusr1 to dump the
- stacktrace of the current thread to stdout.
-
-*******************************************************************************/
-
-void stacktrace_dump_trace(threadobject *thread)
-{
- stacktracebuffer *stb;
- s4 dumpsize;
-
- /* mark start of dump memory area */
-
- dumpsize = dump_size();
-
- /* create a stacktrace for the current thread */
-
- stb = stacktrace_create(thread);
-
- /* print stacktrace */
-
- if (stb != NULL)
- stacktrace_print_trace_from_buffer(stb);
- else {
- puts("\t<<No stacktrace available>>");
- fflush(stdout);
- }
-
- dump_release(dumpsize);
-}
-
-
/* stacktrace_print_trace ******************************************************
Print the stacktrace of a given exception. More or less a wrapper
*******************************************************************************/
-void stacktrace_print_trace(java_objectheader *xptr)
+void stacktrace_print_trace(java_handle_t *xptr)
{
java_lang_Throwable *t;
#if defined(WITH_CLASSPATH_GNU)
/* now print the stacktrace */
#if defined(WITH_CLASSPATH_GNU)
- vmt = t->vmState;
- stc = (stacktracecontainer *) vmt->vmData;
- stb = &(stc->stb);
-#elif defined(WITH_CLASSPATH_CLDC1_1)
+ LLNI_field_get_ref(t, vmState, vmt);
+ stc = (stacktracecontainer *) LLNI_field_direct(vmt, vmData);
+#elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1)
stc = (stacktracecontainer *) t->backtrace;
- stb = &(stc->stb);
+#else
+# error unknown classpath configuration
#endif
+ stb = &(stc->stb);
+
stacktrace_print_trace_from_buffer(stb);
}