diff options
Diffstat (limited to '')
-rw-r--r-- | src/jit/bc.lua | 19 | ||||
-rw-r--r-- | src/jit/bcsave.lua | 8 | ||||
-rw-r--r-- | src/jit/dis_arm.lua | 18 | ||||
-rw-r--r-- | src/jit/dis_mips.lua | 30 | ||||
-rw-r--r-- | src/jit/dis_mipsel.lua | 15 | ||||
-rw-r--r-- | src/jit/dis_ppc.lua | 18 | ||||
-rw-r--r-- | src/jit/dis_x64.lua | 15 | ||||
-rw-r--r-- | src/jit/dis_x86.lua | 38 | ||||
-rw-r--r-- | src/jit/dump.lua | 29 | ||||
-rw-r--r-- | src/jit/p.lua | 218 | ||||
-rw-r--r-- | src/jit/v.lua | 12 | ||||
-rw-r--r-- | src/jit/zone.lua | 41 |
12 files changed, 361 insertions, 100 deletions
diff --git a/src/jit/bc.lua b/src/jit/bc.lua index cef47524..566b09c3 100644 --- a/src/jit/bc.lua +++ b/src/jit/bc.lua | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | -- Cache some library functions and objects. | 42 | -- Cache some library functions and objects. |
43 | local jit = require("jit") | 43 | local jit = require("jit") |
44 | assert(jit.version_num == 20002, "LuaJIT core/library version mismatch") | 44 | assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") |
45 | local jutil = require("jit.util") | 45 | local jutil = require("jit.util") |
46 | local vmdef = require("jit.vmdef") | 46 | local vmdef = require("jit.vmdef") |
47 | local bit = require("bit") | 47 | local bit = require("bit") |
@@ -179,13 +179,12 @@ local function bcliston(outfile) | |||
179 | end | 179 | end |
180 | 180 | ||
181 | -- Public module functions. | 181 | -- Public module functions. |
182 | module(...) | 182 | return { |
183 | 183 | line = bcline, | |
184 | line = bcline | 184 | dump = bcdump, |
185 | dump = bcdump | 185 | targets = bctargets, |
186 | targets = bctargets | 186 | on = bcliston, |
187 | 187 | off = bclistoff, | |
188 | on = bcliston | 188 | start = bcliston -- For -j command line option. |
189 | off = bclistoff | 189 | } |
190 | start = bcliston -- For -j command line option. | ||
191 | 190 | ||
diff --git a/src/jit/bcsave.lua b/src/jit/bcsave.lua index e6d566e5..8aad7596 100644 --- a/src/jit/bcsave.lua +++ b/src/jit/bcsave.lua | |||
@@ -11,7 +11,7 @@ | |||
11 | ------------------------------------------------------------------------------ | 11 | ------------------------------------------------------------------------------ |
12 | 12 | ||
13 | local jit = require("jit") | 13 | local jit = require("jit") |
14 | assert(jit.version_num == 20002, "LuaJIT core/library version mismatch") | 14 | assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") |
15 | local bit = require("bit") | 15 | local bit = require("bit") |
16 | 16 | ||
17 | -- Symbol name prefix for LuaJIT bytecode. | 17 | -- Symbol name prefix for LuaJIT bytecode. |
@@ -653,7 +653,7 @@ end | |||
653 | ------------------------------------------------------------------------------ | 653 | ------------------------------------------------------------------------------ |
654 | 654 | ||
655 | -- Public module functions. | 655 | -- Public module functions. |
656 | module(...) | 656 | return { |
657 | 657 | start = docmd -- Process -b command line option. | |
658 | start = docmd -- Process -b command line option. | 658 | } |
659 | 659 | ||
diff --git a/src/jit/dis_arm.lua b/src/jit/dis_arm.lua index dc7ca71f..87a84e93 100644 --- a/src/jit/dis_arm.lua +++ b/src/jit/dis_arm.lua | |||
@@ -658,7 +658,7 @@ local function disass_block(ctx, ofs, len) | |||
658 | end | 658 | end |
659 | 659 | ||
660 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). | 660 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). |
661 | local function create_(code, addr, out) | 661 | local function create(code, addr, out) |
662 | local ctx = {} | 662 | local ctx = {} |
663 | ctx.code = code | 663 | ctx.code = code |
664 | ctx.addr = addr or 0 | 664 | ctx.addr = addr or 0 |
@@ -670,20 +670,20 @@ local function create_(code, addr, out) | |||
670 | end | 670 | end |
671 | 671 | ||
672 | -- Simple API: disassemble code (a string) at address and output via out. | 672 | -- Simple API: disassemble code (a string) at address and output via out. |
673 | local function disass_(code, addr, out) | 673 | local function disass(code, addr, out) |
674 | create_(code, addr, out):disass() | 674 | create(code, addr, out):disass() |
675 | end | 675 | end |
676 | 676 | ||
677 | -- Return register name for RID. | 677 | -- Return register name for RID. |
678 | local function regname_(r) | 678 | local function regname(r) |
679 | if r < 16 then return map_gpr[r] end | 679 | if r < 16 then return map_gpr[r] end |
680 | return "d"..(r-16) | 680 | return "d"..(r-16) |
681 | end | 681 | end |
682 | 682 | ||
683 | -- Public module functions. | 683 | -- Public module functions. |
684 | module(...) | 684 | return { |
685 | 685 | create = create, | |
686 | create = create_ | 686 | disass = disass, |
687 | disass = disass_ | 687 | regname = regname |
688 | regname = regname_ | 688 | } |
689 | 689 | ||
diff --git a/src/jit/dis_mips.lua b/src/jit/dis_mips.lua index 830db409..9ba0e019 100644 --- a/src/jit/dis_mips.lua +++ b/src/jit/dis_mips.lua | |||
@@ -384,7 +384,7 @@ local function disass_block(ctx, ofs, len) | |||
384 | end | 384 | end |
385 | 385 | ||
386 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). | 386 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). |
387 | local function create_(code, addr, out) | 387 | local function create(code, addr, out) |
388 | local ctx = {} | 388 | local ctx = {} |
389 | ctx.code = code | 389 | ctx.code = code |
390 | ctx.addr = addr or 0 | 390 | ctx.addr = addr or 0 |
@@ -396,33 +396,33 @@ local function create_(code, addr, out) | |||
396 | return ctx | 396 | return ctx |
397 | end | 397 | end |
398 | 398 | ||
399 | local function create_el_(code, addr, out) | 399 | local function create_el(code, addr, out) |
400 | local ctx = create_(code, addr, out) | 400 | local ctx = create(code, addr, out) |
401 | ctx.get = get_le | 401 | ctx.get = get_le |
402 | return ctx | 402 | return ctx |
403 | end | 403 | end |
404 | 404 | ||
405 | -- Simple API: disassemble code (a string) at address and output via out. | 405 | -- Simple API: disassemble code (a string) at address and output via out. |
406 | local function disass_(code, addr, out) | 406 | local function disass(code, addr, out) |
407 | create_(code, addr, out):disass() | 407 | create(code, addr, out):disass() |
408 | end | 408 | end |
409 | 409 | ||
410 | local function disass_el_(code, addr, out) | 410 | local function disass_el(code, addr, out) |
411 | create_el_(code, addr, out):disass() | 411 | create_el(code, addr, out):disass() |
412 | end | 412 | end |
413 | 413 | ||
414 | -- Return register name for RID. | 414 | -- Return register name for RID. |
415 | local function regname_(r) | 415 | local function regname(r) |
416 | if r < 32 then return map_gpr[r] end | 416 | if r < 32 then return map_gpr[r] end |
417 | return "f"..(r-32) | 417 | return "f"..(r-32) |
418 | end | 418 | end |
419 | 419 | ||
420 | -- Public module functions. | 420 | -- Public module functions. |
421 | module(...) | 421 | return { |
422 | 422 | create = create, | |
423 | create = create_ | 423 | create_el = create_el, |
424 | create_el = create_el_ | 424 | disass = disass, |
425 | disass = disass_ | 425 | disass_el = disass_el, |
426 | disass_el = disass_el_ | 426 | regname = regname |
427 | regname = regname_ | 427 | } |
428 | 428 | ||
diff --git a/src/jit/dis_mipsel.lua b/src/jit/dis_mipsel.lua index 8a10c462..60e0233b 100644 --- a/src/jit/dis_mipsel.lua +++ b/src/jit/dis_mipsel.lua | |||
@@ -8,13 +8,10 @@ | |||
8 | -- MIPS disassembler module. All the interesting stuff is there. | 8 | -- MIPS disassembler module. All the interesting stuff is there. |
9 | ------------------------------------------------------------------------------ | 9 | ------------------------------------------------------------------------------ |
10 | 10 | ||
11 | local require = require | 11 | local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips") |
12 | 12 | return { | |
13 | module(...) | 13 | create = dis_mips.create_el, |
14 | 14 | disass = dis_mips.disass_el, | |
15 | local dis_mips = require(_PACKAGE.."dis_mips") | 15 | regname = dis_mips.regname |
16 | 16 | } | |
17 | create = dis_mips.create_el | ||
18 | disass = dis_mips.disass_el | ||
19 | regname = dis_mips.regname | ||
20 | 17 | ||
diff --git a/src/jit/dis_ppc.lua b/src/jit/dis_ppc.lua index 169a534c..5143d47a 100644 --- a/src/jit/dis_ppc.lua +++ b/src/jit/dis_ppc.lua | |||
@@ -560,7 +560,7 @@ local function disass_block(ctx, ofs, len) | |||
560 | end | 560 | end |
561 | 561 | ||
562 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). | 562 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). |
563 | local function create_(code, addr, out) | 563 | local function create(code, addr, out) |
564 | local ctx = {} | 564 | local ctx = {} |
565 | ctx.code = code | 565 | ctx.code = code |
566 | ctx.addr = addr or 0 | 566 | ctx.addr = addr or 0 |
@@ -572,20 +572,20 @@ local function create_(code, addr, out) | |||
572 | end | 572 | end |
573 | 573 | ||
574 | -- Simple API: disassemble code (a string) at address and output via out. | 574 | -- Simple API: disassemble code (a string) at address and output via out. |
575 | local function disass_(code, addr, out) | 575 | local function disass(code, addr, out) |
576 | create_(code, addr, out):disass() | 576 | create(code, addr, out):disass() |
577 | end | 577 | end |
578 | 578 | ||
579 | -- Return register name for RID. | 579 | -- Return register name for RID. |
580 | local function regname_(r) | 580 | local function regname(r) |
581 | if r < 32 then return map_gpr[r] end | 581 | if r < 32 then return map_gpr[r] end |
582 | return "f"..(r-32) | 582 | return "f"..(r-32) |
583 | end | 583 | end |
584 | 584 | ||
585 | -- Public module functions. | 585 | -- Public module functions. |
586 | module(...) | 586 | return { |
587 | 587 | create = create, | |
588 | create = create_ | 588 | disass = disass, |
589 | disass = disass_ | 589 | regname = regname |
590 | regname = regname_ | 590 | } |
591 | 591 | ||
diff --git a/src/jit/dis_x64.lua b/src/jit/dis_x64.lua index 4a1894ac..2f4f6e7c 100644 --- a/src/jit/dis_x64.lua +++ b/src/jit/dis_x64.lua | |||
@@ -8,13 +8,10 @@ | |||
8 | -- x86/x64 disassembler module. All the interesting stuff is there. | 8 | -- x86/x64 disassembler module. All the interesting stuff is there. |
9 | ------------------------------------------------------------------------------ | 9 | ------------------------------------------------------------------------------ |
10 | 10 | ||
11 | local require = require | 11 | local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86") |
12 | 12 | return { | |
13 | module(...) | 13 | create = dis_x86.create64, |
14 | 14 | disass = dis_x86.disass64, | |
15 | local dis_x86 = require(_PACKAGE.."dis_x86") | 15 | regname = dis_x86.regname64 |
16 | 16 | } | |
17 | create = dis_x86.create64 | ||
18 | disass = dis_x86.disass64 | ||
19 | regname = dis_x86.regname64 | ||
20 | 17 | ||
diff --git a/src/jit/dis_x86.lua b/src/jit/dis_x86.lua index c442a176..14b0fd61 100644 --- a/src/jit/dis_x86.lua +++ b/src/jit/dis_x86.lua | |||
@@ -28,6 +28,8 @@ local type = type | |||
28 | local sub, byte, format = string.sub, string.byte, string.format | 28 | local sub, byte, format = string.sub, string.byte, string.format |
29 | local match, gmatch, gsub = string.match, string.gmatch, string.gsub | 29 | local match, gmatch, gsub = string.match, string.gmatch, string.gsub |
30 | local lower, rep = string.lower, string.rep | 30 | local lower, rep = string.lower, string.rep |
31 | local bit = require("bit") | ||
32 | local tohex = bit.tohex | ||
31 | 33 | ||
32 | -- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on. | 34 | -- Map for 1st opcode byte in 32 bit mode. Ugly? Well ... read on. |
33 | local map_opc1_32 = { | 35 | local map_opc1_32 = { |
@@ -532,7 +534,7 @@ local function putpat(ctx, name, pat) | |||
532 | local lo = imm % 0x1000000 | 534 | local lo = imm % 0x1000000 |
533 | x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo) | 535 | x = format("0x%02x%06x", (imm-lo) / 0x1000000, lo) |
534 | else | 536 | else |
535 | x = format("0x%08x", imm) | 537 | x = "0x"..tohex(imm) |
536 | end | 538 | end |
537 | elseif p == "R" then | 539 | elseif p == "R" then |
538 | local r = byte(code, pos-1, pos-1)%8 | 540 | local r = byte(code, pos-1, pos-1)%8 |
@@ -782,7 +784,7 @@ local function disass_block(ctx, ofs, len) | |||
782 | end | 784 | end |
783 | 785 | ||
784 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). | 786 | -- Extended API: create a disassembler context. Then call ctx:disass(ofs, len). |
785 | local function create_(code, addr, out) | 787 | local function create(code, addr, out) |
786 | local ctx = {} | 788 | local ctx = {} |
787 | ctx.code = code | 789 | ctx.code = code |
788 | ctx.addr = (addr or 0) - 1 | 790 | ctx.addr = (addr or 0) - 1 |
@@ -796,8 +798,8 @@ local function create_(code, addr, out) | |||
796 | return ctx | 798 | return ctx |
797 | end | 799 | end |
798 | 800 | ||
799 | local function create64_(code, addr, out) | 801 | local function create64(code, addr, out) |
800 | local ctx = create_(code, addr, out) | 802 | local ctx = create(code, addr, out) |
801 | ctx.x64 = true | 803 | ctx.x64 = true |
802 | ctx.map1 = map_opc1_64 | 804 | ctx.map1 = map_opc1_64 |
803 | ctx.aregs = map_regs.Q | 805 | ctx.aregs = map_regs.Q |
@@ -805,32 +807,32 @@ local function create64_(code, addr, out) | |||
805 | end | 807 | end |
806 | 808 | ||
807 | -- Simple API: disassemble code (a string) at address and output via out. | 809 | -- Simple API: disassemble code (a string) at address and output via out. |
808 | local function disass_(code, addr, out) | 810 | local function disass(code, addr, out) |
809 | create_(code, addr, out):disass() | 811 | create(code, addr, out):disass() |
810 | end | 812 | end |
811 | 813 | ||
812 | local function disass64_(code, addr, out) | 814 | local function disass64(code, addr, out) |
813 | create64_(code, addr, out):disass() | 815 | create64(code, addr, out):disass() |
814 | end | 816 | end |
815 | 817 | ||
816 | -- Return register name for RID. | 818 | -- Return register name for RID. |
817 | local function regname_(r) | 819 | local function regname(r) |
818 | if r < 8 then return map_regs.D[r+1] end | 820 | if r < 8 then return map_regs.D[r+1] end |
819 | return map_regs.X[r-7] | 821 | return map_regs.X[r-7] |
820 | end | 822 | end |
821 | 823 | ||
822 | local function regname64_(r) | 824 | local function regname64(r) |
823 | if r < 16 then return map_regs.Q[r+1] end | 825 | if r < 16 then return map_regs.Q[r+1] end |
824 | return map_regs.X[r-15] | 826 | return map_regs.X[r-15] |
825 | end | 827 | end |
826 | 828 | ||
827 | -- Public module functions. | 829 | -- Public module functions. |
828 | module(...) | 830 | return { |
829 | 831 | create = create, | |
830 | create = create_ | 832 | create64 = create64, |
831 | create64 = create64_ | 833 | disass = disass, |
832 | disass = disass_ | 834 | disass64 = disass64, |
833 | disass64 = disass64_ | 835 | regname = regname, |
834 | regname = regname_ | 836 | regname64 = regname64 |
835 | regname64 = regname64_ | 837 | } |
836 | 838 | ||
diff --git a/src/jit/dump.lua b/src/jit/dump.lua index 7441b74d..4b79ad6a 100644 --- a/src/jit/dump.lua +++ b/src/jit/dump.lua | |||
@@ -54,7 +54,7 @@ | |||
54 | 54 | ||
55 | -- Cache some library functions and objects. | 55 | -- Cache some library functions and objects. |
56 | local jit = require("jit") | 56 | local jit = require("jit") |
57 | assert(jit.version_num == 20002, "LuaJIT core/library version mismatch") | 57 | assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") |
58 | local jutil = require("jit.util") | 58 | local jutil = require("jit.util") |
59 | local vmdef = require("jit.vmdef") | 59 | local vmdef = require("jit.vmdef") |
60 | local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc | 60 | local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc |
@@ -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, shl, shr = bit.band, bit.lshift, bit.rshift | 65 | local band, shl, shr, tohex = bit.band, bit.lshift, 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, char, rep = string.byte, string.char, string.rep | 67 | local byte, char, rep = string.byte, string.char, string.rep |
68 | local type, tostring = type, tostring | 68 | local type, tostring = type, tostring |
@@ -90,6 +90,7 @@ local function fillsymtab_tr(tr, nexit) | |||
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) |
@@ -103,7 +104,10 @@ local function fillsymtab(tr, nexit) | |||
103 | local ircall = vmdef.ircall | 104 | local ircall = vmdef.ircall |
104 | for i=0,#ircall do | 105 | for i=0,#ircall do |
105 | local addr = ircalladdr(i) | 106 | local addr = ircalladdr(i) |
106 | if addr ~= 0 then t[addr] = ircall[i] end | 107 | if addr ~= 0 then |
108 | if addr < 0 then addr = addr + 2^32 end | ||
109 | t[addr] = ircall[i] | ||
110 | end | ||
107 | end | 111 | end |
108 | end | 112 | end |
109 | if nexitsym == 1000000 then -- Per-trace exit stubs. | 113 | if nexitsym == 1000000 then -- Per-trace exit stubs. |
@@ -117,6 +121,7 @@ local function fillsymtab(tr, nexit) | |||
117 | nexit = 1000000 | 121 | nexit = 1000000 |
118 | break | 122 | break |
119 | end | 123 | end |
124 | if addr < 0 then addr = addr + 2^32 end | ||
120 | t[addr] = tostring(i) | 125 | t[addr] = tostring(i) |
121 | end | 126 | end |
122 | nexitsym = nexit | 127 | nexitsym = nexit |
@@ -135,6 +140,7 @@ local function dump_mcode(tr) | |||
135 | local mcode, addr, loop = tracemc(tr) | 140 | local mcode, addr, loop = tracemc(tr) |
136 | if not mcode then return end | 141 | if not mcode then return end |
137 | if not disass then disass = require("jit.dis_"..jit.arch) end | 142 | if not disass then disass = require("jit.dis_"..jit.arch) end |
143 | if addr < 0 then addr = addr + 2^32 end | ||
138 | out:write("---- TRACE ", tr, " mcode ", #mcode, "\n") | 144 | out:write("---- TRACE ", tr, " mcode ", #mcode, "\n") |
139 | local ctx = disass.create(mcode, addr, dumpwrite) | 145 | local ctx = disass.create(mcode, addr, dumpwrite) |
140 | ctx.hexdump = 0 | 146 | ctx.hexdump = 0 |
@@ -269,8 +275,7 @@ local litname = { | |||
269 | ["CONV "] = setmetatable({}, { __index = function(t, mode) | 275 | ["CONV "] = setmetatable({}, { __index = function(t, mode) |
270 | local s = irtype[band(mode, 31)] | 276 | local s = irtype[band(mode, 31)] |
271 | s = irtype[band(shr(mode, 5), 31)].."."..s | 277 | s = irtype[band(shr(mode, 5), 31)].."."..s |
272 | if band(mode, 0x400) ~= 0 then s = s.." trunc" | 278 | 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, 14) | 279 | local c = shr(mode, 14) |
275 | if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end | 280 | if c == 2 then s = s.." index" elseif c == 3 then s = s.." check" end |
276 | t[mode] = s | 281 | t[mode] = s |
@@ -279,6 +284,8 @@ local litname = { | |||
279 | ["FLOAD "] = vmdef.irfield, | 284 | ["FLOAD "] = vmdef.irfield, |
280 | ["FREF "] = vmdef.irfield, | 285 | ["FREF "] = vmdef.irfield, |
281 | ["FPMATH"] = vmdef.irfpm, | 286 | ["FPMATH"] = vmdef.irfpm, |
287 | ["BUFHDR"] = { [0] = "RESET", "APPEND" }, | ||
288 | ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, | ||
282 | } | 289 | } |
283 | 290 | ||
284 | local function ctlsub(c) | 291 | local function ctlsub(c) |
@@ -608,7 +615,7 @@ local function dump_texit(tr, ex, ngpr, nfpr, ...) | |||
608 | end | 615 | end |
609 | else | 616 | else |
610 | for i=1,ngpr do | 617 | for i=1,ngpr do |
611 | out:write(format(" %08x", regs[i])) | 618 | out:write(" ", tohex(regs[i])) |
612 | if i % 8 == 0 then out:write("\n") end | 619 | if i % 8 == 0 then out:write("\n") end |
613 | end | 620 | end |
614 | end | 621 | end |
@@ -692,9 +699,9 @@ local function dumpon(opt, outfile) | |||
692 | end | 699 | end |
693 | 700 | ||
694 | -- Public module functions. | 701 | -- Public module functions. |
695 | module(...) | 702 | return { |
696 | 703 | on = dumpon, | |
697 | on = dumpon | 704 | off = dumpoff, |
698 | off = dumpoff | 705 | start = dumpon -- For -j command line option. |
699 | start = dumpon -- For -j command line option. | 706 | } |
700 | 707 | ||
diff --git a/src/jit/p.lua b/src/jit/p.lua new file mode 100644 index 00000000..75d93215 --- /dev/null +++ b/src/jit/p.lua | |||
@@ -0,0 +1,218 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT profiler. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2013 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT license. See Copyright Notice in luajit.h | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- | ||
8 | -- This module is a simple command line interface to the built-in | ||
9 | -- low-overhead profiler of LuaJIT. | ||
10 | -- | ||
11 | -- The lower-level API of the profiler is accessible via the "jit.profile" | ||
12 | -- module or the luaJIT_profile_* C API. | ||
13 | -- | ||
14 | -- Example usage: | ||
15 | -- | ||
16 | -- luajit -jp myapp.lua | ||
17 | -- luajit -jp=s myapp.lua | ||
18 | -- luajit -jp=-s myapp.lua | ||
19 | -- luajit -jp=vl myapp.lua | ||
20 | -- luajit -jp=G,profile.txt myapp.lua | ||
21 | -- | ||
22 | -- The following dump features are available: | ||
23 | -- | ||
24 | -- f Stack dump: function name, Otherwise module:line. Default mode | ||
25 | -- F Stack dump: ditto, but always prepend module. | ||
26 | -- l Stack dump: module:line. | ||
27 | -- <number> stack dump depth (callee < caller). Default: 1. | ||
28 | -- -<number> Inverse stack dump depth (caller > callee). | ||
29 | -- s Split stack dump after first stack level. Implies abs(depth) >= 2. | ||
30 | -- p Show full path for module names. | ||
31 | -- v Show VM states. Can be combined with stack dumps, e.g. vf or fv. | ||
32 | -- z Show zones. Can be combined with stack dumps, e.g. zf or fz. | ||
33 | -- r Show raw sample counts. Default: show percentages. | ||
34 | -- G Produce output suitable for graphical tools (e.g. flame graphs). | ||
35 | -- n<number> Show top N samples. Default: 10. | ||
36 | -- i<number> Sampling interval in milliseconds. Default: 10. | ||
37 | -- | ||
38 | ---------------------------------------------------------------------------- | ||
39 | |||
40 | -- Cache some library functions and objects. | ||
41 | local jit = require("jit") | ||
42 | assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") | ||
43 | local profile = require("jit.profile") | ||
44 | local vmdef = require("jit.vmdef") | ||
45 | local pairs, tonumber, floor, min = pairs, tonumber, math.floor, math.min | ||
46 | local sort, format = table.sort, string.format | ||
47 | local stdout = io.stdout | ||
48 | local zone -- Load jit.zone module on demand. | ||
49 | |||
50 | -- Output file handle. | ||
51 | local out | ||
52 | |||
53 | ------------------------------------------------------------------------------ | ||
54 | |||
55 | local prof_ud | ||
56 | local prof_states, prof_split, prof_maxn, prof_raw, prof_fmt, prof_depth | ||
57 | local prof_count1, prof_count2, prof_samples | ||
58 | |||
59 | local map_vmmode = { | ||
60 | N = "Compiled", | ||
61 | I = "Interpreted", | ||
62 | C = "C code", | ||
63 | G = "Garbage Collector", | ||
64 | J = "JIT Compiler", | ||
65 | } | ||
66 | |||
67 | -- Profiler callback. | ||
68 | local function prof_cb(th, samples, vmmode) | ||
69 | prof_samples = prof_samples + samples | ||
70 | local key_stack, key_stack2, key_state | ||
71 | -- Collect keys for sample. | ||
72 | if prof_states then | ||
73 | if prof_states == "v" then | ||
74 | key_state = map_vmmode[vmmode] or vmmode | ||
75 | else | ||
76 | key_state = zone:get() or "(none)" | ||
77 | end | ||
78 | end | ||
79 | if prof_fmt then | ||
80 | key_stack = profile.dumpstack(th, prof_fmt, prof_depth) | ||
81 | key_stack = key_stack:gsub("%[builtin#(%d+)%]", function(x) | ||
82 | return vmdef.ffnames[tonumber(x)] | ||
83 | end) | ||
84 | if prof_split == 2 then | ||
85 | local k1, k2 = key_stack:match("(.-) [<>] (.*)") | ||
86 | if k2 then key_stack, key_stack2 = k1, k2 end | ||
87 | end | ||
88 | end | ||
89 | -- Order keys. | ||
90 | local k1, k2 | ||
91 | if prof_split == 1 then | ||
92 | if key_state then | ||
93 | k1 = key_state | ||
94 | if key_stack then k2 = key_stack end | ||
95 | end | ||
96 | elseif key_stack then | ||
97 | k1 = key_stack | ||
98 | if key_stack2 then k2 = key_stack2 elseif key_state then k2 = key_state end | ||
99 | end | ||
100 | -- Coalesce samples in one or two levels. | ||
101 | if k1 then | ||
102 | local t1 = prof_count1 | ||
103 | t1[k1] = (t1[k1] or 0) + samples | ||
104 | if k2 then | ||
105 | local t2 = prof_count2 | ||
106 | local t3 = t2[k1] | ||
107 | if not t3 then t3 = {}; t2[k1] = t3 end | ||
108 | t3[k2] = (t3[k2] or 0) + samples | ||
109 | end | ||
110 | end | ||
111 | end | ||
112 | |||
113 | ------------------------------------------------------------------------------ | ||
114 | |||
115 | -- Show top N list. | ||
116 | local function prof_top(count1, count2, samples, indent) | ||
117 | local t, n = {}, 0 | ||
118 | for k, v in pairs(count1) do | ||
119 | n = n + 1 | ||
120 | t[n] = k | ||
121 | end | ||
122 | sort(t, function(a, b) return count1[a] > count1[b] end) | ||
123 | local raw = prof_raw | ||
124 | for i=1,min(n, prof_maxn) do | ||
125 | local k = t[i] | ||
126 | local v = count1[k] | ||
127 | if not raw then | ||
128 | out:write(format("%s%2d%% %s\n", indent, floor(v*100/samples + 0.5), k)) | ||
129 | elseif raw == "r" then | ||
130 | out:write(format("%s%5d %s\n", indent, v, k)) | ||
131 | else | ||
132 | out:write(format("%s %d\n", k, v)) | ||
133 | end | ||
134 | if count2 then | ||
135 | local r = count2[k] | ||
136 | if r then | ||
137 | prof_top(r, nil, v, prof_depth < 0 and " -> " or " <- ") | ||
138 | end | ||
139 | end | ||
140 | end | ||
141 | end | ||
142 | |||
143 | ------------------------------------------------------------------------------ | ||
144 | |||
145 | -- Finish profiling and dump result. | ||
146 | local function prof_finish() | ||
147 | if prof_ud then | ||
148 | profile.stop() | ||
149 | local samples = prof_samples | ||
150 | if samples == 0 then | ||
151 | if prof_raw ~= true then out:write("[no samples collected]\n") end | ||
152 | return | ||
153 | end | ||
154 | prof_top(prof_count1, prof_count2, samples, "") | ||
155 | prof_count1 = nil | ||
156 | prof_count2 = nil | ||
157 | prof_ud = nil | ||
158 | end | ||
159 | end | ||
160 | |||
161 | -- Start profiling. | ||
162 | local function prof_start(mode) | ||
163 | local interval = "" | ||
164 | mode = mode:gsub("i%d*", function(s) interval = s; return "" end) | ||
165 | prof_maxn = 10 | ||
166 | mode = mode:gsub("n(%d+)", function(s) prof_maxn = tonumber(s); return "" end) | ||
167 | prof_depth = 1 | ||
168 | mode = mode:gsub("%-?%d+", function(s) prof_depth = tonumber(s); return "" end) | ||
169 | local m = {} | ||
170 | for c in mode:gmatch(".") do m[c] = c end | ||
171 | prof_states = m.z or m.v | ||
172 | if prof_states == "z" then zone = require("jit.zone") end | ||
173 | local scope = m.l or m.f or m.F or (prof_states and "" or "f") | ||
174 | local flags = (m.p or "") | ||
175 | prof_raw = m.r | ||
176 | if m.s then | ||
177 | prof_split = 2 | ||
178 | if prof_depth == -1 or m["-"] then prof_depth = -2 | ||
179 | elseif prof_depth == 1 then prof_depth = 2 end | ||
180 | else | ||
181 | prof_split = (scope == "" or mode:find("[zv].*[lfF]")) and 1 or 0 | ||
182 | end | ||
183 | if m.G and scope ~= "" then | ||
184 | prof_fmt = flags..scope.."Z;" | ||
185 | prof_depth = -100 | ||
186 | prof_raw = true | ||
187 | prof_maxn = 2147483647 | ||
188 | elseif scope == "" then | ||
189 | prof_fmt = false | ||
190 | else | ||
191 | prof_fmt = flags..scope..(prof_depth >= 0 and "Z < " or "Z > ") | ||
192 | end | ||
193 | prof_count1 = {} | ||
194 | prof_count2 = {} | ||
195 | prof_samples = 0 | ||
196 | profile.start(scope:lower()..interval, prof_cb) | ||
197 | prof_ud = newproxy(true) | ||
198 | getmetatable(prof_ud).__gc = prof_finish | ||
199 | end | ||
200 | |||
201 | ------------------------------------------------------------------------------ | ||
202 | |||
203 | local function start(mode, outfile) | ||
204 | if not outfile then outfile = os.getenv("LUAJIT_PROFILEFILE") end | ||
205 | if outfile then | ||
206 | out = outfile == "-" and stdout or assert(io.open(outfile, "w")) | ||
207 | else | ||
208 | out = stdout | ||
209 | end | ||
210 | prof_start(mode or "f") | ||
211 | end | ||
212 | |||
213 | -- Public module functions. | ||
214 | return { | ||
215 | start = start, -- For -j command line option. | ||
216 | stop = prof_finish | ||
217 | } | ||
218 | |||
diff --git a/src/jit/v.lua b/src/jit/v.lua index d7df7126..22bee3ff 100644 --- a/src/jit/v.lua +++ b/src/jit/v.lua | |||
@@ -59,7 +59,7 @@ | |||
59 | 59 | ||
60 | -- Cache some library functions and objects. | 60 | -- Cache some library functions and objects. |
61 | local jit = require("jit") | 61 | local jit = require("jit") |
62 | assert(jit.version_num == 20002, "LuaJIT core/library version mismatch") | 62 | assert(jit.version_num == 20100, "LuaJIT core/library version mismatch") |
63 | local jutil = require("jit.util") | 63 | local jutil = require("jit.util") |
64 | local vmdef = require("jit.vmdef") | 64 | local vmdef = require("jit.vmdef") |
65 | local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo | 65 | local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo |
@@ -159,9 +159,9 @@ local function dumpon(outfile) | |||
159 | end | 159 | end |
160 | 160 | ||
161 | -- Public module functions. | 161 | -- Public module functions. |
162 | module(...) | 162 | return { |
163 | 163 | on = dumpon, | |
164 | on = dumpon | 164 | off = dumpoff, |
165 | off = dumpoff | 165 | start = dumpon -- For -j command line option. |
166 | start = dumpon -- For -j command line option. | 166 | } |
167 | 167 | ||
diff --git a/src/jit/zone.lua b/src/jit/zone.lua new file mode 100644 index 00000000..da2eccb0 --- /dev/null +++ b/src/jit/zone.lua | |||
@@ -0,0 +1,41 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT profiler zones. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2013 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT license. See Copyright Notice in luajit.h | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- | ||
8 | -- This module implements a simple hierarchical zone model. | ||
9 | -- | ||
10 | -- Example usage: | ||
11 | -- | ||
12 | -- local zone = require("jit.zone") | ||
13 | -- zone("AI") | ||
14 | -- ... | ||
15 | -- zone("A*") | ||
16 | -- ... | ||
17 | -- print(zone:get()) --> "A*" | ||
18 | -- ... | ||
19 | -- zone() | ||
20 | -- ... | ||
21 | -- print(zone:get()) --> "AI" | ||
22 | -- ... | ||
23 | -- zone() | ||
24 | -- | ||
25 | ---------------------------------------------------------------------------- | ||
26 | |||
27 | local remove = table.remove | ||
28 | |||
29 | return setmetatable({ | ||
30 | flush = function(t) | ||
31 | for i=#t,1,-1 do t[i] = nil end | ||
32 | end, | ||
33 | get = function(t) | ||
34 | return t[#t] | ||
35 | end | ||
36 | }, { | ||
37 | __call = function(t, zone) | ||
38 | if zone then t[#t+1] = zone else return assert(remove(t)) end | ||
39 | end | ||
40 | }) | ||
41 | |||