Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimise ROTable accesses and interface #2505

Merged
merged 2 commits into from
Oct 13, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions app/include/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,8 @@
const LOCK_IN_SECTION(libs) \
luaL_Reg MODULE_PASTE_(lua_lib_,cfgname) = { luaname, initfunc }; \
const LOCK_IN_SECTION(rotable) \
luaR_table MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
= { luaname, map }

luaR_entry MODULE_EXPAND_PASTE_(cfgname,MODULE_EXPAND_PASTE_(_module_selected,MODULE_PASTE_(LUA_USE_MODULES_,cfgname))) \
= {LSTRKEY(luaname), LROVAL(map)}

/* System module registration support, not using LUA_USE_MODULES_XYZ. */
#define BUILTIN_LIB_INIT(name, luaname, initfunc) \
Expand All @@ -68,7 +67,7 @@

#define BUILTIN_LIB(name, luaname, map) \
const LOCK_IN_SECTION(rotable) \
luaR_table MODULE_PASTE_(lua_rotable_,name) = { luaname, map }
luaR_entry MODULE_PASTE_(lua_rotable_,name) = {LSTRKEY(luaname), LROVAL(map)}

#if !defined(LUA_CROSS_COMPILER) && !(MIN_OPT_LEVEL==2 && LUA_OPTIMIZE_MEMORY==2)
# error "NodeMCU modules must be built with LTR enabled (MIN_OPT_LEVEL=2 and LUA_OPTIMIZE_MEMORY=2)"
Expand Down
11 changes: 1 addition & 10 deletions app/lua/lauxlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
#define lauxlib_c
#define LUA_LIB

#include "lrotable.h"

#include "lauxlib.h"
#include "lgc.h"
#include "ldo.h"
Expand Down Expand Up @@ -555,14 +553,7 @@ LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
if (e == NULL) e = fname + c_strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) {
/* If looking for a global variable, check the rotables too */
void *ptable = luaR_findglobal(fname, e - fname);
if (ptable) {
lua_pop(L, 1);
lua_pushrotable(L, ptable);
}
}

if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
Expand Down
105 changes: 43 additions & 62 deletions app/lua/lbaselib.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,71 +462,51 @@ static int luaB_newproxy (lua_State *L) {
return 1;
}

#define LUA_BASELIB_FUNCLIST\
{LSTRKEY("assert"), LFUNCVAL(luaB_assert)},\
{LSTRKEY("collectgarbage"), LFUNCVAL(luaB_collectgarbage)},\
{LSTRKEY("dofile"), LFUNCVAL(luaB_dofile)},\
{LSTRKEY("error"), LFUNCVAL(luaB_error)},\
{LSTRKEY("gcinfo"), LFUNCVAL(luaB_gcinfo)},\
{LSTRKEY("getfenv"), LFUNCVAL(luaB_getfenv)},\
{LSTRKEY("getmetatable"), LFUNCVAL(luaB_getmetatable)},\
{LSTRKEY("loadfile"), LFUNCVAL(luaB_loadfile)},\
{LSTRKEY("load"), LFUNCVAL(luaB_load)},\
{LSTRKEY("loadstring"), LFUNCVAL(luaB_loadstring)},\
{LSTRKEY("next"), LFUNCVAL(luaB_next)},\
{LSTRKEY("pcall"), LFUNCVAL(luaB_pcall)},\
{LSTRKEY("print"), LFUNCVAL(luaB_print)},\
{LSTRKEY("rawequal"), LFUNCVAL(luaB_rawequal)},\
{LSTRKEY("rawget"), LFUNCVAL(luaB_rawget)},\
{LSTRKEY("rawset"), LFUNCVAL(luaB_rawset)},\
{LSTRKEY("select"), LFUNCVAL(luaB_select)},\
{LSTRKEY("setfenv"), LFUNCVAL(luaB_setfenv)},\
{LSTRKEY("setmetatable"), LFUNCVAL(luaB_setmetatable)},\
{LSTRKEY("tonumber"), LFUNCVAL(luaB_tonumber)},\
{LSTRKEY("tostring"), LFUNCVAL(luaB_tostring)},\
{LSTRKEY("type"), LFUNCVAL(luaB_type)},\
{LSTRKEY("unpack"), LFUNCVAL(luaB_unpack)},\
{LSTRKEY("xpcall"), LFUNCVAL(luaB_xpcall)}

#if LUA_OPTIMIZE_MEMORY == 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 2
#include "lrodefs.h"
const LUA_REG_TYPE base_funcs_list[] = {
LUA_BASELIB_FUNCLIST,
{LNILKEY, LNILVAL}
};
#ifdef LUA_CROSS_COMPILER
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".rodata1." #s)))
#else
#define LOCK_IN_SECTION(s) __attribute__((used,unused,section(".lua_" #s)))
#endif
#define LUA_BASE_DECL(n) \
LOCK_IN_SECTION(rotable) luaR_entry lua_rotable_ ## n
#define LUA_BASELIB_FUNC(n,p) LUA_BASE_DECL(n) = {LSTRKEY(#n), LFUNCVAL(p)}


