diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-01-16 14:54:37 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-01-16 14:54:37 -0200 |
commit | 7e2015a46df7976bddee313b994742e49e420714 (patch) | |
tree | 0b2db30f1214a478ccb3664d165c8a431f0d5850 /lstring.c | |
parent | 5b01cb39b5ec36c544152351c35c43149d9bbfec (diff) | |
download | lua-7e2015a46df7976bddee313b994742e49e420714.tar.gz lua-7e2015a46df7976bddee313b994742e49e420714.tar.bz2 lua-7e2015a46df7976bddee313b994742e49e420714.zip |
size of short strings stored in a single byte, to reduce the size
of struct 'TString'
Diffstat (limited to 'lstring.c')
-rw-r--r-- | lstring.c | 27 |
1 files changed, 15 insertions, 12 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 2.44 2014/07/21 16:02:10 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.45 2014/11/02 19:19:04 roberto Exp roberto $ |
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 | */ | 5 | */ |
@@ -36,10 +36,10 @@ | |||
36 | ** equality for long strings | 36 | ** equality for long strings |
37 | */ | 37 | */ |
38 | int luaS_eqlngstr (TString *a, TString *b) { | 38 | int luaS_eqlngstr (TString *a, TString *b) { |
39 | size_t len = a->len; | 39 | size_t len = a->u.lnglen; |
40 | lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); | 40 | lua_assert(a->tt == LUA_TLNGSTR && b->tt == LUA_TLNGSTR); |
41 | return (a == b) || /* same instance or... */ | 41 | return (a == b) || /* same instance or... */ |
42 | ((len == b->len) && /* equal length and ... */ | 42 | ((len == b->u.lnglen) && /* equal length and ... */ |
43 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ | 43 | (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ |
44 | } | 44 | } |
45 | 45 | ||
@@ -69,9 +69,9 @@ void luaS_resize (lua_State *L, int newsize) { | |||
69 | TString *p = tb->hash[i]; | 69 | TString *p = tb->hash[i]; |
70 | tb->hash[i] = NULL; | 70 | tb->hash[i] = NULL; |
71 | while (p) { /* for each node in the list */ | 71 | while (p) { /* for each node in the list */ |
72 | TString *hnext = p->hnext; /* save next */ | 72 | TString *hnext = p->u.hnext; /* save next */ |
73 | unsigned int h = lmod(p->hash, newsize); /* new position */ | 73 | unsigned int h = lmod(p->hash, newsize); /* new position */ |
74 | p->hnext = tb->hash[h]; /* chain it */ | 74 | p->u.hnext = tb->hash[h]; /* chain it */ |
75 | tb->hash[h] = p; | 75 | tb->hash[h] = p; |
76 | p = hnext; | 76 | p = hnext; |
77 | } | 77 | } |
@@ -97,7 +97,6 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l, | |||
97 | totalsize = sizelstring(l); | 97 | totalsize = sizelstring(l); |
98 | o = luaC_newobj(L, tag, totalsize); | 98 | o = luaC_newobj(L, tag, totalsize); |
99 | ts = gco2ts(o); | 99 | ts = gco2ts(o); |
100 | ts->len = l; | ||
101 | ts->hash = h; | 100 | ts->hash = h; |
102 | ts->extra = 0; | 101 | ts->extra = 0; |
103 | memcpy(getaddrstr(ts), str, l * sizeof(char)); | 102 | memcpy(getaddrstr(ts), str, l * sizeof(char)); |
@@ -110,8 +109,8 @@ void luaS_remove (lua_State *L, TString *ts) { | |||
110 | stringtable *tb = &G(L)->strt; | 109 | stringtable *tb = &G(L)->strt; |
111 | TString **p = &tb->hash[lmod(ts->hash, tb->size)]; | 110 | TString **p = &tb->hash[lmod(ts->hash, tb->size)]; |
112 | while (*p != ts) /* find previous element */ | 111 | while (*p != ts) /* find previous element */ |
113 | p = &(*p)->hnext; | 112 | p = &(*p)->u.hnext; |
114 | *p = (*p)->hnext; /* remove element from its list */ | 113 | *p = (*p)->u.hnext; /* remove element from its list */ |
115 | tb->nuse--; | 114 | tb->nuse--; |
116 | } | 115 | } |
117 | 116 | ||
@@ -124,8 +123,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
124 | global_State *g = G(L); | 123 | global_State *g = G(L); |
125 | unsigned int h = luaS_hash(str, l, g->seed); | 124 | unsigned int h = luaS_hash(str, l, g->seed); |
126 | TString **list = &g->strt.hash[lmod(h, g->strt.size)]; | 125 | TString **list = &g->strt.hash[lmod(h, g->strt.size)]; |
127 | for (ts = *list; ts != NULL; ts = ts->hnext) { | 126 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { |
128 | if (l == ts->len && | 127 | if (l == ts->shrlen && |
129 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { | 128 | (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { |
130 | /* found! */ | 129 | /* found! */ |
131 | if (isdead(g, ts)) /* dead (but not collected yet)? */ | 130 | if (isdead(g, ts)) /* dead (but not collected yet)? */ |
@@ -138,7 +137,8 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
138 | list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ | 137 | list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */ |
139 | } | 138 | } |
140 | ts = createstrobj(L, str, l, LUA_TSHRSTR, h); | 139 | ts = createstrobj(L, str, l, LUA_TSHRSTR, h); |
141 | ts->hnext = *list; | 140 | ts->shrlen = cast_byte(l); |
141 | ts->u.hnext = *list; | ||
142 | *list = ts; | 142 | *list = ts; |
143 | g->strt.nuse++; | 143 | g->strt.nuse++; |
144 | return ts; | 144 | return ts; |
@@ -152,9 +152,12 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
152 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ | 152 | if (l <= LUAI_MAXSHORTLEN) /* short string? */ |
153 | return internshrstr(L, str, l); | 153 | return internshrstr(L, str, l); |
154 | else { | 154 | else { |
155 | TString *ts; | ||
155 | if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char)) | 156 | if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char)) |
156 | luaM_toobig(L); | 157 | luaM_toobig(L); |
157 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed); | 158 | ts = createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed); |
159 | ts->u.lnglen = l; | ||
160 | return ts; | ||
158 | } | 161 | } |
159 | } | 162 | } |
160 | 163 | ||