From: Stefan Ring Date: Mon, 5 May 2008 13:02:09 +0000 (+0200) Subject: Merged with tip. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=8c81647e1c96715f45498a3ada7f795b5c9dfe81;hp=-c;p=cacao.git Merged with tip. --- 8c81647e1c96715f45498a3ada7f795b5c9dfe81 diff --combined src/vm/jit/i386/darwin/md-asm.h index 588811a39,1228b0607..d610cc3ce --- a/src/vm/jit/i386/darwin/md-asm.h +++ b/src/vm/jit/i386/darwin/md-asm.h @@@ -1,7 -1,9 +1,7 @@@ /* src/vm/jit/i386/darwin/md-asm.h - assembler defines for i386 Darwin ABI - Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@@ -20,6 -22,12 +20,6 @@@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Contact: cacao@cacaojvm.org - - Authors: Christian Thalinger - - Changes: - */ @@@ -93,13 -101,16 +93,13 @@@ #define asm_builtin_d2i _asm_builtin_d2i #define asm_builtin_d2l _asm_builtin_d2l -#define asm_criticalsections _asm_criticalsections -#define asm_getclassvalues_atomic _asm_getclassvalues_atomic - /* external defines ***********************************************************/ #define exceptions_get_and_clear_exception _exceptions_get_and_clear_exception #define builtin_throw_exception _builtin_throw_exception -#define codegen_get_pv_from_pc _codegen_get_pv_from_pc +#define methodtree_find _methodtree_find #define exceptions_handle_exception _exceptions_handle_exception #define jit_asm_compile _jit_asm_compile @@@ -117,6 -128,8 +117,8 @@@ #define builtin_d2i _builtin_d2i #define builtin_d2l _builtin_d2l + #define asm_get_cycle_count _asm_get_cycle_count + #endif /* _MD_ASM_H */ diff --combined src/vm/jit/stacktrace.c index 493e1c5f7,e8d59d422..461c09d18 --- a/src/vm/jit/stacktrace.c +++ b/src/vm/jit/stacktrace.c @@@ -1,7 -1,9 +1,7 @@@ /* src/vm/jit/stacktrace.c - machine independent stacktrace system - Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@@ -42,16 -44,17 +42,16 @@@ #include "vm/global.h" /* required here for native includes */ #include "native/jni.h" #include "native/llni.h" + +#include "native/include/java_lang_Object.h" #include "native/include/java_lang_Throwable.h" #if defined(WITH_CLASSPATH_GNU) +# include "native/include/gnu_classpath_Pointer.h" # include "native/include/java_lang_VMThrowable.h" #endif -#if defined(ENABLE_THREADS) -# include "threads/native/threads.h" -#else -# include "threads/none/threads.h" -#endif +#include "threads/thread.h" #include "toolbox/logging.h" @@@ -66,17 -69,19 +66,18 @@@ #include "vm/jit/codegen-common.h" #include "vm/jit/linenumbertable.h" #include "vm/jit/methodheader.h" +#include "vm/jit/methodtree.h" #include "vmcore/class.h" #include "vmcore/loader.h" +#include "vmcore/method.h" #include "vmcore/options.h" /* global variables ***********************************************************/ -#if !defined(ENABLE_THREADS) -stackframeinfo_t *_no_threads_stackframeinfo = NULL; -#endif CYCLES_STATS_DECLARE(stacktrace_overhead , 100, 1) + CYCLES_STATS_DECLARE(stacktrace_fillInStackTrace, 40, 5000) CYCLES_STATS_DECLARE(stacktrace_get, 40, 5000) CYCLES_STATS_DECLARE(stacktrace_getClassContext , 40, 5000) CYCLES_STATS_DECLARE(stacktrace_getCurrentClass , 40, 5000) @@@ -92,15 -97,18 +93,15 @@@ CYCLES_STATS_DECLARE(stacktrace_get_sta void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, u1 *pv, u1 *sp, u1 *ra, u1 *xpc) { - stackframeinfo_t **psfi; - codeinfo *code; -#if !defined(__I386__) && !defined(__X86_64__) && !defined(__S390__) && !defined(__M68K__) - bool isleafmethod; -#endif + stackframeinfo_t *currentsfi; + codeinfo *code; #if defined(ENABLE_JIT) s4 framesize; #endif - /* get current stackframe info pointer */ + /* Get current stackframe info. */ - psfi = &STACKFRAMEINFO; + currentsfi = threads_get_current_stackframeinfo(); /* sometimes we don't have pv handy (e.g. in asmpart.S: L_asm_call_jit_compiler_exception or in the interpreter). */ @@@ -108,7 -116,7 +109,7 @@@ if (pv == NULL) { #if defined(ENABLE_INTRP) if (opt_intrp) - pv = codegen_get_pv_from_pc(ra); + pv = methodtree_find(ra); else #endif { @@@ -127,7 -135,7 +128,7 @@@ code = code_get_codeinfo_for_pv(pv); /* XXX */ -/* assert(m != NULL); */ + /* assert(m != NULL); */ #if defined(ENABLE_JIT) # if defined(ENABLE_INTRP) @@@ -146,13 -154,14 +147,13 @@@ ra = md_stacktrace_get_returnaddress(sp, framesize); # else - /* If the method is a non-leaf function, we need to get the return - address from the stack. For leaf functions the return address - is set correctly. This makes the assembler and the signal - handler code simpler. */ - - isleafmethod = *((s4 *) (pv + IsLeaf)); + /* If the method is a non-leaf function, we need to get the + return address from the stack. For leaf functions the + return address is set correctly. This makes the assembler + and the signal handler code simpler. The code is NULL is + the asm_vm_call_method special case. */ - if (!isleafmethod) { + if ((code == NULL) || !code_is_leafmethod(code)) { framesize = *((u4 *) (pv + FrameSize)); ra = md_stacktrace_get_returnaddress(sp, framesize); @@@ -174,7 -183,7 +175,7 @@@ /* Fill new stackframeinfo structure. */ - sfi->prev = *psfi; + sfi->prev = currentsfi; sfi->code = code; sfi->pv = pv; sfi->sp = sp; @@@ -194,7 -203,7 +195,7 @@@ /* Store new stackframeinfo pointer. */ - *psfi = sfi; + threads_set_current_stackframeinfo(sfi); /* set the native world flag for the current thread */ /* ATTENTION: This flag tells the GC how to treat this thread in case of @@@ -213,11 -222,17 +214,11 @@@ void stacktrace_stackframeinfo_remove(stackframeinfo_t *sfi) { - stackframeinfo_t **psfi; - - /* clear the native world flag for the current thread */ - /* ATTENTION: Clear this flag _before_ removing the stackframe info */ + /* Clear the native world flag for the current thread. */ + /* ATTENTION: Clear this flag _before_ removing the stackframe info. */ THREAD_NATIVEWORLD_EXIT; - /* get current stackframe info pointer */ - - psfi = &STACKFRAMEINFO; - #if !defined(NDEBUG) if (opt_DebugStackFrameInfo) { log_start(); @@@ -229,9 -244,9 +230,9 @@@ } #endif - /* restore the old pointer */ + /* Set previous stackframe info. */ - *psfi = sfi->prev; + threads_set_current_stackframeinfo(sfi->prev); } @@@ -267,8 -282,18 +268,8 @@@ static inline void stacktrace_stackfram tmpsfi->prev = sfi->prev; #if !defined(NDEBUG) - /* Print current method information. */ - - if (opt_DebugStackTrace) { - log_println("[stacktrace start]"); - log_start(); - log_print("[stacktrace: method=%p, pv=%p, sp=%p, ra=%p, xpc=%p, method=", - tmpsfi->code->m, tmpsfi->pv, tmpsfi->sp, tmpsfi->ra, - tmpsfi->xpc); - method_print(tmpsfi->code->m); - log_print("]"); - log_finish(); - } + if (opt_DebugStackTrace) + log_println("[stacktrace fill]"); #endif } @@@ -335,7 -360,7 +336,7 @@@ static inline void stacktrace_stackfram #if defined(ENABLE_INTRP) if (opt_intrp) - pv = codegen_get_pv_from_pc(ra); + pv = methodtree_find(ra); else #endif { @@@ -507,20 -532,18 +508,20 @@@ static int stacktrace_depth(stackframei /* stacktrace_get ************************************************************** - Builds and returns a stacktrace from the current thread for and - returns the stacktrace structure wrapped in a Java byte-array to - not confuse the GC. + Builds and returns a stacktrace starting from the given stackframe + info and returns the stacktrace structure wrapped in a Java + byte-array to not confuse the GC. + + IN: + sfi ... stackframe info to start stacktrace from RETURN: stacktrace as Java byte-array *******************************************************************************/ -java_handle_bytearray_t *stacktrace_get(void) +java_handle_bytearray_t *stacktrace_get(stackframeinfo_t *sfi) { - stackframeinfo_t *sfi; stackframeinfo_t tmpsfi; int depth; java_handle_bytearray_t *ba; @@@ -541,6 -564,10 +542,6 @@@ skip_fillInStackTrace = true; skip_init = true; - /* Get the stacktrace depth of the current thread. */ - - sfi = STACKFRAMEINFO; - depth = stacktrace_depth(sfi); if (depth == 0) @@@ -596,7 -623,7 +597,7 @@@ /* For GNU Classpath we also need to skip VMThrowable.fillInStackTrace(). */ - if ((m->class == class_java_lang_VMThrowable) && + if ((m->clazz == class_java_lang_VMThrowable) && (m->name == utf_fillInStackTrace)) continue; #endif @@@ -612,8 -639,8 +613,8 @@@ exception we are going to skipping them in stack trace. */ if (skip_init == true) { - if (m->name == utf_init) { -/* throwable->is_a(method->method_holder())) { */ + if ((m->name == utf_init) && + (class_issubclass(m->clazz, class_java_lang_Throwable))) { continue; } else { @@@ -656,105 -683,6 +657,105 @@@ return_NULL } +/* stacktrace_get_current ****************************************************** + + Builds and returns a stacktrace from the current thread and returns + the stacktrace structure wrapped in a Java byte-array to not + confuse the GC. + + RETURN: + stacktrace as Java byte-array + +*******************************************************************************/ + +java_handle_bytearray_t *stacktrace_get_current(void) +{ + stackframeinfo_t *sfi; + java_handle_bytearray_t *ba; + + sfi = threads_get_current_stackframeinfo(); + ba = stacktrace_get(sfi); + + return ba; +} + + +/* stacktrace_get_caller_class ************************************************* + + Get the class on the stack at the given depth. This function skips + various special classes or methods. + + ARGUMENTS: + depth ... depth to get caller class of + + RETURN: + caller class + +*******************************************************************************/ + +#if defined(ENABLE_JAVASE) +classinfo *stacktrace_get_caller_class(int depth) +{ + stackframeinfo_t *sfi; + stackframeinfo_t tmpsfi; + methodinfo *m; + classinfo *c; + int i; + +#if !defined(NDEBUG) + if (opt_DebugStackTrace) + log_println("[stacktrace_get_caller_class]"); +#endif + + /* Get the stackframeinfo of the current thread. */ + + sfi = threads_get_current_stackframeinfo(); + + /* Iterate over the whole stack until we reached the requested + depth. */ + + i = 0; + + for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi); + stacktrace_stackframeinfo_end_check(&tmpsfi) == false; + stacktrace_stackframeinfo_next(&tmpsfi)) { + + m = tmpsfi.code->m; + c = m->clazz; + + /* Skip builtin methods. */ + + if (m->flags & ACC_METHOD_BUILTIN) + continue; + +#if defined(WITH_CLASSPATH_SUN) + /* NOTE: See hotspot/src/share/vm/runtime/vframe.cpp + (vframeStreamCommon::security_get_caller_frame). */ + + /* This is java.lang.reflect.Method.invoke(), skip it. */ + + if (m == method_java_lang_reflect_Method_invoke) + continue; + + /* This is an auxiliary frame, skip it. */ + + if (class_issubclass(c, class_sun_reflect_MagicAccessorImpl)) + continue; +#endif + + /* We reached the requested depth. */ + + if (i >= depth) + return c; + + i++; + } + + return NULL; +} +#endif + + /* stacktrace_first_nonnull_classloader **************************************** Returns the first non-null (user-defined) classloader on the stack. @@@ -765,12 -693,12 +766,12 @@@ *******************************************************************************/ -classloader *stacktrace_first_nonnull_classloader(void) +classloader_t *stacktrace_first_nonnull_classloader(void) { stackframeinfo_t *sfi; stackframeinfo_t tmpsfi; methodinfo *m; - classloader *cl; + classloader_t *cl; #if !defined(NDEBUG) if (opt_DebugStackTrace) @@@ -779,7 -707,7 +780,7 @@@ /* Get the stackframeinfo of the current thread. */ - sfi = STACKFRAMEINFO; + sfi = threads_get_current_stackframeinfo(); /* Iterate over the whole stack. */ @@@ -788,7 -716,7 +789,7 @@@ stacktrace_stackframeinfo_next(&tmpsfi)) { m = tmpsfi.code->m; - cl = class_get_classloader(m->class); + cl = class_get_classloader(m->clazz); if (cl != NULL) return cl; @@@ -825,7 -753,7 +826,7 @@@ java_handle_objectarray_t *stacktrace_g log_println("[stacktrace_getClassContext]"); #endif - sfi = STACKFRAMEINFO; + sfi = threads_get_current_stackframeinfo(); /* Get the depth of the current stack. */ @@@ -873,7 -801,7 +874,7 @@@ /* Store the class in the array. */ - data[i] = (java_object_t *) m->class; + data[i] = (java_object_t *) m->clazz; i++; } @@@ -919,7 -847,7 +920,7 @@@ classinfo *stacktrace_get_current_class /* Get the stackframeinfo of the current thread. */ - sfi = STACKFRAMEINFO; + sfi = threads_get_current_stackframeinfo(); /* If the stackframeinfo is NULL then FindClass is called through the Invocation Interface and we return NULL */ @@@ -939,16 -867,16 +940,16 @@@ m = tmpsfi.code->m; - if (m->class == class_java_security_PrivilegedAction) { + if (m->clazz == class_java_security_PrivilegedAction) { CYCLES_STATS_END(stacktrace_getCurrentClass); return NULL; } - if (m->class != NULL) { + if (m->clazz != NULL) { CYCLES_STATS_END(stacktrace_getCurrentClass); - return m->class; + return m->clazz; } } @@@ -993,7 -921,7 +994,7 @@@ java_handle_objectarray_t *stacktrace_g /* Get the stackframeinfo of the current thread. */ - sfi = STACKFRAMEINFO; + sfi = threads_get_current_stackframeinfo(); /* Get the depth of the current stack. */ @@@ -1046,7 -974,7 +1047,7 @@@ /* NOTE: We use a LLNI-macro here, because a classinfo is not a handle. */ - LLNI_array_direct(classes, i) = (java_object_t *) m->class; + LLNI_array_direct(classes, i) = (java_object_t *) m->clazz; /* Store the name in the array. */ @@@ -1072,51 -1000,6 +1073,51 @@@ return_NULL #endif +/* stacktrace_print_entry **************************************************** + + Print line for a stacktrace entry. + + ARGUMENTS: + m ............ methodinfo of the entry + linenumber ... linenumber of the entry + +*******************************************************************************/ + +static void stacktrace_print_entry(methodinfo *m, int32_t linenumber) +{ + /* Sanity check. */ + + assert(m != NULL); + + printf("\tat "); + + if (m->flags & ACC_METHOD_BUILTIN) + printf("NULL"); + else + utf_display_printable_ascii_classname(m->clazz->name); + + printf("."); + utf_display_printable_ascii(m->name); + utf_display_printable_ascii(m->descriptor); + + if (m->flags & ACC_NATIVE) { + puts("(Native Method)"); + } + else { + if (m->flags & ACC_METHOD_BUILTIN) { + puts("(builtin)"); + } + else { + printf("("); + utf_display_printable_ascii(m->clazz->sourcefile); + printf(":%d)\n", linenumber); + } + } + + fflush(stdout); +} + + /* stacktrace_print ************************************************************ Print the given stacktrace with CACAO intern methods only (no Java @@@ -1146,99 -1029,28 +1147,99 @@@ void stacktrace_print(stacktrace_t *st linenumber = linenumbertable_linenumber_for_pc(&m, ste->code, ste->pc); - printf("\tat "); - utf_display_printable_ascii_classname(m->class->name); - printf("."); - utf_display_printable_ascii(m->name); - utf_display_printable_ascii(m->descriptor); + stacktrace_print_entry(m, linenumber); + } +} + - if (m->flags & ACC_NATIVE) { - puts("(Native Method)"); - } - else { - printf("("); - utf_display_printable_ascii(m->class->sourcefile); - printf(":%d)\n", linenumber); - } +/* stacktrace_print_current **************************************************** + + Print the current stacktrace of the current thread. + + NOTE: This function prints all frames of the stacktrace and does + not skip frames like stacktrace_get. + +*******************************************************************************/ + +void stacktrace_print_current(void) +{ + stackframeinfo_t *sfi; + stackframeinfo_t tmpsfi; + codeinfo *code; + methodinfo *m; + int32_t linenumber; + + sfi = threads_get_current_stackframeinfo(); + + if (sfi == NULL) { + puts("\t<>"); + fflush(stdout); + return; } - /* just to be sure */ + for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi); + stacktrace_stackframeinfo_end_check(&tmpsfi) == false; + stacktrace_stackframeinfo_next(&tmpsfi)) { + /* Get the methodinfo. */ + + code = tmpsfi.code; + m = code->m; - fflush(stdout); + /* Get the line number. */ + + linenumber = linenumbertable_linenumber_for_pc(&m, code, tmpsfi.xpc); + + stacktrace_print_entry(m, linenumber); + } } +/* stacktrace_print_of_thread ************************************************** + + Print the current stacktrace of the given thread. + + ARGUMENTS: + t ... thread + +*******************************************************************************/ + +#if defined(ENABLE_THREADS) +void stacktrace_print_of_thread(threadobject *t) +{ + stackframeinfo_t *sfi; + stackframeinfo_t tmpsfi; + codeinfo *code; + methodinfo *m; + int32_t linenumber; + + /* Build a stacktrace for the passed thread. */ + + sfi = t->_stackframeinfo; + + if (sfi == NULL) { + puts("\t<>"); + fflush(stdout); + return; + } + + for (stacktrace_stackframeinfo_fill(&tmpsfi, sfi); + stacktrace_stackframeinfo_end_check(&tmpsfi) == false; + stacktrace_stackframeinfo_next(&tmpsfi)) { + /* Get the methodinfo. */ + + code = tmpsfi.code; + m = code->m; + + /* Get the line number. */ + + linenumber = linenumbertable_linenumber_for_pc(&m, code, tmpsfi.xpc); + + stacktrace_print_entry(m, linenumber); + } +} +#endif + + /* stacktrace_print_exception ************************************************** Print the stacktrace of a given exception (more or less a wrapper @@@ -1252,12 -1064,9 +1253,12 @@@ void stacktrace_print_exception(java_handle_t *h) { java_lang_Throwable *o; + #if defined(WITH_CLASSPATH_GNU) java_lang_VMThrowable *vmt; #endif + + java_lang_Object *backtrace; java_handle_bytearray_t *ba; stacktrace_t *st; @@@ -1271,18 -1080,16 +1272,18 @@@ #if defined(WITH_CLASSPATH_GNU) LLNI_field_get_ref(o, vmState, vmt); - LLNI_field_get_ref(vmt, vmData, ba); + LLNI_field_get_ref(vmt, vmdata, backtrace); #elif defined(WITH_CLASSPATH_SUN) || defined(WITH_CLASSPATH_CLDC1_1) - LLNI_field_get_ref(o, backtrace, ba); + LLNI_field_get_ref(o, backtrace, backtrace); #else # error unknown classpath configuration #endif + ba = (java_handle_bytearray_t *) backtrace; + /* Sanity check. */ assert(ba != NULL);