summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2018-11-11 18:27:19 -0500
committerWilliam Wilgus <me.theuser@yahoo.com>2019-07-11 00:31:41 +0200
commitc6fcb1cf45b249b059c2d53a062f9a6c7f449047 (patch)
tree229eacd12461605a8320eb7590ff83eea13538d6 /apps
parent42240f6990156fb907a7dce7258be2f1235fab44 (diff)
downloadrockbox-c6fcb1cf45b249b059c2d53a062f9a6c7f449047.tar.gz
rockbox-c6fcb1cf45b249b059c2d53a062f9a6c7f449047.zip
lua inbinary strings
Allows saving of ram by reusing strings already stored in the binary and storing a pointer instead of malloc and copy to get them inside the lua state Saves about 1.5K overall Derivative of work by bogdanm RAM optimizations: pseudo RO strings, functions in Flash https://github.com/elua/elua/commit/d54659b5723bcd2b1e3900362398c72c18a9aa0b Change-Id: I21d6dcfa32523877efd9f70fb0f88f2a02872649
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/lua/lauxlib.c21
-rw-r--r--apps/plugins/lua/lgc.c2
-rw-r--r--apps/plugins/lua/llex.c4
-rw-r--r--apps/plugins/lua/lobject.c15
-rw-r--r--apps/plugins/lua/lobject.h4
-rw-r--r--apps/plugins/lua/lstring.c33
-rw-r--r--apps/plugins/lua/lstring.h23
-rw-r--r--apps/plugins/lua/ltm.c6
-rw-r--r--apps/plugins/lua/rockconf.h1
-rw-r--r--apps/plugins/lua/rocklib.c4
10 files changed, 88 insertions, 25 deletions
diff --git a/apps/plugins/lua/lauxlib.c b/apps/plugins/lua/lauxlib.c
index 9597f63c60..5e7c15931d 100644
--- a/apps/plugins/lua/lauxlib.c
+++ b/apps/plugins/lua/lauxlib.c
@@ -11,10 +11,12 @@
11#include <stdio.h> 11#include <stdio.h>
12#include <stdlib.h> 12#include <stdlib.h>
13#include <string.h> 13#include <string.h>
14#include "lstring.h" /* ROCKLUA ADDED */
14 15
15 16
16/* This file uses only the official API of Lua. 17/* This file uses only the official API of Lua.
17** Any function declared here could be written as an application function. 18** Any function declared here could be written as an application function.
19** Note ** luaS_newlloc breaks this guarantee ROCKLUA ADDED
18*/ 20*/
19 21
20#define lauxlib_c 22#define lauxlib_c
@@ -239,23 +241,36 @@ LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
239} 241}
240 242
241 243
244 /* ROCKLUA ADDED */
245static int libsize_storenames (lua_State *L, const char* libname, const luaL_Reg *l) {
246 int size = 0;
247 if (libname)
248 luaS_newlloc(L, libname, TSTR_INBIN);
249 for (; l->name; l++) {
250 size++;
251 luaS_newlloc(L, l->name, TSTR_INBIN);
252 }
253 return size;
254}
255
256
242LUALIB_API void (luaL_register) (lua_State *L, const char *libname, 257LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
243 const luaL_Reg *l) { 258 const luaL_Reg *l) {
244 luaI_openlib(L, libname, l, 0); 259 luaI_openlib(L, libname, l, 0);
245} 260}
246 261
247 262#if 0
248static int libsize (const luaL_Reg *l) { 263static int libsize (const luaL_Reg *l) {
249 int size = 0; 264 int size = 0;
250 for (; l->name; l++) size++; 265 for (; l->name; l++) size++;
251 return size; 266 return size;
252} 267}
253 268#endif
254 269
255LUALIB_API void luaI_openlib (lua_State *L, const char *libname, 270LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
256 const luaL_Reg *l, int nup) { 271 const luaL_Reg *l, int nup) {
272 int size = libsize_storenames(L, libname, l);
257 if (libname) { 273 if (libname) {
258 int size = libsize(l);
259 /* check whether lib already exists */ 274 /* check whether lib already exists */
260 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); 275 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
261 lua_getfield(L, -1, libname); /* get _LOADED[libname] */ 276 lua_getfield(L, -1, libname); /* get _LOADED[libname] */
diff --git a/apps/plugins/lua/lgc.c b/apps/plugins/lua/lgc.c
index e909c79a96..98194c1771 100644
--- a/apps/plugins/lua/lgc.c
+++ b/apps/plugins/lua/lgc.c
@@ -388,7 +388,7 @@ static void freeobj (lua_State *L, GCObject *o) {
388 } 388 }
389 case LUA_TSTRING: { 389 case LUA_TSTRING: {
390 G(L)->strt.nuse--; 390 G(L)->strt.nuse--;
391 luaM_freemem(L, o, sizestring(gco2ts(o))); 391 luaM_freemem(L, o, sizetstring((gco2ts(o))->type, (gco2ts(o))->len));
392 break; 392 break;
393 } 393 }
394 case LUA_TUSERDATA: { 394 case LUA_TUSERDATA: {
diff --git a/apps/plugins/lua/llex.c b/apps/plugins/lua/llex.c
index 6f78d48983..723d46c1ce 100644
--- a/apps/plugins/lua/llex.c
+++ b/apps/plugins/lua/llex.c
@@ -64,8 +64,8 @@ static void save (LexState *ls, int c) {
64void luaX_init (lua_State *L) { 64void luaX_init (lua_State *L) {
65 int i; 65 int i;
66 for (i=0; i<NUM_RESERVED; i++) { 66 for (i=0; i<NUM_RESERVED; i++) {
67 TString *ts = luaS_new(L, luaX_tokens[i]); 67 /* reserved words are never collected */
68 luaS_fix(ts); /* reserved words are never collected */ 68 TString *ts = luaS_newlloc(L, luaX_tokens[i], TSTR_INBIN | TSTR_FIXED);
69 lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN); 69 lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
70 ts->tsv.reserved = cast_byte(i+1); /* reserved word */ 70 ts->tsv.reserved = cast_byte(i+1); /* reserved word */
71 } 71 }
diff --git a/apps/plugins/lua/lobject.c b/apps/plugins/lua/lobject.c
index a351ff41da..65a23cf938 100644
--- a/apps/plugins/lua/lobject.c
+++ b/apps/plugins/lua/lobject.c
@@ -107,6 +107,21 @@ static void pushstr (lua_State *L, const char *str) {
107} 107}
108 108
109 109
110/* ROCKLUA ADDED -- Retrieves C string from TString */
111const char *luaO_getstring(const TString * ts){
112 const char *string;
113#ifdef INBINARYSTRINGS
114 if (testbits((ts)->tsv.type, TSTR_INBIN))
115 string = *(cast(const char **, (ts) + 1));
116 else
117#else
118 if (true)
119#endif
120 string = cast(const char *, (ts) + 1);
121 return string;
122}
123
124
110/* this function handles only `%d', `%c', %f, %p, and `%s' formats */ 125/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
111const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { 126const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
112 int n = 1; 127 int n = 1;
diff --git a/apps/plugins/lua/lobject.h b/apps/plugins/lua/lobject.h
index 93288fe0fb..26d2a81b49 100644
--- a/apps/plugins/lua/lobject.h
+++ b/apps/plugins/lua/lobject.h
@@ -201,13 +201,14 @@ typedef union TString {
201 struct { 201 struct {
202 CommonHeader; 202 CommonHeader;
203 lu_byte reserved; 203 lu_byte reserved;
204 lu_byte type;
204 unsigned int hash; 205 unsigned int hash;
205 size_t len; 206 size_t len;
206 } tsv; 207 } tsv;
207} TString; 208} TString;
208 209
209 210
210#define getstr(ts) cast(const char *, (ts) + 1) 211#define getstr(ts) (luaO_getstring(ts)) /* ROCKLUA ADDED */
211#define svalue(o) getstr(rawtsvalue(o)) 212#define svalue(o) getstr(rawtsvalue(o))
212 213
213 214
@@ -371,6 +372,7 @@ LUAI_FUNC int luaO_int2fb (unsigned int x);
371LUAI_FUNC int luaO_fb2int (int x); 372LUAI_FUNC int luaO_fb2int (int x);
372LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); 373LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
373LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); 374LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
375LUAI_FUNC const char *luaO_getstring(const TString * ts); /* ROCKLUA ADDED */
374LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, 376LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
375 va_list argp); 377 va_list argp);
376LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); 378LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
diff --git a/apps/plugins/lua/lstring.c b/apps/plugins/lua/lstring.c
index 49113151cc..bf0536e311 100644
--- a/apps/plugins/lua/lstring.c
+++ b/apps/plugins/lua/lstring.c
@@ -2,6 +2,8 @@
2** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $ 2** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
3** String table (keeps all strings handled by Lua) 3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5** luaS_newllocstr is adapted from "elua -- pseudo RO strings"
6** by bogdanm, distributed under a MIT license.
5*/ 7*/
6 8
7 9
@@ -48,19 +50,26 @@ void luaS_resize (lua_State *L, int newsize) {
48 50
49 51
50static TString *newlstr (lua_State *L, const char *str, size_t l, 52static TString *newlstr (lua_State *L, const char *str, size_t l,
51 unsigned int h) { 53 unsigned int h, char type) {
52 TString *ts; 54 TString *ts;
53 stringtable *tb; 55 stringtable *tb;
54 if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) 56 if (l > ((MAX_SIZET - sizeof(TString))/sizeof(char)) - sizeof(""))
55 luaM_toobig(L); 57 luaM_toobig(L);
56 ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); 58 ts = cast(TString *, luaM_malloc(L, sizetstring(type, l)));
57 ts->tsv.len = l; 59 ts->tsv.len = l;
58 ts->tsv.hash = h; 60 ts->tsv.hash = h;
59 ts->tsv.marked = luaC_white(G(L)); 61 ts->tsv.marked = luaC_white(G(L));
62 if (testbits(type, TSTR_FIXED))
63 luaS_fix(ts);
60 ts->tsv.tt = LUA_TSTRING; 64 ts->tsv.tt = LUA_TSTRING;
61 ts->tsv.reserved = 0; 65 ts->tsv.reserved = 0;
62 memcpy(ts+1, str, l*sizeof(char)); 66 ts->tsv.type = cast_byte(type);
63 ((char *)(ts+1))[l] = '\0'; /* ending 0 */ 67 if (testbits(type, TSTR_INBIN)) /* ROCKLUA ADDED */
68 *(const char **)(ts+1) = str; /* store a pointer to the string instead */
69 else {
70 memcpy(ts+1, str, l*sizeof(char));
71 ((char *)(ts+1))[l] = '\0'; /* ending 0 */
72 }
64 tb = &G(L)->strt; 73 tb = &G(L)->strt;
65 h = lmod(h, tb->size); 74 h = lmod(h, tb->size);
66 ts->tsv.next = tb->hash[h]; /* chain new entry */ 75 ts->tsv.next = tb->hash[h]; /* chain new entry */
@@ -72,8 +81,16 @@ static TString *newlstr (lua_State *L, const char *str, size_t l,
72} 81}
73 82
74 83
75TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { 84TString *luaS_newllocstr (lua_State *L, const char *str, size_t l, char type) {
76 GCObject *o; 85 GCObject *o;
86 if (testbits(type, TSTR_CHKSZ))
87 l = strlen(str);
88#ifdef INBINARYSTRINGS
89 else if (!testbits(type, TSTR_ISLIT))
90#else
91 if (true)
92#endif
93 resetbits(type, TSTR_INBIN); /* only whole strings can be used inbin */
77 unsigned int h = cast(unsigned int, l); /* seed */ 94 unsigned int h = cast(unsigned int, l); /* seed */
78 size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ 95 size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
79 size_t l1; 96 size_t l1;
@@ -86,10 +103,12 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
86 if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { 103 if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
87 /* string may be dead */ 104 /* string may be dead */
88 if (isdead(G(L), o)) changewhite(o); 105 if (isdead(G(L), o)) changewhite(o);
106 if (testbits(type, TSTR_FIXED))
107 luaS_fix(ts);
89 return ts; 108 return ts;
90 } 109 }
91 } 110 }
92 return newlstr(L, str, l, h); /* not found */ 111 return newlstr(L, str, l, h, type); /* not found */
93} 112}
94 113
95 114
diff --git a/apps/plugins/lua/lstring.h b/apps/plugins/lua/lstring.h
index c88e4c12a9..8ca69b8de3 100644
--- a/apps/plugins/lua/lstring.h
+++ b/apps/plugins/lua/lstring.h
@@ -12,20 +12,29 @@
12#include "lobject.h" 12#include "lobject.h"
13#include "lstate.h" 13#include "lstate.h"
14 14
15 15/* ROCKLUA ADDED */
16#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) 16#define TSTR_INBLOB 0 /* string will be allocated at end of tstring struct */
17#define TSTR_INBIN 1 /* string is static within binary, pointer stored */
18#define TSTR_FIXED 2 /* string won't be collected for duration of L state */
19#define TSTR_CHKSZ 4 /* luaS_newllocstr shall determine size of string */
20#define TSTR_ISLIT 8 | TSTR_INBIN /* literal string static within binary */
21#define sizetstring(t, l) (sizeof(union TString) + (testbits((t), TSTR_INBIN) ? \
22 sizeof(const char **) : ((l)+1)*sizeof(char)))
17 23
18#define sizeudata(u) (sizeof(union Udata)+(u)->len) 24#define sizeudata(u) (sizeof(union Udata)+(u)->len)
19 25
20#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s))) 26#define luaS_new(L, s) (luaS_newllocstr(L, s, 0, TSTR_INBLOB | TSTR_CHKSZ))
21#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 27#define luaS_newlstr(L, s, len) (luaS_newllocstr(L, s, len, TSTR_INBLOB))
22 (sizeof(s)/sizeof(char))-1)) 28#define luaS_newlloc(L, s, t) (luaS_newllocstr(L, s, 0, ((t) | TSTR_CHKSZ)))
29#define luaS_newliteral(L, s) (luaS_newllocstr(L, "" s, \
30 (sizeof(s)/sizeof(char))-1, TSTR_ISLIT))
23 31
24#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) 32#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
25 33
26LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 34LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
27LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); 35LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
28LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 36/* ROCKLUA ADDED */
29 37LUAI_FUNC TString *luaS_newllocstr (lua_State *L,
38 const char *str, size_t l, char type);
30 39
31#endif 40#endif
diff --git a/apps/plugins/lua/ltm.c b/apps/plugins/lua/ltm.c
index c27f0f6fab..946028006f 100644
--- a/apps/plugins/lua/ltm.c
+++ b/apps/plugins/lua/ltm.c
@@ -36,10 +36,8 @@ void luaT_init (lua_State *L) {
36 "__concat", "__call" 36 "__concat", "__call"
37 }; 37 };
38 int i; 38 int i;
39 for (i=0; i<TM_N; i++) { 39 for (i=0; i<TM_N; i++) /* never collect these names */
40 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); 40 G(L)->tmname[i] = luaS_newlloc(L, luaT_eventname[i], TSTR_INBIN | TSTR_FIXED);
41 luaS_fix(G(L)->tmname[i]); /* never collect these names */
42 }
43} 41}
44 42
45 43
diff --git a/apps/plugins/lua/rockconf.h b/apps/plugins/lua/rockconf.h
index a13146d7e9..89ab82e377 100644
--- a/apps/plugins/lua/rockconf.h
+++ b/apps/plugins/lua/rockconf.h
@@ -31,6 +31,7 @@
31 31
32#undef LUA_PATH_DEFAULT 32#undef LUA_PATH_DEFAULT
33#define LUA_PATH_DEFAULT "$/?.lua;" "$/?/init.lua;" VIEWERS_DIR"/lua/?.lua;" VIEWERS_DIR"/lua/?/init.lua;" 33#define LUA_PATH_DEFAULT "$/?.lua;" "$/?/init.lua;" VIEWERS_DIR"/lua/?.lua;" VIEWERS_DIR"/lua/?/init.lua;"
34#define INBINARYSTRINGS /* Static strings stored as pointer rather than copied into lua state */
34 35
35#include <setjmp.h> 36#include <setjmp.h>
36 37
diff --git a/apps/plugins/lua/rocklib.c b/apps/plugins/lua/rocklib.c
index 9ad6411b2f..426dd079af 100644
--- a/apps/plugins/lua/rocklib.c
+++ b/apps/plugins/lua/rocklib.c
@@ -25,6 +25,7 @@
25#define LUA_LIB 25#define LUA_LIB
26 26
27#include "lua.h" 27#include "lua.h"
28#include "lstring.h"
28 29
29#include "lauxlib.h" 30#include "lauxlib.h"
30#include "rocklib.h" 31#include "rocklib.h"
@@ -835,6 +836,7 @@ LUALIB_API int luaopen_rock(lua_State *L)
835 static const struct lua_int_reg* rlci = rlib_const_int; 836 static const struct lua_int_reg* rlci = rlib_const_int;
836 for (; rlci->name; rlci++) { 837 for (; rlci->name; rlci++) {
837 lua_pushinteger(L, rlci->value); 838 lua_pushinteger(L, rlci->value);
839 luaS_newlloc(L, rlci->name, TSTR_INBIN);
838 lua_setfield(L, -2, rlci->name); 840 lua_setfield(L, -2, rlci->name);
839 } 841 }
840 842
@@ -853,7 +855,9 @@ LUALIB_API int luaopen_rock(lua_State *L)
853 855
854 static const struct lua_str_reg* rlcs = rlib_const_str; 856 static const struct lua_str_reg* rlcs = rlib_const_str;
855 for (; rlcs->name; rlcs++) { 857 for (; rlcs->name; rlcs++) {
858 luaS_newlloc(L, rlcs->value, TSTR_INBIN);
856 lua_pushstring(L, rlcs->value); 859 lua_pushstring(L, rlcs->value);
860 luaS_newlloc(L, rlcs->name, TSTR_INBIN);
857 lua_setfield(L, -2, rlcs->name); 861 lua_setfield(L, -2, rlcs->name);
858 } 862 }
859 863