Przeglądaj źródła

Add trace recorder infrastructure for instruction post-processing.

Mike Pall 14 lat temu
rodzic
commit
66ba1e68aa
3 zmienionych plików z 32 dodań i 1 usunięć
  1. 9 1
      src/lj_jit.h
  2. 20 0
      src/lj_record.c
  3. 3 0
      src/lj_trace.c

+ 9 - 1
src/lj_jit.h

@@ -104,9 +104,15 @@ typedef enum {
   LJ_TRACE_START,	/* New trace started. */
   LJ_TRACE_END,		/* End of trace. */
   LJ_TRACE_ASM,		/* Assemble trace. */
-  LJ_TRACE_ERR,		/* Trace aborted with error. */
+  LJ_TRACE_ERR		/* Trace aborted with error. */
 } TraceState;
 
+/* Post-processing action. */
+typedef enum {
+  LJ_POST_NONE,		/* No action. */
+  LJ_POST_FIXGUARD	/* Fixup and emit pending guard. */
+} PostProc;
+
 /* Machine code type. */
 typedef uint8_t MCode;
 
@@ -284,6 +290,8 @@ typedef struct jit_State {
   SnapEntry *snapmapbuf;  /* Temp. snapshot map buffer. */
   MSize sizesnapmap;	/* Size of temp. snapshot map buffer. */
 
+  PostProc postproc;	/* Required post-processing after execution. */
+
   GCRef *trace;		/* Array of traces. */
   TraceNo freetrace;	/* Start of scan for next free trace. */
   MSize sizetrace;	/* Size of trace array. */

+ 20 - 0
src/lj_record.c

@@ -1365,6 +1365,26 @@ void lj_record_ins(jit_State *J)
   BCOp op;
   TRef ra, rb, rc;
 
+  /* Perform post-processing action before recording the next instruction. */
+  if (LJ_UNLIKELY(J->postproc != LJ_POST_NONE)) {
+    switch (J->postproc) {
+    case LJ_POST_FIXGUARD:  /* Fixup and emit pending guard. */
+      if (!tvistruecond(&J2G(J)->tmptv2)) {
+	BCReg s;
+	J->fold.ins.o ^= 1;  /* Flip guard to opposite. */
+	for (s = 0; s < J->maxslot; s++)  /* Fixup stack slot (if any). */
+	  if (J->base[s] == TREF_TRUE && tvisfalse(&J->L->base[s])) {
+	    J->base[s] = TREF_FALSE;
+	    break;
+	  }
+      }
+      lj_opt_fold(J);  /* Emit pending guard. */
+      break;
+    default: lua_assert(0); break;
+    }
+    J->postproc = LJ_POST_NONE;
+  }
+
   /* Need snapshot before recording next bytecode (e.g. after a store). */
   if (J->needsnap) {
     J->needsnap = 0;

+ 3 - 0
src/lj_trace.c

@@ -388,6 +388,7 @@ static void trace_start(jit_State *J)
   J->needsnap = 0;
   J->bcskip = 0;
   J->guardemit.irt = 0;
+  J->postproc = LJ_POST_NONE;
   setgcref(J->cur.startpt, obj2gco(J->pt));
 
   L = J->L;
@@ -454,6 +455,7 @@ static void trace_stop(jit_State *J)
 
   /* Commit new mcode only after all patching is done. */
   lj_mcode_commit(J, J->cur.mcode);
+  J->postproc = LJ_POST_NONE;
   trace_save(J);
 
   L = J->L;
@@ -485,6 +487,7 @@ static int trace_abort(jit_State *J)
   TraceError e = LJ_TRERR_RECERR;
   TraceNo traceno;
 
+  J->postproc = LJ_POST_NONE;
   lj_mcode_abort(J);
   if (tvisnum(L->top-1))
     e = (TraceError)lj_num2int(numV(L->top-1));