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