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)
downloadluajit2-c2c08ba9b33ed89feb190aa3484bf2360db779a0.tar.gz
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)
callhook(L, LUA_HOOKRET, -1);
}
-/* Initialize call. Ensure stack space and clear missing parameters. */
-static void call_init(lua_State *L, GCfunc *fn)
+/* Initialize call. Ensure stack space and return # of missing parameters. */
+static int call_init(lua_State *L, GCfunc *fn)
{
if (isluafunc(fn)) {
- MSize numparams = funcproto(fn)->numparams;
- TValue *o;
- lj_state_checkstack(L, numparams);
- for (o = L->base + numparams; L->top < o; L->top++)
- setnilV(L->top); /* Clear missing parameters. */
+ int numparams = funcproto(fn)->numparams;
+ int gotparams = (int)(L->top - L->base);
+ lj_state_checkstack(L, (MSize)numparams);
+ numparams -= gotparams;
+ return numparams >= 0 ? numparams : 0;
} else {
lj_state_checkstack(L, LUA_MINSTACK);
+ return 0;
}
}
@@ -407,7 +408,7 @@ ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
#if LJ_HASJIT
jit_State *J = G2J(g);
#endif
- call_init(L, fn);
+ int missing = call_init(L, fn);
#if LJ_HASJIT
J->L = L;
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)
lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
}
#endif
- if ((g->hookmask & LUA_MASKCALL))
+ if ((g->hookmask & LUA_MASKCALL)) {
+ int i;
+ for (i = 0; i < missing; i++) /* Add missing parameters. */
+ setnilV(L->top++);
callhook(L, LUA_HOOKCALL, -1);
+ /* Preserve modifications of missing parameters by lua_setlocal(). */
+ while (missing-- > 0 && tvisnil(L->top - 1))
+ L->top--;
+ }
#if LJ_HASJIT
out:
#endif