aboutsummaryrefslogtreecommitdiff
path: root/src/jit
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/jit/bc.lua19
-rw-r--r--src/jit/bcsave.lua8
-rw-r--r--src/jit/dis_arm.lua18
-rw-r--r--src/jit/dis_mips.lua30
-rw-r--r--src/jit/dis_mipsel.lua15
-rw-r--r--src/jit/dis_ppc.lua18
-rw-r--r--src/jit/dis_x64.lua15
-rw-r--r--src/jit/dis_x86.lua38
-rw-r--r--src/jit/dump.lua29
-rw-r--r--src/jit/p.lua218
-rw-r--r--src/jit/v.lua12
-rw-r--r--src/jit/zone.lua41
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.
43local jit = require("jit") 43local jit = require("jit")
44assert(jit.version_num == 20002, "LuaJIT core/library version mismatch") 44assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
45local jutil = require("jit.util") 45local jutil = require("jit.util")
46local vmdef = require("jit.vmdef") 46local vmdef = require("jit.vmdef")
47local bit = require("bit") 47local bit = require("bit")
@@ -179,13 +179,12 @@ local function bcliston(outfile)
179end 179end
180 180
181-- Public module functions. 181-- Public module functions.
182module(...) 182return {
183 183 line = bcline,
184line = bcline 184 dump = bcdump,
185dump = bcdump 185 targets = bctargets,
186targets = bctargets 186 on = bcliston,
187 187 off = bclistoff,
188on = bcliston 188 start = bcliston -- For -j command line option.
189off = bclistoff 189}
190start = 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
13local jit = require("jit") 13local jit = require("jit")
14assert(jit.version_num == 20002, "LuaJIT core/library version mismatch") 14assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
15local bit = require("bit") 15local 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.
656module(...) 656return {
657 657 start = docmd -- Process -b command line option.
658start = 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)
658end 658end
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).
661local function create_(code, addr, out) 661local 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)
670end 670end
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.
673local function disass_(code, addr, out) 673local function disass(code, addr, out)
674 create_(code, addr, out):disass() 674 create(code, addr, out):disass()
675end 675end
676 676
677-- Return register name for RID. 677-- Return register name for RID.
678local function regname_(r) 678local 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)
681end 681end
682 682
683-- Public module functions. 683-- Public module functions.
684module(...) 684return {
685 685 create = create,
686create = create_ 686 disass = disass,
687disass = disass_ 687 regname = regname
688regname = 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)
384end 384end
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).
387local function create_(code, addr, out) 387local 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
397end 397end
398 398
399local function create_el_(code, addr, out) 399local 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
403end 403end
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.
406local function disass_(code, addr, out) 406local function disass(code, addr, out)
407 create_(code, addr, out):disass() 407 create(code, addr, out):disass()
408end 408end
409 409
410local function disass_el_(code, addr, out) 410local function disass_el(code, addr, out)
411 create_el_(code, addr, out):disass() 411 create_el(code, addr, out):disass()
412end 412end
413 413
414-- Return register name for RID. 414-- Return register name for RID.
415local function regname_(r) 415local 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)
418end 418end
419 419
420-- Public module functions. 420-- Public module functions.
421module(...) 421return {
422 422 create = create,
423create = create_ 423 create_el = create_el,
424create_el = create_el_ 424 disass = disass,
425disass = disass_ 425 disass_el = disass_el,
426disass_el = disass_el_ 426 regname = regname
427regname = 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
11local require = require 11local dis_mips = require((string.match(..., ".*%.") or "").."dis_mips")
12 12return {
13module(...) 13 create = dis_mips.create_el,
14 14 disass = dis_mips.disass_el,
15local dis_mips = require(_PACKAGE.."dis_mips") 15 regname = dis_mips.regname
16 16}
17create = dis_mips.create_el
18disass = dis_mips.disass_el
19regname = 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)
560end 560end
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).
563local function create_(code, addr, out) 563local 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)
572end 572end
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.
575local function disass_(code, addr, out) 575local function disass(code, addr, out)
576 create_(code, addr, out):disass() 576 create(code, addr, out):disass()
577end 577end
578 578
579-- Return register name for RID. 579-- Return register name for RID.
580local function regname_(r) 580local 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)
583end 583end
584 584
585-- Public module functions. 585-- Public module functions.
586module(...) 586return {
587 587 create = create,
588create = create_ 588 disass = disass,
589disass = disass_ 589 regname = regname
590regname = 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
11local require = require 11local dis_x86 = require((string.match(..., ".*%.") or "").."dis_x86")
12 12return {
13module(...) 13 create = dis_x86.create64,
14 14 disass = dis_x86.disass64,
15local dis_x86 = require(_PACKAGE.."dis_x86") 15 regname = dis_x86.regname64
16 16}
17create = dis_x86.create64
18disass = dis_x86.disass64
19regname = 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
28local sub, byte, format = string.sub, string.byte, string.format 28local sub, byte, format = string.sub, string.byte, string.format
29local match, gmatch, gsub = string.match, string.gmatch, string.gsub 29local match, gmatch, gsub = string.match, string.gmatch, string.gsub
30local lower, rep = string.lower, string.rep 30local lower, rep = string.lower, string.rep
31local bit = require("bit")
32local 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.
33local map_opc1_32 = { 35local 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)
782end 784end
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).
785local function create_(code, addr, out) 787local 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
797end 799end
798 800
799local function create64_(code, addr, out) 801local 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)
805end 807end
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.
808local function disass_(code, addr, out) 810local function disass(code, addr, out)
809 create_(code, addr, out):disass() 811 create(code, addr, out):disass()
810end 812end
811 813
812local function disass64_(code, addr, out) 814local function disass64(code, addr, out)
813 create64_(code, addr, out):disass() 815 create64(code, addr, out):disass()
814end 816end
815 817
816-- Return register name for RID. 818-- Return register name for RID.
817local function regname_(r) 819local 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]
820end 822end
821 823
822local function regname64_(r) 824local 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]
825end 827end
826 828
827-- Public module functions. 829-- Public module functions.
828module(...) 830return {
829 831 create = create,
830create = create_ 832 create64 = create64,
831create64 = create64_ 833 disass = disass,
832disass = disass_ 834 disass64 = disass64,
833disass64 = disass64_ 835 regname = regname,
834regname = regname_ 836 regname64 = regname64
835regname64 = 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.
56local jit = require("jit") 56local jit = require("jit")
57assert(jit.version_num == 20002, "LuaJIT core/library version mismatch") 57assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
58local jutil = require("jit.util") 58local jutil = require("jit.util")
59local vmdef = require("jit.vmdef") 59local vmdef = require("jit.vmdef")
60local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc 60local funcinfo, funcbc = jutil.funcinfo, jutil.funcbc
@@ -62,7 +62,7 @@ local traceinfo, traceir, tracek = jutil.traceinfo, jutil.traceir, jutil.tracek
62local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap 62local tracemc, tracesnap = jutil.tracemc, jutil.tracesnap
63local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr 63local traceexitstub, ircalladdr = jutil.traceexitstub, jutil.ircalladdr
64local bit = require("bit") 64local bit = require("bit")
65local band, shl, shr = bit.band, bit.lshift, bit.rshift 65local band, shl, shr, tohex = bit.band, bit.lshift, bit.rshift, bit.tohex
66local sub, gsub, format = string.sub, string.gsub, string.format 66local sub, gsub, format = string.sub, string.gsub, string.format
67local byte, char, rep = string.byte, string.char, string.rep 67local byte, char, rep = string.byte, string.char, string.rep
68local type, tostring = type, tostring 68local 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
284local function ctlsub(c) 291local 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)
692end 699end
693 700
694-- Public module functions. 701-- Public module functions.
695module(...) 702return {
696 703 on = dumpon,
697on = dumpon 704 off = dumpoff,
698off = dumpoff 705 start = dumpon -- For -j command line option.
699start = 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.
41local jit = require("jit")
42assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
43local profile = require("jit.profile")
44local vmdef = require("jit.vmdef")
45local pairs, tonumber, floor, min = pairs, tonumber, math.floor, math.min
46local sort, format = table.sort, string.format
47local stdout = io.stdout
48local zone -- Load jit.zone module on demand.
49
50-- Output file handle.
51local out
52
53------------------------------------------------------------------------------
54
55local prof_ud
56local prof_states, prof_split, prof_maxn, prof_raw, prof_fmt, prof_depth
57local prof_count1, prof_count2, prof_samples
58
59local 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.
68local 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
111end
112
113------------------------------------------------------------------------------
114
115-- Show top N list.
116local 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
141end
142
143------------------------------------------------------------------------------
144
145-- Finish profiling and dump result.
146local 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
159end
160
161-- Start profiling.
162local 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
199end
200
201------------------------------------------------------------------------------
202
203local 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")
211end
212
213-- Public module functions.
214return {
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.
61local jit = require("jit") 61local jit = require("jit")
62assert(jit.version_num == 20002, "LuaJIT core/library version mismatch") 62assert(jit.version_num == 20100, "LuaJIT core/library version mismatch")
63local jutil = require("jit.util") 63local jutil = require("jit.util")
64local vmdef = require("jit.vmdef") 64local vmdef = require("jit.vmdef")
65local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo 65local funcinfo, traceinfo = jutil.funcinfo, jutil.traceinfo
@@ -159,9 +159,9 @@ local function dumpon(outfile)
159end 159end
160 160
161-- Public module functions. 161-- Public module functions.
162module(...) 162return {
163 163 on = dumpon,
164on = dumpon 164 off = dumpoff,
165off = dumpoff 165 start = dumpon -- For -j command line option.
166start = 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
27local remove = table.remove
28
29return 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