diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/LuaJIT-1.1.7/jit/dump.lua | 265 |
1 files changed, 0 insertions, 265 deletions
diff --git a/libraries/LuaJIT-1.1.7/jit/dump.lua b/libraries/LuaJIT-1.1.7/jit/dump.lua deleted file mode 100644 index 2287c23..0000000 --- a/libraries/LuaJIT-1.1.7/jit/dump.lua +++ /dev/null | |||
@@ -1,265 +0,0 @@ | |||
1 | ---------------------------------------------------------------------------- | ||
2 | -- LuaJIT machine code dumper module. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
5 | -- Released under the MIT/X license. See luajit.h for full copyright notice. | ||
6 | ---------------------------------------------------------------------------- | ||
7 | -- Activate this module to dump the machine code for all functions | ||
8 | -- immediately after they have been compiled. The disassembler | ||
9 | -- output is mixed with the bytecode listing. | ||
10 | -- | ||
11 | -- Try: luajit -j dump -e 'print "foo"' | ||
12 | -- luajit -j dump=foo.dump foo.lua | ||
13 | -- luajit -j off -j dump -e 'jit.compile(assert(loadfile"foo.lua")))' | ||
14 | -- | ||
15 | -- Default output is to stderr. To redirect output to a file, | ||
16 | -- pass a filename as an argument or set the environment variable | ||
17 | -- "LUAJIT_DUMPFILE". | ||
18 | -- Note: The file is overwritten each time you run luajit. | ||
19 | -- | ||
20 | -- TODO: Find a way to be more selective on what to dump. | ||
21 | ------------------------------------------------------------------------------ | ||
22 | |||
23 | -- Priority for compiler pipeline. Must run after backend (negative) | ||
24 | -- and should be even because we only catch successful compiles. | ||
25 | local PRIORITY = -98 | ||
26 | |||
27 | -- Cache some library functions and objects. | ||
28 | local jit = require("jit") | ||
29 | assert(jit.version_num == 10107, "LuaJIT core/library version mismatch") | ||
30 | local jutil = require("jit.util") | ||
31 | local type, format, gsub = type, string.format, string.gsub | ||
32 | local bytecode, const = jutil.bytecode, jutil.const | ||
33 | local getinfo = debug.getinfo | ||
34 | local stdout, stderr = io.stdout, io.stderr | ||
35 | |||
36 | -- Load the right disassembler. | ||
37 | local dis = require("jit.dis_"..jit.arch) | ||
38 | local discreate, disass_ = dis.create, dis.disass | ||
39 | |||
40 | -- Turn compilation off for the whole module. LuaJIT would do that anyway. | ||
41 | jit.off(true, true) | ||
42 | |||
43 | -- Separator line. | ||
44 | local sepline = "-------------------------------" | ||
45 | |||
46 | -- Map JSUB indices to names. | ||
47 | -- CHECK: must match the order in ljit_x86.h. Regenerate with: | ||
48 | -- grep '^ *JSUB_[^_].*,' ljit_x86.h | sed -e 's/^ *JSUB_/ "/' -e 's/,.*/",/' | ||
49 | local jsubnames = { | ||
50 | "STACKPTR", | ||
51 | "GATE_LJ", | ||
52 | "GATE_JL", | ||
53 | "GATE_JC", | ||
54 | "GROW_STACK", | ||
55 | "GROW_CI", | ||
56 | "GATE_JC_PATCH", | ||
57 | "GATE_JC_DEBUG", | ||
58 | "DEOPTIMIZE_CALLER", | ||
59 | "DEOPTIMIZE", | ||
60 | "DEOPTIMIZE_OPEN", | ||
61 | "HOOKINS", | ||
62 | "GCSTEP", | ||
63 | "STRING_SUB3", | ||
64 | "STRING_SUB2", | ||
65 | "HOOKCALL", | ||
66 | "HOOKRET", | ||
67 | "METACALL", | ||
68 | "METATAILCALL", | ||
69 | "BARRIERF", | ||
70 | "GETGLOBAL", | ||
71 | "GETTABLE_KSTR", | ||
72 | "GETTABLE_STR", | ||
73 | "BARRIERBACK", | ||
74 | "SETGLOBAL", | ||
75 | "SETTABLE_KSTR", | ||
76 | "SETTABLE_STR", | ||
77 | "GETTABLE_KNUM", | ||
78 | "GETTABLE_NUM", | ||
79 | "SETTABLE_KNUM", | ||
80 | "SETTABLE_NUM", | ||
81 | "LOG2_TWORD", | ||
82 | "CONCAT_STR2", | ||
83 | } | ||
84 | |||
85 | -- Generate map from JSUB addresses to JSUB names. | ||
86 | local jsubmap = {} | ||
87 | do | ||
88 | local jsubmcode = jutil.jsubmcode | ||
89 | for pc=0,100000 do | ||
90 | local addr = jsubmcode(pc) | ||
91 | if not addr then break end | ||
92 | jsubmap[addr] = jsubnames[pc+1] or "JSUB#"..pc | ||
93 | end | ||
94 | end | ||
95 | |||
96 | -- Pretty-print a constant. | ||
97 | local function conststr(func, idx) | ||
98 | local k = const(func, idx) | ||
99 | if k == nil then return "nil" | ||
100 | elseif k == true then return "true" | ||
101 | elseif k == false then return "false" | ||
102 | elseif type(k) == "string" then | ||
103 | if #k > 10 then return format('"%.10s"~', k) | ||
104 | else return '"'..k..'"' end | ||
105 | else return k.."" end | ||
106 | end | ||
107 | |||
108 | -- Pretty-print a bytecode instruction (one or two lines). | ||
109 | local function bytecodeout(out, func, pc) | ||
110 | local op, a, b, c = bytecode(func, pc) | ||
111 | if not op then | ||
112 | return true | ||
113 | elseif op == "JMP" then | ||
114 | out:write(format("\n--%04d-- JMP => %04d", pc, pc+1+b)) | ||
115 | elseif op == "FORLOOP" or op == "FORPREP" then | ||
116 | out:write(format("\n--%04d-- %-9s %3d => %04d", pc, op, a, pc+1+b)) | ||
117 | else | ||
118 | out:write(format("\n--%04d-- %-9s %3d %4s %4s", | ||
119 | pc, op, a, b or "", c or "")) | ||
120 | if b and b < 0 then out:write(" ; ", conststr(func, b)) end | ||
121 | if c and c < 0 then out:write(" ; ", conststr(func, c)) end | ||
122 | end | ||
123 | end | ||
124 | |||
125 | -- Dump machine code and mix it with the bytecode listing. | ||
126 | local function dumpfunc(func, out, deopt) | ||
127 | if not out then out = stderr end | ||
128 | local info = getinfo(func, "S") | ||
129 | |||
130 | -- Don't bother checking for the right blocks to dump. | ||
131 | -- Dump the main block (if not deopt) and always all deopt blocks. | ||
132 | for block=deopt and 2 or 1,1000000 do | ||
133 | local addr, code, mfmiter = jutil.mcode(func, block) | ||
134 | if not addr then | ||
135 | if code then return code end -- Not compiled: return status. | ||
136 | break -- No more blocks to dump. | ||
137 | end | ||
138 | |||
139 | -- Print header. | ||
140 | out:write(sepline, " ", info.source, ":", info.linedefined) | ||
141 | if block ~= 1 then out:write(" DEOPT block ", block) end | ||
142 | |||
143 | -- Create disassembler context. | ||
144 | local ctx = discreate(code, addr, function(s) out:write(s) end) | ||
145 | ctx.symtab = jsubmap | ||
146 | |||
147 | -- Dump an mcode block. | ||
148 | local pc, ofs = 1, 0 | ||
149 | local len, isdeopt = mfmiter() | ||
150 | if isdeopt then pc = len; len = 0 | ||
151 | elseif block ~= 1 then break end -- Stop before next main block. | ||
152 | for t, m in mfmiter do | ||
153 | if t == "COMBINE" then | ||
154 | bytecodeout(out, func, pc) | ||
155 | else | ||
156 | if len ~= 0 then | ||
157 | out:write("\n") | ||
158 | if len > 0 then | ||
159 | ctx:disass(ofs, len) | ||
160 | ofs = ofs + len | ||
161 | else | ||
162 | out:write(format("%08x ** deoptimized\n", addr+ofs)) | ||
163 | ofs = ofs - len | ||
164 | end | ||
165 | len = 0 | ||
166 | end | ||
167 | if type(t) == "number" then | ||
168 | if m then | ||
169 | if isdeopt then | ||
170 | pc = t - 1 | ||
171 | else | ||
172 | bytecodeout(out, func, pc) | ||
173 | len = -t | ||
174 | end | ||
175 | else | ||
176 | len = t | ||
177 | if bytecodeout(out, func, pc) then break end | ||
178 | end | ||
179 | end | ||
180 | end | ||
181 | pc = pc + 1 | ||
182 | end | ||
183 | if len and len ~= 0 then | ||
184 | out:write(sepline, " tail code\n") | ||
185 | ctx:disass(ofs, len) | ||
186 | end | ||
187 | end | ||
188 | |||
189 | -- Print footer. | ||
190 | out:write(sepline, "\n") | ||
191 | out:flush() | ||
192 | end | ||
193 | |||
194 | -- Dump the internal JIT subroutines. | ||
195 | local function dumpjsub_(out) | ||
196 | if not out then out = stderr end | ||
197 | local addr, code = jutil.jsubmcode() | ||
198 | |||
199 | -- Create disassembler context. | ||
200 | local ctx = discreate(code, addr, function(s) out:write(s) end) | ||
201 | ctx.symtab = jsubmap | ||
202 | |||
203 | -- Collect addresses and sort them. | ||
204 | local t = {} | ||
205 | for addr in pairs(jsubmap) do t[#t+1] = addr end | ||
206 | t[#t+1] = addr + #code | ||
207 | table.sort(t) | ||
208 | |||
209 | -- Go through the addresses in ascending order. | ||
210 | local ofs = addr | ||
211 | for i=2,#t do | ||
212 | local next = t[i] | ||
213 | out:write("\n->", jsubmap[ofs], ":\n") -- Output label for JSUB. | ||
214 | ctx:disass(ofs-addr, next-ofs) -- Disassemble corresponding code block. | ||
215 | ofs = next | ||
216 | end | ||
217 | out:flush() | ||
218 | end | ||
219 | |||
220 | |||
221 | -- Active flag and output file handle. | ||
222 | local active, out | ||
223 | |||
224 | -- Dump handler for compiler pipeline. | ||
225 | local function h_dump(st) | ||
226 | local ok, err = pcall(dumpfunc, st.func, out, st.deopt) | ||
227 | if not ok then | ||
228 | stderr:write("\nERROR: jit.dump disabled: ", err, "\n") | ||
229 | jit.attach(h_dump) -- Better turn ourselves off after a failure. | ||
230 | if out and out ~= stdout then out:close() end | ||
231 | out = nil | ||
232 | active = nil | ||
233 | end | ||
234 | end | ||
235 | |||
236 | -- Detach dump handler from compiler pipeline. | ||
237 | local function dumpoff() | ||
238 | if active then | ||
239 | active = false | ||
240 | jit.attach(h_dump) | ||
241 | if out and out ~= stdout then out:close() end | ||
242 | out = nil | ||
243 | end | ||
244 | end | ||
245 | |||
246 | -- Open the output file and attach dump handler to compiler pipeline. | ||
247 | local function dumpon(filename) | ||
248 | if active then dumpoff() end | ||
249 | local outfile = filename or os.getenv("LUAJIT_DUMPFILE") | ||
250 | out = outfile and (outfile == "-" and stdout or assert(io.open(outfile, "w"))) | ||
251 | jit.attach(h_dump, PRIORITY) | ||
252 | active = true | ||
253 | end | ||
254 | |||
255 | |||
256 | -- Public module functions. | ||
257 | module(...) | ||
258 | |||
259 | disass = disass_ | ||
260 | dump = dumpfunc | ||
261 | dumpjsub = dumpjsub_ | ||
262 | on = dumpon | ||
263 | off = dumpoff | ||
264 | start = dumpon -- For -j command line option. | ||
265 | |||