From c8cfca05578932567d2c65d59262f398e8acaed2 Mon Sep 17 00:00:00 2001
From: Mike Pall
+An extra library function table.new() can be made available via +require("table.new"). This creates a pre-sized table, just like +the C API equivalent lua_createtable(). This is useful for big +tables if the final table size is known and automatic table resizing is +too expensive. +
+LuaJIT uses a Tausworthe PRNG with period 2^223 to implement diff --git a/src/Makefile.dep b/src/Makefile.dep index a285df2c..5b35ddf5 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -40,7 +40,7 @@ lib_string.o: lib_string.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lj_char.h lj_strfmt.h lj_lib.h lj_libdef.h lib_table.o: lib_table.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ lj_def.h lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_buf.h lj_str.h \ - lj_tab.h lj_lib.h lj_libdef.h + lj_tab.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h lj_alloc.o: lj_alloc.c lj_def.h lua.h luaconf.h lj_arch.h lj_alloc.h lj_api.o: lj_api.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h lj_func.h lj_udata.h \ diff --git a/src/lib_table.c b/src/lib_table.c index d7df8399..85ca660e 100644 --- a/src/lib_table.c +++ b/src/lib_table.c @@ -18,6 +18,7 @@ #include "lj_err.h" #include "lj_buf.h" #include "lj_tab.h" +#include "lj_ff.h" #include "lj_lib.h" /* ------------------------------------------------------------------------ */ @@ -264,6 +265,24 @@ LJLIB_CF(table_pack) } #endif +LJLIB_NOREG LJLIB_CF(table_new) LJLIB_REC(.) +{ + int32_t a = lj_lib_checkint(L, 1); + int32_t h = lj_lib_checkint(L, 2); + lua_createtable(L, a, h); + return 1; +} + +static int luaopen_table_new(lua_State *L) +{ + GCfunc *fn = lj_lib_pushcc(L, lj_cf_table_new, FF_table_new, 0); + GCtab *t = tabref(curr_func(L)->c.env); /* Reference to "table". */ + setfuncV(L, lj_tab_setstr(L, t, lj_str_newlit(L, "new")), fn); + lj_gc_anybarriert(L, t); + setfuncV(L, L->top++, fn); + return 1; +} + /* ------------------------------------------------------------------------ */ #include "lj_libdef.h" @@ -275,6 +294,7 @@ LUALIB_API int luaopen_table(lua_State *L) lua_getglobal(L, "unpack"); lua_setfield(L, -2, "unpack"); #endif + lj_lib_prereg(L, LUA_TABLIBNAME ".new", luaopen_table_new, tabV(L->top-1)); return 1; } diff --git a/src/lj_api.c b/src/lj_api.c index 8aaafdc5..05fb41a7 100644 --- a/src/lj_api.c +++ b/src/lj_api.c @@ -640,10 +640,8 @@ LUA_API void lua_pushlightuserdata(lua_State *L, void *p) LUA_API void lua_createtable(lua_State *L, int narray, int nrec) { - GCtab *t; lj_gc_check(L); - t = lj_tab_new(L, (uint32_t)(narray > 0 ? narray+1 : 0), hsize2hbits(nrec)); - settabV(L, L->top, t); + settabV(L, L->top, lj_tab_new_ah(L, narray, nrec)); incr_top(L); } diff --git a/src/lj_asm.c b/src/lj_asm.c index 2bf273e1..0d6875a6 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -1659,6 +1659,9 @@ static void asm_ir(ASMState *as, IRIns *ir) case IR_STRTO: asm_strto(as, ir); break; /* Calls. */ + case IR_CALLA: + as->gcsteps++; + /* fallthrough */ case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break; case IR_CALLXS: asm_callx(as, ir); break; case IR_CARG: break; diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 918cc9cf..29916e71 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c @@ -1003,6 +1003,14 @@ static void LJ_FASTCALL recff_table_concat(jit_State *J, RecordFFData *rd) UNUSED(rd); } +static void LJ_FASTCALL recff_table_new(jit_State *J, RecordFFData *rd) +{ + TRef tra = lj_opt_narrow_toint(J, J->base[0]); + TRef trh = lj_opt_narrow_toint(J, J->base[1]); + J->base[0] = lj_ir_call(J, IRCALL_lj_tab_new_ah, tra, trh); + UNUSED(rd); +} + /* -- I/O library fast functions ------------------------------------------ */ /* Get FILE* for I/O function. Any I/O error aborts recording, so there's diff --git a/src/lj_ir.h b/src/lj_ir.h index 54bbbdda..30878b91 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -139,6 +139,7 @@ \ /* Calls. */ \ _(CALLN, N , ref, lit) \ + _(CALLA, A , ref, lit) \ _(CALLL, L , ref, lit) \ _(CALLS, S , ref, lit) \ _(CALLXS, S , ref, ref) \ diff --git a/src/lj_ircall.h b/src/lj_ircall.h index 9e1fb367..53eb4638 100644 --- a/src/lj_ircall.h +++ b/src/lj_ircall.h @@ -25,6 +25,7 @@ typedef struct CCallInfo { #define CCI_OP(ci) ((ci)->flags >> CCI_OPSHIFT) /* Get op. */ #define CCI_CALL_N (IR_CALLN << CCI_OPSHIFT) +#define CCI_CALL_A (IR_CALLA << CCI_OPSHIFT) #define CCI_CALL_L (IR_CALLL << CCI_OPSHIFT) #define CCI_CALL_S (IR_CALLS << CCI_OPSHIFT) #define CCI_CALL_FN (CCI_CALL_N|CCI_CC_FASTCALL) @@ -140,6 +141,7 @@ typedef struct CCallInfo { _(ANY, lj_buf_putstr_rep, 3, L, P32, 0) \ _(ANY, lj_buf_puttab, 5, L, P32, 0) \ _(ANY, lj_buf_tostr, 1, FL, STR, 0) \ + _(ANY, lj_tab_new_ah, 3, A, TAB, CCI_L) \ _(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \ _(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \ _(ANY, lj_tab_newkey, 3, S, P32, CCI_L) \ diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 9c00f7e7..2ca04a69 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -165,7 +165,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J); (J->chain[IR_SNEW] || J->chain[IR_XSNEW] || \ J->chain[IR_TNEW] || J->chain[IR_TDUP] || \ J->chain[IR_CNEW] || J->chain[IR_CNEWI] || \ - J->chain[IR_BUFSTR] || J->chain[IR_TOSTR])) + J->chain[IR_BUFSTR] || J->chain[IR_TOSTR] || J->chain[IR_CALLA])) /* -- Constant folding for FP numbers ------------------------------------- */ @@ -2319,8 +2319,9 @@ LJFOLD(XSTORE any any) LJFOLDX(lj_opt_dse_xstore) LJFOLD(NEWREF any any) /* Treated like a store. */ -LJFOLD(CALLS any any) +LJFOLD(CALLA any any) LJFOLD(CALLL any any) /* Safeguard fallback. */ +LJFOLD(CALLS any any) LJFOLD(CALLXS any any) LJFOLD(XBAR) LJFOLD(RETF any any) /* Modifies BASE. */ diff --git a/src/lj_tab.c b/src/lj_tab.c index ccad1f68..496904ee 100644 --- a/src/lj_tab.c +++ b/src/lj_tab.c @@ -149,6 +149,12 @@ GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits) return t; } +/* The API of this function conforms to lua_createtable(). */ +GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h) +{ + return lj_tab_new(L, (uint32_t)(a > 0 ? a+1 : 0), hsize2hbits(h)); +} + #if LJ_HASJIT GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize) { diff --git a/src/lj_tab.h b/src/lj_tab.h index d361137c..c57bdd82 100644 --- a/src/lj_tab.h +++ b/src/lj_tab.h @@ -34,6 +34,7 @@ static LJ_AINLINE uint32_t hashrot(uint32_t lo, uint32_t hi) #define hsize2hbits(s) ((s) ? ((s)==1 ? 1 : 1+lj_fls((uint32_t)((s)-1))) : 0) LJ_FUNCA GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits); +LJ_FUNC GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h); #if LJ_HASJIT LJ_FUNC GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize); #endif