Permalink
Show file tree
Hide file tree
2 comments
on commit
sign in to comment.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
RAM optimizations: pseudo RO strings, functions in Flash
This patch adds more RAM optimizations to eLua:
- direct file memory mapping: files in ROMFS will be read directly from Flash,
without allocating any additional buffers. This doesn't help with RAM
consumption in itself, but enables the set of optimizations below.
- pseudo read-only strings. These are still TStrings, but the actual string
content can point directly to Flash. Original Lua strings are kept in
TStrings structures (lobject.h):
typedef union TString {
L_Umaxalign dummy; /* ensures maximum alignment for strings */
struct {
CommonHeader;
lu_byte reserved;
unsigned int hash;
size_t len;
} tsv;
} TString;
The actual string content comes right after the union TString above.
Pseudo RO strings have the same header, but instead of having the string
content after TString, they have a pointer that points to the actual
string content (which should exist in a RO memory (Flash) that is directly
accesbile from the MCU bus (like its internal Flash memory)). lua_newlstr
detects automatically if it should create a regular string or a pseudo RO
string by checking if the string pointer comes from the Flash region of the
MCU. This optimization works for both precompiled (.lc) files that exist in
ROMFS and for internal Lua strings (C code).
- functions in Flash: for precompiled (.lc) files that exist in ROMFS, the code
of the functions and a part of the debug information will be read directly
from Flash.
- ROMFS was changed to support files that are larger than 2**16 bytes and it
aligns all its files to an offset which is a multiple of 4 in order to prevent
data alignment issues with precompiled Lua code.
- the Lua bytecode dumper was changed to align all the instructions in a Lua
function and a part of the debug information to an offset which is a multiple
of 4. This might slightly increase the size of the precompiled Lua file.
These changes were succesfully checked against the Lua 5.1 test suite.
These changes were tested in eLua on LM3S and AVR32.- Loading branch information
Showing
27 changed files
with
260 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
d54659bThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay in any response here. I'll be doing some testing of this code shortly, including with LuaRPC to make sure there shouldn't be any problems there with the code dumper etc.
So, if I understand correctly, this optimization applies to compiled Lua scripts on ROMFS, not to uncompiled code? Obviously it can't do anything for subsequent bytecode, but does it prevent copying of the raw Lua source into SRAM for compilation? It looks like you've hooked the loading functions, but I haven't traced through exactly what happens for source.
I'm a little less clear on the implications for strings otherwise. Certainly a string needs to be in FLASH for the optimization to apply. Does this generally make it so that generally, at least when using Lua API functions that existing strings in flash that get pushed over via the stack stay in flash?
Otherwise, thanks for getting this one in. These SRAM optimizations have been great :-)
d54659bThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
Thanks, this is exactly where I need help from you.
I don't think it does anything at all for uncompiled code. I'm quite sure that uncompiled code doesn't get loaded fully to RAM while compiling anyway, it's read sequentially from a small buffer instead.
Yes.
Yes. The interesting piece of code is here (src/lua/lstring.c):
TString luaS_newlstr (lua_State *L, const char *str, size_t l) {
// If the pointer is in a read-only memory and the string is at least 4 chars in length,
// create it as a read-only string instead
if(lua_is_ptr_in_ro_area(str) && l+1 > sizeof(char*))
return luaS_newlstr_helper(L, str, l, 1);
else
return luaS_newlstr_helper(L, str, l, 0);
}
As you can see, the code automatically decides to create a string or a "rostring" based on the physical location of the pointer. If it is in Flash (and if it's smaller than the size of the pointer (otherwise you'd actually increase memory usage, not decrease it)) it will be automagically constructed as a "rostring". There is also a luaS_newrolstr that creates a rostring directly, but that's mainly for later use, when we finally get to implement these pesky loadable modules and the "is the string in Flash" test won't be good enough anymore.
You're welcome. I actually got a bit crazy on this one and I have some code that dumps the complete TString structure in Flash and reads it from there, saving quite a bit of memory in the process. It's far from being complete or tested properly (it runs life and hangman though :), but I was finally able to anchor "foreign" TStrings inside eLua's data structures.