* Removed all Id tags.
[cacao.git] / src / vm / jit / stacktrace.c
index aaf44661df70d64d8ae0f43a933a664db97a252c..98e96d149af0121bbf9933d24e52524131b7824b 100644 (file)
@@ -1,6 +1,6 @@
-/* src/vm/jit/stacktrace.c - machine independet stacktrace system
+/* src/vm/jit/stacktrace.c - machine independent stacktrace system
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Joseph Wenninger
-
-   Changes: Christian Thalinger
-            Edwin Steiner
-
-   $Id: stacktrace.c 5085 2006-07-08 14:20:59Z twisti $
-
 */
 
 
 
 #include "vm/types.h"
 
-#include "mm/boehm.h"
+#include "mm/gc-common.h"
 #include "mm/memory.h"
-#include "native/native.h"
+
+#include "vm/jit/stacktrace.h"
 
 #include "vm/global.h"                   /* required here for native includes */
-#include "native/include/java_lang_ClassLoader.h"
+#include "native/jni.h"
+#include "native/llni.h"
 #include "native/include/java_lang_Throwable.h"
-#include "native/include/java_lang_VMThrowable.h"
+
+#if defined(WITH_CLASSPATH_GNU)
+# include "native/include/java_lang_VMThrowable.h"
+#endif
 
 #if defined(ENABLE_THREADS)
 # include "threads/native/threads.h"
 #endif
 
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
+#include "vm/cycles-stats.h"
 #include "vm/exceptions.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/methodheader.h"
-#include "vm/cycles-stats.h"
-
-
-/* linenumbertable_entry ******************************************************/
 
-/* Keep the type of line the same as the pointer type, otherwise we
-   run into alignment troubles (like on MIPS64). */
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
 
-typedef struct linenumbertable_entry linenumbertable_entry;
-
-struct linenumbertable_entry {
-       ptrint  line;               /* NOTE: see doc/inlining_stacktrace.txt for  */
-       u1     *pc;                 /*       special meanings of line and pc.     */
-};
 
 /* global variables ***********************************************************/
-
 #if !defined(ENABLE_THREADS)
 stackframeinfo *_no_threads_stackframeinfo = NULL;
 #endif
