diff options
Diffstat (limited to 'src/jit/dump.lua')
-rw-r--r-- | src/jit/dump.lua | 78 |
1 files changed, 52 insertions, 26 deletions
diff --git a/src/jit/dump.lua b/src/jit/dump.lua index 344fa926..18e7a4b7 100644 --- a/src/jit/dump.lua +++ b/src/jit/dump.lua | |||
@@ -55,7 +55,7 @@ | |||
55 | 55 | ||
56 | -- Cache some library functions and objects. | 56 | -- Cache some library functions and objects. |
57 | local jit = require("jit") | 57 | local jit = require("jit") |
58 | assert(jit.version_num == 20005, "LuaJIT core/library version mismatch") | 58 | assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") |
59 | local jutil = require("jit.util") | 59 | local jutil = require("jit.util") |
60 | local vmdef = require("jit.vmdef") | 60 | local vmdef = require("jit.vmdef") |
61 | local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc | 61 | local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc |
@@ -63,7 +63,7 @@ local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek | |||
63 | local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap | 63 | local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap |
64 | local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr | 64 | local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr |
65 | local bit = require("bit") | 65 | local bit = require("bit") |
66 | local band, shr = bit.band, bit.rshift | 66 | local band, shr, tohex = bit.band, bit.rshift, bit.tohex |
67 | local sub, gsub, format = string.sub, string.gsub, string.format | 67 | local sub, gsub, format = string.sub, string.gsub, string.format |
68 | local byte, rep = string.byte, string.rep | 68 | local byte, rep = string.byte, string.rep |
69 | local type, tostring = type, tostring | 69 | local type, tostring = type, tostring |
@@ -85,12 +85,13 @@ local nexitsym = 0 | |||
85 | local function fillsymtab_tr(tr, nexit) | 85 | local function fillsymtab_tr(tr, nexit) |
86 | local t = {} | 86 | local t = {} |
87 | symtabmt.__index = t | 87 | symtabmt.__index = t |
88 | if jit.arch == "mips" or jit.arch == "mipsel" then | 88 | if jit.arch:sub(1, 4) == "mips" then |
89 | t[traceexitstub(tr, 0)] = "exit" | 89 | t[traceexitstub(tr, 0)] = "exit" |
90 | return | 90 | return |
91 | end | 91 | end |
92 | for i=0,nexit-1 do | 92 | for i=0,nexit-1 do |
93 | local addr = traceexitstub(tr, i) | 93 | local addr = traceexitstub(tr, i) |
94 | if addr < 0 then addr = addr + 2^32 end | ||
94 | t[addr] = tostring(i) | 95 | t[addr] = tostring(i) |
95 | end | 96 | end |
96 | local addr = traceexitstub(tr, nexit) | 97 | local addr = traceexitstub(tr, nexit) |
@@ -101,10 +102,15 @@ end | |||
101 | local function fillsymtab(tr, nexit) | 102 | local function fillsymtab(tr, nexit) |
102 | local t = symtab | 103 | local t = symtab |
103 | if nexitsym == 0 then | 104 | if nexitsym == 0 then |
105 | local maskaddr = jit.arch == "arm" and -2 | ||
104 | local ircall = vmdef.ircall | 106 | local ircall = vmdef.ircall |
105 | for i=0,#ircall do | 107 | for i=0,#ircall do |
106 | local addr = ircalladdr(i) | 108 | local addr = ircalladdr(i) |
107 | if addr ~= 0 then t[addr] = ircall[i] end | 109 | if addr ~= 0 then |
110 | if maskaddr then addr = band(addr, maskaddr) end | ||
111 | if addr < 0 then addr = addr + 2^32 end | ||
112 | t[addr] = ircall[i] | ||
113 | end | ||
108 | end | 114 | end |
109 | end | 115 | end |
110 | if nexitsym == 1000000 then -- Per-trace exit stubs. | 116 | if nexitsym == 1000000 then -- Per-trace exit stubs. |
@@ -118,6 +124,7 @@ local function fillsymtab(tr, nexit) | |||
118 | nexit = 1000000 | 124 | nexit = 1000000 |
119 | break | 125 | break |
120 | end | 126 | end |
127 | if addr < 0 then addr = addr + 2^32 end | ||
121 | t[addr] = tostring(i) | 128 | t[addr] = tostring(i) |
122 | end | 129 | end |
123 | nexitsym = nexit | 130 | nexitsym = nexit |
@@ -136,6 +143,7 @@ local function dump_mcode(tr) | |||
136 | local mcode, addr, loop = tracemc(tr) | 143 | local mcode, addr, loop = tracemc(tr) |
137 | if not mcode then return end | 144 | if not mcode then return end |
138 | if not disass then disass = require("jit.dis_"..jit.arch) end | 145 | if not disass then disass = require("jit.dis_"..jit.arch) end |
146 | if addr < 0 then addr = addr + 2^32 end | ||
139 | out:write("---- TRACE ", tr, " mcode ", #mcode, "\n") | 147 | out:write("---- TRACE ", tr, " mcode ", #mcode, "\n") |
140 | local ctx = disass.create(mcode, addr, dumpwrite) | 148 | local ctx = disass.create(mcode, addr, dumpwrite) |
141 | ctx.hexdump = 0 | 149 | ctx.hexdump = 0 |
@@ -211,8 +219,10 @@ local function colorize_text(s) | |||
211 | return s | 219 | return s |
212 | end | 220 | end |
213 | 221 | ||
214 | local function colorize_ansi(s, t) | 222 | local function colorize_ansi(s, t, extra) |
215 | return format(colortype_ansi[t], s) | 223 | local out = format(colortype_ansi[t], s) |
224 | if extra then out = "\027[3m"..out end | ||
225 | return out | ||
216 | end | 226 | end |
217 | 227 | ||
218 | local irtype_ansi = setmetatable({}, | 228 | local irtype_ansi = setmetatable({}, |
@@ -221,9 +231,10 @@ local irtype_ansi = setmetatable({}, | |||
221 | 231 | ||
222 | local html_escape = { ["<"] = "<", [">"] = ">", ["&"] = "&", } | 232 | local html_escape = { ["<"] = "<", [">"] = ">", ["&"] = "&", } |
223 | 233 | ||
224 | local function colorize_html(s, t) | 234 | local function colorize_html(s, t, extra) |
225 | s = gsub(s, "[<>&]", html_escape) | 235 | s = gsub(s, "[<>&]", html_escape) |
226 | return format('<span class="irt_%s">%s</span>', irtype_text[t], s) | 236 | return format('<span class="irt_%s%s">%s</span>', |
237 | irtype_text[t], extra and " irt_extra" or "", s) | ||
227 | end | 238 | end |
228 | 239 | ||
229 | local irtype_html = setmetatable({}, | 240 | local irtype_html = setmetatable({}, |
@@ -248,6 +259,7 @@ span.irt_tab { color: #c00000; } | |||
248 | span.irt_udt, span.irt_lud { color: #00c0c0; } | 259 | span.irt_udt, span.irt_lud { color: #00c0c0; } |
249 | span.irt_num { color: #4040c0; } | 260 | span.irt_num { color: #4040c0; } |
250 | span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b040b0; } | 261 | span.irt_int, span.irt_i8, span.irt_u8, span.irt_i16, span.irt_u16 { color: #b040b0; } |
262 | span.irt_extra { font-style: italic; } | ||
251 | </style> | 263 | </style> |
252 | ]] | 264 | ]] |
253 | 265 | ||
@@ -263,6 +275,7 @@ local litname = { | |||
263 | if band(mode, 8) ~= 0 then s = s.."C" end | 275 | if band(mode, 8) ~= 0 then s = s.."C" end |
264 | if band(mode, 16) ~= 0 then s = s.."R" end | 276 | if band(mode, 16) ~= 0 then s = s.."R" end |
265 | if band(mode, 32) ~= 0 then s = s.."I" end | 277 | if band(mode, 32) ~= 0 then s = s.."I" end |
278 | if band(mode, 64) ~= 0 then s = s.."K" end | ||
266 | t[mode] = s | 279 | t[mode] = s |
267 | return s | 280 | return s |
268 | end}), | 281 | end}), |
@@ -270,16 +283,20 @@ local litname = { | |||
270 | ["CONV "] = setmetatable({}, { __index = function(t, mode) | 283 | ["CONV "] = setmetatable({}, { __index = function(t, mode) |
271 | local s = irtype[band(mode, 31)] | 284 | local s = irtype[band(mode, 31)] |
272 | s = irtype[band(shr(mode, 5), 31)].."."..s | 285 | s = irtype[band(shr(mode, 5), 31)].."."..s |
273 | if band(mode, 0x400) ~= 0 then s = s.." trunc" | 286 | if band(mode, 0x800) ~= 0 then s = s.." sext" end |
274 | elseif band(mode, 0x800) ~= 0 then s = s.." sext" end | ||
275 | local c = shr(mode, 12) | 287 | local c = shr(mode, 12) |
276 | if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end | 288 | if c == 1 then s = s.." none" |
289 | elseif c == 2 then s = s.." index" | ||
290 | elseif c == 3 then s = s.." check" end | ||
277 | t[mode] = s | 291 | t[mode] = s |
278 | return s | 292 | return s |
279 | end}), | 293 | end}), |
280 | ["FLOAD "] = vmdef.irfield, | 294 | ["FLOAD "] = vmdef.irfield, |
281 | ["FREF "] = vmdef.irfield, | 295 | ["FREF "] = vmdef.irfield, |
282 | ["FPMATH"] = vmdef.irfpm, | 296 | ["FPMATH"] = vmdef.irfpm, |
297 | ["TMPREF"] = { [0] = "", "IN", "OUT", "INOUT", "", "", "OUT2", "INOUT2" }, | ||
298 | ["BUFHDR"] = { [0] = "RESET", "APPEND", "WRITE" }, | ||
299 | ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, | ||
283 | } | 300 | } |
284 | 301 | ||
285 | local function ctlsub(c) | 302 | local function ctlsub(c) |
@@ -303,15 +320,19 @@ local function fmtfunc(func, pc) | |||
303 | end | 320 | end |
304 | end | 321 | end |
305 | 322 | ||
306 | local function formatk(tr, idx) | 323 | local function formatk(tr, idx, sn) |
307 | local k, t, slot = tracek(tr, idx) | 324 | local k, t, slot = tracek(tr, idx) |
308 | local tn = type(k) | 325 | local tn = type(k) |
309 | local s | 326 | local s |
310 | if tn == "number" then | 327 | if tn == "number" then |
311 | if k == 2^52+2^51 then | 328 | if t < 12 then |
329 | s = k == 0 and "NULL" or format("[0x%08x]", k) | ||
330 | elseif band(sn or 0, 0x30000) ~= 0 then | ||
331 | s = band(sn, 0x20000) ~= 0 and "contpc" or "ftsz" | ||
332 | elseif k == 2^52+2^51 then | ||
312 | s = "bias" | 333 | s = "bias" |
313 | else | 334 | else |
314 | s = format("%+.14g", k) | 335 | s = format(0 < k and k < 0x1p-1026 and "%+a" or "%+.14g", k) |
315 | end | 336 | end |
316 | elseif tn == "string" then | 337 | elseif tn == "string" then |
317 | s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub)) | 338 | s = format(#k > 20 and '"%.20s"~' or '"%s"', gsub(k, "%c", ctlsub)) |
@@ -329,10 +350,12 @@ local function formatk(tr, idx) | |||
329 | elseif t == 21 then -- int64_t | 350 | elseif t == 21 then -- int64_t |
330 | s = sub(tostring(k), 1, -3) | 351 | s = sub(tostring(k), 1, -3) |
331 | if sub(s, 1, 1) ~= "-" then s = "+"..s end | 352 | if sub(s, 1, 1) ~= "-" then s = "+"..s end |
353 | elseif sn == 0x1057fff then -- SNAP(1, SNAP_FRAME | SNAP_NORESTORE, REF_NIL) | ||
354 | return "----" -- Special case for LJ_FR2 slot 1. | ||
332 | else | 355 | else |
333 | s = tostring(k) -- For primitives. | 356 | s = tostring(k) -- For primitives. |
334 | end | 357 | end |
335 | s = colorize(format("%-4s", s), t) | 358 | s = colorize(format("%-4s", s), t, band(sn or 0, 0x100000) ~= 0) |
336 | if slot then | 359 | if slot then |
337 | s = format("%s @%d", s, slot) | 360 | s = format("%s @%d", s, slot) |
338 | end | 361 | end |
@@ -347,12 +370,12 @@ local function printsnap(tr, snap) | |||
347 | n = n + 1 | 370 | n = n + 1 |
348 | local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS | 371 | local ref = band(sn, 0xffff) - 0x8000 -- REF_BIAS |
349 | if ref < 0 then | 372 | if ref < 0 then |
350 | out:write(formatk(tr, ref)) | 373 | out:write(formatk(tr, ref, sn)) |
351 | elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM | 374 | elseif band(sn, 0x80000) ~= 0 then -- SNAP_SOFTFPNUM |
352 | out:write(colorize(format("%04d/%04d", ref, ref+1), 14)) | 375 | out:write(colorize(format("%04d/%04d", ref, ref+1), 14)) |
353 | else | 376 | else |
354 | local m, ot, op1, op2 = traceir(tr, ref) | 377 | local m, ot, op1, op2 = traceir(tr, ref) |
355 | out:write(colorize(format("%04d", ref), band(ot, 31))) | 378 | out:write(colorize(format("%04d", ref), band(ot, 31), band(sn, 0x100000) ~= 0)) |
356 | end | 379 | end |
357 | out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME | 380 | out:write(band(sn, 0x10000) == 0 and " " or "|") -- SNAP_FRAME |
358 | else | 381 | else |
@@ -545,7 +568,7 @@ local function dump_trace(what, tr, func, pc, otr, oex) | |||
545 | if what == "start" then | 568 | if what == "start" then |
546 | if dumpmode.H then out:write('<pre class="ljdump">\n') end | 569 | if dumpmode.H then out:write('<pre class="ljdump">\n') end |
547 | out:write("---- TRACE ", tr, " ", what) | 570 | out:write("---- TRACE ", tr, " ", what) |
548 | if otr then out:write(" ", otr, "/", oex) end | 571 | if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end |
549 | out:write(" ", fmtfunc(func, pc), "\n") | 572 | out:write(" ", fmtfunc(func, pc), "\n") |
550 | elseif what == "stop" or what == "abort" then | 573 | elseif what == "stop" or what == "abort" then |
551 | out:write("---- TRACE ", tr, " ", what) | 574 | out:write("---- TRACE ", tr, " ", what) |
@@ -595,23 +618,26 @@ end | |||
595 | 618 | ||
596 | ------------------------------------------------------------------------------ | 619 | ------------------------------------------------------------------------------ |
597 | 620 | ||
621 | local gpr64 = jit.arch:match("64") | ||
622 | local fprmips32 = jit.arch == "mips" or jit.arch == "mipsel" | ||
623 | |||
598 | -- Dump taken trace exits. | 624 | -- Dump taken trace exits. |
599 | local function dump_texit(tr, ex, ngpr, nfpr, ...) | 625 | local function dump_texit(tr, ex, ngpr, nfpr, ...) |
600 | out:write("---- TRACE ", tr, " exit ", ex, "\n") | 626 | out:write("---- TRACE ", tr, " exit ", ex, "\n") |
601 | if dumpmode.X then | 627 | if dumpmode.X then |
602 | local regs = {...} | 628 | local regs = {...} |
603 | if jit.arch == "x64" then | 629 | if gpr64 then |
604 | for i=1,ngpr do | 630 | for i=1,ngpr do |
605 | out:write(format(" %016x", regs[i])) | 631 | out:write(format(" %016x", regs[i])) |
606 | if i % 4 == 0 then out:write("\n") end | 632 | if i % 4 == 0 then out:write("\n") end |
607 | end | 633 | end |
608 | else | 634 | else |
609 | for i=1,ngpr do | 635 | for i=1,ngpr do |
610 | out:write(format(" %08x", regs[i])) | 636 | out:write(" ", tohex(regs[i])) |
611 | if i % 8 == 0 then out:write("\n") end | 637 | if i % 8 == 0 then out:write("\n") end |
612 | end | 638 | end |
613 | end | 639 | end |
614 | if jit.arch == "mips" or jit.arch == "mipsel" then | 640 | if fprmips32 then |
615 | for i=1,nfpr,2 do | 641 | for i=1,nfpr,2 do |
616 | out:write(format(" %+17.14g", regs[ngpr+i])) | 642 | out:write(format(" %+17.14g", regs[ngpr+i])) |
617 | if i % 8 == 7 then out:write("\n") end | 643 | if i % 8 == 7 then out:write("\n") end |
@@ -692,9 +718,9 @@ local function dumpon(opt, outfile) | |||
692 | end | 718 | end |
693 | 719 | ||
694 | -- Public module functions. | 720 | -- Public module functions. |
695 | module(...) | 721 | return { |
696 | 722 | on = dumpon, | |
697 | on = dumpon | 723 | off = dumpoff, |
698 | off = dumpoff | 724 | start = dumpon -- For -j command line option. |
699 | start = dumpon -- For -j command line option. | 725 | } |
700 | 726 | ||