summaryrefslogtreecommitdiff
path: root/src/lj_dispatch.c
diff options
context:
space:
mode:
authorMike Pall <mike>2010-09-12 01:37:02 +0200
committerMike Pall <mike>2010-09-12 01:44:13 +0200
commitc2c08ba9b33ed89feb190aa3484bf2360db779a0 (patch)
treef657ced04905297363784bdaf15e5855b2c6b6b0 /src/lj_dispatch.c
parentb72ae54dc0d2bf63f23f0b9a47238ea96b0239ed (diff)
downloadluajit-c2c08ba9b33ed89feb190aa3484bf2360db779a0.tar.gz
luajit-c2c08ba9b33ed89feb190aa3484bf2360db779a0.tar.bz2
luajit-c2c08ba9b33ed89feb190aa3484bf2360db779a0.zip
Record calls to vararg functions.
This loop is now roughly 1000x faster than the Lua interpreter: local function f(a,b,...) end; for i=1,2e8 do f(1,2,i) end Yet another silly microbenchmark -- I know.
Diffstat (limited to 'src/lj_dispatch.c')
-rw-r--r--src/lj_dispatch.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index 491c5aa3..3b1be7e2 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -384,17 +384,18 @@ void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
384 callhook(L, LUA_HOOKRET, -1); 384 callhook(L, LUA_HOOKRET, -1);
385} 385}
386 386
387/* Initialize call. Ensure stack space and clear missing parameters. */ 387/* Initialize call. Ensure stack space and return # of missing parameters. */
388static void call_init(lua_State *L, GCfunc *fn) 388static int call_init(lua_State *L, GCfunc *fn)
389{ 389{
390 if (isluafunc(fn)) { 390 if (isluafunc(fn)) {
391 MSize numparams = funcproto(fn)->numparams; 391 int numparams = funcproto(fn)->numparams;
392 TValue *o; 392 int gotparams = (int)(L->top - L->base);
393 lj_state_checkstack(L, numparams); 393 lj_state_checkstack(L, (MSize)numparams);
394 for (o = L->base + numparams; L->top < o; L->top++) 394 numparams -= gotparams;
395 setnilV(L->top); /* Clear missing parameters. */ 395 return numparams >= 0 ? numparams : 0;
396 } else { 396 } else {
397 lj_state_checkstack(L, LUA_MINSTACK); 397 lj_state_checkstack(L, LUA_MINSTACK);
398 return 0;
398 } 399 }
399} 400}
400 401
@@ -407,7 +408,7 @@ ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
407#if LJ_HASJIT 408#if LJ_HASJIT
408 jit_State *J = G2J(g); 409 jit_State *J = G2J(g);
409#endif 410#endif
410 call_init(L, fn); 411 int missing = call_init(L, fn);
411#if LJ_HASJIT 412#if LJ_HASJIT
412 J->L = L; 413 J->L = L;
413 if ((uintptr_t)pc & 1) { /* Marker for hot call. */ 414 if ((uintptr_t)pc & 1) { /* Marker for hot call. */
@@ -420,8 +421,15 @@ ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
420 lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */ 421 lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
421 } 422 }
422#endif 423#endif
423 if ((g->hookmask & LUA_MASKCALL)) 424 if ((g->hookmask & LUA_MASKCALL)) {
425 int i;
426 for (i = 0; i < missing; i++) /* Add missing parameters. */
427 setnilV(L->top++);
424 callhook(L, LUA_HOOKCALL, -1); 428 callhook(L, LUA_HOOKCALL, -1);
429 /* Preserve modifications of missing parameters by lua_setlocal(). */
430 while (missing-- > 0 && tvisnil(L->top - 1))
431 L->top--;
432 }
425#if LJ_HASJIT 433#if LJ_HASJIT
426out: 434out:
427#endif 435#endif