@@ -113,19 +99,19 @@ void stacktrace_create_stackframeinfo(stackframeinfo *sfi, u1 *pv, u1 *sp,
 
        /* get current stackframe info pointer */
 
-       psfi = STACKFRAMEINFO;
+       psfi = &STACKFRAMEINFO;
 
        /* if we don't have pv handy */
 
        if (pv == NULL) {
 #if defined(ENABLE_INTRP)
                if (opt_intrp)
-                       pv = codegen_findmethod(ra);
+                       pv = codegen_get_pv_from_pc(ra);
                else
 #endif
                        {
 #if defined(ENABLE_JIT)
-                               pv = md_codegen_findmethod(ra);
+                               pv = md_codegen_get_pv_from_pc(ra);
 #endif
                        }
        }
@@ -157,46 +143,6 @@ void stacktrace_create_stackframeinfo(stackframeinfo *sfi, u1 *pv, u1 *sp,
 #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_findmethod(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
@@ -208,7 +154,7 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
                                                                                         u1 *sp, u1 *ra, u1 *xpc)
 {
        stackframeinfo **psfi;
-#if !defined(__I386__) && !defined(__X86_64__)
+#if !defined(__I386__) && !defined(__X86_64__) && !defined(__S390__) && !defined(__M68K__)
        bool             isleafmethod;
 #endif
 #if defined(ENABLE_JIT)
@@ -217,7 +163,7 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 
        /* 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). */
@@ -225,12 +171,16 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
        if (pv == NULL) {
 #if defined(ENABLE_INTRP)
                if (opt_intrp)
-                       pv = codegen_findmethod(ra);
+                       pv = codegen_get_pv_from_pc(ra);
                else
 #endif
                        {
 #if defined(ENABLE_JIT)
-                               pv = md_codegen_findmethod(ra);
+# if defined(__SPARC_64__)
+                               pv = md_get_pv_from_stackframe(sp);
+# else
+                               pv = md_codegen_get_pv_from_pc(ra);
+# endif
 #endif
                        }
        }
@@ -241,9 +191,12 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 
        if (!opt_intrp) {
 # endif
-# if defined(__I386__) || defined(__X86_64__)
+# 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. */
 
                framesize = *((u4 *) (pv + FrameSize));
 
@@ -305,7 +258,7 @@ void stacktrace_create_native_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 
        /* get current stackframe info pointer */
 
-       psfi = STACKFRAMEINFO;
+       psfi = &STACKFRAMEINFO;
 
        /* fill new stackframe info structure */
 
@@ -334,7 +287,7 @@ void stacktrace_remove_stackframeinfo(stackframeinfo *sfi)
 
        /* get current stackframe info pointer */
 
-       psfi = STACKFRAMEINFO;
+       psfi = &STACKFRAMEINFO;
 
        /* restore the old pointer */
 
@@ -342,250 +295,6 @@ void stacktrace_remove_stackframeinfo(stackframeinfo *sfi)
 }
 
 
-/* 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 = 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 = 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 = 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)
-{
-       stackframeinfo     sfi;
-       java_objectheader *o;
-
-       /* create stackframeinfo */
-
-       stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
-       /* create exception */
-
-       o = new_classcastexception();
-
-       /* remove stackframeinfo */
-
-       stacktrace_remove_stackframeinfo(&sfi);
-
-       return o;
-}
-
-
-/* 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 = 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 */
-
-       m = class_resolvemethod(o->vftbl->class,
-                                                       utf_fillInStackTrace,
-                                                       utf_void__java_lang_Throwable);
-
-       /* 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 = 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 = new_nullpointerexception();
-
-       /* remove stackframeinfo */
-
-       stacktrace_remove_stackframeinfo(&sfi);
-
-       return o;
-}
-
-
 /* stacktrace_add_entry ********************************************************
 
    Adds a new entry to the stacktrace buffer.
@@ -622,94 +331,6 @@ static void stacktrace_add_entry(stacktracebuffer *stb, methodinfo *m, u2 line)
 }
 
 
-/* stacktrace_add_method_intern ************************************************
-
-   This function is used by stacktrace_add_method to search the line number
-   table for the line corresponding to a given pc. The function recurses for
-   inlined methods.
-
-*******************************************************************************/
-
-static bool stacktrace_add_method_intern(stacktracebuffer *stb, 
-                                                                                methodinfo *m, 
-                                                                                linenumbertable_entry *lntentry,
-                                                                                ptrint lntsize,
-                                                                                u1 *pc)
-{
-       linenumbertable_entry *lntinline;   /* special entry for inlined method */
-
-       assert(stb);
-       assert(lntentry);
-
-       /* Find the line number for the specified PC (going backwards
-          in the linenumber table). The linenumber table size is zero
-          in native stubs. */
-
-       for (; lntsize > 0; lntsize--, lntentry--) {
-
-               /* did we reach the current line? */
-
-               /* Note: In case of inlining this may actually compare the pc
-                  against a methodinfo *, yielding a non-sensical
-                  result. This is no problem, however, as we ignore such
-                  entries in the switch below. This way we optimize for the
-                  common case (ie. a real pc in lntentry->pc). */
-
-               if (pc >= lntentry->pc) {
-
-                       /* check for special inline entries (see
-                          doc/inlining_stacktrace.txt for details */
-
-                       if ((s4)lntentry->line < 0) {
-                               switch (lntentry->line) {
-                                       case -1: 
-                                               /* begin of inlined method (ie. INLINE_END
-                                                  instruction) */
-
-                                               lntinline = --lntentry;/* get entry with methodinfo * */
-                                               lntentry--;            /* skip the special entry      */
-                                               lntsize -= 2;
-
-                                               /* search inside the inlined method */
-                                               if (stacktrace_add_method_intern(
-                                                                       stb, 
-                                                                       (methodinfo*) lntinline->pc,
-                                                                       lntentry,
-                                                                       lntsize,
-                                                                       pc))
-                                               {
-                                                       /* the inlined method contained the pc */
-                                                       assert(lntinline->line <= -3);
-                                                       stacktrace_add_entry(stb, m, (-3) - lntinline->line);
-                                                       return true;
-                                               }
-                                               /* pc was not in inlined method, continue
-                                                  search.  Entries inside the inlined method
-                                                  will be skipped because their lntentry->pc
-                                                  is higher than pc.  */
-                                               break;
-
-                                       case -2: 
-                                               /* end of inlined method */
-                                               return false;
-
-                                       /* default: is only reached for an -3-line entry
-                                          after a skipped -2 entry. We can safely ignore
-                                          it and continue searching.  */
-                               }
-                       }
-                       else {
-                               /* found a normal entry */
-                               stacktrace_add_entry(stb, m, lntentry->line);
-                               return true;
-                       }
-               }
-       }
-
-       /* not found */
-       return false;
-}
-
 /* stacktrace_add_method *******************************************************
 
    Add stacktrace entries[1] for the given method to the stacktrace buffer.
@@ -731,61 +352,20 @@ static bool stacktrace_add_method_intern(stacktracebuffer *stb,
 static bool stacktrace_add_method(stacktracebuffer *stb, methodinfo *m, u1 *pv,
                                                                  u1 *pc)
 {
-       ptrint                 lntsize;     /* size of line number table          */
-       u1                    *lntstart;    /* start of line number table         */
-       linenumbertable_entry *lntentry;    /* points to last entry in the table  */
-       codeinfo              *code;        /* compiled realization of method     */
-
-       /* get size of line number table */
-
-       lntsize  = *((ptrint *) (pv + LineNumberTableSize));
-       lntstart = *((u1 **)    (pv + LineNumberTableStart));
-
-       /* Subtract the size of the line number entry of the structure,
-          since the line number table start points to the pc. */
-
-       lntentry = (linenumbertable_entry *) (lntstart - SIZEOF_VOID_P);
+       codeinfo *code;                     /* compiled realization of method     */
+       s4        linenumber;
 
        /* find the realization of the method the pc is in */
 
