Sfoglia il codice sorgente

Differentiate between IR_KPTR and IR_KKPTR.

IR_KPTR holds a const pointer to possibly non-const content.
IR_KKPTR holds a const pointer to definitely const content.
Note that only content known by the VM to be const qualifies.
Content tagged as const by users (e.g. const char *) doesn't.
Mike Pall 14 anni fa
parent
commit
925050fe3f
6 ha cambiato i file con 32 aggiunte e 23 eliminazioni
  1. 3 3
      src/lj_asm.c
  2. 8 6
      src/lj_ir.c
  3. 3 1
      src/lj_ir.h
  4. 3 1
      src/lj_iropt.h
  5. 12 9
      src/lj_opt_fold.c
  6. 3 3
      src/lj_record.c

+ 3 - 3
src/lj_asm.c

@@ -636,7 +636,7 @@ static Reg ra_rematk(ASMState *as, IRIns *ir)
 #endif
   } else {
     lua_assert(ir->o == IR_KINT || ir->o == IR_KGC ||
-	       ir->o == IR_KPTR || ir->o == IR_KNULL);
+	       ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL);
     emit_loadi(as, r, ir->i);
   }
   return r;
@@ -946,7 +946,7 @@ static void ra_left(ASMState *as, Reg dest, IRRef lref)
 #endif
       } else {
 	lua_assert(ir->o == IR_KINT || ir->o == IR_KGC ||
-		   ir->o == IR_KPTR || ir->o == IR_KNULL);
+		   ir->o == IR_KPTR || ir->o == IR_KKPTR || ir->o == IR_KNULL);
 	emit_loadi(as, dest, ir->i);
 	return;
       }
