소스 검색

PPC: Add support for per-trace exit stubs.

Mike Pall 14 년 전
부모
커밋
cb1dd159e3
3개의 변경된 파일40개의 추가작업 그리고 6개의 파일을 삭제
  1. 25 5
      lib/dump.lua
  2. 13 1
      src/lib_jit.c
  3. 2 0
      src/lj_target.h

+ 25 - 5
lib/dump.lua

@@ -76,11 +76,24 @@ local active, out, dumpmode
 
 ------------------------------------------------------------------------------
 
+local symtabmt = { __index = false }
 local symtab = {}
 local nexitsym = 0
 
--- Fill symbol table with trace exit addresses.
-local function fillsymtab(nexit)
+-- Fill nested symbol table with per-trace exit stub addresses.
+local function fillsymtab_tr(tr, nexit)
+  local t = {}
+  symtabmt.__index = t
+  for i=0,nexit-1 do
+    local addr = traceexitstub(tr, i)
+    t[addr] = tostring(i)
+  end
+  local addr = traceexitstub(tr, nexit)
+  if addr then t[addr] = "stack_check" end
+end
+
+-- Fill symbol table with trace exit stub addresses.
+local function fillsymtab(tr, nexit)
   local t = symtab
   if nexitsym == 0 then
     local ircall = vmdef.ircall
@@ -89,10 +102,17 @@ local function fillsymtab(nexit)
       if addr ~= 0 then t[addr] = ircall[i] end
     end
   end
-  if nexit > nexitsym then
+  if nexitsym == 1000000 then -- Per-trace exit stubs.
+    fillsymtab_tr(tr, nexit)
+  elseif nexit > nexitsym then -- Shared exit stubs.
     for i=nexitsym,nexit-1 do
       local addr = traceexitstub(i)
-      if addr == nil then nexit = 1000000; break end
+      if addr == nil then -- Fall back to per-trace exit stubs.
+	fillsymtab_tr(tr, nexit)
+	setmetatable(symtab, symtabmt)
+	nexit = 1000000
+	break
+      end
       t[addr] = tostring(i)
     end
     nexitsym = nexit
@@ -114,7 +134,7 @@ local function dump_mcode(tr)
   out:write("---- TRACE ", tr, " mcode ", #mcode, "\n")
   local ctx = disass.create(mcode, addr, dumpwrite)
   ctx.hexdump = 0
-  ctx.symtab = fillsymtab(info.nexit)
+  ctx.symtab = fillsymtab(tr, info.nexit)
   if loop ~= 0 then
     symtab[addr+loop] = "LOOP"
     ctx:disass(0, loop)

+ 13 - 1
src/lib_jit.c

@@ -377,15 +377,27 @@ LJLIB_CF(jit_util_tracemc)
   return 0;
 }
 
-/* local addr = jit.util.traceexitstub(idx) */
+/* local addr = jit.util.traceexitstub([tr,] exitno) */
 LJLIB_CF(jit_util_traceexitstub)
 {
+#ifdef EXITSTUBS_PER_GROUP
   ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1);
   jit_State *J = L2J(L);
   if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) {
     setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno));
     return 1;
   }
+#else
+  if (L->top > L->base+1) {  /* Don't throw for one-argument variant. */
+    GCtrace *T = jit_checktrace(L);
+    ExitNo exitno = (ExitNo)lj_lib_checkint(L, 2);
+    ExitNo maxexit = T->root ? T->nsnap+1 : T->nsnap;
+    if (T && T->mcode != NULL && exitno < maxexit) {
+      setintptrV(L->top-1, (intptr_t)(void *)exitstub_trace_addr(T, exitno));
+      return 1;
+    }
+  }
+#endif
   return 0;
 }
 

+ 2 - 0
src/lj_target.h

@@ -131,6 +131,7 @@ typedef uint32_t RegCost;
 #error "Missing include for target CPU"
 #endif
 
+#ifdef EXITSTUBS_PER_GROUP
 /* Return the address of an exit stub. */
 static LJ_AINLINE MCode *exitstub_addr(jit_State *J, ExitNo exitno)
 {
@@ -138,5 +139,6 @@ static LJ_AINLINE MCode *exitstub_addr(jit_State *J, ExitNo exitno)
   return (MCode *)((char *)J->exitstubgroup[exitno / EXITSTUBS_PER_GROUP] +
 		   EXITSTUB_SPACING*(exitno % EXITSTUBS_PER_GROUP));
 }
+#endif
 
 #endif