Merged new changes from default (manually: src/vm/jit/i386/codegen.c).
authorStefan Ring <stefan@complang.tuwien.ac.at>
Sun, 12 Oct 2008 10:26:13 +0000 (12:26 +0200)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Sun, 12 Oct 2008 10:26:13 +0000 (12:26 +0200)
--HG--
branch : subtype-trunk

1  2 
src/vm/class.cpp
src/vm/jit/builtin.cpp
src/vm/jit/builtin.hpp
src/vm/jit/i386/codegen.c
src/vm/jit/i386/patcher.c

Simple merge
Simple merge
Simple merge
index eb6a518c55da4971b4f92b587cffba4dd7fb6a0f,b7e808cabc8f7ecaa927bb0ea5b0bb89c9e6e26a..bdedf5b6459f6c813c9f85ff1099689106b164ad
@@@ -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);
                                        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);
Simple merge