x86_64* )
ARCH_DIR="x86_64"
- STATIC_CLASSPATH="1"
+ STATIC_CLASSPATH="0"
CFLAGS="-D__X86_64__"
;;
$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
#!/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
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 $
*/
#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
-/* 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"
#include "vm/builtin.h"
#include "vm/tables.h"
-
-#ifndef __I386__
/*
* Class: java/lang/SecurityManager
* Method: currentClassLoader
{
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
*/
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) {
-/* 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"
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;
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;
}
#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
*/
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
}
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 $
*/
void *oldThreadspecificHeadValue;
void **addressOfThreadspecificHead;
methodinfo *method;
+ void *beginOfJavaStackframe; /*only used if != 0*/
void *returnToFromNative;
#if 0
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 {
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 $
*/
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);
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>
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;
/* 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;
#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
--- /dev/null
+#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
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
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
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
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
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
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 */
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
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
-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:
#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
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 $
*/
#include <stdio.h>
#include <ucontext.h>
+#ifdef __FreeBSD__
+#include <machine/signal.h>
+#endif
#include "config.h"
#include "native/jni.h"
#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 ************************************************/
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 */
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 */
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); */
/* 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 */
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;
}
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);
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);
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);
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);
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);
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);
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);
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*/
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 */
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;
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 */
/* 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*/
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*/
/*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 */
--- /dev/null
+/* 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 */
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 $
*/
}
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(".");
--- /dev/null
+/* 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:
+ */
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 */
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 ************************************************/
t_inlining_globals *id;
s4 dumpsize;
+ void **callAddrPatchPos=0;
+ u1 *jmpInstrPos=0;
+ void **jmpInstrPatchPos=0;
+
/* mark start of dump memory area */
dumpsize = dump_size();
}
}
- 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])) {
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 */
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 */
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);
}
public static void main (String args[]) {
try {
nestedstaticinitializers2_clinit1 x[]=new nestedstaticinitializers2_clinit1[10];
+ x[0]=new nestedstaticinitializers2_clinit1();
} catch (Throwable t) {
t.printStackTrace();
}
--- /dev/null
+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();
+ }
+ }
+}