#include "vm/jit/x86_64/codegen.h"
#include "vm/jit/x86_64/emit.h"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
-#include "native/jni.h"
-#include "native/localref.h"
-#include "native/native.h"
+#include "native/localref.hpp"
+#include "native/native.hpp"
-#include "threads/lock-common.h"
+#include "threads/lock.hpp"
-#include "vm/builtin.h"
+#include "vm/jit/builtin.hpp"
#include "vm/exceptions.hpp"
#include "vm/global.h"
+#include "vm/loader.hpp"
+#include "vm/options.h"
#include "vm/primitive.hpp"
+#include "vm/statistics.h"
#include "vm/string.hpp"
#include "vm/vm.hpp"
#include "vm/jit/abi.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/code.h"
-#include "vm/jit/codegen-common.h"
+#include "vm/jit/code.hpp"
+#include "vm/jit/codegen-common.hpp"
#include "vm/jit/dseg.h"
-#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/linenumbertable.h"
+#include "vm/jit/emit-common.hpp"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/linenumbertable.hpp"
#include "vm/jit/methodheader.h"
-#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/parse.hpp"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/trap.h"
# include "vm/jit/allocator/lsra.h"
#endif
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-#include "vmcore/statistics.h"
-
/* codegen_emit ****************************************************************
M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
M_ALD(REG_ITMP3, RIP, disp);
- M_ILD(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_LCMP_MEMINDEX(REG_ITMP2, 0, REG_ITMP1, 0, REG_ITMP3);
+ emit_label_beq(cd, BRANCH_LABEL_6); /* good */
- /* if (s1 != REG_ITMP1) { */
- /* emit_movl_membase_reg(cd, REG_ITMP3, */
- /* OFFSET(vftbl_t, baseval), */
- /* REG_ITMP1); */
- /* emit_movl_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_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
+ emit_label_bne(cd, BRANCH_LABEL_10); /* throw */
+ }
- /* } else { */
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
+ M_ICMP_MEMBASE(REG_ITMP2, OFFSET(vftbl_t, subtype_depth), REG_ITMP1);
+ emit_label_bgt(cd, BRANCH_LABEL_9); /* throw */
- M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
- M_ISUB(REG_ITMP3, REG_ITMP2);
- M_ALD(REG_ITMP3, RIP, disp);
- M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
- /* } */
+ M_ALD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, subtype_overflow));
+ M_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, 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);
- M_ICMP(REG_ITMP3, REG_ITMP2);
- emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1);
+ /* 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_LCMP_MEMBASE(REG_ITMP2, super->vftbl->subtype_offset, REG_ITMP3);
+ emit_classcast_check(cd, iptr, BRANCH_NE, REG_ITMP3, s1);
+ }
if (super != NULL)
emit_label(cd, BRANCH_LABEL_5);
disp = dseg_add_address(cd, super->vftbl);
}
- M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
- M_ALD(REG_ITMP2, RIP, disp);
+ M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
+ M_ALD(REG_ITMP3, RIP, disp);
+
+ if (super == NULL || super->vftbl->subtype_depth >= DISPLAY_SIZE) {
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_offset));
+ M_LCMP_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_LINC(d);
+ emit_label_br(cd, BRANCH_LABEL_6); /* true */
+ emit_label(cd, BRANCH_LABEL_8);
- 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));
+ if (super == NULL) {
+ M_LCMP_IMM(OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]), REG_ITMP1);
+ emit_label_bne(cd, BRANCH_LABEL_10); /* false */
+ }
- M_ISUB(REG_ITMP2, REG_ITMP1);
- M_CLR(d); /* may be REG_ITMP2 */
- M_ICMP(REG_ITMP3, REG_ITMP1);
- M_SETULE(d);
+ M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, subtype_depth));
+ M_ICMP_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_LCMP_MEMINDEX(REG_ITMP2, -8*DISPLAY_SIZE, REG_ITMP1, 3, 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_LCMP_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);
case TYPE_INT:
case TYPE_LNG:
case TYPE_ADR:
- switch (md->returntype.decltype) {
+ switch (md->returntype.primitivetype) {
case PRIMITIVETYPE_BOOLEAN:
M_BZEXT(REG_RESULT, REG_RESULT);
break;