use two functions for creating/removing items of the native stackframe list (i386...
authorjowenn <none@none>
Sat, 4 Dec 2004 12:02:08 +0000 (12:02 +0000)
committerjowenn <none@none>
Sat, 4 Dec 2004 12:02:08 +0000 (12:02 +0000)
20 files changed:
configure.in
contrib/debugSetPathes
src/boehm-gc/autogen.sh
src/native/vm/VMRuntime.c
src/native/vm/VMSecurityManager.c
src/native/vm/VMThrowable.c
src/vm/global.h
src/vm/jit/asmpart.h
src/vm/jit/codegen.inc
src/vm/jit/i386/asmoffsets.h [new file with mode: 0644]
src/vm/jit/i386/asmpart.S
src/vm/jit/i386/codegen.c
src/vm/jit/i386/symcat.h [new file with mode: 0644]
src/vm/jit/stack.c
src/vm/jit/stacktrace.c [new file with mode: 0644]
src/vm/jit/x86_64/asmpart.S
src/vm/jit/x86_64/codegen.c
tests/InlineExTest.java
tests/stack/nestedstaticinitializers2.java
tests/stack/nestedstaticinitializers3.java [new file with mode: 0644]

index f148eb16f4547673c86779cdd857d2d251cdd128..3c58e945fb45f74f5d16716456eac75c591ca5df 100644 (file)
@@ -40,7 +40,7 @@ powerpc* | ppc* )
 
 x86_64* )
        ARCH_DIR="x86_64"
-        STATIC_CLASSPATH="1"
+        STATIC_CLASSPATH="0"
        CFLAGS="-D__X86_64__"
        ;;
 
index 20f93f67b59928bcbcd745065592fca9c41e39e2..f06b2ee5aec2b2bf49936c718303ff798c12ff15 100644 (file)
@@ -3,5 +3,5 @@ $PWD/classpath/native/jni/java-util/.libs:$PWD/classpath/native/jni/java-awt/.li
 $PWD/classpath/native/jni/java-io/.libs:$PWD/classpath/native/jni/classpath/.libs:\
 $PWD/classpath/native/jni/java-net/.libs:$LD_LIBRARY_PATH
 export CLASSPATH=.:$PWD/classpath/lib/glibj.zip:$CLASSPATH
-export PATH=$PWD:$PATH
+export PATH=$PWD/cacao:$PATH
 
index b97a7c9025bbd0cf6dbe3e8e4767df32412bc1fe..0ab131fa3dc308e79c3cd0083c83f65e1c446ce4 100755 (executable)
@@ -1,7 +1,12 @@
 #!/bin/sh
 
 libtoolize --automake
-aclocal
+if test `uname` == 'FreeBSD'; then
+       echo "FreeBSD (only tested with 5.3-RELEASE though"
+       aclocal  -I . -I /usr/local/share/aclocal -I /usr/local/share/aclocal19
+else
+       aclocal
+fi
 autoheader
 automake --add-missing
 autoconf
index 5cf652e482b9c9329bca6e1c2696a7647710f209..ba11e35aa4d710d1963e7b6557869b3149106eba 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Joseph Wenninger
             Christian Thalinger
 
-   $Id: VMRuntime.c 1621 2004-11-30 13:06:55Z twisti $
+   $Id: VMRuntime.c 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
@@ -333,7 +333,7 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass cla
 #ifndef STATIC_CLASSPATH
        /*here it could be interesting to store the references in a list eg for nicely cleaning up or for certain platforms*/
         if (dlopen(data->text,RTLD_NOW | RTLD_GLOBAL)) {
-               log_text("LIBLOADED");
+               /*log_text("LIBLOADED");*/
                 retVal=1;
         }
 #else
index d2f1220952cb8281baef28cc8354705f817ee32f..a4e2df869cfae882b3cdca5f840f5055c80e865e 100644 (file)
@@ -1,4 +1,4 @@
-/* native/vm/VMSecurityManager.c - java/lang/VMSecurityManager
+/* nat/SecurityManager.c - java/lang/SecurityManager
 
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
 
    Changes: Joseph Wenninger
 
-   $Id: VMSecurityManager.c 1621 2004-11-30 13:06:55Z twisti $
+   $Id: VMSecurityManager.c 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
-
 #include "native/jni.h"
 #include "native/native.h"
 #include "native/include/java_lang_ClassLoader.h"
@@ -40,8 +39,6 @@
 #include "vm/builtin.h"
 #include "vm/tables.h"
 
-
-#ifndef __I386__
 /*
  * Class:     java/lang/SecurityManager
  * Method:    currentClassLoader
@@ -51,19 +48,20 @@ JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMSecurityManager_curren
 {
        log_text("Java_java_lang_VMSecurityManager_currentClassLoader");
 
-       /* XXX TWISTI temporary hack! FIX ME jowenn */
        if (cacao_initializing)
                return NULL;
 
-       init_systemclassloader();
+#ifdef __I386__
+       return cacao_currentClassLoader();
+#else
+       return 0;
+#endif
+/*     init_systemclassloader();
 
-       return SystemClassLoader;
+       return SystemClassLoader;*/
 }
-#endif
 
 
-#ifndef __I386__
-/*THIS IS IN ASMPART NOW*/
 /*
  * Class:     java/lang/SecurityManager
  * Method:    getClassContext
@@ -71,12 +69,14 @@ JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMSecurityManager_curren
  */
 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMSecurityManager_getClassContext(JNIEnv *env, jclass clazz)
 {
-  log_text("Java_java_lang_VMSecurityManager_getClassContext  called");
-
-  /* XXX should use vftbl directly */
-  return (java_objectarray *) builtin_newarray(0, class_array_of(class_java_lang_Class)->vftbl);
-}
+       log_text("Java_java_lang_VMSecurityManager_getClassContext  called");
+       if (cacao_initializing) return 0;
+#ifdef __I386__
+       return cacao_createClassContextArray();
+#else
+       return 0;
 #endif