-#if 0
        code = *((codeinfo **) (pv + CodeinfoPointer));
-#endif
-
-#if 1
-       /* XXX Note: This is preliminary. It would be cleaner */
-       /* to get the codeinfo * from the PV                  */
-
-       code = m->code;
-       while (1) {
-               if (!code) {
-#ifndef NDEBUG
-                       method_println(m);
-                       dolog("Could not find codeinfo for Current PC: %p",(void*)pc);
-#endif
-                       abort();
-               }
-
-               if (((ptrint)pc >= (ptrint)code->entrypoint)
-                               &&
-                       ( (pc - (u1*)code->entrypoint) < code->mcodelength ))
-               {
-                       /* found */
-                       break;
-               }
-
-               code = code->prev;
-       }
-#endif
 
        /* search the line number table */
 
-       if (stacktrace_add_method_intern(stb, m, lntentry, lntsize, pc))
-               return true;
+       linenumber = dseg_get_linenumber_from_pc(&m, pv, pc);
 
-       /* If we get here, just add the entry with line number 0. */
+       /* now add a new entry to the staktrace */
 
-       stacktrace_add_entry(stb, m, 0);
+       stacktrace_add_entry(stb, m, linenumber);
 
        return true;
 }
@@ -794,19 +374,23 @@ static bool stacktrace_add_method(stacktracebuffer *stb, methodinfo *m, u1 *pv,
 /* 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;
@@ -829,19 +413,6 @@ stacktracebuffer *stacktrace_create(threadobject* thread)
        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
@@ -884,12 +455,12 @@ stacktracebuffer *stacktrace_create(threadobject* thread)
 
 #if defined(ENABLE_INTRP)
                                if (opt_intrp)
-                                       pv = codegen_findmethod(ra);
+                                       pv = codegen_get_pv_from_pc(ra);
                                else
 #endif
                                        {
 #if defined(ENABLE_JIT)
-                                               pv = md_codegen_findmethod(ra);
+                                               pv = md_codegen_get_pv_from_pc(ra);
 #endif
                                        }
 
@@ -963,8 +534,10 @@ stacktracebuffer *stacktrace_create(threadobject* thread)
                                        /* 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
@@ -973,7 +546,7 @@ stacktracebuffer *stacktrace_create(threadobject* thread)
                                           parent method */
 
 #if defined(ENABLE_JIT)
-                                       pv = md_codegen_findmethod(ra);
+                                       pv = md_codegen_get_pv_from_pc(ra);
 #endif
 
                                        code = *((codeinfo **) (pv + CodeinfoPointer));
@@ -1040,12 +613,17 @@ stacktracebuffer *stacktrace_create(threadobject* thread)
 
 #if defined(ENABLE_INTRP)
                        if (opt_intrp)
-                               pv = codegen_findmethod(ra);
+                               pv = codegen_get_pv_from_pc(ra);
                        else
 #endif
                                {
 #if defined(ENABLE_JIT)
-                                       pv = md_codegen_findmethod(ra);
+# 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
                                }
 
@@ -1063,8 +641,10 @@ stacktracebuffer *stacktrace_create(threadobject* thread)
                        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
@@ -1074,7 +654,10 @@ stacktracebuffer *stacktrace_create(threadobject* thread)
 
        /* return the stacktracebuffer */
 
-       return stb;
+       if (stb->used == 0)
+               return NULL;
+       else
+               return stb;
 }
 
 
