* JAVA_ANEWARRAY, JAVA_MULTIANEWARRAY, JAVA_CHECKCAST, JAVA_INSTANCEOF: Use
[cacao.git] / src / vm / jit / stacktrace.c
index a254c1b4ef032acf87647e1cc1f1bfaa44ba28a8..3440f02d802f5ad41154aa2a37617331701fdc1c 100644 (file)
@@ -1,4 +1,4 @@
-/* src/vm/jit/stacktrace.c
+/* src/vm/jit/stacktrace.c - machine independet stacktrace system
 
    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
@@ -28,7 +28,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: stacktrace.c 3048 2005-07-18 15:07:19Z twisti $
+   $Id: stacktrace.c 3540 2005-11-03 20:33:20Z twisti $
 
 */
 
@@ -38,7 +38,6 @@
 #include <string.h>
 
 #include "config.h"
-#include "asmoffsets.h"
 
 #include "mm/boehm.h"
 #include "native/native.h"
 #include "vm/class.h"
 #include "vm/exceptions.h"
 #include "vm/loader.h"
+#include "vm/options.h"
 #include "vm/stringlocal.h"
 #include "vm/tables.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen.inc.h"
-
-
-#undef JWDEBUG
-#undef JWDEBUG2
-#undef JWDEBUG3
+#include "vm/jit/methodheader.h"
 
 
 /* lineNumberTableEntry *******************************************************/
 
-/* The special value of -1 means that a inlined function starts, a value of */
-/* -2 means that an inlined function ends */
+/* Keep the type of line the same as the pointer type, otherwise we run into  */
+/* alignment troubles (like on MIPS64).                                       */
 
 typedef struct lineNumberTableEntry {
-       ptrint  line; /* XXX change me to u2 */
+       ptrint  line;
        u1     *pc;
 } lineNumberTableEntry;
 
@@ -80,12 +76,64 @@ typedef struct lineNumberTableEntryInlineBegin {
 } lineNumberTableEntryInlineBegin;
 
 
-typedef void(*CacaoStackTraceCollector)(void **,stackTraceBuffer*);
+typedef bool(*CacaoStackTraceCollector)(void **, stackTraceBuffer*);
 
 #define BLOCK_INITIALSIZE 40
 #define BLOCK_SIZEINCREMENT 40
 
 
+/* global variables ***********************************************************/
+
+#if !defined(USE_THREADS)
+stackframeinfo *_no_threads_stackframeinfo = NULL;
+#endif
+
+
+/* stacktrace_create_stackframeinfo ********************************************
+
+   Creates an stackframe info structure for inline code in the
+   interpreter.
+
+*******************************************************************************/
+
+#if defined(ENABLE_INTRP)
+void stacktrace_create_stackframeinfo(stackframeinfo *sfi, u1 *pv,
+                                                                         u1 *sp, functionptr ra)
+{
+       stackframeinfo **psfi;
+       methodinfo      *m;
+
+       /* get current stackframe info pointer */
+
+       psfi = STACKFRAMEINFO;
+
+       /* if we don't have pv handy */
+
+       if (pv == NULL)
+               pv = (u1 *) (ptrint) codegen_findmethod(ra);
+
+       /* get methodinfo pointer from data segment */
+
+       m = *((methodinfo **) (pv + MethodPointer));
+
+       /* 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 fillInStackTrace */
+
+       sfi->xpc = ra;
+
+       /* store new stackframe info pointer */
+
+       *psfi = sfi;
+}
+#endif /* defined(ENABLE_INTRP) */
+
 /* stacktrace_create_inline_stackframeinfo *************************************
 
    Creates an stackframe info structure for an inline exception stub.
@@ -96,16 +144,25 @@ void stacktrace_create_inline_stackframeinfo(stackframeinfo *sfi, u1 *pv,
                                                                                         u1 *sp, functionptr ra,
                                                                                         functionptr xpc)
 {
-       void **osfi;
+       stackframeinfo **psfi;
 
        /* get current stackframe info pointer */
 
