History

Lua 5.3.0-work2

Lua Team committed 12 years ago

Commit ad386d91 parent b83a40a60 files · +3280 −2672Browse files

Showing the changes to src/lstring.c (1 of 60 files). Show all

Unified · Split

src/lstring.c+46−55
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstring.c,v 2.27 2013/06/19 14:27:00 roberto Exp $2** $Id: lstring.c,v 2.38 2014/03/19 18:51:42 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.h4** See Copyright Notice in lua.h
5*/5*/
@@ -12,12 +12,15 @@ · 6 unmodified lines
12 12
13#include "lua.h"13#include "lua.h"
14 14
15#include "ldebug.h"
16#include "ldo.h"
15#include "lmem.h"17#include "lmem.h"
16#include "lobject.h"18#include "lobject.h"
17#include "lstate.h"19#include "lstate.h"
18#include "lstring.h"20#include "lstring.h"
19 21
20 22
23
21/*24/*
22** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to25** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
23** compute its hash26** compute its hash
@@ -39,15 +42,6 @@ int luaS_eqlngstr (TString *a, TString *b) { · 15 unmodified lines
39}42}
40 43
41 44
42/*
43** equality for strings
44*/
45int luaS_eqstr (TString *a, TString *b) {
46 return (a->tsv.tt == b->tsv.tt) &&
47 (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b));
48}
49
50
51unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {45unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
52 unsigned int h = seed ^ cast(unsigned int, l);46 unsigned int h = seed ^ cast(unsigned int, l);
53 size_t l1;47 size_t l1;
@@ -64,43 +58,41 @@ unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { · 10 unmodified lines
64void luaS_resize (lua_State *L, int newsize) {58void luaS_resize (lua_State *L, int newsize) {
65 int i;59 int i;
66 stringtable *tb = &G(L)->strt;60 stringtable *tb = &G(L)->strt;
67 /* cannot resize while GC is traversing strings */61 if (newsize > tb->size) { /* grow table if needed */
68 luaC_runtilstate(L, ~bitmask(GCSsweepstring));62 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
69 if (newsize > tb->size) {63 for (i = tb->size; i < newsize; i++)
70 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);64 tb->hash[i] = NULL;
71 for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
72 }65 }
73 /* rehash */66 for (i = 0; i < tb->size; i++) { /* rehash */
74 for (i=0; i<tb->size; i++) {67 TString *p = tb->hash[i];
75 GCObject *p = tb->hash[i];
76 tb->hash[i] = NULL;68 tb->hash[i] = NULL;
77 while (p) { /* for each node in the list */69 while (p) { /* for each node in the list */
78 GCObject *next = gch(p)->next; /* save next */70 TString *hnext = p->tsv.hnext; /* save next */
79 unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */71 unsigned int h = lmod(p->tsv.hash, newsize); /* new position */
80 gch(p)->next = tb->hash[h]; /* chain it */72 p->tsv.hnext = tb->hash[h]; /* chain it */
81 tb->hash[h] = p;73 tb->hash[h] = p;
82 resetoldbit(p); /* see MOVE OLD rule */74 p = hnext;
83 p = next;
84 }75 }
85 }76 }
86 if (newsize < tb->size) {77 if (newsize < tb->size) { /* shrink table if needed */
87 /* shrinking slice must be empty */78 /* vanishing slice should be empty */
88 lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);79 lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
89 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);80 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
90 }81 }
91 tb->size = newsize;82 tb->size = newsize;
92}83}
93 84
94 85
86
95/*87/*
96** creates a new string object88** creates a new string object
97*/89*/
98static TString *createstrobj (lua_State *L, const char *str, size_t l,90static TString *createstrobj (lua_State *L, const char *str, size_t l,
99 int tag, unsigned int h, GCObject **list) {91 int tag, unsigned int h) {
100 TString *ts;92 TString *ts;
101 size_t totalsize; /* total size of TString object */93 size_t totalsize; /* total size of TString object */
102 totalsize = sizeof(TString) + ((l + 1) * sizeof(char));94 totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
103 ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts;95 ts = &luaC_newobj(L, tag, totalsize)->ts;
104 ts->tsv.len = l;96 ts->tsv.len = l;
105 ts->tsv.hash = h;97 ts->tsv.hash = h;
106 ts->tsv.extra = 0;98 ts->tsv.extra = 0;
@@ -110,20 +102,13 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l, · 3 unmodified lines
110}102}
111 103
112 104
113/*105LUAI_FUNC void luaS_remove (lua_State *L, TString *ts) {
114** creates a new short string, inserting it into string table
115*/
116static TString *newshrstr (lua_State *L, const char *str, size_t l,
117 unsigned int h) {
118 GCObject **list; /* (pointer to) list where it will be inserted */
119 stringtable *tb = &G(L)->strt;106 stringtable *tb = &G(L)->strt;
120 TString *s;107 TString **p = &tb->hash[lmod(ts->tsv.hash, tb->size)];
121 if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)108 while (*p != ts) /* find previous element */
122 luaS_resize(L, tb->size*2); /* too crowded */109 p = &(*p)->tsv.hnext;
123 list = &tb->hash[lmod(h, tb->size)];110 *p = (*p)->tsv.hnext; /* remove element from its list */
124 s = createstrobj(L, str, l, LUA_TSHRSTR, h, list);111 tb->nuse--;
125 tb->nuse++;
126 return s;
127}112}
128 113
129 114
@@ -131,22 +116,28 @@ static TString *newshrstr (lua_State *L, const char *str, size_t l, · 1 unmodified line
131** checks whether short string exists and reuses it or creates a new one116** checks whether short string exists and reuses it or creates a new one
132*/117*/
133static TString *internshrstr (lua_State *L, const char *str, size_t l) {118static TString *internshrstr (lua_State *L, const char *str, size_t l) {
134 GCObject *o;119 TString *ts;
135 global_State *g = G(L);120 global_State *g = G(L);
136 unsigned int h = luaS_hash(str, l, g->seed);121 unsigned int h = luaS_hash(str, l, g->seed);
137 for (o = g->strt.hash[lmod(h, g->strt.size)];122 TString **list = &g->strt.hash[lmod(h, g->strt.size)];
138 o != NULL;123 for (ts = *list; ts != NULL; ts = ts->tsv.hnext) {
139 o = gch(o)->next) {124 if (l == ts->tsv.len &&
140 TString *ts = rawgco2ts(o);
141 if (h == ts->tsv.hash &&
142 l == ts->tsv.len &&
143 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {125 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
144 if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */126 /* found! */
145 changewhite(o); /* resurrect it */127 if (isdead(g, obj2gco(ts))) /* dead (but not collected yet)? */
128 changewhite(obj2gco(ts)); /* resurrect it */
146 return ts;129 return ts;
147 }130 }
148 }131 }
149 return newshrstr(L, str, l, h); /* not found; create a new string */132 if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) {
133 luaS_resize(L, g->strt.size * 2);
134 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
135 }
136 ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
137 ts->tsv.hnext = *list;
138 *list = ts;
139 g->strt.nuse++;
140 return ts;
150}141}
151 142
152 143
@@ -159,7 +150,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { · 6 unmodified lines
159 else {150 else {
160 if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))151 if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
161 luaM_toobig(L);152 luaM_toobig(L);
162 return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL);153 return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
163 }154 }
164}155}
165 156
@@ -172,14 +163,14 @@ TString *luaS_new (lua_State *L, const char *str) { · 6 unmodified lines
172}163}
173 164
174 165
175Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {166Udata *luaS_newudata (lua_State *L, size_t s) {
176 Udata *u;167 Udata *u;
177 if (s > MAX_SIZE - sizeof(Udata))168 if (s > MAX_SIZE - sizeof(Udata))
178 luaM_toobig(L);169 luaM_toobig(L);
179 u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u;170 u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s)->u;
180 u->uv.len = s;171 u->uv.len = s;
181 u->uv.metatable = NULL;172 u->uv.metatable = NULL;
182 u->uv.env = e;173 setuservalue(L, u, luaO_nilobject);
183 return u;174 return u;
184}175}
185 176