@@ -1085,11 +668,12 @@ stacktracebuffer *stacktrace_create(threadobject* thread)
 
 *******************************************************************************/
 
-stacktracebuffer *stacktrace_fillInStackTrace(void)
+stacktracecontainer *stacktrace_fillInStackTrace(void)
 {
-       stacktracebuffer *stb;
-       stacktracebuffer *gcstb;
-       s4                dumpsize;
+       stacktracebuffer    *stb;
+       stacktracecontainer *gcstc;
+       s4                   gcstc_size;
+       s4                   dumpsize;
        CYCLES_STATS_DECLARE_AND_START_WITH_OVERHEAD
 
        /* mark start of dump memory area */
@@ -1098,25 +682,27 @@ stacktracebuffer *stacktrace_fillInStackTrace(void)
 
        /* 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 */
+       /* ATTENTION: use stacktracecontainer for this and make it look like
+       an array */
 
-       gcstb = GCNEW(stacktracebuffer);
+       gcstc_size = sizeof(stacktracebuffer) +
+                    sizeof(stacktrace_entry) * stb->used;
+       gcstc = (stacktracecontainer *) builtin_newarray_byte(gcstc_size);
 
-       if (gcstb == NULL)
+       if (gcstc == NULL)
                goto return_NULL;
 
-       gcstb->capacity = stb->capacity;
-       gcstb->used     = stb->used;
-       gcstb->entries  = GCMNEW(stacktrace_entry, stb->used);
-
-       if (gcstb->entries == NULL)
-               goto return_NULL;
+       gcstc->stb.capacity = stb->capacity;
+       gcstc->stb.used     = stb->used;
+       gcstc->stb.entries  = gcstc->data;
 
-       MCOPY(gcstb->entries, stb->entries, stacktrace_entry, stb->used);
+       MCOPY(gcstc->data, stb->entries, stacktrace_entry, stb->used);
 
        /* release dump memory */
 
@@ -1124,7 +710,7 @@ stacktracebuffer *stacktrace_fillInStackTrace(void)
 
        CYCLES_STATS_END_WITH_OVERHEAD(stacktrace_fillInStackTrace,
                                                                   stacktrace_overhead)
-       return gcstb;
+       return gcstc;
 
 return_NULL:
        dump_release(dumpsize);
@@ -1146,14 +732,14 @@ return_NULL:
 
 *******************************************************************************/
 
-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 */
@@ -1162,8 +748,9 @@ java_objectarray *stacktrace_getClassContext(void)
 
        /* 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 */
@@ -1193,7 +780,7 @@ java_objectarray *stacktrace_getClassContext(void)
                        continue;
                }
 
-               oa->data[i] = (java_objectheader *) ste->method->class;
+               oa->data[i] = (java_object_t *) ste->method->class;
        }
 
        /* release dump memory */
@@ -1230,6 +817,7 @@ return_NULL:
 
 *******************************************************************************/
 