@@ -1312,7 +1312,7 @@ static void asm_fusexref(ASMState *as, IRRef ref, RegSet allow)
 {
   IRIns *ir = IR(ref);
   as->mrm.idx = RID_NONE;
-  if (ir->o == IR_KPTR) {
+  if (ir->o == IR_KPTR || ir->o == IR_KKPTR) {
     as->mrm.ofs = ir->i;
     as->mrm.base = RID_NONE;
   } else if (ir->o == IR_STRREF) {

+ 8 - 6
src/lj_ir.c

@@ -311,21 +311,21 @@ found:
 }
 
 /* Intern 32 bit pointer constant. */
-TRef lj_ir_kptr(jit_State *J, void *ptr)
+TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr)
 {
   IRIns *ir, *cir = J->cur.ir;
   IRRef ref;
   lua_assert((void *)(intptr_t)i32ptr(ptr) == ptr);
-  for (ref = J->chain[IR_KPTR]; ref; ref = cir[ref].prev)
+  for (ref = J->chain[op]; ref; ref = cir[ref].prev)
     if (mref(cir[ref].ptr, void) == ptr)
       goto found;
   ref = ir_nextk(J);
   ir = IR(ref);
   setmref(ir->ptr, ptr);
   ir->t.irt = IRT_P32;
-  ir->o = IR_KPTR;
-  ir->prev = J->chain[IR_KPTR];
-  J->chain[IR_KPTR] = (IRRef1)ref;
+  ir->o = op;
+  ir->prev = J->chain[op];
+  J->chain[op] = (IRRef1)ref;
 found:
   return TREF(ref, IRT_P32);
 }
@@ -382,7 +382,9 @@ void lj_ir_kvalue(lua_State *L, TValue *tv, const IRIns *ir)
   case IR_KPRI: setitype(tv, irt_toitype(ir->t)); break;
   case IR_KINT: setintV(tv, ir->i); break;
   case IR_KGC: setgcV(L, tv, ir_kgc(ir), irt_toitype(ir->t)); break;
-  case IR_KPTR: case IR_KNULL: setlightudV(tv, mref(ir->ptr, void)); break;
+  case IR_KPTR: case IR_KKPTR: case IR_KNULL:
+    setlightudV(tv, mref(ir->ptr, void));
+    break;
   case IR_KNUM: setnumV(tv, ir_knum(ir)->n); break;
 #if LJ_HASFFI
   case IR_KINT64: {

+ 3 - 1
src/lj_ir.h

@@ -42,6 +42,7 @@
   _(KINT,	N , cst, ___) \
   _(KGC,	N , cst, ___) \
   _(KPTR,	N , cst, ___) \
+  _(KKPTR,	N , cst, ___) \
   _(KNULL,	N , cst, ___) \
   _(KNUM,	N , cst, ___) \
   _(KINT64,	N , cst, ___) \
@@ -566,7 +567,8 @@ typedef union IRIns {
 #define ir_kint64(ir)	check_exp((ir)->o == IR_KINT64, mref((ir)->ptr,cTValue))
 #define ir_k64(ir) \
   check_exp((ir)->o == IR_KNUM || (ir)->o == IR_KINT64, mref((ir)->ptr,cTValue))
-#define ir_kptr(ir)	check_exp((ir)->o == IR_KPTR, mref((ir)->ptr, void))
+#define ir_kptr(ir) \
+  check_exp((ir)->o == IR_KPTR || (ir)->o == IR_KKPTR, mref((ir)->ptr, void))
 
 LJ_STATIC_ASSERT((int)IRT_GUARD == (int)IRM_W);
 

+ 3 - 1
src/lj_iropt.h

@@ -46,7 +46,7 @@ LJ_FUNC TRef lj_ir_knum_u64(jit_State *J, uint64_t u64);
 LJ_FUNC TRef lj_ir_knumint(jit_State *J, lua_Number n);
 LJ_FUNC TRef lj_ir_kint64(jit_State *J, uint64_t u64);
 LJ_FUNC TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t);
-LJ_FUNC TRef lj_ir_kptr(jit_State *J, void *ptr);
+LJ_FUNC TRef lj_ir_kptr_(jit_State *J, IROp op, void *ptr);
 LJ_FUNC TRef lj_ir_knull(jit_State *J, IRType t);
 LJ_FUNC TRef lj_ir_kslot(jit_State *J, TRef key, IRRef slot);
 
@@ -66,6 +66,8 @@ static LJ_AINLINE TRef lj_ir_knum(jit_State *J, lua_Number n)
 #define lj_ir_kstr(J, str)	lj_ir_kgc(J, obj2gco((str)), IRT_STR)
 #define lj_ir_ktab(J, tab)	lj_ir_kgc(J, obj2gco((tab)), IRT_TAB)
 #define lj_ir_kfunc(J, func)	lj_ir_kgc(J, obj2gco((func)), IRT_FUNC)
+#define lj_ir_kptr(J, ptr)	lj_ir_kptr_(J, IR_KPTR, (ptr))
+#define lj_ir_kkptr(J, ptr)	lj_ir_kptr_(J, IR_KKPTR, (ptr))
 
 /* Special FP constants. */
 #define lj_ir_knum_zero(J)	lj_ir_knum_u64(J, U64x(00000000,00000000))

+ 12 - 9
src/lj_opt_fold.c

@@ -385,7 +385,7 @@ LJFOLDF(kfold_int64comp0)
 
 /* -- Constant folding for strings ---------------------------------------- */
 
-LJFOLD(SNEW KPTR KINT)
+LJFOLD(SNEW KKPTR KINT)
 LJFOLDF(kfold_snew_kptr)
 {
   GCstr *s = lj_str_new(J->L, (const char *)ir_kptr(fleft), (size_t)fright->i);
@@ -405,7 +405,7 @@ LJFOLDF(kfold_strref)
 {
   GCstr *str = ir_kstr(fleft);
   lua_assert((MSize)fright->i < str->len);
-  return lj_ir_kptr(J, (char *)strdata(str) + fright->i);
+  return lj_ir_kkptr(J, (char *)strdata(str) + fright->i);
 }
 
 LJFOLD(STRREF SNEW any)
@@ -451,11 +451,13 @@ LJFOLDF(kfold_add_kgc)
 #else
   ptrdiff_t ofs = fright->i;
 #endif
-  return lj_ir_kptr(J, (char *)o + ofs);
+  return lj_ir_kkptr(J, (char *)o + ofs);
 }
 
 LJFOLD(ADD KPTR KINT)
 LJFOLD(ADD KPTR KINT64)
+LJFOLD(ADD KKPTR KINT)
+LJFOLD(ADD KKPTR KINT64)
 LJFOLDF(kfold_add_kptr)
 {
   void *p = ir_kptr(fleft);
@@ -464,7 +466,7 @@ LJFOLDF(kfold_add_kptr)
 #else
   ptrdiff_t ofs = fright->i;
 #endif
-  return lj_ir_kptr(J, (char *)p + ofs);
+  return lj_ir_kptr_(J, fleft->o, (char *)p + ofs);
 }
 
 /* -- Constant folding of conversions ------------------------------------- */
@@ -1574,8 +1576,8 @@ LJFOLD(ALOAD any)
 LJFOLDX(lj_opt_fwd_aload)
 
 /* From HREF fwd (see below). Must eliminate, not supported by fwd/backend. */
-LJFOLD(HLOAD KPTR)
-LJFOLDF(kfold_hload_kptr)
+LJFOLD(HLOAD KKPTR)
+LJFOLDF(kfold_hload_kkptr)
 {
   UNUSED(J);
   lua_assert(ir_kptr(fleft) == niltvg(J2G(J)));
@@ -1625,7 +1627,7 @@ LJFOLD(HREF TNEW any)
 LJFOLDF(fwd_href_tnew)
 {
   if (lj_opt_fwd_href_nokey(J))
-    return lj_ir_kptr(J, niltvg(J2G(J)));
+    return lj_ir_kkptr(J, niltvg(J2G(J)));
   return NEXTFOLD;
 }
 
@@ -1638,7 +1640,7 @@ LJFOLDF(fwd_href_tdup)
   lj_ir_kvalue(J->L, &keyv, fright);
   if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) &&
       lj_opt_fwd_href_nokey(J))
-    return lj_ir_kptr(J, niltvg(J2G(J)));
+    return lj_ir_kkptr(J, niltvg(J2G(J)));
   return NEXTFOLD;
 }
 
