## 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
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)
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 $
*/
}
+/* _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.
}
+/* _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.
}
+/* _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.
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
/* 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
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 $
*/
} imm_union;
+/* alignment macros ***********************************************************/
+
+#define ALIGN_2(a) do { if ((a) & 0x1) (a)++; } while (0)
+
+
/* forward typedefs ***********************************************************/
typedef struct java_objectheader java_objectheader;
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 $
*/
#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[];
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 $
*/
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
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]
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 $
*/
/* 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 */
}
}
#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;
}
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)) {
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);
/* 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;
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);
/* 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. */
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;
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);
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
#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 {
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 $
*/
#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)
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
}
}
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;
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 $
*/
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++) {
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 =
#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;
}
*******************************************************************************/
-#define ALIGN_2(a) do { if ((a) & 0x1) (a)++; } while (0)
-
void md_param_alloc_native(methoddesc *md)
{
paramdesc *pd;
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 $
*/
Machine code:
<patched call position>
- 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;
}
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 $
*/
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)
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
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 */
#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:
-#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 */
/* 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;
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 $
*/
else {
/* catch any problems */
- assert(0);
+ vm_abort("md_get_method_patch_address: unknown instruction %x", mcode);
}
return pa;