diff options
author | William Wilgus <me.theuser@yahoo.com> | 2018-11-11 18:27:19 -0500 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2019-07-11 00:31:41 +0200 |
commit | c6fcb1cf45b249b059c2d53a062f9a6c7f449047 (patch) | |
tree | 229eacd12461605a8320eb7590ff83eea13538d6 | |
parent | 42240f6990156fb907a7dce7258be2f1235fab44 (diff) | |
download | rockbox-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
-rw-r--r-- | apps/plugins/lua/lauxlib.c | 21 | ||||
-rw-r--r-- | apps/plugins/lua/lgc.c | 2 | ||||
-rw-r--r-- | apps/plugins/lua/llex.c | 4 | ||||
-rw-r--r-- | apps/plugins/lua/lobject.c | 15 | ||||
-rw-r--r-- | apps/plugins/lua/lobject.h | 4 | ||||
-rw-r--r-- | apps/plugins/lua/lstring.c | 33 | ||||
-rw-r--r-- | apps/plugins/lua/lstring.h | 23 | ||||
-rw-r--r-- | apps/plugins/lua/ltm.c | 6 | ||||
-rw-r--r-- | apps/plugins/lua/rockconf.h | 1 | ||||
-rw-r--r-- | apps/plugins/lua/rocklib.c | 4 |
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 */ | ||
245 | static 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 | |||
242 | LUALIB_API void (luaL_register) (lua_State *L, const char *libname, | 257 | LUALIB_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 | |
248 | static int libsize (const luaL_Reg *l) { | 263 | static 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 | ||
255 | LUALIB_API void luaI_openlib (lua_State *L, const char *libname, | 270 | LUALIB_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) { | |||
64 | void luaX_init (lua_State *L) { | 64 | void 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 */ | ||
111 | const 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 */ |
111 | const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { | 126 | const 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); | |||
371 | LUAI_FUNC int luaO_fb2int (int x); | 372 | LUAI_FUNC int luaO_fb2int (int x); |
372 | LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); | 373 | LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2); |
373 | LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); | 374 | LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result); |
375 | LUAI_FUNC const char *luaO_getstring(const TString * ts); /* ROCKLUA ADDED */ | ||
374 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, | 376 | LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, |
375 | va_list argp); | 377 | va_list argp); |
376 | LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); | 378 | LUAI_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 | ||
50 | static TString *newlstr (lua_State *L, const char *str, size_t l, | 52 | static 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 | ||
75 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | 84 | TString *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 | ||
26 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | 34 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
27 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); | 35 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); |
28 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); | 36 | /* ROCKLUA ADDED */ |
29 | 37 | LUAI_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 | ||