diff options
Diffstat (limited to 'src/jit/dump.lua')
| -rw-r--r-- | src/jit/dump.lua | 83 |
1 files changed, 57 insertions, 26 deletions
diff --git a/src/jit/dump.lua b/src/jit/dump.lua index 5097db94..6a700bbe 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 |
| @@ -529,7 +552,12 @@ local recdepth = 0 | |||
| 529 | local function fmterr(err, info) | 552 | local function fmterr(err, info) |
| 530 | if type(err) == "number" then | 553 | if type(err) == "number" then |
| 531 | if type(info) == "function" then info = fmtfunc(info) end | 554 | if type(info) == "function" then info = fmtfunc(info) end |
| 532 | err = format(vmdef.traceerr[err], info) | 555 | local fmt = vmdef.traceerr[err] |
| 556 | if fmt == "NYI: bytecode %s" then | ||
| 557 | local oidx = 6 * info | ||
| 558 | info = sub(vmdef.bcnames, oidx+1, oidx+6) | ||
| 559 | end | ||
| 560 | err = format(fmt, info) | ||
| 533 | end | 561 | end |
| 534 | return err | 562 | return err |
| 535 | end | 563 | end |
| @@ -544,7 +572,7 @@ local function dump_trace(what, tr, func, pc, otr, oex) | |||
| 544 | if what == "start" then | 572 | if what == "start" then |
| 545 | if dumpmode.H then out:write('<pre class="ljdump">\n') end | 573 | if dumpmode.H then out:write('<pre class="ljdump">\n') end |
| 546 | out:write("---- TRACE ", tr, " ", what) | 574 | out:write("---- TRACE ", tr, " ", what) |
| 547 | if otr then out:write(" ", otr, "/", oex) end | 575 | if otr then out:write(" ", otr, "/", oex == -1 and "stitch" or oex) end |
| 548 | out:write(" ", fmtfunc(func, pc), "\n") | 576 | out:write(" ", fmtfunc(func, pc), "\n") |
| 549 | elseif what == "stop" or what == "abort" then | 577 | elseif what == "stop" or what == "abort" then |
| 550 | out:write("---- TRACE ", tr, " ", what) | 578 | out:write("---- TRACE ", tr, " ", what) |
| @@ -594,23 +622,26 @@ end | |||
| 594 | 622 | ||
| 595 | ------------------------------------------------------------------------------ | 623 | ------------------------------------------------------------------------------ |
| 596 | 624 | ||
| 625 | local gpr64 = jit.arch:match("64") | ||
| 626 | local fprmips32 = jit.arch == "mips" or jit.arch == "mipsel" | ||
| 627 | |||
| 597 | -- Dump taken trace exits. | 628 | -- Dump taken trace exits. |
| 598 | local function dump_texit(tr, ex, ngpr, nfpr, ...) | 629 | local function dump_texit(tr, ex, ngpr, nfpr, ...) |
| 599 | out:write("---- TRACE ", tr, " exit ", ex, "\n") | 630 | out:write("---- TRACE ", tr, " exit ", ex, "\n") |
| 600 | if dumpmode.X then | 631 | if dumpmode.X then |
| 601 | local regs = {...} | 632 | local regs = {...} |
| 602 | if jit.arch == "x64" then | 633 | if gpr64 then |
| 603 | for i=1,ngpr do | 634 | for i=1,ngpr do |
| 604 | out:write(format(" %016x", regs[i])) | 635 | out:write(format(" %016x", regs[i])) |
| 605 | if i % 4 == 0 then out:write("\n") end | 636 | if i % 4 == 0 then out:write("\n") end |
| 606 | end | 637 | end |
| 607 | else | 638 | else |
| 608 | for i=1,ngpr do | 639 | for i=1,ngpr do |
| 609 | out:write(format(" %08x", regs[i])) | 640 | out:write(" ", tohex(regs[i])) |
| 610 | if i % 8 == 0 then out:write("\n") end | 641 | if i % 8 == 0 then out:write("\n") end |
| 611 | end | 642 | end |
| 612 | end | 643 | end |
| 613 | if jit.arch == "mips" or jit.arch == "mipsel" then | 644 | if fprmips32 then |
| 614 | for i=1,nfpr,2 do | 645 | for i=1,nfpr,2 do |
| 615 | out:write(format(" %+17.14g", regs[ngpr+i])) | 646 | out:write(format(" %+17.14g", regs[ngpr+i])) |
| 616 | if i % 8 == 7 then out:write("\n") end | 647 | if i % 8 == 7 then out:write("\n") end |
| @@ -691,9 +722,9 @@ local function dumpon(opt, outfile) | |||
| 691 | end | 722 | end |
| 692 | 723 | ||
| 693 | -- Public module functions. | 724 | -- Public module functions. |
| 694 | module(...) | 725 | return { |
| 695 | 726 | on = dumpon, | |
| 696 | on = dumpon | 727 | off = dumpoff, |
| 697 | off = dumpoff | 728 | start = dumpon -- For -j command line option. |
| 698 | start = dumpon -- For -j command line option. | 729 | } |
| 699 | 730 | ||