+}
 
 java_objectarray* temporaryGetClassContextHelper(methodinfo *m) {
        if (!m) {
index f2a3a4b79fbb21ce78155f8a15ad71cfe1bf62df..3a7ad0b670367896c1a9751de6d48072e82a4e87 100644 (file)
@@ -1,4 +1,4 @@
-/* native/vm/VMThrowable.c - java/lang/VMThrowable
+/* nat/VMThrowable.c - java/lang/Throwable
 
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
 
    Authors: Joseph Wenninger
 
-   $Id: VMThrowable.c 1621 2004-11-30 13:06:55Z twisti $
+   $Id: VMThrowable.c 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
-
 #include "native/jni.h"
 #include "native/native.h"
 #include "native/include/java_lang_Class.h"
@@ -64,18 +63,15 @@ JNIEXPORT java_lang_VMThrowable* JNICALL Java_java_lang_VMThrowable_fillInStackT
        if (vmthrow == NULL)
                panic("Needed instance of class  java.lang.VMThrowable could not be created");
 
-#if defined(__I386__)
-       (void) asm_get_stackTrace(&(vmthrow->vmData));
-#else
-       vmthrow->vmData=0;
+#ifdef __I386__
+       cacao_stacktrace_NormalTrace(&(vmthrow->vmData));
 #endif
-
        return vmthrow;
 }
 
 
-
-java_objectarray* generateStackTraceArray(JNIEnv *env,stacktraceelement *source,long pos,long size)
+static
+java_objectarray* generateStackTraceArray(JNIEnv *env,stacktraceelement *el,long size)
 {
        long resultPos;
        methodinfo *m;
@@ -103,13 +99,12 @@ java_objectarray* generateStackTraceArray(JNIEnv *env,stacktraceelement *source,
                return 0;
 
 /*     printf("Should return an array with %ld element(s)\n",size);*/
-       pos--;
-       
+       /*pos--;*/
        
-       for(resultPos=0;pos>=0;resultPos++,pos--) {
+       for(resultPos=0;size>0;size--,el++,resultPos++) {
                java_objectheader *element;
 
-               if (source[pos].method==0) {
+               if (el->method==0) {
                        resultPos--;
                        continue;
                }
@@ -123,25 +118,25 @@ java_objectarray* generateStackTraceArray(JNIEnv *env,stacktraceelement *source,
 #endif
 #if 0
                (*env)->CallVoidMethod(env,element,m,
-                       javastring_new(source[pos].method->class->sourcefile),
+                       javastring_new(el->method->class->sourcefile),
                        source[size].linenumber,
-                       javastring_new(source[pos].method->class->name),
-                       javastring_new(source[pos].method->name),
-                       source[pos].method->flags & ACC_NATIVE);
+                       javastring_new(el->method->class->name),
+                       javastring_new(el->method->name),
+                       el->method->flags & ACC_NATIVE);
 #else
-               if (!(source[pos].method->flags & ACC_NATIVE))setfield_critical(c,element,"fileName",          
+               if (!(el->method->flags & ACC_NATIVE))setfield_critical(c,element,"fileName",          
                "Ljava/lang/String;",  jobject, 
-               (jobject) javastring_new(source[pos].method->class->sourcefile));
+               (jobject) javastring_new(el->method->class->sourcefile));
 /*             setfield_critical(c,element,"className",          "Ljava/lang/String;",  jobject,  */
-/*             (jobject) javastring_new(source[pos].method->class->name)); */
-               setfield_critical(c,element,"declaringClass",      "Ljava/lang/String;",  jobject, 
-               (jobject) Java_java_lang_VMClass_getName(env, NULL, (java_lang_Class *) source[pos].method->class));
+/*             (jobject) javastring_new(el->method->class->name)); */
+               setfield_critical(c,element,"declaringClass",          "Ljava/lang/String;",  jobject, 
+               (jobject) Java_java_lang_VMClass_getName(env, NULL, (java_lang_Class *) el->method->class));
                setfield_critical(c,element,"methodName",          "Ljava/lang/String;",  jobject, 
-               (jobject) javastring_new(source[pos].method->name));
+               (jobject) javastring_new(el->method->name));
                setfield_critical(c,element,"lineNumber",          "I",  jint, 
-               (jint) ((source[pos].method->flags & ACC_NATIVE) ? -1:(source[pos].linenumber)));
+               (jint) ((el->method->flags & ACC_NATIVE) ? -1:(el->linenumber)));
                setfield_critical(c,element,"isNative",          "Z",  jboolean, 
-               (jboolean) ((source[pos].method->flags & ACC_NATIVE) ? 1:0));
+               (jboolean) ((el->method->flags & ACC_NATIVE) ? 1:0));
 
 
 #endif                 
@@ -161,56 +156,46 @@ java_objectarray* generateStackTraceArray(JNIEnv *env,stacktraceelement *source,
  */
 JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *env, java_lang_VMThrowable *this, java_lang_Throwable *par1)
 {
-       long  pos;
-       long  maxpos;
-       long  sizediff;
-       utf*  classname=par1->header.vftbl->class->name;
+#ifdef __I386__
+       stackTraceBuffer *buf=(stackTraceBuffer*)this->vmData;
+       u8 size;
+       stacktraceelement *el;
+       classinfo  *excClass=par1->header.vftbl->class;
        utf*  init=utf_new_char("<init>");
        utf*  throwable=utf_new_char("java/lang/Throwable");
-       stacktraceelement *el=(stacktraceelement*)this->vmData;
-
-       /*      log_text("Java_java_lang_VMThrowable_getStackTrace");
-       utf_display(par1->header.vftbl->class->name);
-       printf("\n----------------------------------------------\n");*/
-
-       sizediff=0;
-       if (el == 0) {
-               return generateStackTraceArray(env, el, 0,0);
-       }       
-
-       for (pos = 0; !((el[pos].method == 0) && (el[pos].linenumber ==-1)); pos++) {
-               if (el[pos].method==0) sizediff++;
-       }
-
-       if (pos == 0) {
-               panic("Stacktrace cannot have zero length");
-       }
-
-       pos--;
-       pos--;
-       maxpos = pos;
-       if (el[pos].method!=0) { /* if == 0 -> some builtin native */
-               if (el[pos].method->class->name == throwable && el[pos].method->name == init) {
-                       for (; pos >= 0 && el[pos].method->name == init && el[pos].method->class->name != classname; pos--) {
-/*                             log_text("ignoring:");
-                               utf_display(el[pos].method->name);
-                               log_text("");
-                               utf_display(el[pos].method->class->name);
-                               log_text("");*/
-
-                       };
-                       pos--;
-                       if (pos < 0) {
-                               log_text("Invalid stack trace for Throwable.getStackTrace()");
+       long destElementCount;
+       stacktraceelement *tmpEl;
 
+       if (!buf) panic("Invalid java.lang.VMThrowable.vmData field in java.lang.VMThrowable.getStackTrace native code");
+       
+       size=buf->full;
+       if (size<=2) panic("Invalid java.lang.VMThrowable.vmData field in java.lang.VMThrowable.getStackTrace native code (length<=2)");
+       size -=2;
+       el=&(buf->start[2]); /* element 0==VMThrowable.fillInStackTrace native call, 1==Throwable.fillInStackTrace*/
+       if (el->method!=0) { /* => not a builtin native wrapper*/
+               if ((el->method->class->name==throwable) && (el->method->name == init) ){
+                       /* We assume that we are within the initializer of the exception object, the exception object itself should not appear
+                               in the stack trace, so we skip till we reach the first function, which is not an init function or till we reach the exception object class*/
+                       for (; (size>0) && (el->method->name==init) && (el->method->class!=excClass); el++, size--) {
+                               /* just loop*/
+                       }
+                       size --;
+                       el++;
+                       if (size<1) {
+                               log_text("Invalid stacktrace for VMThrowable.getStackTrace()");
                        }
                }
        }
+
        
-       /* build the result array*/
-       pos++; /*arraysize*/
+       for (destElementCount = 0, tmpEl=el; size>0; size--,tmpEl++) {
+               if (tmpEl->method!=0) destElementCount++;
+       }
 
-       return generateStackTraceArray(env,el,pos,pos-sizediff);        
+       return generateStackTraceArray(env,el,destElementCount);
+#else
+       return 0;
+#endif
 }
 
 
index 94051a3762c7fadd59994040ce0461a0b29a366c..8f5f2c63b99bd23e6428be21cdf933d3fc481b45 100644 (file)
@@ -31,7 +31,7 @@
             Philipp Tomsich
                        Edwin Steiner
 
-   $Id: global.h 1658 2004-12-03 15:28:15Z twisti $
+   $Id: global.h 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
@@ -303,6 +303,7 @@ struct native_stackframeinfo {
        void *oldThreadspecificHeadValue;
        void **addressOfThreadspecificHead;
        methodinfo *method;
+       void *beginOfJavaStackframe; /*only used if != 0*/
        void *returnToFromNative;
 
 #if 0
@@ -327,6 +328,15 @@ struct stacktraceelement {
 
 typedef struct stacktraceelement stacktraceelement;
 
+typedef struct stackTraceBuffer {
+        int needsFree;
+        struct stacktraceelement* start;
+        size_t size;
+        size_t full;
+} stackTraceBuffer;
+
+
+
 /* data structure for calls from c code to java methods */
 
 struct jni_callblock {
index 0af87fd086824e36146f7e2882d5248ad4128fb5..9ed1690355dea6d1b2a19d92ab6032708a1fd443 100644 (file)
@@ -29,7 +29,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: asmpart.h 1661 2004-12-03 15:45:56Z twisti $
+   $Id: asmpart.h 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
@@ -128,6 +128,9 @@ extern threadcritnode asm_criticalsections;
 
 void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out);
 
+void asm_prepare_native_stackinfo(void*ret,void*stackbegin);
+void asm_remove_native_stackinfo();
+
 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
 void asm_perform_threadswitch(u1 **from, u1 **to, u1 **stackTop);
 u1*  asm_initialize_thread_stack(void *func, u1 *stack);
index 12fc08811bcf74676f21cc590940fede56f5da73..a2300e621348f624d2e5c61d010db077d0561045 100644 (file)
    memory. All functions writing values into the data area return the offset
    relative the begin of the code area (start of procedure).   
 
-   $Id: codegen.inc 1662 2004-12-03 15:46:18Z twisti $
+   $Id: codegen.inc 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
+#ifndef _CODEGEN_INC_H_
+#define _CODEGEN_INC_H_
 
 #include <string.h>
 
@@ -965,16 +967,20 @@ static void codegen_resolve_native(methodinfo *m,void **insertionPoint,void *jmp
        void *sym;
 
   builtin_monitorenter((java_objectheader*) m);
+#if defined(__X86_64__)
+  if ((*((s4*)jmpPatchTarget))==((s4)jmpTarget)) {
+#else
   if ((*jmpPatchTarget)==jmpTarget) {
+#endif
     builtin_monitorexit((java_objectheader*) m);
     return;
   }
-  log_text("trying to resolve a native method");
+  /*log_text("trying to resolve a native method");
   utf_display(m->class->name);
-  utf_display(m->name);
+  utf_display(m->name);*/
   
-  lib=dlopen(0,RTLD_NOW | RTLD_GLOBAL);
-  if (lib) {
+  lib=dlopen(0,RTLD_NOW | RTLD_GLOBAL); /* open the application execution image */
+  if (lib) { /* it did work -> good, otherwise fail with error*/
     int ok=0;
     /*generate the name of the native function in the form Java_package1_package2...._classname_methodname*/
     nativeLen=/*Java_*/5+strlen(m->class->name->text)+/*_*/1+strlen(m->name->text)+/*\0*/1;
@@ -999,38 +1005,46 @@ static void codegen_resolve_native(methodinfo *m,void **insertionPoint,void *jmp
 
 /*     printf("nativename: %s\n",nativeName); */
 
+    /*try to find the symbal fo the function */
     sym=dlsym(lib,nativeName);
     if (sym) {
-      ok=1;
-      log_text("resolved");
+      ok=1; /* it worked, everything fine */
+      /*log_text("resolved");*/
       MFREE(nativeName,char,nativeLen);
-    } else {
+    } else { /* we didn't find the symbol yet, try to resolve an overlaoded function (having the types in it's name*/
       size_t overloadedNativeLen=nativeLen+codegen_overloadPartLen(m->descriptor);
       char *overloadedNative=MNEW(char,overloadedNativeLen);
       sprintf(overloadedNative,"%s",nativeName);
       MFREE(nativeName,char,nativeLen);
       codegen_fillInOverloadPart(overloadedNative,m->descriptor);
-      log_text("symbol not found,trying harder (overloaded member ?)");
+      /*log_text("symbol not found,trying harder (overloaded member ?)");*/
       sym=dlsym(lib,overloadedNative);
       if (sym) {
         MFREE(overloadedNative,char,overloadedNativeLen);
-        ok=1;
-        log_text("resolved");
+        ok=1; /* we eventually found the native function -> everything ok*/
+        /*log_text("resolved");*/
       } else { 
+         /* we failed to find the native function within the execution image (app + loaded libraries) -> will cause an exit*/
          MFREE(overloadedNative,char,overloadedNativeLen);
          log_text("It was not possible to find the native function implementation. Not even in overloading case");
       }
    }
+    /* patch the address of the native function into the stub and make the stub jump over this function call in the future */
     if (ok) {
       (*insertionPoint)=sym;
+#if defined(__X86_64__)
+      (*((s4*)jmpPatchTarget))=(s4)jmpTarget;
+#else
       (*jmpPatchTarget)=jmpTarget;
+#endif
       builtin_monitorexit((java_objectheader *) m );
       return;
     }
 
   } else log_text("library not found");
   
-
+  /* There was an error, either the app image could not be opened or the native does not exist in the application and the
+     loaded libraries. Show an additional error and exit the vm*/
   {
     char *info;
     size_t slen;
@@ -1047,6 +1061,8 @@ static void codegen_resolve_native(methodinfo *m,void **insertionPoint,void *jmp
 #endif
 
 
+#endif
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
diff --git a/src/vm/jit/i386/asmoffsets.h b/src/vm/jit/i386/asmoffsets.h
new file mode 100644 (file)
index 0000000..801ffdf
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __ASMOFFSETS_H_
+#define __ASMOFFSETS_H_
+
+/* data segment offsets */
+
+#define MethodPointer           -4
+#define FrameSize               -8
+#define IsSync                  -12
+#define IsLeaf                  -16
+#define IntSave                 -20
+#define FltSave                 -24
+#define LineNumberTableSize     -28
+#define LineNumberTableStart    -32
+#define ExTableSize             -36
+#define ExTableStart            -36
+
+#define ExEntrySize     -16
+#define ExStartPC       -4
+#define ExEndPC         -8
+#define ExHandlerPC     -12
+#define ExCatchType     -16
+
+
+#define LineEntrySize   -8
+#define LinePC          0
+#define LineLine        -4
+
+#endif
index 602525902bc72a4c257a8fcb58e75437abd9a850..0908b73c68500b62659ddab49d9218942c791609 100644 (file)
             Reinhard Grafl
             Christian Thalinger
 
-   $Id: asmpart.S 1623 2004-11-30 14:18:19Z twisti $
+   $Id: asmpart.S 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
 
 #include "config.h"
 #include "vm/jit/i386/offsets.h"
-
-
-/* data segment offsets */
-
-#define MethodPointer          -4
-#define FrameSize              -8
-#define IsSync                 -12
-#define IsLeaf                 -16
-#define IntSave                -20
-#define FltSave                -24
-#define LineNumberTableSize    -28
-#define LineNumberTableStart   -32
-#define ExTableSize            -36
-#define ExTableStart           -36
-
-#define ExEntrySize     -16
-#define ExStartPC       -4
-#define ExEndPC         -8
-#define ExHandlerPC     -12
-#define ExCatchType     -16
-
-
-#define LineEntrySize  -8
-#define LinePC         0
-#define LineLine       -4
+#include "vm/jit/i386/asmoffsets.h"
 
 
 #define itmp1    %eax
        .globl asm_initialize_thread_stack
        .globl asm_switchstackandcall
        .globl asm_getcallingmethod
-       .globl Java_java_lang_VMSecurityManager_getClassContext
-       .globl Java_java_lang_VMSecurityManager_currentClassLoader    
        .globl asm_builtin_new
-       .globl asm_get_stackTrace
        .globl asm_criticalsections
        .globl asm_getclassvalues_atomic
-
+       .globl asm_prepare_native_stackinfo
+       .globl asm_remove_native_stackinfo
 /*************************** imported functions *******************************/
 
        .globl jit_compile
        .globl builtin_trace_exception
        .globl class_java_lang_Object
        .globl codegen_findmethod
-/*     .globl codegen_findmethod1*/
-       .globl builtin_asm_createclasscontextarray
-       .globl builtin_asm_getclassloader
        .globl callgetexceptionptrptr
        .globl asm_throw_and_handle_exception
        .globl asm_throw_and_handle_hardware_arithmetic_exception
@@ -400,7 +371,14 @@ L_exception:
        pop     %ecx                /* delete return address                      */
        sub     $2,%ecx             /* faulting address is return adress - 2      */
 
-L_refillinStacktrace:
+L_refillinStacktrace:               /*a compilation error should cause a stacktrace
+                                    which starts at the method call, which caused
+                                    the compilation of the new function. Until this
+                                    point the trace is invalid anyways, since it is
+                                    not complete. Compared to other runtimes it will
+                                    not be correct either, since we report eg class
+                                    not found errors too early, since we always
+                                    compile methods completely*/
        push %ecx               /* store fault adress */
        push %eax               /* temporarily save exception pointer*/
        call builtin_asm_get_stackframeinfo
@@ -457,18 +435,6 @@ asm_handle_nat_exception:
                add     $4,%esp                                         /* clear return address of native stub */
                
 asm_handle_exception:
-#if 0
-               push %ebp
-               mov %esp,%ebp
-               push %eax       /* exception pointer */
-               push %ecx       /* excepiton pc */
-
-               call asm_get_stackTrace
-
-               pop %ecx
-               pop %eax
-               pop %ebp
-#endif
 asm_handle_exception_loop:
                push    %ebp
                mov     %esp,%ebp
@@ -704,33 +670,25 @@ asm_check_clinit:
        test    %eax,%eax
        jnz     L_is_initialized
 
-#if 0
-       sub     $16,%esp                    /* build stack frame (4 * 4 bytes)    */
-       mov     %eax,(%esp)                 /* put classpointer on stack          */
-       call    builtin_asm_get_stackframeinfo
-
-       movl    $0,12(%esp)
-       mov     %eax,8(%esp)
-       mov     (%eax),%ecx
-       mov     %ecx,4(%esp)
-       mov     %esp,%ecx
-       add     $4,%ecx
-       mov     %ecx,(%eax)
-#endif
+       /*3*4 bytes*/
+       mov 16(%esp),itmp1
+       push itmp1                        /*return adress into java machine code */
+       mov 4(%esp),itmp1
+       push itmp1                        /*begin of java stack frame*/
+       pushl $0                           /*internal (invisible) method*/
+       call asm_prepare_native_stackinfo /*puts additional 2 *4 bytes of
+                                               data onto the stack */
 
        sub     $4,%esp
-       mov     4+4(%esp),itmp1             /* get class pointer                  */
+       mov     20+4+4(%esp),itmp1          /* get class pointer                  */
        mov     itmp1,(%esp)                /* store class pointer as a0          */
        call    class_init                  /* call class_init function           */
        add     $4,%esp
 
-#if 0
-       mov     4(%esp),%edx
-       mov     8(%esp),%ecx
-       mov     %edx,(%ecx)
-
-       add     $16,%esp
-#endif
+       call asm_remove_native_stackinfo  /* removes 4* 4 bytes and leaves ret
+                                                into java machine code on stack  */
+       add     $4,%esp                   /* ret address no longer needed, is still
+                                               on stack a few bytes above */
 
        test    %eax,%eax                   /* we had an exception                */
        je      L_initializererror
@@ -1045,11 +1003,18 @@ nb_aastore_null:
        jmp             asm_handle_exception
 #endif
 nb_aastore_bound:
-       push    %ecx                        /* itmp2 contains array index         */
+       add     $12,%esp
+       mov     %ecx,%eax                        /* itmp2 contains array index         */
+       pushl   $0  /*directly below return adress*/
+       pushl   $0  /*internal (invisible) method*/
+       call    asm_prepare_native_stackinfo /* puts 2*4 bytes onto stack*/
+
+       push    %eax
        call    new_arrayindexoutofboundsexception
        add     $(1*4),%esp
 
-       add     $12,%esp
+       call    asm_remove_native_stackinfo /*return adress is the first on stack again*/
+
        pop     %ecx                        /* delete return address              */
        sub     $2,%ecx                     /* faulting address is return adress - 2 */
        jmp     asm_handle_exception
@@ -1207,224 +1172,39 @@ asm_switchstackandcall:
        ret
 
                
-Java_java_lang_VMSecurityManager_currentClassLoader:
-       mov  cacao_initializing,%eax
-       test %eax,%eax
-       jz   Java_java_lang_VMSecurityManager_cont
-
-       mov $0,%eax
-       ret
-Java_java_lang_VMSecurityManager_cont:
-       lea  builtin_asm_getclassloader,%eax 
-       push %eax       /*store collector function pointer*/
-       jmp getClassContext_begin
-Java_java_lang_VMSecurityManager_getClassContext:
-       lea  builtin_asm_createclasscontextarray,%eax 
-       push %eax /*store collector function pointer*/
-getClassContext_begin: /*start the real work*/
-
-       mov %esp,%eax
-       sub $4,%eax
-       sub $68,%esp /*64 memory location without overwriting return adress and collector function adress*/
-       mov %esp,%ebx   /*end of allocated memory block for classpointers is the adress of the working data block +4 */
-       push $0 /*%esp+32 was native*/
-       push %eax /*%esp+24 blkbegin*/
-       push %eax /*%esp+20 currentpos*/
-       push %ebx /*%esp+16 blkend*/
-
-       call builtin_asm_get_threadrootmethod
-       push %eax /*%esp+12*/
-       movl 104(%esp),%eax /*(stack contains: threadRootMethod,blkend,blkpos,blkbegin,was native, data(64kB),collector,ret,env,class,frame stack info of stub, we want the frame stack info  of thestub*/
-       movl %esp,%edx
-       addl $116, %edx
-       push %edx /*esp+8*/ /*position of return address of native stub*/
-       call builtin_asm_get_stackframeinfo
-/*     movl (%eax),%eax*/ /*TEST*/
-       push 0(%eax) /*esp+4*/ /*address of frame info block*/
-       movl 124(%esp),%edx
-
-/*DEBUG*/
-/*     mov %esp,%eax
-       addl $116,%eax
-       push %eax
-       call i386_native_stub_debug
-       pop %eax*/
-
-       push %edx /*esp+0*/ /*return adress out of native stub*/
-       call codegen_findmethod /*find calling java method, this one is still to be skipped (==SecurityManager.getClassContext (or .currentClassLoader)*/
-
-/*DEBUGGING*/
-/*     push %eax
-       movl MethodPointer(%eax),%eax
-       push %eax
-       call temporaryGetClassContextHelper
-       pop %eax
-       call traverseStackInfo
-       pop %eax
-*/
-
-       movl 20(%esp),%edx
-       movl MethodPointer(%eax),%ebx
-       movl offclassmethodinfo(%ebx),%ecx
-       movl %ecx,(%edx)
-       subl $4,%edx
-       movl %edx,20(%esp)
-
-       mov 8(%esp),%ebx /*pos of return adress */
-       add FrameSize(%eax),%ebx
-       add $4,%ebx     /*adress of new return adress (out of Securitymanager.*/
-       mov %ebx,8(%esp) 
-       mov %eax,(%esp)
-
-       /* by now we have skipped this method call*/
-
-getClassContext_next:  
-       movl 8(%esp),%eax
-       movl (%eax),%eax
-       movl %eax,(%esp) /*return adress*/
-
-       call codegen_findmethod
-
-       cmp $1,32(%esp)
-       mov 8(%esp),%ebx
-       add FrameSize(%eax),%ebx
-       add $4,%ebx
-       mov %ebx,8(%esp) /*store adress of next return adress*/
-getClassContext_nextRetStored:
-
-       mov MethodPointer(%eax),%ecx    /*get struct methodinfo*/
-
-       cmp $0,%ecx
-       je getClassContext_nativeCall
-       /*save class pointer*/
-       movl $0,32(%esp)
-getClassContext_saveClassPointer:
-       movl 20(%esp),%ebx      /*get temporary memory adress in stack*/
-       movl offclassmethodinfo(%ecx),%edx /* get class pointer of method*/
-       movl %edx,(%ebx) /*save */
-       sub $4,%ebx     /*calculate next position */
-       movl %ebx,20(%esp) /* check if the new adress would overwrite our working data */
-       cmp %ebx,16(%esp)
-       je getClassContext_incStack
-getClassContext_checkLeave:
-       
-       cmp 12(%esp),%ecx       /*check if we reached the toplevel method of our thread*/
-       je  getClassContext_leave /*yes ->leave*/
-
-/*DEBUGING*/
-/*     mov %ecx,(%esp)
-       call temporaryGetClassContextHelper
-*/
-       
-       
-       jmp getClassContext_next /*continue*/
-
-
-getClassContext_nativeCall:
-       movl $1,32(%esp)
-       movl 4(%esp),%eax       /*get top most element on stackframe help information stack*/
-       test %eax,%eax
-       jz getClassContext_leave
-       movl 0(%eax),%ecx 
-       movl %ecx,4(%esp)
-       addl $8,%eax
-       movl (%eax),%ecx
-       addl $4,%eax
-       movl %eax,8(%esp)
-       
-       cmp $0,%ecx
-       je getClassContext_checkLeave
-       jmp getClassContext_saveClassPointer
-
-getClassContext_incStack:
-       /*make another 64 in our temporary storage free and store the workingdata */
-       movl %esp,%edx
-       subl $40,%esp /*should be 32*/
-       push 32(%edx)
-       push 28(%edx)
-       push 24(%edx)
-       push 20(%edx)
-       push 16(%edx)
-       push 12(%edx)
-       push 8(%edx)
-       push 4(%edx)
-       push 0(%edx)
-       subl $64,16(%esp)
-
-       jmp getClassContext_checkLeave /* continue */
-
-getClassContext_leave:
-/*DEBUGING*/
-/*     mov %ecx,(%esp)
-       call temporaryGetClassContextHelper*/
-
-       /*call collector function with begin/end of temporary classarray*/
-       push 24(%esp)
-       push 24(%esp)
-       
-       movl 32(%esp),%eax
-       add $4,%eax
-       movl (%eax),%ebx
-       call *%ebx
-
-       /* free stack memory of this function*/
-       mov 32(%esp),%esp
-       add $8,%esp
-       ret
-
-
 asm_throw_and_handle_exception:
-       sub $20,%esp /*build stack frame*/
-       mov %ecx,16(%esp) /*save eip of problem */
-       mov %eax,(%esp)
-       movl $0,12(%esp) /*internal function -> no function description */
-       call builtin_asm_get_stackframeinfo
-       mov %eax,8(%esp)
-       mov (%eax),%ecx
-       mov %ecx,4(%esp)
-       mov %esp,%ecx
-       add $4,%ecx
-       mov %ecx,(%eax)
+       push %ecx
+       pushl $0 /* the pushed XPC is directly below the java frame*/
+       pushl $0
+       call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
        
-/*     mov string_java_lang_NullPointerException,%eax
-       mov %eax,(%esp)*/
-        call new_exception
        push %eax
-       mov 8(%esp),%eax
-       mov 12(%esp),%ecx
-       mov %eax,(%ecx)
-       pop %eax
-       add $16,%esp
+        call new_exception
+       add $4,%esp   /*remove parameter*/
+
+       call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
+
        pop %ecx
        jmp asm_handle_exception
        ret /*should never be reached */
 
 asm_throw_and_handle_hardware_arithmetic_exception:
-       sub $24,%esp /*build stack frame*/
-       mov %ecx,20(%esp) /*save eip of problem */
        
-       movl $0,16(%esp) /*internal function -> no function description */
-       call builtin_asm_get_stackframeinfo
-       mov %eax,12(%esp)
-       mov (%eax),%ecx
-       mov %ecx,8(%esp)
-       mov %esp,%ecx
-       add $8,%ecx
-       mov %ecx,(%eax)
+       push %ecx
+       pushl $0 /* the pushed XPC is directly below the java frame*/
+       pushl $0
+       call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
        
-       mov string_java_lang_ArithmeticException,%eax
-       mov %eax,(%esp)
        mov string_java_lang_ArithmeticException_message,%eax
-       mov %eax,4(%esp)
+       push %eax
+       mov string_java_lang_ArithmeticException,%eax
+       push %eax
 
        call new_exception_message
+       add $8,%esp /*remove parameters */
+
+       call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained below*/
 
-       push %eax
-       mov 12(%esp),%eax
-       mov 16(%esp),%ecx
-       mov %eax,(%ecx)
-       pop %eax
-       add $20,%esp
        pop %ecx
        jmp asm_handle_exception
        ret /*should never be reached */
@@ -1442,6 +1222,13 @@ asm_builtin_new:
                test    %ecx,%ecx
                jnz             L_builtin_new_noinit
 
+               mov 4(%esp),%eax /* class pointer, is kept during the asm_prepare... calls */
+
+               /* 2 *4 bytes, the return adress is used directy */
+               pushl $0  /* the structure is placed directly below the java stackframe*/
+               pushl $0  /* builtin (invisible) method */
+               call  asm_prepare_native_stackinfo /*puts 2*4 additional bytes on stack*/
+#if 0
                 sub             $16,%esp                                 /* build stack frame (4 * 4 bytes) */
 
                 mov             20(%esp),%eax
@@ -1455,15 +1242,20 @@ asm_builtin_new:
                mov     %esp,%ecx
                add     $4,%ecx
                mov     %ecx,(%eax)
-
+#endif
+               push    %eax
                 call    builtin_new
+               add     $4,%esp
 
+               call    asm_remove_native_stackinfo /*first element on stack is return adress again*/
+#if 0          
+               call    
                mov     4(%esp),%ebx
                mov     8(%esp),%ecx
                mov     %ebx,(%ecx)
 
                 add             $16,%esp
-
+#endif
                jmp L_builtin_new_patch
 
 
@@ -1485,104 +1277,6 @@ L_builtin_new_patch:
 
 
 
-asm_get_stackTrace:
-       push %ebp /*(%ebp-4)*/
-       mov %esp,%ebp
-       add $4,%ebp
-       push %edi /*(%ebp-8)*/
-       push %esi /*(%ebp-12)*/
-       push %ebx /*(%ebp-16)*/
-       call builtin_asm_get_stackframeinfo
-       movl (%eax),%eax
-       pushl 0(%eax) /*(%ebp-20)*/
-       lea 12(%eax),%edi
-       call builtin_asm_get_threadrootmethod
-       pushl %eax /*(%ebp-24)*/
-
-       pushl (%edi)
-asm_get_stackTraceLoop:
-       call codegen_findmethod
-       mov %eax,%esi
-       add $4,%esp
-       pushl $1 /*no indent*/
-
-       mov (%edi),%edx
-       sub $4,%edx
-
-get_stackTrace_line:
-       movl LineNumberTableSize(%esi),%ecx
-       test    %ecx,%ecx /* skip if empty line table */
-       je      get_stackTrace_noLineInfo
-
-       movl LineNumberTableStart(%esi),%ebx
-       
-get_stackTrace_lineLoop:
-       cmp %edx,LinePC(%ebx)
-       jg get_stackTrace_nextLineInfo
-
-       pushl LineLine(%ebx)
-       jmp get_stackTrace_cont
-
-get_stackTrace_nextLineInfo:   
-       lea LineEntrySize(%ebx),%ebx
-       dec %ecx
-       test %ecx,%ecx
-
-       jne get_stackTrace_lineLoop
-
-get_stackTrace_noLineInfo:
-       pushl $0
-
-
-get_stackTrace_cont:
-       pushl (%edi) /*4*/
-       pushl MethodPointer(%esi)
-       pushl $0 /*8(%ebp)*/ /*exception ptr*/
-       call builtin_trace_exception
-       add $12,%esp
-
-       movl MethodPointer(%esi),%eax
-       movl %eax,4(%esp)
-       test %eax,%eax
-       je get_stackTrace_nat
-
-       cmp %eax,-24(%ebp)
-       je get_stackTrace_leave
-
-       mov FrameSize(%esi),%eax
-       add $4,%edi
-       add %eax,%edi
-       pushl (%edi)
-       jmp asm_get_stackTraceLoop
-
-get_stackTrace_nat:
-       add $8,%esp
-       movl -20(%ebp),%eax
-       cmp $0,%eax
-       je get_stackTrace_leave
-       movl  0(%eax),%ebx
-       movl  %ebx,-20(%ebp)
-       pushl 8(%eax)
-       pushl $0
-       lea 12(%eax),%edi
-       pushl (%edi)
-       jmp asm_get_stackTraceLoop
-
-get_stackTrace_leave:
-       mov %esp,%eax
-       lea -24(%ebp),%ebx
-       push %ebx
-       push %eax
-       push 4(%ebp)
-       call builtin_stacktrace_copy
-
-       lea -16(%ebp),%esp
-       pop %ebx
-       pop %esi
-       pop %edi
-       pop %ebp
-       ret
-
 
 asm_getclassvalues_atomic:
 _crit_restart2:
@@ -1614,6 +1308,107 @@ asm_criticalsections:
 #endif
        .long 0
 
+
+
+/************************ function asm_prepare_native_stackinfo ****************************
+*                                                                                          *
+*    creates a stackfame for the begin of a native function (either builtin or not )       *
+*    expected stack at begin of function                                                   *
+*                                        ....                                              *
+*                   address of the jit call which invokes the native                       *
+*                   begin address of stack frame of the java method                        *
+*                   method pointer or 0 (for built ins)                                    *
+*                   return address                                                         *
+*                                                                                          *
+*    at end of function:                                                                   *
+*                                          ...                                             *
+*                   address of the jit call which invokes the native                       *
+*                   begin address of stack frame of the java method                        *
+*                   method pointer or 0 (for built ins)                                    *
+*                   address of thread specific top of native list                          *
+*                   old value of thread specific head                                      *
+*                   return address                                                         *
+*                                                                                          *
+*                                        ....                                              *
+* This thing is less efficient than the original #define (callerside)                      *
+* destroyes REG_ITMP2, keeps REG_ITMP1                                                     *
+********************************************************************************************/
+
+
+asm_prepare_native_stackinfo:
+        sub $8,%esp
+        mov 8(%esp),%ecx
+        mov %ecx,(%esp)
+        push %eax
+        lea     builtin_asm_get_stackframeinfo,%ecx
+        call    *%ecx
+        mov %eax, 12(%esp)
+        mov (%eax),%ecx
+        mov %ecx,8(%esp)
+        mov %esp,%ecx
+        add $8,%ecx
+        mov %ecx,(%eax)
+        pop %eax
+        ret
+#if 0
+#define PREPARE_NATIVE_STACKINFO \
+    i386_push_reg(cd, REG_ITMP1);       /*save itmp1, needed by some stubs */ \
+    i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
+    i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
+    i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/ \
+    i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
+    i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/ \
+    i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/ \
+    i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
+    i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4);     /* store value on stack */ \
+    i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
+    i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
+    i386_mov_imm_membase(cd, 0,REG_SP, 2*4);    /* builtin */
+#endif
+
+
+/************************ function asm_remove _native_stackinfo *******************************************
+*                                                                                                         *
+*    creates a stackfame for the begin of a native function (either builtin or not)                       *
+*    expected stack at begin of function                                                                  *
+*                   address of the jit call which invokes the native                                      *
+*                   begin address of stack frame of the java method                                       *
+*                   method pointer or 0 (for built ins)                                                   *
+*                   address thread specific top of native list                                            *
+*                   old value of thread specific head                                                     *
+*                   return address                                                                        *
+*                                                                                                         *
+*    at end of function:                                                                                  *
+*                             ....                                                                        *
+*                   return adresss of the jit call which invokes the native                               *
+*                   return address                                                                        *
+*                                                                                                         *
+*                   REG_ITMP2_XPC = address of the jit call which invokes the native                      *
+*                                                                                                         *
+*                                                                                                         *
+* This thing is less efficient than the original #define (callerside), uses ITMP3,uses ITMP3,keeps ITMP1  *
+***********************************************************************************************************/
+
+asm_remove_native_stackinfo:
+        mov 4(%esp),%ecx
+        mov 8(%esp),%edx
+        mov %ecx,(%edx)
+        pop %edx
+        add $16,%esp
+        push %edx
+       ret
+
+#if 0
+#define REMOVE_NATIVE_STACKINFO \
+    i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
+    i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
+    i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
+    i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
+#endif
+
+
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index f3065623e1ee7cbb6f84fc9f0f271f434f51abbd..00be85b017e1ced23cd57b288ed9dc44b20eb08c 100644 (file)
@@ -28,7 +28,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.c 1641 2004-12-01 13:13:31Z christian $
+   $Id: codegen.c 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
@@ -37,6 +37,9 @@
 
 #include <stdio.h>
 #include <ucontext.h>
+#ifdef __FreeBSD__
+#include <machine/signal.h>
+#endif
 
 #include "config.h"
 #include "native/jni.h"
@@ -53,6 +56,9 @@
 #include "vm/jit/i386/codegen.h"
 #include "vm/jit/i386/emitfuncs.h"
 #include "vm/jit/i386/types.h"
+#include "vm/jit/i386/asmoffsets.h"
+#include "vm/jit/stacktrace.inc"
+
 
 /* register descripton - array ************************************************/
 
@@ -106,33 +112,18 @@ void codegen_general_stubcalled() {
 void thread_restartcriticalsection(ucontext_t *uc)
 {
        void *critical;
+#ifdef __FreeBSD__
+       if ((critical = thread_checkcritical((void*) uc->uc_mcontext.mc_eip)) != NULL)
+               uc->uc_mcontext.mc_eip = (u4) critical;
+#else
        if ((critical = thread_checkcritical((void*) uc->uc_mcontext.gregs[REG_EIP])) != NULL)
                uc->uc_mcontext.gregs[REG_EIP] = (u4) critical;
+
+#endif
 }
 #endif
 
 
-#define PREPARE_NATIVE_STACKINFO \
-    i386_push_reg(cd, REG_ITMP1);      /*save itmp1, needed by some stubs */ \
-    i386_alu_imm_reg(cd, I386_SUB, 2*4, REG_SP); /* build stack frame (2 * 4 bytes), together with previous =3*4 */ \
-    i386_mov_imm_reg(cd, (s4) codegen_stubcalled,REG_ITMP1); \
-    i386_call_reg(cd, REG_ITMP1);                /*call    codegen_stubcalled*/ \
-    i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo,REG_ITMP1); \
-    i386_call_reg(cd, REG_ITMP1);                /*call    builtin_asm_get_stackframeinfo*/ \
-    i386_mov_reg_membase(cd, REG_RESULT,REG_SP,1*4); /* save thread pointer  to native call stack*/ \
-    i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); /* get old value of thread specific native call stack */ \
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,0*4);     /* store value on stack */ \
-    i386_mov_reg_membase(cd, REG_SP,REG_RESULT,0); /* store pointer to new stack frame information */ \
-    i386_mov_membase_reg(cd, REG_SP,2*4,REG_ITMP1); /* restore ITMP1, need for some stubs*/ \
-    i386_mov_imm_membase(cd, 0,REG_SP, 2*4);    /* builtin */ 
-
-
-#define REMOVE_NATIVE_STACKINFO \
-    i386_mov_membase_reg(cd, REG_SP,0,REG_ITMP2); \
-    i386_mov_membase_reg(cd, REG_SP,4,REG_ITMP3); \
-    i386_mov_reg_membase(cd, REG_ITMP2,REG_ITMP3,0); \
-    i386_alu_imm_reg(cd, I386_ADD,3*4,REG_SP);
-
 
 /* NullPointerException signal handler for hardware null pointer check */
 
@@ -141,8 +132,13 @@ void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
        sigset_t nsig;
 /*     long     faultaddr; */
 
-    struct ucontext *_uc = (struct ucontext *) _p;
-    struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
+#ifdef __FreeBSD__
+       ucontext_t *_uc = (ucontext_t *) _p;
+       mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
+#else
+       struct ucontext *_uc = (struct ucontext *) _p;
+       struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
+#endif
        struct sigaction act;
 
        /* Reset signal handler - necessary for SysV, does no harm for BSD */
@@ -158,15 +154,20 @@ void catch_NullPointerException(int sig, siginfo_t *siginfo, void *_p)
        act.sa_flags = SA_SIGINFO;
        sigaction(sig, &act, NULL);                          /* reinstall handler */
 
-               sigemptyset(&nsig);
-               sigaddset(&nsig, sig);
-               sigprocmask(SIG_UNBLOCK, &nsig, NULL);           /* unblock signal    */
+       sigemptyset(&nsig);
+       sigaddset(&nsig, sig);
+       sigprocmask(SIG_UNBLOCK, &nsig, NULL);           /* unblock signal    */
 
-               sigctx->ecx = sigctx->eip;                       /* REG_ITMP2_XPC     */
-               sigctx->eax = (u4) string_java_lang_NullPointerException;
-               sigctx->eip = (u4) asm_throw_and_handle_exception;
-               
-               return;
+#ifdef __FreeBSD__
+       sigctx->mc_ecx = sigctx->mc_eip;     /* REG_ITMP2_XPC*/
+       sigctx->mc_eax = (u4) string_java_lang_NullPointerException;
+       sigctx->mc_eip = (u4) asm_throw_and_handle_exception;
+#else
+       sigctx->ecx = sigctx->eip;             /* REG_ITMP2_XPC     */
+       sigctx->eax = (u4) string_java_lang_NullPointerException;
+       sigctx->eip = (u4) asm_throw_and_handle_exception;
+#endif
+       return;
 
 /*     } else { */
 /*             faultaddr += (long) ((instr << 16) >> 16); */
@@ -184,8 +185,15 @@ void catch_ArithmeticException(int sig, siginfo_t *siginfo, void *_p)
 
 /*     void **_p = (void **) &sig; */
 /*     struct sigcontext *sigctx = (struct sigcontext *) ++_p; */
-    struct ucontext *_uc = (struct ucontext *) _p;
-    struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
+
+#ifdef __FreeBSD__
+       ucontext_t *_uc = (ucontext_t *) _p;
+       mcontext_t *sigctx = (mcontext_t *) &_uc->uc_mcontext;
+#else
+       struct ucontext *_uc = (struct ucontext *) _p;
+       struct sigcontext *sigctx = (struct sigcontext *) &_uc->uc_mcontext;
+#endif
+
        struct sigaction act;
 
        /* Reset signal handler - necessary for SysV, does no harm for BSD        */
@@ -199,9 +207,13 @@ void catch_ArithmeticException(int sig, siginfo_t *siginfo, void *_p)
        sigaddset(&nsig, sig);
        sigprocmask(SIG_UNBLOCK, &nsig, NULL);               /* unblock signal    */
 
-       sigctx->ecx = sigctx->eip;                           /* REG_ITMP2_XPC     */
+#ifdef __FreeBSD__
+       sigctx->mc_ecx = sigctx->mc_eip;                 /* REG_ITMP2_XPC     */
+       sigctx->mc_eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
+#else
+       sigctx->ecx = sigctx->eip;                     /* REG_ITMP2_XPC     */
        sigctx->eip = (u4) asm_throw_and_handle_hardware_arithmetic_exception;
-
+#endif
        return;
 }
 
@@ -4466,7 +4478,11 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
 
                        i386_alu_imm_reg(cd, I386_SUB, 1 * 4, REG_SP);
                        i386_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0 * 4);
@@ -4474,7 +4490,9 @@ gen_method: {
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
                        i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4514,14 +4532,23 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
+
 
                        i386_mov_imm_reg(cd, (u4) new_negativearraysizeexception, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
                        /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
 
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4561,14 +4588,22 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_mov_imm_reg(cd, (u4) new_classcastexception, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
                        /*i386_alu_imm_reg(cd, I386_ADD, 1 * 4, REG_SP);*/
 
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4608,12 +4643,21 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
+
 
                        i386_mov_imm_reg(cd, (u4) new_arithmeticexception, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4653,7 +4697,12 @@ gen_method: {
 
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_mov_imm_reg(cd, (s4) codegen_general_stubcalled, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);                
@@ -4701,7 +4750,10 @@ java stack at this point*/
                        i386_pop_reg(cd, REG_ITMP1_XPTR);
                        i386_pop_reg(cd, REG_ITMP3); /* just remove the no longer needed 0 from the stack*/
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
                        i386_pop_reg(cd, REG_ITMP2_XPC);
 
@@ -4741,7 +4793,13 @@ java stack at this point*/
                        
                        i386_push_reg(cd, REG_ITMP2_XPC);
 
-                       PREPARE_NATIVE_STACKINFO;
+                       /*PREPARE_NATIVE_STACKINFO;*/
+                       i386_push_imm(cd,0); /* the pushed XPC is directly below the java frame*/
+                       i386_push_imm(cd,0);
+                       i386_mov_imm_reg(cd,(s4)asm_prepare_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
+
 
 #if 0
                        /* create native call block*/
@@ -4763,7 +4821,10 @@ java stack at this point*/
                        i386_mov_imm_reg(cd, (u4) new_nullpointerexception, REG_ITMP1);
                        i386_call_reg(cd, REG_ITMP1);   /* return value is REG_ITMP1_XPTR */
 
-                       REMOVE_NATIVE_STACKINFO;
+                       /*REMOVE_NATIVE_STACKINFO;*/
+                       i386_mov_imm_reg(cd,(s4)asm_remove_native_stackinfo,REG_ITMP3);
+                       i386_call_reg(cd,REG_ITMP3);
+
 
 #if 0
                        /* restore native call stack */
@@ -4928,8 +4989,8 @@ u1 *createnativestub(functionptr f, methodinfo *m)
     int addmethod=0;
     u1 *tptr;
     int i;
-    int stackframesize = 4+12;           /* initial 4 bytes is space for jni env,
-                                               + 4 byte thread pointer + 4 byte previous pointer + method info*/
+    int stackframesize = 4+16;           /* initial 4 bytes is space for jni env,
+                                               + 4 byte thread pointer + 4 byte previous pointer + method info + 4 offset native*/
     int stackframeoffset = 4;
 
     int p, t;
@@ -5096,14 +5157,15 @@ u1 *createnativestub(functionptr f, methodinfo *m)
        i386_alu_imm_reg(cd, I386_SUB, stackframesize, REG_SP);
 
 /* CREATE DYNAMIC STACK INFO -- BEGIN*/
-   i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-4);
+   i386_mov_imm_membase(cd,0,REG_SP,stackframesize-4);
+   i386_mov_imm_membase(cd, (s4) m, REG_SP,stackframesize-8);
    i386_mov_imm_reg(cd, (s4) builtin_asm_get_stackframeinfo, REG_ITMP1);
    i386_call_reg(cd, REG_ITMP1);
-   i386_mov_reg_membase(cd, REG_RESULT,REG_SP,stackframesize-8); /*save thread specific pointer*/
+   i386_mov_reg_membase(cd, REG_RESULT,REG_SP,stackframesize-12); /*save thread specific pointer*/
    i386_mov_membase_reg(cd, REG_RESULT,0,REG_ITMP2); 
-   i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,stackframesize-12); /*save previous value of memory adress pointed to by thread specific pointer*/
+   i386_mov_reg_membase(cd, REG_ITMP2,REG_SP,stackframesize-16); /*save previous value of memory adress pointed to by thread specific pointer*/
    i386_mov_reg_reg(cd, REG_SP,REG_ITMP2);
-   i386_alu_imm_reg(cd, I386_ADD,stackframesize-12,REG_ITMP2);
+   i386_alu_imm_reg(cd, I386_ADD,stackframesize-16,REG_ITMP2);
    i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT,0);
 
 /*TESTING ONLY */
@@ -5116,7 +5178,7 @@ u1 *createnativestub(functionptr f, methodinfo *m)
 /* RESOLVE NATIVE METHOD -- BEGIN*/
 #ifndef STATIC_CLASSPATH
    if (f==0) {
-     log_text("Dynamic classpath: preparing for delayed native function resolving");
+     /*log_text("Dynamic classpath: preparing for delayed native function resolving");*/
      i386_jmp_imm(cd,0);
      jmpInstrPos=cd->mcodeptr-4;
      /*patchposition*/
@@ -5143,7 +5205,7 @@ u1 *createnativestub(functionptr f, methodinfo *m)
      i386_pop_reg(cd,REG_ITMP1);
      /*fix jmp offset replacement*/
      (*jmpInstrPatchPos)=cd->mcodeptr-jmpInstrPos-4;
-   } else log_text("Dynamic classpath: immediate native function resolution possible");
+   } /*else log_text("Dynamic classpath: immediate native function resolution possible");*/
 #endif
 /* RESOLVE NATIVE METHOD -- END*/
 
@@ -5191,8 +5253,8 @@ u1 *createnativestub(functionptr f, methodinfo *m)
 
 /*REMOVE DYNAMIC STACK INFO -BEGIN */
     i386_push_reg(cd, REG_RESULT2);
-    i386_mov_membase_reg(cd, REG_SP,stackframesize-8,REG_ITMP2); /*old value*/
-    i386_mov_membase_reg(cd, REG_SP,stackframesize-4,REG_RESULT2); /*pointer*/
+    i386_mov_membase_reg(cd, REG_SP,stackframesize-12,REG_ITMP2); /*old value*/
+    i386_mov_membase_reg(cd, REG_SP,stackframesize-8,REG_RESULT2); /*pointer*/
     i386_mov_reg_membase(cd, REG_ITMP2,REG_RESULT2,0);
     i386_pop_reg(cd, REG_RESULT2);
 /*REMOVE DYNAMIC STACK INFO -END */
diff --git a/src/vm/jit/i386/symcat.h b/src/vm/jit/i386/symcat.h
new file mode 100644 (file)
index 0000000..61ce1e9
--- /dev/null
@@ -0,0 +1,49 @@
+/* Symbol concatenation utilities.
+
+   Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef SYM_CAT_H
+#define SYM_CAT_H
+
+#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
+#define CONCAT2(a,b)    a##b
+#define CONCAT3(a,b,c)  a##b##c
+#define CONCAT4(a,b,c,d) a##b##c##d
+#define STRINGX(s) #s
+#else
+/* Note one should never pass extra whitespace to the CONCATn macros,
+   e.g. CONCAT2(foo, bar) because traditonal C will keep the space between
+   the two labels instead of concatenating them.  Instead, make sure to
+   write CONCAT2(foo,bar).  */
+#define CONCAT2(a,b)    a/**/b
+#define CONCAT3(a,b,c)  a/**/b/**/c
+#define CONCAT4(a,b,c,d) a/**/b/**/c/**/d
+#define STRINGX(s) "s"
+#endif
+
+#define XCONCAT2(a,b)     CONCAT2(a,b)
+#define XCONCAT3(a,b,c)   CONCAT3(a,b,c)
+#define XCONCAT4(a,b,c,d) CONCAT4(a,b,c,d)
+
+/* Note the layer of indirection here is typically used to allow
+   stringification of the expansion of macros.  I.e. "#define foo
+   bar", "XSTRING(foo)", to yield "bar".  Be aware that this only
+   works for __STDC__, not for traditional C which will still resolve
+   to "foo".  */
+#define XSTRING(s) STRINGX(s) 
+
+#endif /* SYM_CAT_H */
index 2b56938fe1c228bffb3452381cc1952ecbf1c270..25fad8880f771d2f328ecff0be41c4a43d798e7a 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: stack.c 1642 2004-12-01 13:21:54Z christian $
+   $Id: stack.c 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
@@ -2630,7 +2630,7 @@ void show_icmd(instruction *iptr, bool deadcode)
                }
                break;
        }
-/*     printf(" Line number: %d, method:",iptr->line); */
+       printf(" Line number: %d, method:",iptr->line);
 /*        printf("\t\t");
        utf_display(iptr->method->class->name); 
        printf("."); 
diff --git a/src/vm/jit/stacktrace.c b/src/vm/jit/stacktrace.c
new file mode 100644 (file)
index 0000000..8f6746f
--- /dev/null
@@ -0,0 +1,408 @@
+/* jit/stacktrace.inc
+
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
+   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
+   P. Tomsich, J. Wenninger
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.
+
+   Contact: cacao@complang.tuwien.ac.at
+
+   Authors: Joseph Wenninger
+
+   $Id: stacktrace.c 1680 2004-12-04 12:02:08Z jowenn $
+
+*/
+
+#ifndef _STACKTRACE_H_
+#define _STACKTRACE_H_
+
+#include "vm/global.h"
+#include "toolbox/logging.h"
+#include "vm/jit/codegen.inc"
+
+#include <stdlib.h>
+#include <string.h>
+
+#undef JWDEBUG
+
+extern classinfo *class_java_lang_Class;
+extern classinfo *class_java_lang_SecurityManager;
+
+/* the line number is only u2, but to avoid alignment problems it is made the same size as a native
+       pointer. In the structures where this is used, values of -1 or -2 have a special meainging, so
+       if java bytecode is ever extended to support more than 65535 lines/file, this could will have to
+       be changed.*/
+
+#ifdef _ALPHA_
+       #define LineNumber u8
+#else
+       #define LineNumber u4
+#endif
+
+typedef struct lineNumberTableEntry {
+/* The special value of -1 means that a inlined function starts, a value of -2 means that an inlined function ends*/
+       LineNumber lineNr;
+       void *pc;
+} lineNumberTableEntry;
+
+typedef struct lineNumberTableEntryInlineBegin {
+/*this should have the same layout and size as the lineNumberTableEntry*/
+       LineNumber lineNrOuter;
+       methodinfo *method;
+} lineNumberTableEntryInlineBegin;
+
+
+typedef void(*CacaoStackTraceCollector)(void **,stackTraceBuffer*);
+
+#define BLOCK_INITIALSIZE 40
+#define BLOCK_SIZEINCREMENT 40
+
+static void addEntry(stackTraceBuffer* buffer,methodinfo*method ,LineNumber line) {
+       if (buffer->size>buffer->full) {
+               stacktraceelement *tmp=&(buffer->start[buffer->full]);
+               tmp->method=method;
+               tmp->linenumber=line;
+               buffer->full = buffer->full + 1;
+#ifdef JWDEBUG
+               log_text("addEntry (stacktrace):");
+               if (method) utf_display(method->name); else printf("Native");
+               if (method) {printf("\n");utf_display(method->class->name);}
+               printf("\nLine:%ld\n",line);
+#endif
+       } else {
+               stacktraceelement *newBuffer=(stacktraceelement*)
+                       malloc((buffer->size+BLOCK_SIZEINCREMENT)*sizeof(stacktraceelement));
+               if (newBuffer==0) panic("OOM during stacktrace creation");
+               memcpy(newBuffer,buffer->start,buffer->size*sizeof(stacktraceelement));
+               if (buffer->needsFree) free(buffer->start);
+               buffer->start=newBuffer;
+               buffer->size=buffer->size+BLOCK_SIZEINCREMENT;
+               buffer->needsFree=1;
+               addEntry(buffer,method,line);
+       }
+}
+
+static int fillInStackTrace_methodRecursive(stackTraceBuffer *buffer,methodinfo 
+               *method,lineNumberTableEntry *startEntry, lineNumberTableEntry **entry, size_t *entriesAhead,void *adress) {
+
+       size_t ahead=*entriesAhead;
+       lineNumberTableEntry *ent=*entry;
+       lineNumberTableEntryInlineBegin *ilStart;
+
+       for (;ahead>0;ahead--,ent++) {
+               if (adress>=ent->pc) {
+                       switch (ent->lineNr) {
+                               case -1: /*begin of inlined method */
+                                       ilStart=(lineNumberTableEntryInlineBegin*)(++ent);
+                                       ent ++;
+                                       ahead--; ahead--;
+                                       if (fillInStackTrace_methodRecursive(buffer,ilStart->method,ent,&ent,&ahead,adress)) {
+                                               addEntry(buffer,method,ilStart->lineNrOuter);
+                                               return 1;
+                                       }
+                                       break;
+                               case -2: /*end of inlined method*/
+                                       *entry=ent;
+                                       *entriesAhead=ahead;
+                                       return 0;
+                                       break;
+                               default:
+                                       if (adress==ent->pc) {
+                                               addEntry(buffer,method,ent->lineNr);
+                                               return 1;
+                                       }
+                                       break;
+                       }
+               } else {
+                       if (adress>startEntry->pc) {
+                               ent--;
+                               addEntry(buffer,method,ent->lineNr);
+                               return 1;       
+                       } else panic("trace point before method");
+               }
+       }
+       ent--;
+       addEntry(buffer,method,ent->lineNr);
+       return 1;
+       
+}
+
+static void fillInStackTrace_method(stackTraceBuffer *buffer,methodinfo *method,char *dataSeg, void* adress) {
+       size_t lineNumberTableSize=(*((size_t*)(dataSeg+LineNumberTableSize)));
+
+
+       if ( lineNumberTableSize == 0) {
+               /*right now this happens only on 
+               i386,if the native stub causes an exception in a <clinit> invocation (jowenn)*/
+               addEntry(buffer,method,0);
+               return;
+       } else {
+               lineNumberTableEntry *ent; /*=(lineNumberTableEntry*) ((*((char**)(dataSeg+LineNumberTableStart))) - (sizeof(lineNumberTableEntry)-sizeof(void*)));*/
+               void **calc;
+               lineNumberTableEntry *startEntry;
+
+               /*              printf("dataSeg: %p\n",dataSeg);*/
+               calc=dataSeg+LineNumberTableStart;
+               /*              printf("position of line number table start reference in data segment: %p\n",calc);
+                               printf("line number table start as found in table: %p\n",*calc);*/
+               ent=(lineNumberTableEntry *) (((char*)(*calc) - (sizeof(lineNumberTableEntry)-sizeof(void*))));
+               /*              printf("line number table start as calculated: %p\n",ent);*/
+               ent-=(lineNumberTableSize-1);
+               startEntry=ent;
+               /*              printf("line number table real start (bottom end) as calculated(2): %p\n",startEntry);*/
+
+               if (!fillInStackTrace_methodRecursive(buffer,method,startEntry,&ent,&lineNumberTableSize,adress)) {
+                       panic("Trace point not found in suspected method");
+               }
+       }
+}
+
+
+void  cacao_stacktrace_fillInStackTrace(void **target,CacaoStackTraceCollector coll)
+{
+
+       stacktraceelement primaryBlock[BLOCK_INITIALSIZE*sizeof(stacktraceelement)]; 
+               /*In most cases this should be enough -> one malloc less. I don't think temporary data should be
+               allocated with the GC, only the result*/
+       stackTraceBuffer buffer;
+       buffer.needsFree=0;
+       buffer.start=primaryBlock;
+       buffer.size=BLOCK_INITIALSIZE*sizeof(stacktraceelement);
+       buffer.full=0;
+
+
+       {
+               struct native_stackframeinfo *info=(*(((void**)(builtin_asm_get_stackframeinfo()))));
+               if (!info) {
+                       log_text("info ==0");
+                       *target=0;
+                       return;
+               } else {
+                       char *dataseg; /*make it byte addressable*/
+                       methodinfo *currentMethod=0;
+                       void *returnAdress;
+                       char* stackPtr;
+
+/*                     utf_display(info->method->class->name);
+                       utf_display(info->method->name);*/
+                       
+                       while ((currentMethod!=0) ||  (info!=0)) {
+                               if (currentMethod==0) { /*some builtin native */
+                                       currentMethod=info->method;
+                                       returnAdress=info->returnToFromNative;
+                                       /*log_text("native");*/
+                                       if (currentMethod) {
+                                               /*utf_display(currentMethod->class->name);
+                                               utf_display(currentMethod->name);*/
+                                               addEntry(&buffer,currentMethod,0);
+                                       }
+                                       dataseg=codegen_findmethod(returnAdress);
+                                       currentMethod=(*((methodinfo**)(dataseg+MethodPointer)));
+                                       if (info->beginOfJavaStackframe==0)
+                                               stackPtr=((char*)info)+sizeof(native_stackframeinfo);
+                                       else
+                                               stackPtr=(char*)(info->beginOfJavaStackframe)+sizeof(void*);
+                                       info=info->oldThreadspecificHeadValue;
+                               } else { /*method created by jit*/
+                                       u4 frameSize;
+                                       /*log_text("JIT");*/
+                                       if (currentMethod->isleafmethod) panic("How could that happen ??? A leaf method in the middle of a stacktrace ??");
+                                       /*utf_display(currentMethod->class->name);
+                                       utf_display(currentMethod->name);*/
+                                       fillInStackTrace_method(&buffer,currentMethod,dataseg,returnAdress);
+                                       frameSize=*((u4*)(dataseg+FrameSize));
+#ifdef __ALPHA__
+                                       /* cacao saves the return adress as the first element of the stack frame on alphas*/
+                                       dataseg=codegen_findmethod(*((void**)(stackPtr+frameSize-sizeof(void*))));
+                                       returnAdress=(*((void**)(stackPtr+frameSize-sizeof(void*))));
+#else
+                                       /* on i386 the return adress is the first element before the stack frme*/
+                                       returnAdress=(*((void**)(stackPtr+frameSize)));
+                                       dataseg=codegen_findmethod(*((void**)(stackPtr+frameSize)));
+#endif
+/*                                     printf ("threadrootmethod %p\n",builtin_asm_get_threadrootmethod());
+                                       if (currentMethod==builtin_asm_get_threadrootmethod()) break;*/
+                                       currentMethod=(*((methodinfo**)(dataseg+MethodPointer)));
+#ifdef __ALPHA__
+                                       stackPtr+=frameSize;
+#else
+                                       stackPtr+=frameSize+sizeof(void*);
+#endif
+                               }
+                       }
+                       
+                       if (coll) coll(target,&buffer);
+                       if (buffer.needsFree) free(buffer.start);
+                       return;
+               }
+               /*log_text("\n=========================================================");*/
+       }
+       *target=0;
+
+}
+
+
+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));
+
+       dest->needsFree=0;
+       dest->size=dest->full;
+       dest->start=dest+1;
+
+       /*
+       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");
+       */
+}
+
+
+void  cacao_stacktrace_NormalTrace(void **target) {
+       cacao_stacktrace_fillInStackTrace(target,&stackTraceCollector);
+}
+
+
+
+static
+void classContextCollector(void **target, stackTraceBuffer *buffer) {
+        java_objectarray *tmpArray;
+        int i;
+        stacktraceelement *current;
+        stacktraceelement *start;
+        classinfo *c;
+        size_t size;
+       size_t targetSize;
+
+       size=buffer->full;
+       targetSize=0;
+       for (i=0;i<size;i++)
+               if (buffer->start[i].method!=0) targetSize++;
+       start=buffer->start;
+       start++;
+       targetSize--;
+        if (!class_java_lang_Class)
+                class_java_lang_Class = class_new(utf_new_char("java/lang/Class"));
+
+        if (!class_java_lang_SecurityManager)
+                class_java_lang_SecurityManager =
+                        class_new(utf_new_char("java/lang/SecurityManager"));
+
+        if (targetSize > 0) {
+                if ((start->method) && (start->method->class== class_java_lang_SecurityManager)) {
+                        targetSize--;
+                        start++;
+                }
+        }
+
+        tmpArray =
+                builtin_newarray(targetSize, class_array_of(class_java_lang_Class)->vftbl);
+
+        for(i = 0, current = start; i < targetSize; i++, current++) {
+                if (current->method==0) { i--; continue;}
+               /*printf("adding item to class context array:%s\n",current->method->class->name->text);
+               printf("method for class: :%s\n",current->method->name->text);*/
+                use_class_as_object(current->method->class);
+                tmpArray->data[i] = (java_objectheader *) current->method->class;
+        }
+
+        *target=tmpArray;
+}
+
+
+
+java_objectarray *cacao_createClassContextArray() {
+       java_objectarray *array=0;
+       cacao_stacktrace_fillInStackTrace(&array,&classContextCollector);
+       return array;
+       
+}
+
+
+static
+void classLoaderCollector(void **target, stackTraceBuffer *buffer) {
+        int i;
+        stacktraceelement *current;
+        stacktraceelement *start;
+        methodinfo *m;
+        classinfo *privilegedAction;
+        size_t size;
+
+        size = buffer->full;
+
+
+        if (!class_java_lang_SecurityManager)
+                class_java_lang_SecurityManager =
+                        class_new(utf_new_char("java/lang/SecurityManager"));
+
+        if (size > 1) {
+               size--;
+               start=&(buffer->start[1]);
+                if (start == class_java_lang_SecurityManager) {
+                        size--;
+                        start--;
+                }
+        } else {
+               start=0;
+               size=0;
+       }
+        privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction"));
+
+        for(i=0, current = start; i < size; i++, current++) {
+                m=start->method;
+               if (!m) continue;
+
+                if (m->class == privilegedAction) {
+                       *target=NULL;
+                        return;
+               }
+
+                if (m->class->classloader) {
+                        *target= (java_lang_ClassLoader *) m->class->classloader;
+                       return;
+               }
+        }
+
+        *target=NULL;
+}
+
+java_objectheader *cacao_currentClassLoader() {
+       java_objectheader *header=0;
+       cacao_stacktrace_fillInStackTrace(&header,&classLoaderCollector);
+       return header;
+}
+
+#endif
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
index cec1b9e4320cc558845656b071fecbe617c5358c..f1a9f544175a44720e461f13b4485571b3d7a7be 100644 (file)
@@ -29,7 +29,7 @@
             Reinhard Grafl
             Christian Thalinger
 
-   $Id: asmpart.S 1621 2004-11-30 13:06:55Z twisti $
+   $Id: asmpart.S 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
 #include "config.h"
 #include "vm/jit/x86_64/arch.h"
 #include "vm/jit/x86_64/offsets.h"
-
-
-#define MethodPointer   -8
-#define FrameSize       -12
-#define IsSync          -16
-#define IsLeaf          -20
-#define IntSave         -24
-#define FltSave         -28
-#define ExTableSize     -32
-#define ExTableStart    -32
-
-#define ExEntrySize     -32
-#define ExStartPC       -8
-#define ExEndPC         -16
-#define ExHandlerPC     -24
-#define ExCatchType     -32
+#include "vm/jit/x86_64/asmoffsets.h"
 
 
 /* define it like the risc way */
index 5385908addf59be7deff2e4d62ac6f8a3fc22b71..25cb8f0d8db05eec596266c9e917febdd0d6baa3 100644 (file)
@@ -28,7 +28,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.c 1668 2004-12-03 16:39:40Z twisti $
+   $Id: codegen.c 1680 2004-12-04 12:02:08Z jowenn $
 
 */
 
 #include "vm/jit/x86_64/codegen.h"
 #include "vm/jit/x86_64/emitfuncs.h"
 #include "vm/jit/x86_64/types.h"
-
+#include "vm/jit/x86_64/asmoffsets.h"
+#if 0
+#include "vm/jit/stacktrace.inc"
+#endif
 
 /* register descripton - array ************************************************/
 
@@ -3857,6 +3860,10 @@ u1 *createnativestub(functionptr f, methodinfo *m)
        t_inlining_globals *id;
        s4 dumpsize;
 
+       void **callAddrPatchPos=0;
+       u1 *jmpInstrPos=0;
+       void **jmpInstrPatchPos=0;
+
        /* mark start of dump memory area */
 
        dumpsize = dump_size();
@@ -3886,27 +3893,28 @@ u1 *createnativestub(functionptr f, methodinfo *m)
                }
        }
 
-       if (runverbose) {
-               s4 p, l, s1;
 
-               x86_64_alu_imm_reg(cd, X86_64_SUB, (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8, REG_SP);
+       x86_64_alu_imm_reg(cd, X86_64_SUB, (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8, REG_SP);
 
-               x86_64_mov_reg_membase(cd, rd->argintregs[0], REG_SP, 1 * 8);
-               x86_64_mov_reg_membase(cd, rd->argintregs[1], REG_SP, 2 * 8);
-               x86_64_mov_reg_membase(cd, rd->argintregs[2], REG_SP, 3 * 8);
-               x86_64_mov_reg_membase(cd, rd->argintregs[3], REG_SP, 4 * 8);
-               x86_64_mov_reg_membase(cd, rd->argintregs[4], REG_SP, 5 * 8);
-               x86_64_mov_reg_membase(cd, rd->argintregs[5], REG_SP, 6 * 8);
+       x86_64_mov_reg_membase(cd, rd->argintregs[0], REG_SP, 1 * 8);
+       x86_64_mov_reg_membase(cd, rd->argintregs[1], REG_SP, 2 * 8);
+       x86_64_mov_reg_membase(cd, rd->argintregs[2], REG_SP, 3 * 8);
+       x86_64_mov_reg_membase(cd, rd->argintregs[3], REG_SP, 4 * 8);
+       x86_64_mov_reg_membase(cd, rd->argintregs[4], REG_SP, 5 * 8);
+       x86_64_mov_reg_membase(cd, rd->argintregs[5], REG_SP, 6 * 8);
 
-               x86_64_movq_reg_membase(cd, rd->argfltregs[0], REG_SP, 7 * 8);
-               x86_64_movq_reg_membase(cd, rd->argfltregs[1], REG_SP, 8 * 8);
-               x86_64_movq_reg_membase(cd, rd->argfltregs[2], REG_SP, 9 * 8);
-               x86_64_movq_reg_membase(cd, rd->argfltregs[3], REG_SP, 10 * 8);
+       x86_64_movq_reg_membase(cd, rd->argfltregs[0], REG_SP, 7 * 8);
+       x86_64_movq_reg_membase(cd, rd->argfltregs[1], REG_SP, 8 * 8);
+       x86_64_movq_reg_membase(cd, rd->argfltregs[2], REG_SP, 9 * 8);
+       x86_64_movq_reg_membase(cd, rd->argfltregs[3], REG_SP, 10 * 8);
 /*             x86_64_movq_reg_membase(cd, rd->argfltregs[4], REG_SP, 11 * 8); */
 /*             x86_64_movq_reg_membase(cd, rd->argfltregs[5], REG_SP, 12 * 8); */
 /*             x86_64_movq_reg_membase(cd, rd->argfltregs[6], REG_SP, 13 * 8); */
 /*             x86_64_movq_reg_membase(cd, rd->argfltregs[7], REG_SP, 14 * 8); */
 
+       if (runverbose) {
+               s4 p, l, s1;
+
                /* show integer hex code for float arguments */
                for (p = 0, l = 0; p < m->paramcount; p++) {
                        if (IS_FLT_DBL_TYPE(m->paramtypes[p])) {
@@ -3921,27 +3929,44 @@ u1 *createnativestub(functionptr f, methodinfo *m)
 
                x86_64_mov_imm_reg(cd, (s8) m, REG_ITMP1);
                x86_64_mov_reg_membase(cd, REG_ITMP1, REG_SP, 0 * 8);
-               x86_64_mov_imm_reg(cd, (s8) builtin_trace_args, REG_ITMP1);
+               x86_64_mov_imm_reg(cd, (s8) builtin_trace_args, REG_ITMP1);
                x86_64_call_reg(cd, REG_ITMP1);
+       }
+/* call method to resolve native function if needed */
+#ifndef STATIC_CLASSPATH
+       if (f==0) { /* only if not already resolved */
+               x86_64_jmp_imm(cd,0);
+               jmpInstrPos=cd->mcodeptr-4; /*needed to patch a jump over this block*/
+               x86_64_mov_imm_reg(cd,(u8)m,rd->argintregs[0]);
+               x86_64_mov_imm_reg(cd,0,rd->argintregs[1]);
+               callAddrPatchPos=cd->mcodeptr-8; /* at this position the place is specified where the native function adress should be patched into*/
+               x86_64_mov_imm_reg(cd,0,rd->argintregs[2]);
+               jmpInstrPatchPos=cd->mcodeptr-8;
+               x86_64_mov_imm_reg(cd,jmpInstrPos,rd->argintregs[3]);
+               x86_64_mov_imm_reg(cd,(s8)codegen_resolve_native,REG_ITMP1);
+               x86_64_call_reg(cd,REG_ITMP1);
+               *(jmpInstrPatchPos)=cd->mcodeptr-jmpInstrPos-1; /*=opcode jmp_imm size*/
+       }
+#endif
 
-               x86_64_mov_membase_reg(cd, REG_SP, 1 * 8, rd->argintregs[0]);
-               x86_64_mov_membase_reg(cd, REG_SP, 2 * 8, rd->argintregs[1]);
-               x86_64_mov_membase_reg(cd, REG_SP, 3 * 8, rd->argintregs[2]);
-               x86_64_mov_membase_reg(cd, REG_SP, 4 * 8, rd->argintregs[3]);
-               x86_64_mov_membase_reg(cd, REG_SP, 5 * 8, rd->argintregs[4]);
-               x86_64_mov_membase_reg(cd, REG_SP, 6 * 8, rd->argintregs[5]);
-
-               x86_64_movq_membase_reg(cd, REG_SP, 7 * 8, rd->argfltregs[0]);
-               x86_64_movq_membase_reg(cd, REG_SP, 8 * 8, rd->argfltregs[1]);
-               x86_64_movq_membase_reg(cd, REG_SP, 9 * 8, rd->argfltregs[2]);
-               x86_64_movq_membase_reg(cd, REG_SP, 10 * 8, rd->argfltregs[3]);
+       x86_64_mov_membase_reg(cd, REG_SP, 1 * 8, rd->argintregs[0]);
+       x86_64_mov_membase_reg(cd, REG_SP, 2 * 8, rd->argintregs[1]);
+       x86_64_mov_membase_reg(cd, REG_SP, 3 * 8, rd->argintregs[2]);
+       x86_64_mov_membase_reg(cd, REG_SP, 4 * 8, rd->argintregs[3]);
+       x86_64_mov_membase_reg(cd, REG_SP, 5 * 8, rd->argintregs[4]);
+       x86_64_mov_membase_reg(cd, REG_SP, 6 * 8, rd->argintregs[5]);
+
+       x86_64_movq_membase_reg(cd, REG_SP, 7 * 8, rd->argfltregs[0]);
+       x86_64_movq_membase_reg(cd, REG_SP, 8 * 8, rd->argfltregs[1]);
+       x86_64_movq_membase_reg(cd, REG_SP, 9 * 8, rd->argfltregs[2]);
+       x86_64_movq_membase_reg(cd, REG_SP, 10 * 8, rd->argfltregs[3]);
 /*             x86_64_movq_membase_reg(cd, REG_SP, 11 * 8, rd->argfltregs[4]); */
 /*             x86_64_movq_membase_reg(cd, REG_SP, 12 * 8, rd->argfltregs[5]); */
 /*             x86_64_movq_membase_reg(cd, REG_SP, 13 * 8, rd->argfltregs[6]); */
 /*             x86_64_movq_membase_reg(cd, REG_SP, 14 * 8, rd->argfltregs[7]); */
 
-               x86_64_alu_imm_reg(cd, X86_64_ADD, (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8, REG_SP);
-       }
+       x86_64_alu_imm_reg(cd, X86_64_ADD, (INT_ARG_CNT + FLT_ARG_CNT + 1) * 8, REG_SP);
+       
 
 #if 0
        x86_64_alu_imm_reg(cd, X86_64_SUB, 7 * 8, REG_SP);    /* keep stack 16-byte aligned */
@@ -4010,6 +4035,10 @@ u1 *createnativestub(functionptr f, methodinfo *m)
        x86_64_mov_imm_reg(cd, (u8) &env, rd->argintregs[0]);
 
        x86_64_mov_imm_reg(cd, (u8) f, REG_ITMP1);
+#ifndef STATIC_CLASSPATH
+       if (f==0)
+               (*callAddrPatchPos)=cd->mcodeptr-8;
+#endif
        x86_64_call_reg(cd, REG_ITMP1);
 
        /* remove stackframe if there is one */
index c89ec81c16d6b2fd17179ab1bc22c320671024b3..542673400d8d3e2195ce959fde1edb0f7d88ac52 100644 (file)
@@ -13,6 +13,7 @@ public class InlineExTest {
                        System.out.println("ERROR EXCEPTION EXPECTED");
                } catch (Exception e) {
                        System.out.println(e);
+                       e.printStackTrace();
                        System.out.println("End of outer exception handler");
                        System.exit(0);
                }
index a1dc61681794d6cf6afca50f2e308325700fcba2..583f033ba23236549ce7f2f3a4f638e5dcafaf8a 100644 (file)
@@ -31,6 +31,7 @@ class nestedstaticinitializers2 {
        public static void main (String args[]) {
                try {
                        nestedstaticinitializers2_clinit1  x[]=new nestedstaticinitializers2_clinit1[10];
+                       x[0]=new nestedstaticinitializers2_clinit1();
                } catch (Throwable t) {
                        t.printStackTrace();
                }
diff --git a/tests/stack/nestedstaticinitializers3.java b/tests/stack/nestedstaticinitializers3.java
new file mode 100644 (file)
index 0000000..d5b40f8
--- /dev/null
@@ -0,0 +1,39 @@
+class nestedstaticinitializers3_clinit1 extends nestedstaticinitializers3_clinit2 {
+
+       public nestedstaticinitializers3_clinit1() {
+               System.out.println("Never reached");
+       }
+
+       public static int x1;
+       static {
+               x1=1;
+       }
+
+}
+
+class nestedstaticinitializers3_clinit2 {
+       public static int x;
+       static {
+               nestedstaticinitializers2_clinit3.x=3;
+       }
+
+}
+
+class nestedstaticinitializers3_clinit3 {
+       public static int x;
+       static {
+               int y[]=new int[-1];
+       }
+
+}
+
+class nestedstaticinitializers3 {
+       public static void main (String args[]) {
+               try {
+                       nestedstaticinitializers2_clinit1  x[]=new nestedstaticinitializers2_clinit1[10];
+                       x[0]=new nestedstaticinitializers2_clinit1();
+               } catch (Throwable t) {
+                       t.printStackTrace();
+               }
+       }
+}