static int luaB_index(lua_State *L) {
#if LUA_OPTIMIZE_MEMORY == 2
int fres;
if ((fres = luaR_findfunction(L, base_funcs_list)) != 0)
return fres;
#endif
const char *keyname = luaL_checkstring(L, 2);
if (!c_strcmp(keyname, "_VERSION")) {
lua_pushliteral(L, LUA_VERSION);
return 1;
}
void *res = luaR_findglobal(keyname, c_strlen(keyname));
if (!res)
return 0;
else {
lua_pushrotable(L, res);
return 1;
}
}
#if defined(LUA_CROSS_COMPILER) && defined(LUA_DEBUG_BUILD)
LUA_BASE_DECL(start_list) = {LNILKEY, LNILVAL};
#endif
LUA_BASELIB_FUNC(assert, luaB_assert);
LUA_BASELIB_FUNC(collectgarbage, luaB_collectgarbage);
LUA_BASELIB_FUNC(dofile, luaB_dofile);
LUA_BASELIB_FUNC(error, luaB_error);
LUA_BASELIB_FUNC(gcinfo, luaB_gcinfo);
LUA_BASELIB_FUNC(getfenv, luaB_getfenv);
LUA_BASELIB_FUNC(getmetatable, luaB_getmetatable);
LUA_BASELIB_FUNC(loadfile, luaB_loadfile);
LUA_BASELIB_FUNC(load, luaB_load);
LUA_BASELIB_FUNC(loadstring, luaB_loadstring);
LUA_BASELIB_FUNC(next, luaB_next);
LUA_BASELIB_FUNC(pcall, luaB_pcall);
LUA_BASELIB_FUNC(print, luaB_print);
LUA_BASELIB_FUNC(rawequal, luaB_rawequal);
LUA_BASELIB_FUNC(rawget, luaB_rawget);
LUA_BASELIB_FUNC(rawset, luaB_rawset);
LUA_BASELIB_FUNC(select, luaB_select);
LUA_BASELIB_FUNC(setfenv, luaB_setfenv);
LUA_BASELIB_FUNC(setmetatable, luaB_setmetatable);
LUA_BASELIB_FUNC(tonumber, luaB_tonumber);
LUA_BASELIB_FUNC(tostring, luaB_tostring);
LUA_BASELIB_FUNC(type, luaB_type);
LUA_BASELIB_FUNC(unpack, luaB_unpack);
LUA_BASELIB_FUNC(xpcall, luaB_xpcall);
#if defined(LUA_CROSS_COMPILER) && !defined(LUA_DEBUG_BUILD)
LUA_BASE_DECL(start_list) = {LNILKEY, LNILVAL};
#endif

static const luaL_Reg base_funcs[] = {
#if LUA_OPTIMIZE_MEMORY != 2
#undef MIN_OPT_LEVEL
#define MIN_OPT_LEVEL 0
#include "lrodefs.h"
LUA_BASELIB_FUNCLIST,
# error "NodeMCU Lua must be built with LTR enabled and LUA_OPTIMIZE_MEMORY=2"
#endif
{"__index", luaB_index},
{NULL, NULL}
};

Expand Down Expand Up @@ -682,7 +662,7 @@ static void auxopen (lua_State *L, const char *name,
lua_setfield(L, -2, name);
}


