aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/LuaJIT-1.1.7/src/ljit_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/LuaJIT-1.1.7/src/ljit_core.c')
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_core.c385
1 files changed, 0 insertions, 385 deletions
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_core.c b/libraries/LuaJIT-1.1.7/src/ljit_core.c
deleted file mode 100644
index f7385f2..0000000
--- a/libraries/LuaJIT-1.1.7/src/ljit_core.c
+++ /dev/null
@@ -1,385 +0,0 @@
1/*
2** Interface to JIT engine.
3** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#define ljit_core_c
7#define LUA_CORE
8
9#include <string.h>
10
11#include "lua.h"
12
13#include "lobject.h"
14#include "lstate.h"
15#include "ldo.h"
16#include "lstring.h"
17#include "ltable.h"
18#include "ldebug.h"
19#include "lopcodes.h"
20
21#include "ljit.h"
22#include "ljit_hints.h"
23#include "luajit.h"
24
25const char luajit_ident[] =
26 "$LuaJIT: " LUAJIT_VERSION " " LUAJIT_COPYRIGHT " " LUAJIT_URL " $\n";
27
28/* ------------------------------------------------------------------------ */
29
30/* Initialize JIT engine state. */
31void luaJIT_initstate(lua_State *L)
32{
33 jit_State *J = luaM_new(L, jit_State);
34 G(L)->jit_state = J;
35 /* Clear JIT engine fields. */
36 J->frontwrap = NULL; /* Filled in by ljitlib before enabling the engine. */
37 J->flags = 0; /* Disable the JIT engine by default. */
38 /* Try to initialize the backend. */
39 if (luaJIT_initbackend(L) != JIT_S_OK)
40 J->flags = JIT_F_INIT_FAILED;
41 J->L = NULL; /* No compiler thread allocated, yet. */
42}
43
44/* Free JIT engine state. */
45void luaJIT_freestate(lua_State *L)
46{
47 jit_State *J = G(L)->jit_state;
48 if (J == NULL) return;
49 luaJIT_freebackend(L);
50 luaM_free(L, J);
51 G(L)->jit_state = NULL;
52}
53
54/* ------------------------------------------------------------------------ */
55
56/* Find relative PC (0 based) for a bytecode pointer or a JIT mcode address. */
57int luaJIT_findpc(Proto *pt, const Instruction *savedpc)
58{
59 ptrdiff_t pcdiff = savedpc - pt->code;
60 if (pcdiff >= 0 && pcdiff <= pt->sizecode) { /* Bytecode pointer? */
61 return (int)pcdiff-1;
62 } else { /* Else translate JIT mcode address to PC. */
63 char *addr = (char *)savedpc;
64 jit_MCTrailer tr;
65 tr.mcode = (char *)pt->jit_mcode;
66 tr.sz = pt->jit_szmcode;
67 /* Follow trailer chain until addr is part of an mcode block. */
68 while (!((size_t)(addr - tr.mcode) < tr.sz)) {
69 memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz),
70 sizeof(jit_MCTrailer));
71 if (tr.mcode == NULL) return -1; /* Not in chain. */
72 }
73 {
74 jit_Mfm *mfm = JIT_MCMFM(tr.mcode, tr.sz);
75 int ofs = (int)(addr - tr.mcode);
76 int isdeopt = !jit_mfm_ismain(mfm);
77 int pc = 0; /* Prologue fragment is at start of main mfm. */
78 while (pc <= pt->sizecode) {
79 int m = *mfm--;
80 switch (m) {
81 default:
82 if (m & JIT_MFM_MARK) {
83 m ^= JIT_MFM_MARK;
84 if (isdeopt) { pc = m; continue; } /* Seek. */
85 }
86 ofs -= m;
87 if (ofs <= 0) return pc-1; /* Found! */
88 case JIT_MFM_COMBINE:
89 case JIT_MFM_DEAD:
90 pc++;
91 break;
92 case JIT_MFM_STOP:
93 jit_assert(0); /* Premature STOP found. */
94 return -1;
95 }
96 }
97 jit_assert(0); /* Address is in .tail. */
98 return -1;
99 }
100 }
101}
102
103/* Lookup mcode address for PC (1 based) in mfm. */
104static void *jit_mfmlookup(jit_Mfm *mfm, char *addr, int mpc)
105{
106 int isdeopt = !jit_mfm_ismain(mfm);
107 int pc = 0; /* Prologue fragment is at start of main mfm. */
108 while (pc != mpc) {
109 int m = *mfm--;
110 switch (m) {
111 default:
112 if (m & JIT_MFM_MARK) {
113 m ^= JIT_MFM_MARK;
114 if (isdeopt) { pc = m; continue; } /* Seek. */
115 }
116 addr += m;
117 case JIT_MFM_COMBINE:
118 case JIT_MFM_DEAD:
119 pc++;
120 break;
121 case JIT_MFM_STOP:
122 return NULL;
123 }
124 }
125 return (void *)addr;
126}
127
128/* Find mcode address for PC (1 based). */
129void *luaJIT_findmcode(Proto *pt, int pc)
130{
131 void *addr = NULL;
132 jit_Mfm *mfm;
133 jit_MCTrailer tr;
134 tr.mcode = (char *)pt->jit_mcode;
135 tr.sz = pt->jit_szmcode;
136 mfm = JIT_MCMFM(tr.mcode, tr.sz);
137 jit_assert(pc >= 1 && pc <= pt->sizecode);
138 while (mfm[-pc] == JIT_MFM_COMBINE) pc--;
139 while (mfm[-pc] == JIT_MFM_DEAD) pc++;
140 jit_assert(pc >= 1 && mfm[-pc] < (JIT_MFM_MARK|JIT_MFM_MAX)); /* Valid? */
141 if (jit_mfm_isdeoptpc(mfm, pc)) { /* Deoptimized instruction. */
142 do { /* Search through deopt mfm chain. */
143 memcpy((void *)&tr, JIT_MCTRAILER(tr.mcode, tr.sz),
144 sizeof(jit_MCTrailer));
145 if (tr.mcode == NULL) break; /* Deopt ins missing in chain. */
146 mfm = JIT_MCMFM(tr.mcode, tr.sz);
147 if (jit_mfm_ismain(mfm)) break; /* Old main mfm stops search, too. */
148 addr = jit_mfmlookup(mfm, tr.mcode, pc);
149 } while (addr == NULL);
150 } else { /* Not deoptimized. Lookup in main mfm. */
151 addr = jit_mfmlookup(mfm, tr.mcode, pc);
152 }
153 jit_assert(addr != NULL); /* Corrupt mfm chain. */
154 return addr;
155}
156
157/* ------------------------------------------------------------------------ */
158
159/* Compile a prototype. */
160/* Note: func pointer may be invalidated because of stack reallocation. */
161static int jit_compile(lua_State *L, StkId func, Table *st, int force)
162{
163 jit_State *J = G(L)->jit_state;
164 Closure *cl = clvalue(func);
165 Proto *pt = cl->l.p;
166 int status;
167
168 /* Check if JIT engine is enabled and prevent recursive invocation. */
169 if ((J->flags & JIT_F_INIT_FAILED) ||
170 (!force && !(J->flags & JIT_F_ON)) ||
171 !J->frontwrap) {
172 status = JIT_S_ENGINE_OFF;
173 } else if (J->flags & JIT_F_COMPILING) {
174 status = JIT_S_DELAYED;
175 } else if (pt->jit_szmcode != 0 && force < 2) { /* Prevent recompile. */
176 /* TODO: Allow recompiles? Use case? Extra flag for jit.compile()? */
177 status = JIT_S_OK;
178 } else {
179 setclvalue(L, luaH_setstr(L, st, luaS_newliteral(L, "func")), cl);
180 /* Call frontend wrapper. */
181 J->flags |= JIT_F_COMPILING;
182 lua_unlock(L);
183 status = J->frontwrap(L, st);
184 lua_lock(L);
185 J->flags &= ~JIT_F_COMPILING;
186 }
187
188 /* Better sanity check what the frontend returns. */
189 if ((status == JIT_S_OK && pt->jit_szmcode == 0) || status == JIT_S_NONE)
190 status = JIT_S_COMPILER_ERROR;
191
192 /* Update closure callgate and prototype status. */
193 cl->l.jit_gate = (status == JIT_S_OK) ? (lua_CFunction)pt->jit_mcode :
194 G(L)->jit_gateJL;
195 pt->jit_status = status;
196 return status;
197}
198
199/* Create the state table and copy the arguments. */
200static Table *jit_createstate(lua_State *L, StkId arg, int nargs)
201{
202 Table *st = luaH_new(L, nargs, COMSTATE_PREALLOC);
203 int i;
204 for (i = 0; i < nargs; i++)
205 setobj2t(L, luaH_setnum(L, st, i+1), arg+i);
206 return st;
207}
208
209/* ------------------------------------------------------------------------ */
210
211/* Compile and run a function. To be used by luaD_precall() only. */
212int luaJIT_run(lua_State *L, StkId func, int nresults)
213{
214 ptrdiff_t funcr = savestack(L, func);
215 Table *st = jit_createstate(L, func+1, L->top-(func+1));
216 int status = jit_compile(L, func, st, 0); /* Compile function. */
217 func = restorestack(L, funcr);
218
219 /* Run the compiled function on success. Fallback to bytecode on failure. */
220 if (status == JIT_S_OK)
221 return G(L)->jit_gateLJ(L, func, nresults);
222 else
223 return luaD_precall(L, func, nresults);
224 /* Note: We are called from luaD_precall and we call it again. */
225 /* So jit_compile makes sure pt->jit_status != JIT_S_NONE. */
226}
227
228/* ------------------------------------------------------------------------ */
229
230/* No more than two ranges for a single deoptimization right now. */
231#define DEOPTRANGE_ALLOC 2
232
233/* Find PC range of combined instructions and return a range hint. */
234static int combinedrange(jit_Mfm *mfm, int pc)
235{
236 int lastpc = pc;
237 while (mfm[-pc] == JIT_MFM_COMBINE) pc--; /* 1st comb. ins. */
238 while (mfm[-(lastpc+1)] == JIT_MFM_COMBINE) lastpc++; /* Last comb. ins. */
239 return JIT_IH_MKIDX(lastpc-pc, pc); /* (#ins-1, pc) in hint format. */
240}
241
242/* Process deoptimization hints for the given PC range. */
243static int deopthints(Proto *pt, jit_Mfm *dh, TValue *dhint, int pcrange)
244{
245 int m;
246 setnvalue(dhint++, (lua_Number)pcrange);
247 while ((m = *dh--) != JIT_MFM_STOP) {
248 if ((unsigned int)(m - JIT_IH_IDX(pcrange)) <=
249 (unsigned int)JIT_IH_LIB(pcrange)) {
250 switch (*dh--) {
251 case JIT_MFM_DEOPT_PAIRS: /* CALL [i]pairs(): deopt TFORLOOP+JMP. */
252 if (GET_OPCODE(pt->code[m+1-1]) == OP_JMP) {
253 int tfpc = m+2 + GETARG_sBx(pt->code[m+1-1]);
254 if ((unsigned)tfpc < (unsigned)pt->sizecode &&
255 GET_OPCODE(pt->code[tfpc-1]) == OP_TFORLOOP) {
256 setnvalue(dhint++, (lua_Number)JIT_IH_MKIDX(1, tfpc));
257 break;
258 }
259 }
260 return 1; /* Bad hint. */
261 default:
262 return 1; /* Cannot tolerate unknown deoptimization hints. */
263 }
264 }
265 }
266 return 0; /* Ok. */
267}
268
269/* Deoptimize the current instruction. Return new mcode addr to continue. */
270void *luaJIT_deoptimize(lua_State *L)
271{
272 StkId func = L->ci->func;
273 Proto *pt = clvalue(func)->l.p;
274 int pc = luaJIT_findpc(pt, L->savedpc)+1; /* Get prev. PC (1 based). */
275 jit_Mfm *mfm = JIT_MCMFM(pt->jit_mcode, pt->jit_szmcode);
276 int pcrange = combinedrange(mfm, pc);
277 if (!jit_mfm_isdeoptpc(mfm, JIT_IH_IDX(pcrange))) { /* Not deopt. yet? */
278 Table *st = jit_createstate(L, NULL, 0); /* Don't know original args. */
279 Table *deopt = luaH_new(L, DEOPTRANGE_ALLOC, 0);
280 sethvalue(L, luaH_setstr(L, st, luaS_newliteral(L, "deopt")), deopt);
281 if (deopthints(pt, mfm-(pt->sizecode+2), deopt->array, pcrange) ||
282 jit_compile(L, func, st, 2) != JIT_S_OK)
283 luaG_runerror(L, "deoptimization failed");
284 }
285 return luaJIT_findmcode(pt, pc);
286}
287
288/* ------------------------------------------------------------------------ */
289
290/* API function: Compile a Lua function. Pass arguments as hints. */
291LUA_API int luaJIT_compile(lua_State *L, int nargs)
292{
293 StkId func;
294 Table *st;
295 int status;
296 lua_lock(L);
297 api_check(L, (nargs+1) <= (L->top - L->base));
298 func = L->top - (nargs+1);
299 st = jit_createstate(L, func+1, nargs);
300 status = isLfunction(func) ? jit_compile(L, func, st, 1) : -1;
301 lua_unlock(L);
302 return status;
303}
304
305/* Recursively set the mode for all subroutines. */
306static void rec_setmode(Proto *pt, int on)
307{
308 int i;
309 for (i = 0; i < pt->sizep; i++) {
310 Proto *pti = pt->p[i];
311 pti->jit_status = on ? (pti->jit_szmcode?JIT_S_OK:JIT_S_NONE) : JIT_S_OFF;
312 rec_setmode(pti, on); /* Recurse into proto. */
313 }
314}
315
316/* API function: Set the JIT mode for the whole engine or a function+subs. */
317LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode)
318{
319 jit_State *J = G(L)->jit_state;
320 int mm = mode & LUAJIT_MODE_MASK;
321 if (J->flags & JIT_F_INIT_FAILED) return -1; /* Init failed. */
322 switch (mm) {
323 case LUAJIT_MODE_ENGINE: /* Set mode for JIT engine. */
324 if (mode & LUAJIT_MODE_ON)
325 J->flags |= JIT_F_ON;
326 else
327 J->flags &= ~JIT_F_ON;
328 break;
329 case LUAJIT_MODE_DEBUG: { /* Set debug mode. */
330 int dbg;
331 switch (idx) {
332 case 0: dbg = 0; break;
333 case 1: dbg = JIT_F_DEBUG_CALL; break;
334 case 2: default: dbg = JIT_F_DEBUG_CALL | JIT_F_DEBUG_INS; break;
335 }
336 J->flags = (J->flags & ~JIT_F_DEBUG) | dbg;
337 luaJIT_debugnotify(J);
338 break;
339 }
340 case LUAJIT_MODE_FUNC: /* Set mode for function. */
341 case LUAJIT_MODE_ALLFUNC: /* Set mode for function + subfuncs. */
342 case LUAJIT_MODE_ALLSUBFUNC: { /* Set mode for subfunctions. */
343 StkId func;
344 lua_lock(L);
345 func = idx == 0 ? (L->ci-1)->func :
346 (idx > 0 ? L->base + (idx-1) : L->top + idx);
347 if (isLfunction(func)) {
348 Closure *cl = clvalue(func);
349 Proto *pt = cl->l.p;
350 if (mm != LUAJIT_MODE_ALLSUBFUNC) {
351 if (mode & LUAJIT_MODE_ON) {
352 if (pt->jit_szmcode) { /* Already compiled? */
353 cl->l.jit_gate = (lua_CFunction)pt->jit_mcode; /* Reenable. */
354 pt->jit_status = JIT_S_OK;
355 } else {
356 pt->jit_status = JIT_S_NONE; /* (Re-)enable proto compilation */
357 }
358 } else {
359 cl->l.jit_gate = G(L)->jit_gateJL; /* Default callgate. */
360 pt->jit_status = JIT_S_OFF; /* Disable proto compilation. */
361 /* Note: compiled code must be retained for suspended threads. */
362 }
363 }
364 if (mm != LUAJIT_MODE_FUNC)
365 rec_setmode(pt, mode & LUAJIT_MODE_ON);
366 lua_unlock(L);
367 } else {
368 lua_unlock(L);
369 return 0; /* Failed. */
370 }
371 break;
372 }
373 default:
374 return 0; /* Failed. */
375 }
376 return 1; /* OK. */
377}
378
379/* Enforce (dynamic) linker error for version mismatches. See lua.c. */
380LUA_API void LUAJIT_VERSION_SYM(void)
381{
382}
383
384/* ------------------------------------------------------------------------ */
385