From f26679c7195e99b32f95ea9f25b47b9981e15d3d Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 23 May 2016 00:34:05 +0200 Subject: [PATCH] LJ_GC64: Add support for 64 bit GCobj constants in the IR. Contributed by Peter Cawley. --- src/lj_asm.c | 11 ++++++++++- src/lj_ir.c | 29 ++++++++++++++++++++--------- src/lj_ir.h | 6 +++--- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/lj_asm.c b/src/lj_asm.c index 0b3e770a..9f784cc8 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -704,6 +704,11 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref) } else if (ir->o == IR_KINT64) { emit_loadk64(as, dest, ir); return; +#if LJ_GC64 + } else if (ir->o == IR_KGC || ir->o == IR_KPTR || ir->o == IR_KKPTR) { + emit_loadk64(as, dest, ir); + return; +#endif #endif } else if (ir->o != IR_KPRI) { lua_assert(ir->o == IR_KINT || ir->o == IR_KGC || @@ -1933,7 +1938,7 @@ static void asm_tail_link(ASMState *as) emit_addptr(as, RID_BASE, 8*(int32_t)baseslot); if (as->J->ktrace) { /* Patch ktrace slot with the final GCtrace pointer. */ - setgcref(IR(as->J->ktrace)->gcr, obj2gco(as->J->curfinal)); + setgcref(IR(as->J->ktrace)[LJ_GC64].gcr, obj2gco(as->J->curfinal)); IR(as->J->ktrace)->o = IR_KGC; } @@ -1965,8 +1970,12 @@ static void asm_setup_regsp(ASMState *as) for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++) { ir->prev = REGSP_INIT; if (irt_is64(ir->t) && ir->o != IR_KNULL) { +#if LJ_GC64 + ir->i = 0; /* Will become non-zero only for RIP-relative addresses. */ +#else /* Make life easier for backends by putting address of constant in i. */ ir->i = (int32_t)(intptr_t)(ir+1); +#endif ir++; } } diff --git a/src/lj_ir.c b/src/lj_ir.c index 9c0a2224..0a206ebb 100644 --- a/src/lj_ir.c +++ b/src/lj_ir.c @@ -185,6 +185,12 @@ static LJ_AINLINE IRRef ir_nextk64(jit_State *J) return ref; } +#if LJ_GC64 +#define ir_nextkgc ir_nextk64 +#else +#define ir_nextkgc ir_nextk +#endif + /* Intern int32_t constant. */ TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k) { @@ -268,15 +274,14 @@ TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t) { IRIns *ir, *cir = J->cur.ir; IRRef ref; - lua_assert(!LJ_GC64); /* TODO_GC64: major changes required. */ lua_assert(!isdead(J2G(J), o)); for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev) if (ir_kgc(&cir[ref]) == o) goto found; - ref = ir_nextk(J); + ref = ir_nextkgc(J); ir = IR(ref); /* NOBARRIER: Current trace is a GC root. */ - setgcref(ir->gcr, o); + setgcref(ir[LJ_GC64].gcr, o); ir->t.irt = (uint8_t)t; ir->o = IR_KGC; ir->prev = J->chain[IR_KGC]; @@ -288,33 +293,39 @@ found: /* Allocate GCtrace constant placeholder (no interning). */ TRef lj_ir_ktrace(jit_State *J) { - IRRef ref = ir_nextk(J); + IRRef ref = ir_nextkgc(J); IRIns *ir = IR(ref); lua_assert(irt_toitype_(IRT_P64) == LJ_TTRACE); ir->t.irt = IRT_P64; - ir->o = IR_KNULL; /* Not IR_KGC yet, but same size. */ + ir->o = LJ_GC64 ? IR_KNUM : IR_KNULL; /* Not IR_KGC yet, but same size. */ ir->prev = 0; return TREF(ref, IRT_P64); } -/* Intern 32 bit pointer constant. */ +/* Intern pointer constant. */ TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr) { IRIns *ir, *cir = J->cur.ir; IRRef ref; +#if LJ_64 && !LJ_GC64 lua_assert((void *)(uintptr_t)u32ptr(ptr) == ptr); +#endif for (ref = J->chain[op]; ref; ref = cir[ref].prev) if (ir_kptr(&cir[ref]) == ptr) goto found; +#if LJ_GC64 + ref = ir_nextk64(J); +#else ref = ir_nextk(J); +#endif ir = IR(ref); - setmref(ir->ptr, ptr); - ir->t.irt = IRT_P32; + setmref(ir[LJ_GC64].ptr, ptr); + ir->t.irt = IRT_PGC; ir->o = op; ir->prev = J->chain[op]; J->chain[op] = (IRRef1)ref; found: - return TREF(ref, IRT_P32); + return TREF(ref, IRT_PGC); } /* Intern typed NULL constant. */ diff --git a/src/lj_ir.h b/src/lj_ir.h index 03377ec1..8b2fe638 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -557,8 +557,7 @@ typedef union IRIns { TValue tv; /* TValue constant (overlaps entire slot). */ } IRIns; -/* TODO_GC64: major changes required. */ -#define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)->gcr)) +#define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)[LJ_GC64].gcr)) #define ir_kstr(ir) (gco2str(ir_kgc((ir)))) #define ir_ktab(ir) (gco2tab(ir_kgc((ir)))) #define ir_kfunc(ir) (gco2func(ir_kgc((ir)))) @@ -568,7 +567,8 @@ typedef union IRIns { #define ir_k64(ir) \ check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64, &(ir)[1].tv) #define ir_kptr(ir) \ - check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, mref((ir)->ptr, void)) + check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, \ + mref((ir)[LJ_GC64].ptr, void)) /* A store or any other op with a non-weak guard has a side-effect. */ static LJ_AINLINE int ir_sideeff(IRIns *ir)