extern const luaR_entry *lua_rotable;
static void base_open (lua_State *L) {
/* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX);
Expand All @@ -691,11 +671,12 @@ static void base_open (lua_State *L) {
luaL_register_light(L, "_G", base_funcs);
#if LUA_OPTIMIZE_MEMORY > 0
lua_pushvalue(L, -1);
lua_setmetatable(L, -2);
#else
lua_setmetatable(L, -2);
lua_pushrotable(L, (void *)lua_rotable);
lua_setglobal(L, "__index");
#endif
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); /* set global _VERSION */
#endif
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
auxopen(L, "pairs", luaB_pairs, luaB_next);
Expand Down
1 change: 0 additions & 1 deletion app/lua/ldblib.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"
#include "lstring.h"
#include "lflash.h"
#include "user_modules.h"
Expand Down
71 changes: 42 additions & 29 deletions app/lua/linit.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,60 +15,73 @@
#include "lauxlib.h"
#include "luaconf.h"
#include "module.h"
extern const luaR_entry strlib[], tab_funcs[], dblib[],
co_funcs[], math_map[], syslib[];
#if defined(LUA_CROSS_COMPILER)
BUILTIN_LIB( start_list, NULL, NULL);
BUILTIN_LIB_INIT( start_list, NULL, NULL);
#if !defined(LUA_DEBUG_BUILD)
const LOCK_IN_SECTION(rotable) luaR_entry lua_rotable_end_list = {LNILKEY, LNILVAL};
#endif
#endif
extern const luaR_entry strlib[], tab_funcs[], dblib[],
co_funcs[], math_map[], syslib[];

BUILTIN_LIB_INIT( BASE, "", luaopen_base);
BUILTIN_LIB_INIT( LOADLIB, LUA_LOADLIBNAME, luaopen_package);

BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
BUILTIN_LIB_INIT( STRING, LUA_STRLIBNAME, luaopen_string);

BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
BUILTIN_LIB_INIT( TABLE, LUA_TABLIBNAME, luaopen_table);

BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
BUILTIN_LIB_INIT( DBG, LUA_DBLIBNAME, luaopen_debug);

BUILTIN_LIB( STRING, LUA_STRLIBNAME, strlib);
BUILTIN_LIB( TABLE, LUA_TABLIBNAME, tab_funcs);
BUILTIN_LIB( DBG, LUA_DBLIBNAME, dblib);
BUILTIN_LIB( CO, LUA_COLIBNAME, co_funcs);

BUILTIN_LIB( MATH, LUA_MATHLIBNAME, math_map);

#if defined(LUA_CROSS_COMPILER)
extern const luaR_entry syslib[], iolib[];
extern const luaR_entry syslib[], io_funcs[];
BUILTIN_LIB( OS, LUA_OSLIBNAME, syslib);
BUILTIN_LIB_INIT( IO, LUA_IOLIBNAME, luaopen_io);
BUILTIN_LIB( end_list, NULL, NULL);
#if defined(LUA_DEBUG_BUILD)
const LOCK_IN_SECTION(rotable) luaR_entry lua_rotable_end_list = {LNILKEY, LNILVAL};
#endif
BUILTIN_LIB_INIT( end_list, NULL, NULL);
#endif

#if defined(LUA_CROSS_COMPILER)
/*
* These base addresses are internal to this module for cross compile builds
* This also exploits feature of the GCC code generator that the variables are
* emitted in either normal OR reverse order within PSECT.
* emitted in either normal OR reverse order within PSECT. A bit of a cludge,
* but exploiting these characteristics and ditto of the GNU linker is simpler
* than replacing the default ld setup.
*/
#define isascending(n) ((&(n ## _end_list)-&(n ## _start_list))>0)
static const luaL_Reg *lua_libs;
const luaR_table *lua_rotable;
#else
/* These base addresses are Xtensa toolchain linker constants for Firmware builds */
extern const luaR_entry lua_rotable_start_list; // Declared in lbaselib.c

#if defined(LUA_DEBUG_BUILD)
const luaL_Reg *lua_libs = &lua_lib_start_list+1;
#else
const luaL_Reg *lua_libs = &lua_lib_end_list+1;
#endif
const luaR_entry *lua_rotable = &lua_rotable_start_list+1;

#else /* Xtensa build */
/*
* These base addresses are Xtensa toolchain linker constants for Firmware builds
*/
extern const luaL_Reg lua_libs_base[];
extern const luaR_table lua_rotable_base[];
static const luaL_Reg *lua_libs = lua_libs_base;
const luaR_table *lua_rotable = lua_rotable_base;
extern const luaR_entry lua_rotable_base[];
const luaL_Reg *lua_libs = lua_libs_base;
const luaR_entry *lua_rotable = lua_rotable_base;
#endif

void luaL_openlibs (lua_State *L) {
#if defined(LUA_CROSS_COMPILER)
lua_libs = (isascending(lua_lib) ? &lua_lib_start_list : &lua_lib_end_list) + 1;
lua_rotable = (isascending(lua_rotable) ? &lua_rotable_start_list : &lua_rotable_end_list) + 1;
#endif
const luaL_Reg *lib = lua_libs;

/* Always open Base first */
lua_pushcfunction(L, luaopen_base);
lua_pushliteral(L, "");
lua_call(L, 1, 0);

/* Now loop round and open other libraries */
for (; lib->name; lib++) {
if (lib->func)
{
if (lib->func) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);
Expand Down
1 change: 0 additions & 1 deletion app/lua/lmathlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"

#undef PI
#define PI (3.14159265358979323846)
Expand Down
15 changes: 10 additions & 5 deletions app/lua/loadlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#include "lauxlib.h"
#include "lualib.h"
#include "lrotable.h"

/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
Expand Down Expand Up @@ -474,10 +473,11 @@ static int ll_require (lua_State *L) {
return 1; /* package is already loaded */
}
/* Is this a readonly table? */
void *res = luaR_findglobal(name, c_strlen(name));
if (res) {
lua_pushrotable(L, res);
lua_getfield(L, LUA_GLOBALSINDEX, name);
if(lua_isrotable(L,-1)) {
return 1;
} else {
lua_pop(L, 1);
}
/* else must load it; iterate over available loaders */
lua_getfield(L, LUA_ENVIRONINDEX, "loaders");
Expand Down Expand Up @@ -563,8 +563,13 @@ static void modinit (lua_State *L, const char *modname) {

static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
if (luaR_findglobal(modname, c_strlen(modname)))
/* Is this a readonly table? */
lua_getfield(L, LUA_GLOBALSINDEX, modname);
if(lua_isrotable(L,-1)) {
return 0;
} else {
lua_pop(L, 1);
}
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
Expand Down
1 change: 1 addition & 0 deletions app/lua/lobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ typedef struct Table {
int sizearray; /* size of `array' array */
} Table;

typedef const struct luaR_entry ROTable;

/*
** `module' operation for hashing (size is always a power of 2)
Expand Down
Loading