-       osfi = builtin_asm_get_stackframeinfo();
+       psfi = STACKFRAMEINFO;
+
+#if defined(ENABLE_INTRP)
+       if (opt_intrp) {
+               /* if we don't have pv handy */
+
+               if (pv == NULL)
+                       pv = (u1 *) (ptrint) codegen_findmethod(ra);
+
+       }
+#endif
 
        /* fill new stackframe info structure */
 
-       sfi->oldThreadspecificHeadValue = *osfi;
-       sfi->addressOfThreadspecificHead = osfi;
+       sfi->prev = *psfi;
        sfi->method = NULL;
        sfi->pv = pv;
        sfi->sp = sp;
@@ -114,7 +171,7 @@ void stacktrace_create_inline_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 
        /* store new stackframe info pointer */
 
-       *osfi = sfi;
+       *psfi = sfi;
 }
 
 
@@ -129,48 +186,55 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
                                                                                         u1 *sp, functionptr ra,
                                                                                         functionptr xpc)
 {
-       void **osfi;
+       stackframeinfo **psfi;
 #if !defined(__I386__) && !defined(__X86_64__)
-       bool   isleafmethod;
+       bool             isleafmethod;
 #endif
-       s4     framesize;
+       s4               framesize;
 
        /* get current stackframe info pointer */
 
-       osfi = builtin_asm_get_stackframeinfo();
+       psfi = STACKFRAMEINFO;
 
-       /* sometimes we don't have pv handy (e.g. in asmpart.S: */
-       /* L_asm_call_jit_compiler_exception) */
+       /* sometimes we don't have pv handy (e.g. in asmpart.S:
+       L_asm_call_jit_compiler_exception or in the interpreter). */
 
        if (pv == NULL)
                pv = (u1 *) (ptrint) codegen_findmethod(ra);
 
-#if defined(__I386__) || defined(__X86_64__)
-       /* On i386 and x86_64 we always have to get the return address from the */
-       /* stack. */
-
-       framesize = *((u4 *) (pv + FrameSize));
+#if defined(ENABLE_INTRP)
+       /* When using the interpreter, we pass RA to the function. */
 
-       ra = md_stacktrace_get_returnaddress(sp, framesize);
-#else
-       /* If the method is a non-leaf function, we need to get the return        */
-       /* address from the stack. For leaf functions the return address is set   */
-       /* correctly. This makes the assembler and the signal handler code        */
-       /* simpler.                                                               */
-
-       isleafmethod = *((s4 *) (pv + IsLeaf));
+       if (!opt_intrp) {
+#endif
+# if defined(__I386__) || defined(__X86_64__)
+               /* On i386 and x86_64 we always have to get the return address
+                  from the stack. */
 
-       if (!isleafmethod) {
                framesize = *((u4 *) (pv + FrameSize));
 
                ra = md_stacktrace_get_returnaddress(sp, framesize);
+# else
+               /* If the method is a non-leaf function, we need to get the return
+                  address from the stack. For leaf functions the return address
+                  is set correctly. This makes the assembler and the signal
+                  handler code simpler. */
+
+               isleafmethod = *((s4 *) (pv + IsLeaf));
+
+               if (!isleafmethod) {
+                       framesize = *((u4 *) (pv + FrameSize));
+
+                       ra = md_stacktrace_get_returnaddress(sp, framesize);
+               }
+# endif
+#if defined(ENABLE_INTRP)
        }
 #endif
 
        /* fill new stackframe info structure */
 
-       sfi->oldThreadspecificHeadValue = *osfi;
-       sfi->addressOfThreadspecificHead = osfi;
+       sfi->prev = *psfi;
        sfi->method = NULL;
        sfi->pv = pv;
        sfi->sp = sp;
@@ -179,7 +243,7 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 
        /* store new stackframe info pointer */
 
-       *osfi = sfi;
+       *psfi = sfi;
 }
 
 
@@ -192,8 +256,8 @@ void stacktrace_create_extern_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 void stacktrace_create_native_stackframeinfo(stackframeinfo *sfi, u1 *pv,
                                                                                         u1 *sp, functionptr ra)
 {
-       void       **osfi;
-       methodinfo  *m;
+       stackframeinfo **psfi;
+       methodinfo      *m;
 
        /* get methodinfo pointer from data segment */
 
@@ -201,12 +265,11 @@ void stacktrace_create_native_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 
        /* get current stackframe info pointer */
 
-       osfi = builtin_asm_get_stackframeinfo();
+       psfi = STACKFRAMEINFO;
 
        /* fill new stackframe info structure */
 
-       sfi->oldThreadspecificHeadValue = *osfi;
-       sfi->addressOfThreadspecificHead = osfi;
+       sfi->prev = *psfi;
        sfi->method = m;
        sfi->pv = NULL;
        sfi->sp = sp;
@@ -215,7 +278,7 @@ void stacktrace_create_native_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 
        /* store new stackframe info pointer */
 
-       *osfi = sfi;
+       *psfi = sfi;
 }
 
 
@@ -227,15 +290,15 @@ void stacktrace_create_native_stackframeinfo(stackframeinfo *sfi, u1 *pv,
 
 void stacktrace_remove_stackframeinfo(stackframeinfo *sfi)
 {
-       void **osfi;
+       stackframeinfo **psfi;
 
-       /* get address of pointer */
+       /* get current stackframe info pointer */
 
-       osfi = sfi->addressOfThreadspecificHead;
+       psfi = STACKFRAMEINFO;
 
        /* restore the old pointer */
 
-       *osfi = sfi->oldThreadspecificHeadValue;
+       *psfi = sfi->prev;
 }
 
 
@@ -357,35 +420,6 @@ java_objectheader *stacktrace_inline_classcastexception(u1 *pv, u1 *sp,
 }
 
 
-/* stacktrace_inline_negativearraysizeexception ********************************
-
-   Creates an NegativeArraySizeException for inline stub.
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_inline_negativearraysizeexception(u1 *pv, u1 *sp,
-                                                                                                                               functionptr ra,
-                                                                                                                               functionptr xpc)
-{
-       stackframeinfo     sfi;
-       java_objectheader *o;
-
-       /* create stackframeinfo */
-
-       stacktrace_create_inline_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
-       /* create exception */
-
-       o = new_negativearraysizeexception();
-
-       /* remove stackframeinfo */
-
-       stacktrace_remove_stackframeinfo(&sfi);
-
-       return o;
-}
-
-
 /* stacktrace_inline_nullpointerexception **************************************
 
    Creates an NullPointerException for inline stub.
@@ -518,51 +552,6 @@ java_objectheader *stacktrace_inline_fillInStackTrace(u1 *pv, u1 *sp,
 }
 
 
-/* stacktrace_extern_fillInStackTrace ******************************************
-
-   Fills in the correct stacktrace into an existing exception object
-   (this one is for calling from assembler code).
-
-*******************************************************************************/
-
-java_objectheader *stacktrace_extern_fillInStackTrace(u1 *pv, u1 *sp,
-                                                                                                         functionptr ra,
-                                                                                                         functionptr xpc)
-{
-       java_objectheader *o;
-       stackframeinfo     sfi;
-       methodinfo        *m;
-
-       /* get exception */
-
-       o = *exceptionptr;
-
-       /* create stackframeinfo */
-
-       stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
-       /* 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 */
-
-       asm_calljavafunction(m, o, NULL, NULL, NULL);
-
-       /* remove stackframeinfo */
-
-       stacktrace_remove_stackframeinfo(&sfi);
-
-       return o;
-}
-
-
 /* addEntry ********************************************************************
 
    XXX
@@ -610,7 +599,7 @@ static void addEntry(stackTraceBuffer *buffer, methodinfo *method, u2 line)
 *******************************************************************************/
 
 static bool stacktrace_fillInStackTrace_methodRecursive(stackTraceBuffer *buffer,
-                                                                                                               methodinfo *method,
+                                                                                                               methodinfo *m,
                                                                                                                lineNumberTableEntry *lntentry,
                                                                                                                s4 lntsize,
                                                                                                                u1 *pc)
@@ -641,7 +630,7 @@ static bool stacktrace_fillInStackTrace_methodRecursive(stackTraceBuffer *buffer
                                                                                                                                &ent,
                                                                                                                                &ahead,
                                                                                                                                pc)) {
-                                       addEntry(buffer, method, ilStart->lineNrOuter);
+                                       addEntry(buffer, m, ilStart->lineNrOuter);
 
                                        return true;
                                }
