From: Stefan Ring Date: Sun, 12 Oct 2008 10:26:13 +0000 (+0200) Subject: Merged new changes from default (manually: src/vm/jit/i386/codegen.c). X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=cacao.git;a=commitdiff_plain;h=e954be2f4bc7a1747c109ea4929d189dd58e401e Merged new changes from default (manually: src/vm/jit/i386/codegen.c). --HG-- branch : subtype-trunk --- e954be2f4bc7a1747c109ea4929d189dd58e401e diff --cc src/vm/jit/i386/codegen.c index eb6a518c5,b7e808cab..bdedf5b64 --- a/src/vm/jit/i386/codegen.c +++ b/src/vm/jit/i386/codegen.c @@@ -3183,44 -3237,31 +3236,45 @@@ gen_method iptr->sx.s23.s3.c.ref, 0); } - M_MOV_IMM(supervftbl, REG_ITMP3); + JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super); - M_ILD32(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); + if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) { + M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset)); + M_CMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3); + emit_label_beq(cd, BRANCH_LABEL_6); /* good */ - /* if (s1 != REG_ITMP1) { */ - /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, baseval), REG_ITMP1); */ - /* emit_mov_membase_reg(cd, REG_ITMP3, OFFSET(vftbl_t, diffval), REG_ITMP3); */ - /* #if defined(ENABLE_THREADS) */ - /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */ - /* #endif */ - /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */ + if (super == NULL) { + M_ICMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1); + emit_label_bne(cd, BRANCH_LABEL_10); /* throw */ + } - /* } else { */ - M_ILD32(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval)); - M_ISUB(REG_ITMP3, REG_ITMP2); - M_MOV_IMM(supervftbl, REG_ITMP3); - JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super); - M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); + M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth)); + M_CMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1); + emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */ + + M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow)); + M_CMP_MEMINDEX(REG_ITMP2, -4*DISPLAY_SIZE, REG_ITMP1, 2, REG_ITMP3); + emit_label_beq(cd, BRANCH_LABEL_7); /* good */ + + emit_label(cd, BRANCH_LABEL_9); + if (super == NULL) + emit_label(cd, BRANCH_LABEL_10); + + /* reload s1, might have been destroyed */ + emit_load_s1(jd, iptr, REG_ITMP1); + M_ALD_MEM(s1, TRAP_ClassCastException); - /* } */ + emit_label(cd, BRANCH_LABEL_7); + emit_label(cd, BRANCH_LABEL_6); + /* reload s1, might have been destroyed */ + emit_load_s1(jd, iptr, REG_ITMP1); + } + else { + M_CMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3); - M_CMP(REG_ITMP3, REG_ITMP2); - emit_classcast_check(cd, iptr, BRANCH_ULE, REG_ITMP3, s1); + emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1); + } if (super != NULL) emit_label(cd, BRANCH_LABEL_5); @@@ -3356,55 -3410,18 +3422,56 @@@ patcher_add_patch_ref(jd, PATCHER_instanceof_class, iptr->sx.s23.s3.c.ref, 0); } - - M_MOV_IMM(supervftbl, REG_ITMP2); + M_MOV_IMM(supervftbl, REG_ITMP3); + JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_VFTBL, super); - M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval)); - M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, diffval)); - M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval)); - - M_ISUB(REG_ITMP2, REG_ITMP1); - M_CLR(d); /* may be REG_ITMP2 */ - M_CMP(REG_ITMP3, REG_ITMP1); - M_BA(5); - M_MOV_IMM(1, d); + + if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) { + M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset)); + M_CMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3); + emit_label_bne(cd, BRANCH_LABEL_8); /* jump over INC/SETE */ + if (d == REG_ITMP2) { + M_SETE(d); + M_BSEXT(d, d); + } else + M_IINC(d); + emit_label_br(cd, BRANCH_LABEL_6); /* true */ + emit_label(cd, BRANCH_LABEL_8); + + if (super == NULL) { + M_ICMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1); + emit_label_bne(cd, BRANCH_LABEL_10); /* false */ + } + + M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth)); + M_CMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1); + emit_label_bgt(cd, BRANCH_LABEL_9); /* false */ + + M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow)); + M_CMP_MEMINDEX(REG_ITMP2, -4*DISPLAY_SIZE, REG_ITMP1, 2, REG_ITMP3); + M_SETE(d); + if (d == REG_ITMP2) { + M_BSEXT(d, d); + + emit_label_br(cd, BRANCH_LABEL_7); /* jump over M_CLR */ + } + + emit_label(cd, BRANCH_LABEL_9); + if (super == NULL) + emit_label(cd, BRANCH_LABEL_10); + if (d == REG_ITMP2) { + M_CLR(d); + + emit_label(cd, BRANCH_LABEL_7); + } + emit_label(cd, BRANCH_LABEL_6); + } + else { + M_CMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3); + + M_SETE(d); + if (d == REG_ITMP2) + M_BSEXT(d, d); + } if (super != NULL) emit_label(cd, BRANCH_LABEL_5);