From: michi Date: Wed, 23 May 2007 09:42:08 +0000 (+0000) Subject: Merged revisions 7918-7939 via svnmerge from X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=ed1bc8b622bc75c8b893dd6b5a4f2077ca52c500;p=cacao.git Merged revisions 7918-7939 via svnmerge from svn+ssh://michi@c1.complang.tuwien.ac.at/ahome/cacao/svn/cacao/trunk ........ r7926 | twisti | 2007-05-21 10:27:06 +0200 (Mon, 21 May 2007) | 12 lines * src/native/jni.c (_Jv_jni_CallLongMethodA): New function. (_Jv_jni_CallFloatMethodA): Likewise. (_Jv_jni_CallDoubleMethodA): Likewise. (_Jv_JNI_CallStaticBooleanMethodA): Implemented. (_Jv_JNI_CallStaticByteMethodA): Likewise. (_Jv_JNI_CallStaticCharMethodA): Likewise. (_Jv_JNI_CallStaticShortMethodA): Likewise. (_Jv_JNI_CallStaticIntMethodA): Likewise. (_Jv_JNI_CallStaticLongMethodA): Likewise. (_Jv_JNI_CallStaticFloatMethodA): Likewise. (_Jv_JNI_CallStaticDoubleMethodA): Likewise. ........ r7927 | twisti | 2007-05-21 10:48:46 +0200 (Mon, 21 May 2007) | 3 lines * src/native/include/Makefile.am (CLEANFILES): Simply clean an *.h files. ........ r7929 | michi | 2007-05-21 13:45:31 +0200 (Mon, 21 May 2007) | 8 lines * src/vm/jit/arm/codegen.h (M_EORLE): Added. * src/vm/jit/arm/codegen.c (codegen_emit): Fixed superindex overflow for ICMD_INSTANCEOF and ICMD_CHECKCAST. * src/vm/jit/arm/patcher.c (patcher_checkcast_instanceof_interface): Adapted patcher to above changes. ........ r7930 | twisti | 2007-05-21 16:40:32 +0200 (Mon, 21 May 2007) | 2 lines * src/vm/global.h (ALIGN_2): Added. ........ r7931 | twisti | 2007-05-21 16:42:28 +0200 (Mon, 21 May 2007) | 6 lines * src/vm/jit/arm/md-abi.c (md_param_alloc): Use EABI internally. (ALIGN_2): Removed. * src/vm/jit/arm/codegen.c (codegen_emit): Removed SPLIT-stuff. * src/vm/jit/arm/emit.c (emit_store): Likewise. ........ r7932 | michi | 2007-05-22 09:00:57 +0200 (Tue, 22 May 2007) | 3 lines * src/vm/jit/arm/md-abi.c (md_param_alloc): Align stack arguments as well. * src/vm/jit/arm/asmpart.S (asm_vm_call_method): Use EABI internally. ........ r7933 | michi | 2007-05-22 09:21:08 +0200 (Tue, 22 May 2007) | 2 lines * src/vm/jit/arm/emit.c (emit_verbosecall_enter): Removed obsolete SPLIT-stuff. ........ r7934 | michi | 2007-05-22 12:07:21 +0200 (Tue, 22 May 2007) | 2 lines * src/vm/jit/arm/codegen.c (codegen_emit_stub_native): Removed obsolete SPLIT-stuff. ........ r7935 | twisti | 2007-05-22 13:18:15 +0200 (Tue, 22 May 2007) | 3 lines * src/vm/jit/x86_64/md.c (md_get_method_patch_address): Replaced assert with vm_abort. ........ r7938 | tbfg | 2007-05-23 11:37:37 +0200 (Wed, 23 May 2007) | 5 lines * src/vm/jit/abi.h (abi_registers_address_name): Added. (abi_registers_address_argument): Likewise. (abi_registers_address_saved): Likewise. (abi_registers_address_temporary): Likewise. ........ r7939 | tbfg | 2007-05-23 11:40:05 +0200 (Wed, 23 May 2007) | 13 lines * src/vm/jit/m68k/codegen.c (codegen_emit): Remove NOP after each ICMD. Add NOP generation at end of basci block when patcher is longer than instruction to be patched. * src/vm/jit/m68k/patcher.c (patcher_get_putfield): Implemented. * src/vm/jit/m68k/codegen.h (COMPILERSTUB_CODESIZE): Correct value. * src/vm/jit/codegen-common.c (codegen_increase): Enable NOP after patcher generation at end of basic block. ........ --HG-- branch : exact-gc --- diff --git a/src/native/include/Makefile.am b/src/native/include/Makefile.am index fd725a47b..59f408ae8 100644 --- a/src/native/include/Makefile.am +++ b/src/native/include/Makefile.am @@ -22,7 +22,7 @@ ## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ## 02110-1301, USA. ## -## $Id: Makefile.am 7601 2007-03-28 23:02:50Z michi $ +## $Id: Makefile.am 7927 2007-05-21 08:48:46Z twisti $ ## Process this file with automake to produce Makefile.in @@ -120,12 +120,7 @@ ADDITIONAL_STATIC_CLASSPATH_HEADER_FILES = \ java_nio_channels_spi_SelectorProvider.h CLEANFILES = \ - $(COMMON_HEADER_FILES) \ - $(JAVASE_HEADER_FILES) \ - $(JAVAME_CLDC1_1_HEADER_FILES) \ - $(JVMTI_HEADER_FILES) \ - $(ADDITIONAL_IMPLEMENTED_VM_CLASSES_HEADER_FILES) \ - $(ADDITIONAL_STATIC_CLASSPATH_HEADER_FILES) + *.h DO_HEADER_FILES = \ $(COMMON_HEADER_FILES) diff --git a/src/native/jni.c b/src/native/jni.c index 261e19864..33ea7eed5 100644 --- a/src/native/jni.c +++ b/src/native/jni.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: jni.c 7921 2007-05-20 23:14:11Z michi $ + $Id: jni.c 7940 2007-05-23 09:42:08Z michi $ */ @@ -689,6 +689,52 @@ static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl, } +/* _Jv_jni_CallLongMethodA ***************************************************** + + Internal function to call Java long methods. + +*******************************************************************************/ + +static jlong _Jv_jni_CallLongMethodA(java_objectheader *o, vftbl_t *vftbl, + methodinfo *m, jvalue *args) +{ + methodinfo *resm; + jlong l; + + STATISTICS(jniinvokation()); + + if (m == NULL) { + exceptions_throw_nullpointerexception(); + return 0; + } + + /* Class initialization is done by the JIT compiler. This is ok + since a static method always belongs to the declaring class. */ + + if (m->flags & ACC_STATIC) { + /* For static methods we reset the object. */ + + if (o != NULL) + o = NULL; + + /* for convenience */ + + resm = m; + } + else { + /* For instance methods we make a virtual function table lookup. */ + + resm = method_vftbl_lookup(vftbl, m); + } + + STATISTICS(jnicallXmethodnvokation()); + + l = vm_call_method_long_jvalue(resm, o, args); + + return l; +} + + /* _Jv_jni_CallFloatMethod ***************************************************** Internal function to call Java float methods. @@ -728,6 +774,45 @@ static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl, } +/* _Jv_jni_CallFloatMethodA **************************************************** + + Internal function to call Java float methods. + +*******************************************************************************/ + +static jfloat _Jv_jni_CallFloatMethodA(java_objectheader *o, vftbl_t *vftbl, + methodinfo *m, jvalue *args) +{ + methodinfo *resm; + jfloat f; + + /* Class initialization is done by the JIT compiler. This is ok + since a static method always belongs to the declaring class. */ + + if (m->flags & ACC_STATIC) { + /* For static methods we reset the object. */ + + if (o != NULL) + o = NULL; + + /* for convenience */ + + resm = m; + } + else { + /* For instance methods we make a virtual function table lookup. */ + + resm = method_vftbl_lookup(vftbl, m); + } + + STATISTICS(jnicallXmethodnvokation()); + + f = vm_call_method_float_jvalue(resm, o, args); + + return f; +} + + /* _Jv_jni_CallDoubleMethod **************************************************** Internal function to call Java double methods. @@ -765,6 +850,43 @@ static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl, } +/* _Jv_jni_CallDoubleMethodA *************************************************** + + Internal function to call Java double methods. + +*******************************************************************************/ + +static jdouble _Jv_jni_CallDoubleMethodA(java_objectheader *o, vftbl_t *vftbl, + methodinfo *m, jvalue *args) +{ + methodinfo *resm; + jdouble d; + + /* Class initialization is done by the JIT compiler. This is ok + since a static method always belongs to the declaring class. */ + + if (m->flags & ACC_STATIC) { + /* For static methods we reset the object. */ + + if (o != NULL) + o = NULL; + + /* for convenience */ + + resm = m; + } + else { + /* For instance methods we make a virtual function table lookup. */ + + resm = method_vftbl_lookup(vftbl, m); + } + + d = vm_call_method_double_jvalue(resm, o, args); + + return d; +} + + /* _Jv_jni_CallVoidMethod ****************************************************** Internal function to call Java void methods. @@ -3327,9 +3449,14 @@ jboolean _Jv_JNI_CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jboolean _Jv_JNI_CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { - log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!"); + methodinfo *m; + jboolean b; - return 0; + m = (methodinfo *) methodID; + + b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args); + + return b; } @@ -3367,9 +3494,14 @@ jbyte _Jv_JNI_CallStaticByteMethodV(JNIEnv *env, jclass clazz, jbyte _Jv_JNI_CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { - log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!"); + methodinfo *m; + jbyte b; - return 0; + m = (methodinfo *) methodID; + + b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args); + + return b; } @@ -3407,9 +3539,14 @@ jchar _Jv_JNI_CallStaticCharMethodV(JNIEnv *env, jclass clazz, jchar _Jv_JNI_CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { - log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!"); + methodinfo *m; + jchar c; - return 0; + m = (methodinfo *) methodID; + + c = _Jv_jni_CallIntMethodA(NULL, NULL, m, args); + + return c; } @@ -3447,9 +3584,14 @@ jshort _Jv_JNI_CallStaticShortMethodV(JNIEnv *env, jclass clazz, jshort _Jv_JNI_CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { - log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!"); + methodinfo *m; + jshort s; - return 0; + m = (methodinfo *) methodID; + + s = _Jv_jni_CallIntMethodA(NULL, NULL, m, args); + + return s; } @@ -3487,9 +3629,14 @@ jint _Jv_JNI_CallStaticIntMethodV(JNIEnv *env, jclass clazz, jint _Jv_JNI_CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { - log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!"); + methodinfo *m; + jint i; - return 0; + m = (methodinfo *) methodID; + + i = _Jv_jni_CallIntMethodA(NULL, NULL, m, args); + + return i; } @@ -3527,9 +3674,14 @@ jlong _Jv_JNI_CallStaticLongMethodV(JNIEnv *env, jclass clazz, jlong _Jv_JNI_CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { - log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!"); + methodinfo *m; + jlong l; - return 0; + m = (methodinfo *) methodID; + + l = _Jv_jni_CallLongMethodA(NULL, NULL, m, args); + + return l; } @@ -3568,9 +3720,14 @@ jfloat _Jv_JNI_CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jfloat _Jv_JNI_CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { - log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!"); + methodinfo *m; + jfloat f; - return 0; + m = (methodinfo *) methodID; + + f = _Jv_jni_CallFloatMethodA(NULL, NULL, m, args); + + return f; } @@ -3608,9 +3765,14 @@ jdouble _Jv_JNI_CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jdouble _Jv_JNI_CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args) { - log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!"); + methodinfo *m; + jdouble d; - return 0; + m = (methodinfo *) methodID; + + d = _Jv_jni_CallDoubleMethodA(NULL, NULL, m, args); + + return d; } diff --git a/src/vm/global.h b/src/vm/global.h index 6c68eb236..a86c6d49c 100644 --- a/src/vm/global.h +++ b/src/vm/global.h @@ -1,6 +1,6 @@ /* src/vm/global.h - global definitions - Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel, + Copyright (C) 1996-2005, 2007, 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 @@ -22,17 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - Contact: cacao@cacaojvm.org - - Authors: Reinhard Grafl - Andreas Krall - Mark Probst - Philipp Tomsich - Edwin Steiner - Joseph Wenninger - Christian Thalinger - - $Id: global.h 7688 2007-04-12 09:05:12Z michi $ + $Id: global.h 7940 2007-05-23 09:42:08Z michi $ */ @@ -81,6 +71,11 @@ typedef union { } imm_union; +/* alignment macros ***********************************************************/ + +#define ALIGN_2(a) do { if ((a) & 0x1) (a)++; } while (0) + + /* forward typedefs ***********************************************************/ typedef struct java_objectheader java_objectheader; diff --git a/src/vm/jit/abi.h b/src/vm/jit/abi.h index 74338d881..ca37b0ae9 100644 --- a/src/vm/jit/abi.h +++ b/src/vm/jit/abi.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: abi.h 7596 2007-03-28 21:05:53Z twisti $ + $Id: abi.h 7938 2007-05-23 09:37:37Z tbfg $ */ @@ -46,6 +46,11 @@ extern s4 nregdescfloat[]; #if defined(HAS_ADDRESS_REGISTER_FILE) extern s4 nregdescadr[]; + +extern const char *abi_registers_address_name[]; +extern const s4 abi_registers_address_argument[]; +extern const s4 abi_registers_address_saved[]; +extern const s4 abi_registers_address_temporary[]; #endif extern const char *abi_registers_integer_name[]; diff --git a/src/vm/jit/arm/asmpart.S b/src/vm/jit/arm/asmpart.S index b88d6bf22..934ba993e 100644 --- a/src/vm/jit/arm/asmpart.S +++ b/src/vm/jit/arm/asmpart.S @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: asmpart.S 7766 2007-04-19 13:24:48Z michi $ + $Id: asmpart.S 7932 2007-05-22 07:00:57Z michi $ */ @@ -133,6 +133,10 @@ asm_vm_call_method_double: */ mov itmp3, #0 /* stack position */ asm_calljava_copyloop: /* reorder stack arguments! */ #if defined(__ARMEL__) + ldr ip, [a2,#offvmargtype] /* align 2_WORD_TYPEs */ + tst ip, #1 + tstne itmp3, #4 + addne itmp3, itmp3, #4 ldr ip, [a2,#offvmargdata] /* get LOW word of argument */ str ip, [sp, itmp3] add itmp3, itmp3, #4 @@ -143,6 +147,9 @@ asm_calljava_copyloop: /* reorder stack arguments! */ addne itmp3, itmp3, #4 #else /* defined(__ARMEB__) */ ldr ip, [a2,#offvmargtype + 4] /* get our item type (it is u8) */ + tst ip, #1 /* align 2_WORD_TYPEs */ + tstne itmp3, #4 + addne itmp3, itmp3, #4 teq ip, #2 /* is it a TYPE_FLOAT? */ ldreq ip, [a2,#offvmargdata] /* yes -> get LOW word of float */ streq ip, [sp, itmp3] diff --git a/src/vm/jit/arm/codegen.c b/src/vm/jit/arm/codegen.c index ab2a5918e..6ab8eaa8b 100644 --- a/src/vm/jit/arm/codegen.c +++ b/src/vm/jit/arm/codegen.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: codegen.c 7918 2007-05-20 20:42:18Z michi $ + $Id: codegen.c 7934 2007-05-22 10:07:21Z michi $ */ @@ -214,36 +214,20 @@ bool codegen_emit(jitdata *jd) /* ATTENTION: we use interger registers for all arguments (even float) */ #if !defined(ENABLE_SOFTFLOAT) - if (IS_INT_LNG_TYPE(t)) { /* integer args */ + if (IS_INT_LNG_TYPE(t)) { #endif - if (!md->params[i].inmemory) { /* register arguments */ - if (!(var->flags & INMEMORY)) { /* reg arg -> register */ - if (GET_LOW_REG(var->vv.regoff) == REG_SPLIT || GET_HIGH_REG(var->vv.regoff) == REG_SPLIT) { - /* TODO: remove this!!! */ - dolog("SPLIT in local var: %x>%x (%s.%s)", s1, var->vv.regoff, m->class->name->text, m->name->text); - assert(s1 == var->vv.regoff); - } - s3 = var->vv.regoff; - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, cd->stackframesize); - SPLIT_OPEN(t, s3, REG_ITMP1); - + if (!md->params[i].inmemory) { + if (!(var->flags & INMEMORY)) { if (IS_2_WORD_TYPE(t)) - M_LNGMOVE(s1, s3); + M_LNGMOVE(s1, var->vv.regoff); else - M_INTMOVE(s1, s3); - - SPLIT_STORE_AND_CLOSE(t, s3, cd->stackframesize); + M_INTMOVE(s1, var->vv.regoff); } - else { /* reg arg -> spilled */ - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, cd->stackframesize); - + else { if (IS_2_WORD_TYPE(t)) M_LST(s1, REG_SP, var->vv.regoff * 4); else M_IST(s1, REG_SP, var->vv.regoff * 4); - /* no SPLIT_CLOSE here because arg is fully spilled now */ } } else { /* stack arguments */ @@ -259,32 +243,27 @@ bool codegen_emit(jitdata *jd) } } #if !defined(ENABLE_SOFTFLOAT) - } else { /* floating args */ - if (!md->params[i].inmemory) { /* register arguments */ - if (!(var->flags & INMEMORY)) { /* reg arg -> register */ - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, cd->stackframesize); + } + else { + if (!md->params[i].inmemory) { + if (!(var->flags & INMEMORY)) { M_CAST_INT_TO_FLT_TYPED(t, s1, var->vv.regoff); } - else { /* reg arg -> spilled */ - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, cd->stackframesize); - + else { if (IS_2_WORD_TYPE(t)) M_LST(s1, REG_SP, var->vv.regoff * 4); else M_IST(s1, REG_SP, var->vv.regoff * 4); - /* no SPLIT_CLOSE here because arg is fully spilled now */ } } - else { /* stack arguments */ - if (!(var->flags & INMEMORY)) { /* stack arg -> register */ + else { + if (!(var->flags & INMEMORY)) { if (IS_2_WORD_TYPE(t)) M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4); else M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4); } - else { /* stack arg -> spilled */ + else { /* Reuse Memory Position on Caller Stack */ var->vv.regoff = cd->stackframesize + s1; } @@ -2239,15 +2218,12 @@ bool codegen_emit(jitdata *jd) if (IS_INT_LNG_TYPE(var->type)) { #endif /* !defined(ENABLE_SOFTFLOAT) */ if (!md->params[s3].inmemory) { - SPLIT_OPEN(var->type, s1, REG_ITMP2); s1 = emit_load(jd, iptr, var, d); if (IS_2_WORD_TYPE(var->type)) M_LNGMOVE(s1, d); else M_INTMOVE(s1, d); - - SPLIT_STORE_AND_CLOSE(var->type, d, 0); } else { if (IS_2_WORD_TYPE(var->type)) { @@ -2264,9 +2240,7 @@ bool codegen_emit(jitdata *jd) else { if (!md->params[s3].inmemory) { s1 = emit_load(jd, iptr, var, REG_FTMP1); - SPLIT_OPEN(var->type, d, REG_ITMP1); M_CAST_FLT_TO_INT_TYPED(var->type, s1, d); - SPLIT_STORE_AND_CLOSE(var->type, d, 0); } else { s1 = emit_load(jd, iptr, var, REG_FTMP1); @@ -2473,10 +2447,13 @@ bool codegen_emit(jitdata *jd) /* interface checkcast code */ if ((super == NULL) || (super->flags & ACC_INTERFACE)) { + if ((super == NULL) || !IS_IMM(superindex)) { + disp = dseg_add_unique_s4(cd, superindex); + } if (super == NULL) { codegen_addpatchref(cd, PATCHER_checkcast_instanceof_interface, - iptr->sx.s23.s3.c.ref, 0); + iptr->sx.s23.s3.c.ref, disp); if (opt_showdisassemble) M_NOP; @@ -2488,12 +2465,40 @@ bool codegen_emit(jitdata *jd) M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl)); M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength)); - assert(IS_IMM(superindex)); - M_CMP_IMM(REG_ITMP3, superindex); + + /* we put unresolved or non-immediate superindices onto dseg */ + if ((super == NULL) || !IS_IMM(superindex)) { + /* disp was computed before we added the patcher */ + M_DSEG_LOAD(REG_ITMP2, disp); + M_CMP(REG_ITMP3, REG_ITMP2); + } else { + assert(IS_IMM(superindex)); + M_CMP_IMM(REG_ITMP3, superindex); + } + emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1); - s2 = OFFSET(vftbl_t, interfacetable[0]) - - superindex * sizeof(methodptr*); + /* if we loaded the superindex out of the dseg above, we do + things differently here! */ + if ((super == NULL) || !IS_IMM(superindex)) { + + M_LDR_INTERN(REG_ITMP3, s1, OFFSET(java_objectheader, vftbl)); + + /* this assumes something */ + assert(OFFSET(vftbl_t, interfacetable[0]) == 0); + + /* this does: REG_ITMP3 - superindex * sizeof(methodptr*) */ + assert(sizeof(methodptr*) == 4); + M_SUB(REG_ITMP2, REG_ITMP3, REG_LSL(REG_ITMP2, 2)); + + s2 = 0; + + } else { + + s2 = OFFSET(vftbl_t, interfacetable[0]) - + superindex * sizeof(methodptr*); + + } M_LDR_INTERN(REG_ITMP3, REG_ITMP2, s2); M_TST(REG_ITMP3, REG_ITMP3); @@ -2643,6 +2648,9 @@ bool codegen_emit(jitdata *jd) /* interface checkcast code */ if ((super == NULL) || (super->flags & ACC_INTERFACE)) { + if ((super == NULL) || !IS_IMM(superindex)) { + disp = dseg_add_unique_s4(cd, superindex); + } if (super == NULL) { /* If d == REG_ITMP2, then it's destroyed in check code above. */ @@ -2651,7 +2659,7 @@ bool codegen_emit(jitdata *jd) codegen_addpatchref(cd, PATCHER_checkcast_instanceof_interface, - iptr->sx.s23.s3.c.ref, 0); + iptr->sx.s23.s3.c.ref, disp); if (opt_showdisassemble) M_NOP; @@ -2665,12 +2673,44 @@ bool codegen_emit(jitdata *jd) M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl)); M_LDR_INTERN(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength)); - assert(IS_IMM(superindex)); - M_CMP_IMM(REG_ITMP3, superindex); - M_BLE(2); - s2 = OFFSET(vftbl_t, interfacetable[0]) - - superindex * sizeof(methodptr*); + /* we put unresolved or non-immediate superindices onto dseg + and do things slightly different */ + if ((super == NULL) || !IS_IMM(superindex)) { + /* disp was computed before we added the patcher */ + M_DSEG_LOAD(REG_ITMP2, disp); + M_CMP(REG_ITMP3, REG_ITMP2); + + if (d == REG_ITMP2) { + M_EORLE(d, d, d); + M_BLE(4); + } else { + M_BLE(3); + } + + /* this assumes something */ + assert(OFFSET(vftbl_t, interfacetable[0]) == 0); + + /* this does: REG_ITMP3 - superindex * sizeof(methodptr*) */ + assert(sizeof(methodptr*) == 4); + M_SUB(REG_ITMP1, REG_ITMP1, REG_LSL(REG_ITMP2, 2)); + + if (d == REG_ITMP2) { + M_EOR(d, d, d); + } + + s2 = 0; + + } else { + assert(IS_IMM(superindex)); + M_CMP_IMM(REG_ITMP3, superindex); + + M_BLE(2); + + s2 = OFFSET(vftbl_t, interfacetable[0]) - + superindex * sizeof(methodptr*); + + } M_LDR_INTERN(REG_ITMP3, REG_ITMP1, s2); M_TST(REG_ITMP3, REG_ITMP3); @@ -2968,8 +3008,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) if (!nmd->params[j].inmemory) { #if !defined(__ARM_EABI__) - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, cd->stackframesize); SPLIT_OPEN(t, s2, REG_ITMP1); #endif @@ -2983,16 +3021,10 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f) #endif } else { -#if !defined(__ARM_EABI__) - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, cd->stackframesize); -#endif - if (IS_2_WORD_TYPE(t)) M_LST(s1, REG_SP, s2 * 4); else M_IST(s1, REG_SP, s2 * 4); - /* no SPLIT_CLOSE here because argument is fully on stack now */ } } else { diff --git a/src/vm/jit/arm/codegen.h b/src/vm/jit/arm/codegen.h index 6a5991744..3c72b7621 100644 --- a/src/vm/jit/arm/codegen.h +++ b/src/vm/jit/arm/codegen.h @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: codegen.h 7693 2007-04-12 14:56:49Z michi $ + $Id: codegen.h 7929 2007-05-21 11:45:31Z michi $ */ @@ -424,6 +424,7 @@ void asm_debug_intern(int a1, int a2, int a3, int a4); #define M_ADDSUB_IMM(d,a,i) if((i)>=0) M_ADD_IMM(d,a,i); else M_SUB_IMM(d,a,-(i)) #define M_MOVEQ(a,d) M_DAT(COND_EQ,0x0d,d,0,0,0,a) +#define M_EORLE(d,a,b) M_DAT(COND_LE,0x01,d,a,0,0,b) #define M_MOVVS_IMM(i,d) M_DAT(COND_VS,0x0d,d,0,0,1,i) #define M_MOVEQ_IMM(i,d) M_DAT(COND_EQ,0x0d,d,0,0,1,i) diff --git a/src/vm/jit/arm/emit.c b/src/vm/jit/arm/emit.c index e16bc2ccc..10f80399f 100644 --- a/src/vm/jit/arm/emit.c +++ b/src/vm/jit/arm/emit.c @@ -246,13 +246,6 @@ void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d) default: vm_abort("emit_store: unknown type %d", dst->type); } -#endif - } - else if (IS_LNG_TYPE(dst->type)) { -#if defined(__ARMEL__) - assert(GET_HIGH_REG(dst->vv.regoff) != REG_SPLIT); -#else - assert(GET_LOW_REG(dst->vv.regoff) != REG_SPLIT); #endif } } @@ -777,10 +770,6 @@ void emit_verbosecall_enter(jitdata *jd) M_MOV_IMM(REG_ITMP1, 0); s1 = PACK_REGS(s1, REG_ITMP1); } - else { - SPLIT_OPEN(t, s1, REG_ITMP1); - SPLIT_LOAD(t, s1, stackframesize); - } } else { s1 = REG_ITMP12_PACKED; diff --git a/src/vm/jit/arm/md-abi.c b/src/vm/jit/arm/md-abi.c index 288458565..ed6eee2a6 100644 --- a/src/vm/jit/arm/md-abi.c +++ b/src/vm/jit/arm/md-abi.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: md-abi.c 7723 2007-04-16 18:03:08Z michi $ + $Id: md-abi.c 7932 2007-05-22 07:00:57Z michi $ */ @@ -135,10 +135,12 @@ void md_param_alloc(methoddesc *md) s4 stacksize; /* set default values */ - reguse = 0; + + reguse = 0; stacksize = 0; /* get params field of methoddesc */ + pd = md->params; for (i = 0; i < md->paramcount; i++, pd++) { @@ -160,7 +162,11 @@ void md_param_alloc(methoddesc *md) case TYPE_LNG: case TYPE_DBL: - if (reguse+1 < INT_ARG_CNT) { + /* interally we use the EABI */ + + ALIGN_2(reguse); + + if (reguse < INT_ARG_CNT) { pd->inmemory = false; #if defined(__ARMEL__) pd->regoff = @@ -173,24 +179,13 @@ void md_param_alloc(methoddesc *md) #endif reguse += 2; } - else if (reguse < INT_ARG_CNT) { - pd->inmemory = false; -#if defined(__ARMEL__) - pd->regoff = - PACK_REGS(abi_registers_integer_argument[reguse], - abi_registers_integer_argument[INT_ARG_CNT]); -#else - pd->regoff = - PACK_REGS(abi_registers_integer_argument[INT_ARG_CNT], - abi_registers_integer_argument[reguse]); -#endif - reguse++; - stacksize++; - } else { - pd->inmemory = true; - pd->regoff = stacksize; - stacksize += 2; + + ALIGN_2(stacksize); + + pd->inmemory = true; + pd->regoff = stacksize; + stacksize += 2; } break; } @@ -224,8 +219,6 @@ void md_param_alloc(methoddesc *md) *******************************************************************************/ -#define ALIGN_2(a) do { if ((a) & 0x1) (a)++; } while (0) - void md_param_alloc_native(methoddesc *md) { paramdesc *pd; diff --git a/src/vm/jit/arm/patcher.c b/src/vm/jit/arm/patcher.c index ec0f72513..0512b75fe 100644 --- a/src/vm/jit/arm/patcher.c +++ b/src/vm/jit/arm/patcher.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: patcher.c 7483 2007-03-08 13:17:40Z michi $ + $Id: patcher.c 7929 2007-05-21 11:45:31Z michi $ */ @@ -580,51 +580,30 @@ bool patcher_checkcast_instanceof_flags(u1 *sp) Machine code: - e59ab000 ldr fp, [sl] - e59b9010 ldr r9, [fp, #16] - e3590000 cmp r9, #0 ; 0x0 - da000000 ble 0x000000 - e59b9000 ldr r9, [fp, #__] - e1190009 tst r9, r9 - 0a000000 beq 0x000000 *******************************************************************************/ bool patcher_checkcast_instanceof_interface(u1 *sp) { - u1 *ra; + s4 disp; constant_classref *cr; + u1 *pv; classinfo *c; /* get stuff from the stack */ - ra = (u1 *) *((ptrint *) (sp + 4 * 4)); - cr = (constant_classref *) *((ptrint *) (sp + 1 * 4)); + disp = *((s4 *) (sp + 5 * 4)); + cr = (constant_classref *) *((ptrint *) (sp + 1 * 4)); + pv = (u1 *) *((ptrint *) (sp + 0 * 4)); /* get the classinfo */ if (!(c = resolve_classref_eager(cr))) return false; - /* if we show disassembly, we have to skip the nop */ - - if (opt_showdisassemble) - ra = ra + 4; - /* patch super class index */ - assert(*((s4 *) (ra + 2 * 4)) == 0xe3590000); - assert(c->index <= 0xff); - - *((s4 *) (ra + 2 * 4)) |= (s4) (c->index & 0x000000ff); - - /* patch super class vftbl index */ - - gen_resolveload(*((s4 *) (ra + 4 * 4)), (s4) (OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * c->index)); - - /* synchronize instruction cache */ - - md_icacheflush(ra + 2 * 4, 3 * 4); + *((s4 *) (pv + disp)) = (s4) c->index; return true; } diff --git a/src/vm/jit/codegen-common.c b/src/vm/jit/codegen-common.c index cccf3acb1..344dcad6c 100644 --- a/src/vm/jit/codegen-common.c +++ b/src/vm/jit/codegen-common.c @@ -39,7 +39,7 @@ memory. All functions writing values into the data area return the offset relative the begin of the code area (start of procedure). - $Id: codegen-common.c 7918 2007-05-20 20:42:18Z michi $ + $Id: codegen-common.c 7940 2007-05-23 09:42:08Z michi $ */ @@ -377,7 +377,7 @@ void codegen_increase(codegendata *cd) cd->mcodeptr = cd->mcodebase + (cd->mcodeptr - oldmcodebase); -#if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(ENABLE_INTRP) +#if defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__) || defined(ENABLE_INTRP) /* adjust the pointer to the last patcher position */ if (cd->lastmcodeptr != NULL) @@ -547,12 +547,13 @@ void codegen_add_patch_ref(codegendata *cd, functionptr patcher, voidptr ref, if (opt_shownops) PATCHER_NOPS; -#if defined(ENABLE_JIT) && (defined(__I386__) || defined(__MIPS__) || defined(__X86_64__)) +#if defined(ENABLE_JIT) && (defined(__I386__) || defined(__MIPS__) || defined(__X86_64__) || defined(__M68K__)) /* On some architectures the patcher stub call instruction might be longer than the actual instruction generated. On this architectures we store the last patcher call position and after the basic block code generation is completed, we check the range and maybe generate some nop's. */ + /* The nops are generated in codegen_emit in each codegen */ cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE; #endif diff --git a/src/vm/jit/m68k/codegen.c b/src/vm/jit/m68k/codegen.c index 687901b97..b6866e503 100644 --- a/src/vm/jit/m68k/codegen.c +++ b/src/vm/jit/m68k/codegen.c @@ -2359,8 +2359,21 @@ nowperformreturn: exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc); return false; } /* switch */ - M_TPF; + /* M_TPF; */ /* nop after each ICMD */ } /* for each instruction */ + + /* At the end of a basic block we may have to append some nops, + because the patcher stub calling code might be longer than the + actual instruction. So codepatching does not change the + following block unintentionally. */ + + if (cd->mcodeptr < cd->lastmcodeptr) { + while (cd->mcodeptr < cd->lastmcodeptr) { + M_NOP; + } + } + + } /* if (btpre->flags >= BBREACHED) */ } /* for each basic block */ diff --git a/src/vm/jit/m68k/codegen.h b/src/vm/jit/m68k/codegen.h index f06e8059f..66a2a00a4 100644 --- a/src/vm/jit/m68k/codegen.h +++ b/src/vm/jit/m68k/codegen.h @@ -65,10 +65,11 @@ #define PATCHER_NOPS \ do { M_TPFL; M_TPF; M_TPF } while (0); +#define PATCHER_CALL_SIZE (3*2) /* stub defines ***************************************************************/ -#define COMPILERSTUB_CODESIZE (6+6+6+2) +#define COMPILERSTUB_CODESIZE (6+6+2) /* coldfire instruction format: @@ -138,7 +139,6 @@ -#define PATCHER_CALL_SIZE 6 #define M_NOP OPWORD(0x139,6,1) /* 0x4371 do not use as it syncs pipeline */ #define M_ILLEGAL OPWORD(0x12b,7,4) /* 0x4afc */ diff --git a/src/vm/jit/m68k/patcher.c b/src/vm/jit/m68k/patcher.c index 1e92250cd..f7923e3fa 100644 --- a/src/vm/jit/m68k/patcher.c +++ b/src/vm/jit/m68k/patcher.c @@ -386,33 +386,48 @@ bool patcher_get_putfield(u1 *sp) /* patch the field's offset */ if (IS_LNG_TYPE(fi->type)) { - /* If the field has type long, we have to patch two - instructions. But we have to check which instruction - is first. We do that with the offset of the first - instruction. */ - assert(0); - disp = *((u4 *) (ra + 1 * 4)); - - if (disp == 4) { - *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); - *((u4 *) (ra + 2 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); - } - else { - *((u4 *) (ra + 1 * 4)) |= (s2) ((fi->offset + 0) & 0x0000ffff); - *((u4 *) (ra + 2 * 4)) |= (s2) ((fi->offset + 4) & 0x0000ffff); - } - } else { /* - * 0x40adb3f6: 0x254d0000 movel %a5,%a2@(0) - * ^^^^ ^ - * to be patched + * 0x40d05bb2: 0x25440000 movel %d4,%a2@(0) + * 0x40d05bb6: 0x25430004 movel %d3,%a2@(4) + * ^^^^ + * both 0000 and 0004 have to be patched */ - assert( (*((uint32_t*)ra) & 0xffff0000) == *((uint32_t*)ra) ); + assert( (fi->offset & 0x0000ffff) == fi->offset ); - *((uint32_t*)ra) |= fi->offset; - /* synchronize instruction cache */ - md_icacheflush(ra, 1 * 4); + assert( (*((uint32_t*)ra) & 0xffff0000) == *((uint32_t*)ra) ); + assert( (*((uint32_t*)(ra+4)) & 0xffff0004) == *((uint32_t*)(ra+4)) ); + + *((int16_t *) (ra + 2)) = (int16_t) ((fi->offset) & 0x0000ffff); + *((int16_t *) (ra + 6)) = (int16_t) ((fi->offset + 4) & 0x0000ffff); + + md_icacheflush(ra, 2 * 4); + } else { + /* Multiple cases here, int, adr, flt and dbl. */ + if ( (*((uint32_t*)ra) & 0xfff00000) == 0xf2200000 ) { + /* flt/dbl case + * 0x40d3ddc2: 0xf22944c0 0x0000xxxx fsmoves %a1@(0),%fp1 + * ^^^^ + * patch here + */ + assert( (fi->offset & 0x0000ffff) == fi->offset ); + assert( (*((uint32_t*)(ra+4)) & 0x0000ffff) == *((uint32_t*)(ra+4)) ); + *((int16_t*)(ra+4)) = (int16_t)fi->offset; + + md_icacheflush(ra+4, 1 * 4); + } else { + /* int/adr case + * 0x40adb3f6: 0x254d0000 movel %a5,%a2@(0) + * ^^^^ ^ + * to be patched + */ + assert( (*((uint32_t*)ra) & 0xffff0000) == *((uint32_t*)ra) ); + assert( (fi->offset & 0x0000ffff) == fi->offset ); + *((int16_t*)(ra+2)) = (int16_t)fi->offset; + + /* synchronize instruction cache */ + md_icacheflush(ra, 1 * 4); + } } return true; diff --git a/src/vm/jit/x86_64/md.c b/src/vm/jit/x86_64/md.c index e16ca49fb..36ca91a5d 100644 --- a/src/vm/jit/x86_64/md.c +++ b/src/vm/jit/x86_64/md.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - $Id: md.c 7601 2007-03-28 23:02:50Z michi $ + $Id: md.c 7935 2007-05-22 11:18:15Z twisti $ */ @@ -153,7 +153,7 @@ u1 *md_get_method_patch_address(u1 *ra, stackframeinfo *sfi, u1 *mptr) else { /* catch any problems */ - assert(0); + vm_abort("md_get_method_patch_address: unknown instruction %x", mcode); } return pa;