@@ -1760,7 +1762,8 @@ LJFOLDF(fwd_sload)
   }
 }
 
-LJFOLD(XLOAD KPTR any)
+/* Only fold for KKPTR. The pointer _and_ the contents must be const. */
+LJFOLD(XLOAD KKPTR any)
 LJFOLDF(xload_kptr)
 {
   TRef tr = kfold_xload(J, fins, ir_kptr(fleft));

+ 3 - 3
src/lj_record.c

@@ -1013,7 +1013,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
     IRType t = itype2irt(oldv);
     TRef res;
     if (oldv == niltvg(J2G(J))) {
-      emitir(IRTG(IR_EQ, IRT_P32), xref, lj_ir_kptr(J, niltvg(J2G(J))));
+      emitir(IRTG(IR_EQ, IRT_P32), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
       res = TREF_NIL;
     } else {
       res = emitir(IRTG(loadop, t), xref, 0);
@@ -1036,7 +1036,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
 	emitir(IRTG(loadop, IRT_NIL), xref, 0);  /* Guard for nil value. */
       else if (xrefop == IR_HREF)
 	emitir(IRTG(oldv == niltvg(J2G(J)) ? IR_EQ : IR_NE, IRT_P32),
-	       xref, lj_ir_kptr(J, niltvg(J2G(J))));
+	       xref, lj_ir_kkptr(J, niltvg(J2G(J))));
       if (ix->idxchain && lj_record_mm_lookup(J, ix, MM_newindex)) {
 	lua_assert(hasmm);
 	goto handlemm;
@@ -1052,7 +1052,7 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
     } else if (!lj_opt_fwd_wasnonnil(J, loadop, tref_ref(xref))) {
       /* Cannot derive that the previous value was non-nil, must do checks. */
       if (xrefop == IR_HREF)  /* Guard against store to niltv. */
-	emitir(IRTG(IR_NE, IRT_P32), xref, lj_ir_kptr(J, niltvg(J2G(J))));
+	emitir(IRTG(IR_NE, IRT_P32), xref, lj_ir_kkptr(J, niltvg(J2G(J))));
       if (ix->idxchain) {  /* Metamethod lookup required? */
 	/* A check for NULL metatable is cheaper (hoistable) than a load. */
 	if (!mt) {