@@ -79,21 +79,50 @@ private __gshared
7979 int elmax; /* max # of allocs at any point */
8080}
8181
82- // ///////////////////////////
83- // Table to gather redundant strings in.
82+ /* ************************
83+ * Cache of strings that are referenced by a Symbol.
84+ * Uses a rotating buffer, perhaps a hash table would be better?
85+ */
8486
85- struct STAB
87+ struct Stab
8688{
87- Symbol* sym; // symbol that refers to the string
88- char [] str; // the string
89- }
89+ nothrow :
90+ enum Length = 16 ; // must be power of 2
91+ size_t si; // next index into arrays
92+ Symbol* [Length] symbols; // Symbol that refers to the string
93+ char [] [Length] strings; // the string
9094
91- private __gshared
92- {
93- STAB [16 ] stable;
94- int stable_si;
95+ @trusted
96+ void insert (Symbol* sym, char [] str)
97+ {
98+ mem_free(strings[si].ptr);
99+ symbols[si] = sym;
100+ strings[si] = str;
101+ si = (si + 1 ) & (Length - 1 ); // wrap-around increment
102+ }
103+
104+ size_t lookup (char [] str)
105+ {
106+ foreach (i; 0 .. Length)
107+ {
108+ if (strings[i][] == str[])
109+ return i;
110+ }
111+ return size_t .max;
112+ }
113+
114+ @trusted
115+ void reset ()
116+ {
117+ foreach (str; strings)
118+ mem_free(str.ptr);
119+ this = Stab.init;
120+ }
95121}
96122
123+ private __gshared Stab stable;
124+
125+
97126/* ***********************
98127 * Initialize el package.
99128 */
@@ -112,10 +141,7 @@ void el_init()
112141@trusted
113142void el_reset ()
114143{
115- stable_si = 0 ;
116- for (int i = 0 ; i < stable.length; i++ )
117- mem_free(stable[i].str.ptr);
118- memset(stable.ptr,0 ,stable.sizeof);
144+ stable.reset();
119145}
120146
121147/* ***********************
@@ -127,8 +153,7 @@ void el_term()
127153{
128154 static if (TERMCODE )
129155 {
130- for (int i = 0 ; i < stable.length; i++ )
131- mem_free(stable[i].str.ptr);
156+ stable.reset();
132157
133158 debug printf(" Max # of elems = %d\n " ,elmax);
134159
@@ -1339,15 +1364,15 @@ private @trusted
13391364elem* el_convstring (elem* e)
13401365{
13411366 // printf("el_convstring()\n");
1342- int i;
13431367 Symbol* s;
13441368 char * p;
13451369
13461370 elem_debug(e);
13471371 assert (e.Eoper == OPstring);
13481372 p = e.Vstring;
1349- e.Vstring = null ;
1373+ e.Vstring = null ; // transfer ownership to p
13501374 size_t len = e.Vstrlen;
1375+ size_t idx;
13511376
13521377 if (eecontext.EEin) // if compiling debugger expression
13531378 {
@@ -1357,16 +1382,12 @@ elem* el_convstring(elem* e)
13571382 }
13581383
13591384 // See if e is already in the string table
1360- for (i = 0 ; i < stable.length; i++ )
1385+ idx = stable.lookup(p[0 .. len]);
1386+ if (idx != size_t .max)
13611387 {
1362- if (stable[i].str.length == len &&
1363- memcmp(stable[i].str.ptr,p,len) == 0 )
1364- {
1365- // Replace e with that symbol
1366- mem_free(p);
1367- s = stable[i].sym;
1368- goto L1 ;
1369- }
1388+ mem_free(p);
1389+ s = stable.symbols[idx]; // replace s with the one in stable
1390+ goto L1 ;
13701391 }
13711392
13721393 // Replace string with a symbol that refers to that string
@@ -1382,10 +1403,7 @@ elem* el_convstring(elem* e)
13821403
13831404 // Remember the string for possible reuse later
13841405 // printf("Adding %d, '%s'\n",stable_si,p);
1385- mem_free(stable[stable_si].str.ptr);
1386- stable[stable_si].str = p[0 .. cast (size_t )len];
1387- stable[stable_si].sym = s;
1388- stable_si = (stable_si + 1 ) & (stable.length - 1 );
1406+ stable.insert(s, p[0 .. len]);
13891407
13901408L1 :
13911409 // Refer e to the symbol generated
0 commit comments