+#if defined(ENABLE_JAVASE)
 classinfo *stacktrace_getCurrentClass(void)
 {
        stacktracebuffer  *stb;
@@ -1245,8 +833,9 @@ classinfo *stacktrace_getCurrentClass(void)
 
        /* 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
@@ -1279,6 +868,7 @@ return_NULL:
 
        return NULL;
 }
+#endif /* ENABLE_JAVASE */
 
 
 /* stacktrace_getStack *********************************************************
@@ -1291,17 +881,18 @@ return_NULL:
 
 *******************************************************************************/
 
-java_objectarray *stacktrace_getStack(void)
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t *stacktrace_getStack(void)
 {
-       stacktracebuffer *stb;
-       stacktrace_entry *ste;
-       java_objectarray *oa;
-       java_objectarray *classes;
-       java_objectarray *methodnames;
-       classinfo        *c;
-       java_lang_String *str;
-       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 */
@@ -1310,8 +901,9 @@ java_objectarray *stacktrace_getStack(void)
 
        /* create a stacktrace for the current thread */
 
-       stb = stacktrace_create(THREADOBJECT);
-       if (!stb)
+       stb = stacktrace_create(STACKFRAMEINFO);
+
+       if (stb == NULL)
                goto return_NULL;
 
        /* get the first stacktrace entry */
@@ -1322,36 +914,37 @@ java_objectarray *stacktrace_getStack(void)
 
        oa = builtin_anewarray(2, arrayclass_java_lang_Object);
 
-       if (!oa)
+       if (oa == NULL)
                goto return_NULL;
 
        classes = builtin_anewarray(stb->used, class_java_lang_Class);
 
-       if (!classes)
+       if (classes == NULL)
                goto return_NULL;
 
        methodnames = builtin_anewarray(stb->used, class_java_lang_String);
 
-       if (!methodnames)
+       if (methodnames == 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;
-               str = javastring_new(ste->method->name);
+               classes->data[i] = (java_object_t *) c;
+
+               string = javastring_new(ste->method->name);
 
-               if (!str)
+               if (string == NULL)
                        goto return_NULL;
 
-               methodnames->data[i] = (java_objectheader *) str;
+               methodnames->data[i] = string;
        }
 
        /* return the 2-dimensional array */
@@ -1369,6 +962,7 @@ return_NULL:
 
        return NULL;
 }
+#endif /* ENABLE_JAVASE */
 
 
 /* stacktrace_print_trace_from_buffer ******************************************
@@ -1379,7 +973,7 @@ return_NULL:
 
 *******************************************************************************/
 
-static void stacktrace_print_trace_from_buffer(stacktracebuffer *stb)
+void stacktrace_print_trace_from_buffer(stacktracebuffer *stb)
 {
        stacktrace_entry *ste;
        methodinfo       *m;
@@ -1412,62 +1006,6 @@ static void stacktrace_print_trace_from_buffer(stacktracebuffer *stb)
 }
 
 
-/* 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(void)
-{
-       stacktracebuffer *stb;
-       s4                dumpsize;
-
-#if 0
-       /* get methodinfo pointer from data segment */
-
-       m = *((methodinfo **) (pv + MethodPointer));
-
-       /* get current stackframe info pointer */
-
-       psfi = STACKFRAMEINFO;
-
-       /* fill new stackframe info structure */
-
-       sfi->prev   = *psfi;
-       sfi->method = NULL;
-       sfi->pv     = NULL;
-       sfi->sp     = sp;
-       sfi->ra     = ra;
-
-       /* store new stackframe info pointer */
-
-       *psfi = sfi;
-#endif
-
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       /* create a stacktrace for the current thread */
-
-       stb = stacktrace_create(THREADOBJECT);
-
-       /* print stacktrace */
-
-       if (stb) {
-               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
@@ -1475,10 +1013,13 @@ void stacktrace_dump_trace(void)
 
 *******************************************************************************/
 
-void stacktrace_print_trace(java_objectheader *xptr)
+void stacktrace_print_trace(java_handle_t *xptr)
 {
        java_lang_Throwable   *t;
+#if defined(WITH_CLASSPATH_GNU)
        java_lang_VMThrowable *vmt;
+#endif
+       stacktracecontainer   *stc;
        stacktracebuffer      *stb;
 
        t = (java_lang_Throwable *) xptr;
@@ -1488,8 +1029,16 @@ void stacktrace_print_trace(java_objectheader *xptr)
 
        /* now print the stacktrace */
 
-       vmt = t->vmState;
-       stb = (stacktracebuffer *) vmt->vmData;
+#if defined(WITH_CLASSPATH_GNU)
+       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;
+#else
+# error unknown classpath configuration
+#endif
+
+       stb = &(stc->stb);
 
        stacktrace_print_trace_from_buffer(stb);
 }