@@ -655,17 +644,24 @@ static bool stacktrace_fillInStackTrace_methodRecursive(stackTraceBuffer *buffer
 #endif
 
                        default:
-                               addEntry(buffer, method, lntentry->line);
+                               addEntry(buffer, m, lntentry->line);
                                return true;
                        }
                }
        }
 
-       /* this should not happen */
+       /* check if we are before the actual JIT code */
+
+       if ((ptrint) pc < (ptrint) m->entrypoint) {
+               dolog("Current pc before start of code: %p < %p", pc, m->entrypoint);
+               assert(0);
+       }
+
+       /* otherwise just add line 0 */
 
-       assert(0);
+       addEntry(buffer, m, 0);
 
-       return false;
+       return true;
 }
 
 
@@ -679,20 +675,18 @@ static void stacktrace_fillInStackTrace_method(stackTraceBuffer *buffer,
                                                                                           methodinfo *method, u1 *pv,
                                                                                           u1 *pc)
 {
-       s4                    lntsize;      /* size of line number table          */
+       ptrint                lntsize;      /* size of line number table          */
        u1                   *lntstart;     /* start of line number table         */
        lineNumberTableEntry *lntentry;     /* points to last entry in the table  */
 
        /* get size of line number table */
 
-       lntsize  = *((s4 *)  (pv + LineNumberTableSize));
-       lntstart = *((u1 **) (pv + LineNumberTableStart));
+       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 */
 
-       /* XXX change me to u2 (or s4) */
-
        lntentry = (lineNumberTableEntry *) (lntstart - SIZEOF_VOID_P);
 
        if (lntsize == 0) {
@@ -719,18 +713,19 @@ static void stacktrace_fillInStackTrace_method(stackTraceBuffer *buffer,
 
 *******************************************************************************/
 
-void cacao_stacktrace_fillInStackTrace(void **target,
-                                                                          CacaoStackTraceCollector coll)
+static bool cacao_stacktrace_fillInStackTrace(void **target,
+                                                                                         CacaoStackTraceCollector coll)
 {
        stacktraceelement primaryBlock[BLOCK_INITIALSIZE*sizeof(stacktraceelement)];
        stackTraceBuffer  buffer;
-       stackframeinfo   *info;
+       stackframeinfo   *sfi;
        methodinfo       *m;
        u1               *pv;
        u1               *sp;
        u4                framesize;
        functionptr       ra;
        functionptr       xpc;
+       bool              result;
 
        /* prevent compiler warnings */
 
@@ -749,17 +744,18 @@ void cacao_stacktrace_fillInStackTrace(void **target,
        /* the first element in the stackframe chain must always be a native      */
        /* stackframeinfo (VMThrowable.fillInStackTrace is a native function)     */
 
-       info = *((void **) builtin_asm_get_stackframeinfo());
+       sfi = *STACKFRAMEINFO;
 
-       if (!info) {
+       if (!sfi) {
                *target = NULL;
-               return;
+               return true;
        }
 
 #define PRINTMETHODS 0
 
 #if PRINTMETHODS
        printf("\n\nfillInStackTrace start:\n");
+       fflush(stdout);
 #endif
 
        /* loop while we have a method pointer (asm_calljavafunction has NULL) or */
@@ -767,7 +763,7 @@ void cacao_stacktrace_fillInStackTrace(void **target,
 
        m = NULL;
 
-       while (m || info) {
+       while (m || sfi) {
                /* m == NULL should only happen for the first time and inline         */
                /* stackframe infos, like from the exception stubs or the patcher     */
                /* wrapper                                                            */
@@ -775,12 +771,12 @@ void cacao_stacktrace_fillInStackTrace(void **target,
                if (m == NULL) {
                        /* for native stub stackframe infos, pv is always NULL */
 
-                       if (info->pv == NULL) {
+                       if (sfi->pv == NULL) {
                                /* get methodinfo, sp and ra from the current stackframe info */
 
-                               m = info->method;
-                               sp = info->sp;          /* sp of parent Java function         */
-                               ra = info->ra;
+                               m  = sfi->method;
+                               sp = sfi->sp;           /* sp of parent Java function         */
+                               ra = sfi->ra;
 
                                if (m)
                                        addEntry(&buffer, m, 0);
@@ -791,6 +787,7 @@ void cacao_stacktrace_fillInStackTrace(void **target,
                                utf_display(m->name);
                                utf_display(m->descriptor);
                                printf(": native stub\n");
+                               fflush(stdout);
 #endif
                                /* this is an native stub stackframe info, so we can get the */
                                /* parent pv from the return address (ICMD_INVOKE*) */
@@ -810,14 +807,15 @@ void cacao_stacktrace_fillInStackTrace(void **target,
 
                                /* get methodinfo, sp and ra from the current stackframe info */
 
-                               m   = info->method;     /* m == NULL                          */
-                               pv  = info->pv;         /* pv of parent Java function         */
-                               sp  = info->sp;         /* sp of parent Java function         */
-                               ra  = info->ra;         /* ra of parent Java function         */
-                               xpc = info->xpc;        /* actual exception position          */
+                               m   = sfi->method;      /* m == NULL                          */
+                               pv  = sfi->pv;          /* pv of parent Java function         */
+                               sp  = sfi->sp;          /* sp of parent Java function         */
+                               ra  = sfi->ra;          /* ra of parent Java function         */
+                               xpc = sfi->xpc;         /* actual exception position          */
 
 #if PRINTMETHODS
                                printf("NULL: inline stub\n");
+                               fflush(stdout);
 #endif
 
                                /* get methodinfo from current Java method */
@@ -827,6 +825,18 @@ void cacao_stacktrace_fillInStackTrace(void **target,
                                /* if m == NULL, this is a asm_calljavafunction call */
 
                                if (m != NULL) {
+#if PRINTMETHODS
+                                       utf_display_classname(m->class->name);
+                                       printf(".");
+                                       utf_display(m->name);
+                                       utf_display(m->descriptor);
+                                       printf(": inline stub parent\n");
+                                       fflush(stdout);
+#endif
+
+#if defined(ENABLE_INTRP)
+                                       if (!opt_intrp) {
+#endif
 
                                        /* add it to the stacktrace */
 
@@ -851,12 +861,22 @@ void cacao_stacktrace_fillInStackTrace(void **target,
 
                                        pv = (u1 *) (ptrint) codegen_findmethod(ra);
                                        m = *((methodinfo **) (pv + MethodPointer));
+
+#if defined(ENABLE_INTRP)
+                                       }
+#endif
+                               }
+#if PRINTMETHODS
+                               else {
+                                       printf("asm_calljavafunction\n");
+                                       fflush(stdout);
                                }
+#endif
                        }
 
-                       /* get next stackframeinfo in the chain */
+                       /* get previous stackframeinfo in the chain */
 
-                       info = info->oldThreadspecificHeadValue;
+                       sfi = sfi->prev;
 
                } else {
 #if PRINTMETHODS
@@ -889,51 +909,67 @@ void cacao_stacktrace_fillInStackTrace(void **target,
 
                        /* walk the stack */
 
+#if defined(ENABLE_INTRP)
+                       if (opt_intrp)
+                               sp = *(u1 **)(sp - framesize);
+                       else
+#endif
+                               {
 #if defined(__I386__) || defined (__X86_64__)
-                       sp += framesize + SIZEOF_VOID_P;
+                                       sp += framesize + SIZEOF_VOID_P;
 #else
-                       sp += framesize;
+                                       sp += framesize;
 #endif
+                               }
                }
        }
                        
        if (coll)
-               coll(target, &buffer);
+               result = coll(target, &buffer);
 
        if (buffer.needsFree)
                free(buffer.start);
+
+       return result;
 }
 
 
-static
-void stackTraceCollector(void **target, stackTraceBuffer *buffer) {
-       stackTraceBuffer *dest=*target=heap_allocate(sizeof(stackTraceBuffer)+buffer->full*sizeof(stacktraceelement),true,0);
-       memcpy(*target,buffer,sizeof(stackTraceBuffer));
-       memcpy(dest+1,buffer->start,buffer->full*sizeof(stacktraceelement));
+/* stackTraceCollector *********************************************************
 
-       dest->needsFree=0;
-       dest->size=dest->full;
-       dest->start=(stacktraceelement*)(dest+1);
+   XXX
+
+*******************************************************************************/
+
+static bool stackTraceCollector(void **target, stackTraceBuffer *buffer)
+{
+       stackTraceBuffer *dest;
+
+       dest = *target = heap_allocate(sizeof(stackTraceBuffer) + buffer->full * sizeof(stacktraceelement), true, 0);
 
-       /*
-       if (buffer->full>0) {
-               printf("SOURCE BUFFER:%s\n",buffer->start[0].method->name->text);
-               printf("DEST BUFFER:%s\n",dest->start[0].method->name->text);
-       } else printf("Buffer is empty\n");
-       */
+       if (!dest)
+               return false;
+
+       memcpy(*target, buffer, sizeof(stackTraceBuffer));
+       memcpy(dest + 1, buffer->start, buffer->full * sizeof(stacktraceelement));
+
+       dest->needsFree = 0;
+       dest->size = dest->full;
+       dest->start = (stacktraceelement *) (dest + 1);
+
+       return true;
 }
 
 
-void cacao_stacktrace_NormalTrace(void **target)
+bool cacao_stacktrace_NormalTrace(void **target)
 {
-       cacao_stacktrace_fillInStackTrace(target, &stackTraceCollector);
+       return cacao_stacktrace_fillInStackTrace(target, &stackTraceCollector);
 }
 
 
 
-static void classContextCollector(void **target, stackTraceBuffer *buffer)
+static bool classContextCollector(void **target, stackTraceBuffer *buffer)
 {
-       java_objectarray  *tmpArray;
+       java_objectarray  *oa;
        stacktraceelement *current;
        stacktraceelement *start;
        size_t size;
@@ -952,17 +988,19 @@ static void classContextCollector(void **target, stackTraceBuffer *buffer)
        targetSize--;
 
        if (targetSize > 0) {
-               if (start->method && (start->method->class == class_java_lang_SecurityManager)) {
+               if (start->method &&
+                       (start->method->class == class_java_lang_SecurityManager)) {
                        targetSize--;
                        start++;
                }
        }
 
-       tmpArray = builtin_anewarray(targetSize, class_java_lang_Class);
+       oa = builtin_anewarray(targetSize, class_java_lang_Class);
 
-       for(i = 0, current = start; i < targetSize; i++, current++) {
-               /* XXX TWISTI: should we use this skipping for native stubs? */
+       if (!oa)
+               return false;
 
+       for(i = 0, current = start; i < targetSize; i++, current++) {
                if (!current->method) {
                        i--;
                        continue;
@@ -970,19 +1008,23 @@ static void classContextCollector(void **target, stackTraceBuffer *buffer)
 
                use_class_as_object(current->method->class);
 
-               tmpArray->data[i] = (java_objectheader *) current->method->class;
+               oa->data[i] = (java_objectheader *) current->method->class;
        }
 
-       *target = tmpArray;
+       *target = oa;
+
+       return true;
 }
 
 
 
 java_objectarray *cacao_createClassContextArray(void)
 {
-       java_objectarray *array=0;
+       java_objectarray *array = NULL;
 
-       cacao_stacktrace_fillInStackTrace((void **) &array, &classContextCollector);
+       if (!cacao_stacktrace_fillInStackTrace((void **) &array,
+                                                                                  &classContextCollector))
+               return NULL;
 
        return array;
 }
@@ -994,7 +1036,7 @@ java_objectarray *cacao_createClassContextArray(void)
 
 *******************************************************************************/
 
-static void stacktrace_classLoaderCollector(void **target,
+static bool stacktrace_classLoaderCollector(void **target,
                                                                                        stackTraceBuffer *buffer)
 {
        stacktraceelement *current;
@@ -1014,16 +1056,18 @@ static void stacktrace_classLoaderCollector(void **target,
 
                if (m->class == class_java_security_PrivilegedAction) {
                        *target = NULL;
-                       return;
+                       return true;
                }
 
                if (m->class->classloader) {
                        *target = (java_lang_ClassLoader *) m->class->classloader;
-                       return;
+                       return true;
                }
        }
 
        *target = NULL;
+
+       return true;
 }
 
 
@@ -1035,79 +1079,65 @@ static void stacktrace_classLoaderCollector(void **target,
 
 java_objectheader *cacao_currentClassLoader(void)
 {
-       java_objectheader *header=0;
+       java_objectheader *header = NULL;
 
-       cacao_stacktrace_fillInStackTrace((void**)&header,
-                                                                         &stacktrace_classLoaderCollector);
+       if (!cacao_stacktrace_fillInStackTrace((void**)&header,
+                                                                                  &stacktrace_classLoaderCollector))
+               return NULL;
 
        return header;
 }
 
 
-static
-void callingMethodCollector(void **target, stackTraceBuffer *buffer) { 
-        if (buffer->full >2) (*target)=buffer->start[2].method;
-       else (*target=0);
-}
-
-methodinfo *cacao_callingMethod() {
-       methodinfo *method;
-       cacao_stacktrace_fillInStackTrace((void**)&method,&callingMethodCollector);
-       return method;
-}
-
-
-static
-void getStackCollector(void **target, stackTraceBuffer *buffer)
+static bool getStackCollector(void **target, stackTraceBuffer *buffer)
 {
-       java_objectarray *classes;
-       java_objectarray *methodnames;
-       java_objectarray **result=(java_objectarray**)target;
-       java_lang_String *str;
-       classinfo *c;
+       java_objectarray  *oa;
+       java_objectarray  *classes;
+       java_objectarray  *methodnames;
+       java_lang_String  *str;
+       classinfo         *c;
        stacktraceelement *current;
-       int i,size;
+       s4                 i, size;
 
-       /*log_text("getStackCollector");*/
+/*     *result = (java_objectarray **) target; */
 
        size = buffer->full;
 
-       *result = builtin_anewarray(2, arrayclass_java_lang_Object);
+       oa = builtin_anewarray(2, arrayclass_java_lang_Object);
 
-       if (!(*result))
-               return;
+       if (!oa)
+               return false;
 
        classes = builtin_anewarray(size, class_java_lang_Class);
 
        if (!classes)
-               return;
+               return false;
 
        methodnames = builtin_anewarray(size, class_java_lang_String);
 
        if (!methodnames)
-               return;
+               return false;
 
-       (*result)->data[0] = (java_objectheader *) classes;
-       (*result)->data[1] = (java_objectheader *) methodnames;
+       oa->data[0] = (java_objectheader *) classes;
+       oa->data[1] = (java_objectheader *) methodnames;
 
-       /*log_text("Before for loop");*/
        for (i = 0, current = &(buffer->start[0]); i < size; i++, current++) {
-               /*log_text("In loop");*/
                c = current->method->class;
+
                use_class_as_object(c);
+
                classes->data[i] = (java_objectheader *) c;
                str = javastring_new(current->method->name);
+
                if (!str)
-                       return;
+                       return false;
+
                methodnames->data[i] = (java_objectheader *) str;
-               /*printf("getStackCollector: %s.%s\n",c->name->text,current->method->name->text);*/
        }
 
-       /*if (*exceptionptr) panic("Exception in getStackCollector");*/
-
-       /*log_text("loop left");*/
-        return;
+       *target = oa;
 
+       return true;
 }
 
 
@@ -1115,7 +1145,9 @@ java_objectarray *cacao_getStackForVMAccessController(void)
 {
        java_objectarray *result = NULL;
 
-       cacao_stacktrace_fillInStackTrace((void **) &result, &getStackCollector);
+       if (!cacao_stacktrace_fillInStackTrace((void **) &result,
+                                                                                  &getStackCollector))
+               return NULL;
 
        return result;
 }
@@ -1131,9 +1163,6 @@ java_objectarray *cacao_getStackForVMAccessController(void)
 void stacktrace_dump_trace(void)
 {
        stackTraceBuffer      *buffer;
-       stacktraceelement     *element;
-       methodinfo            *m;
-       s4                     i;
 
 #if 0
        /* get thread stackframeinfo */
@@ -1158,29 +1187,51 @@ void stacktrace_dump_trace(void)
        /* print stacktrace */
 
        if (buffer) {
-               element = buffer->start;
+               stacktrace_print_trace(buffer);
 
-               for (i = 0; i < buffer->size; i++, element++) {
-                       m = element->method;
+       } else {
+               puts("\t<<No stacktrace available>>");
+               fflush(stdout);
+       }
+}
 
-                       printf("\tat ");
-                       utf_display_classname(m->class->name);
-                       printf(".");
-                       utf_display(m->name);
-                       utf_display(m->descriptor);
 
-                       if (m->flags & ACC_NATIVE) {
-                               printf("(Native Method)\n");
+/* stacktrace_print_trace ******************************************************
 
-                       } else {
-                               printf("(");
-                               utf_display(m->class->sourcefile);
-                               printf(":%d)\n", (u4) element->linenumber);
-                       }
+   Print the stacktrace of a given stackTraceBuffer with CACAO intern
+   methods (no Java help). This method is used by
+   stacktrace_dump_trace and builtin_trace_exception.
+
+*******************************************************************************/
+
+void stacktrace_print_trace(stackTraceBuffer *stb)
+{
+       stacktraceelement *ste;
+       methodinfo        *m;
+       s4                 i;
+
+       ste = stb->start;
+
+       for (i = 0; i < stb->size; i++, ste++) {
+               m = ste->method;
+
+               printf("\tat ");
+               utf_display_classname(m->class->name);
+               printf(".");
+               utf_display(m->name);
+               utf_display(m->descriptor);
+
+               if (m->flags & ACC_NATIVE) {
+                       puts("(Native Method)");
+
+               } else {
+                       printf("(");
+                       utf_display(m->class->sourcefile);
+                       printf(":%d)\n", (u4) ste->linenumber);
                }
        }
 
-       /* flush stdout */
+       /* just to be sure */
 
        fflush(stdout);
 }