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

Updated ROTables 1st tranch #2742

Merged
merged 12 commits into from
May 8, 2019
Merged

Updated ROTables 1st tranch #2742

merged 12 commits into from
May 8, 2019

Conversation

TerryE
Copy link
Collaborator

@TerryE TerryE commented Apr 29, 2019

Fixes #2726

  • This PR is for the dev branch rather than for master.
  • This PR is compliant with the other contributing guidelines as well (if not, please describe why).
  • I have thoroughly tested my contribution.
  • The code changes are reflected in the documentation at docs/*.

Details

This is a large change. I am going to need to rebaseline against dev at the point of merge, but I wanted to make this available for review comment before this. The scope of the changes call into the following broad categories:

  • Changes to the rotable.h macros to support the new declarative style. These are largely in modules.h and rotable.h. Note that the eLua patch used two separate headers, rotable.hand rodefs.h. This second file has been dropped and the residual defines moved into rotable.h.

  • Retiring dead eLua options and code. For at least the last 4 years we have had to build the firmware (and later luac.cross) with a couple of hardwired eLua optimisation settings, and the Lua VM includes dead code that we can't use, so I've removed these options and stripped out this dead code.

  • Minor optimisations to the rotable lookup code. Since we only support character keys, there is no point in having a rotable key type as this doubles the number of flash work accesses in a ROTable lookup scan. Since the new declarative style hides these implementation details we do this doubling largely "for free".

  • Change to the Lua RTS to support the new macros. The base Lua libraries such as string (and os in the case of luac.cross) ave been updated to use the new macros.

  • Bulk largely automated edits of all of the module C files to use the new format ROTable declarations. In terms of files this was the bulk of the change, but this was largely automated though a bunch of ah-hoc sed scripts. Not that none of the functionality has been changed, though lookup is faster due to the optimisations discussed above.

Copy link
Member

@jmattsson jmattsson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this is looking good. Some cleanup needed, but off to a good start here!

app/lua/lbaselib.c Outdated Show resolved Hide resolved
lua_pushrotable(L, (void *)BASE_ROTABLE);
lua_setglobal(L, "__index");
#endif
luaL_register_light(L, "_G", &((luaL_Reg) {0}));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait what? Am I reading this right that we're registering a pointer to a temporary variable here? Shouldn't this be referring to base_funcs?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

luaL_register_light() does multiple things. It registers the library in the global table (_G itself in this case) and also registers a list of functions. There aren't any functions to be registered here since these are in a ROTable for the baselib, so we either call luaL_register_light() with an empty list or clone and copy the subset of the functionality that we used inline. Doing the call is simpler than cut and paste.

#define LROT_FUNCENTRY(n,f) {LRO_STRKEY(#n), LRO_FUNCVAL(f)},
#define LROT_NUMENTRY(n,x) {LRO_STRKEY(#n), LRO_NUMVAL(x)},
#define LROT_LUDENTRY(n,x) {LRO_STRKEY(#n), LRO_LUDATA((void *) x)},
#define LROT_END(t,mt, f) {LRO_NILKEY, LRO_NILVAL} };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the args on LROT_END, when none are being used?

Copy link
Collaborator Author

@TerryE TerryE May 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future proofing. A ROTable is currently a luaR_entry vector, so the Table code need to include conditional logic (is the address in Flash) ? do a ROTable reference : do a Table reference On the next version the LROT_END() will generate a luaR_entry terminator followed by a readonly Table rec which points to the vector. Generating the extra fields in the module source now means that we can implement this change without needing to change the modules again.

The main advantage of ROTables having a Table record is that we can push the RO vs RW abstraction down a level an dump a lot of conditional testing in the Lua VM where it only needs to reference and manipulate the table as an entity. The Table record contains useful stuff like the size of the table, and flags to indicate whether metas such as __index, _newindex and __gc exist.

The ROTable lookup cache now gives a better than 95% hit rate for key-found searches of ROTables. (I've tweaked the lookup algo to give more uniform coverage of the cache and to improve performance, BTW.) There is still a residual performance issue with key misses (even though this code runs about 4× faster than the eLua version). Having the abitity use the flabs byte to short-circuit frequent meta misses, and the length to allow you to sort the key list into ascending order and tag that you can do a binary search on the longer ROTables such as the baselib one, will pretty much remove this penalty all together.
So that in future we can re

app/lua/linit.c Outdated
* configuring builds with a small subset of the total modules.
*
* This linker-based approach is not practical for cross compiler builds which
* must link on a range of platforms, and were we down have control of PSECT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "down" -> "don't"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup 😄 and also were -> where

lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);
#ifndef LUA_CROSS_COMPILER
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it could be pruned before merge.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, but I use this test point so frequently for debugging startup that having left as a commented out hook is simpler. I would prefer to leave this in as it is only a comment for production use.

app/lua/lrotable.h Show resolved Hide resolved
app/lua/lrotable.h Show resolved Hide resolved
app/lua/lstrlib.c Show resolved Hide resolved
@@ -580,7 +580,7 @@ const TValue *luaH_getnum (Table *t, int key) {

/* same thing for rotables */
const TValue *luaH_getnum_ro (void *t, int key) {
const TValue *res = luaR_findentryN(t, key, NULL);
const TValue *res = NULL; // integer values not supported: luaR_findentryN(t, key, NULL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we get a compile-time error if someone does try to register a numeric key in an RO table? If not, can we?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no macro to do this, so they can't. None of our current code uses numerically indexed ROTables, and there is roughly a 2× performance hit in leaving in this feature that we don't use, and so I removed it.

If there we want to add it back we should think about how we could do this but we should have this as a discussion on the issue, as there are trade-offs here.

app/lua/ltable.c Outdated Show resolved Hide resolved
@jmattsson
Copy link
Member

Thanks for the explanations & clarifications. I am satisfied you know what you're doing here :D

Happy for you to merge once you've done the discussed tidying up.

@marcelstoer
Copy link
Member

Not sure if you or Johny noticed but the CI build failed.

gpio.c:323:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'extern'
 extern int gpio_pulse_init(lua_State *);
 ^
In file included from ../include/module.h:5:0,
                 from gpio.c:4:
gpio.c:333:25: error: 'gpio_pulse_map' undeclared here (not in a function)
   LROT_TABENTRY( pulse, gpio_pulse )
                         ^
../lua/lrotable.h:16:39: note: in definition of macro 'LRO_ROVAL'
 #define LRO_ROVAL(v)    {{.p = (void*)v}, LUA_TROTABLE}
                                       ^
gpio.c:333:3: note: in expansion of macro 'LROT_TABENTRY'
   LROT_TABENTRY( pulse, gpio_pulse )
   ^
gpio.c: In function 'luaopen_gpio':
gpio.c:351:3: error: implicit declaration of function 'gpio_pulse_init' [-Werror=implicit-function-declaration]
   gpio_pulse_init(L);

@TerryE
Copy link
Collaborator Author

TerryE commented May 3, 2019

@marcelstoer, thanks Marcel, yes I did. There are a few edge cases with table references that barfed on the CI build. I'll clean these up tomorrow before the merge.

@TerryE
Copy link
Collaborator Author

TerryE commented May 7, 2019

If we don't have any more issues, then I'll merge this into dev tomorrow.

@TerryE TerryE merged commit 1990f95 into nodemcu:dev May 8, 2019
@TerryE TerryE mentioned this pull request May 10, 2019
4 tasks
@marcelstoer marcelstoer added this to the Next release milestone May 21, 2019
@marcelstoer marcelstoer mentioned this pull request Jun 1, 2019
@TerryE TerryE deleted the dev-ROTables-update branch August 21, 2020 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants