|
Line 0
Link Here
|
|
|
1 |
--- file.c.memory 2002-10-03 19:13:42.000000000 -0700 |
| 2 |
+++ file.c 2006-02-01 10:45:32.000000000 -0800 |
| 3 |
@@ -434,7 +434,7 @@ snap_deps () |
| 4 |
if (d->file == 0) |
| 5 |
d->file = enter_file (d->name); |
| 6 |
else |
| 7 |
- free (d->name); |
| 8 |
+ hash_strfree (d->name); |
| 9 |
d->name = 0; |
| 10 |
} |
| 11 |
free (file_slot_0); |
| 12 |
--- implicit.c.memory 2002-09-04 00:26:19.000000000 -0700 |
| 13 |
+++ implicit.c 2006-02-01 10:45:32.000000000 -0800 |
| 14 |
@@ -539,7 +539,7 @@ pattern_search (file, archive, depth, re |
| 15 |
dep->file = enter_file (dep->name); |
| 16 |
/* enter_file uses dep->name _if_ we created a new file. */ |
| 17 |
if (dep->name != dep->file->name) |
| 18 |
- free (dep->name); |
| 19 |
+ hash_strfree (dep->name); |
| 20 |
dep->name = 0; |
| 21 |
dep->file->tried_implicit |= dep->changed; |
| 22 |
} |
| 23 |
--- main.c.memory 2002-08-09 18:27:17.000000000 -0700 |
| 24 |
+++ main.c 2006-02-01 10:45:32.000000000 -0800 |
| 25 |
@@ -501,6 +501,7 @@ initialize_global_hash_tables () |
| 26 |
init_hash_files (); |
| 27 |
hash_init_directories (); |
| 28 |
hash_init_function_table (); |
| 29 |
+ init_hash_strings (); |
| 30 |
} |
| 31 |
|
| 32 |
static struct file * |
| 33 |
--- make.h.memory 2002-09-11 09:55:44.000000000 -0700 |
| 34 |
+++ make.h 2006-02-01 10:45:32.000000000 -0800 |
| 35 |
@@ -427,6 +427,11 @@ extern char *find_char_unquote PARAMS (( |
| 36 |
extern char *find_percent PARAMS ((char *)); |
| 37 |
extern FILE *open_tmpfile PARAMS ((char **, const char *)); |
| 38 |
|
| 39 |
+extern void init_hash_strings PARAMS ((void)); |
| 40 |
+extern char *hash_strdup PARAMS ((const char *)); |
| 41 |
+extern char *hash_savestring PARAMS ((const char *, unsigned int)); |
| 42 |
+extern void hash_strfree PARAMS ((char *)); |
| 43 |
+ |
| 44 |
#ifndef NO_ARCHIVES |
| 45 |
extern int ar_name PARAMS ((char *)); |
| 46 |
extern void ar_parse_name PARAMS ((char *, char **, char **)); |
| 47 |
--- misc.c.memory 2002-09-12 15:15:58.000000000 -0700 |
| 48 |
+++ misc.c 2006-02-01 11:05:44.000000000 -0800 |
| 49 |
@@ -18,8 +18,10 @@ along with GNU Make; see the file COPYIN |
| 50 |
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| 51 |
Boston, MA 02111-1307, USA. */ |
| 52 |
|
| 53 |
+#include <assert.h> |
| 54 |
#include "make.h" |
| 55 |
#include "dep.h" |
| 56 |
+#include "hash.h" |
| 57 |
#include "debug.h" |
| 58 |
|
| 59 |
/* Variadic functions. We go through contortions to allow proper function |
| 60 |
@@ -564,7 +566,7 @@ copy_dep_chain (d) |
| 61 |
c = (struct dep *) xmalloc (sizeof (struct dep)); |
| 62 |
bcopy ((char *) d, (char *) c, sizeof (struct dep)); |
| 63 |
if (c->name != 0) |
| 64 |
- c->name = xstrdup (c->name); |
| 65 |
+ c->name = hash_strdup (c->name); |
| 66 |
c->next = 0; |
| 67 |
if (firstnew == 0) |
| 68 |
firstnew = lastnew = c; |
| 69 |
@@ -891,3 +893,154 @@ atomic_readdir(dir) |
| 70 |
} |
| 71 |
|
| 72 |
#endif /* HAVE_BROKEN_RESTART */ |
| 73 |
+ |
| 74 |
+/* Hash table of duplicated strings. */ |
| 75 |
+ |
| 76 |
+struct hash_string |
| 77 |
+{ |
| 78 |
+ char *string; |
| 79 |
+ unsigned int count; |
| 80 |
+}; |
| 81 |
+ |
| 82 |
+static unsigned long |
| 83 |
+string_hash_1 (key) |
| 84 |
+ const void *key; |
| 85 |
+{ |
| 86 |
+ return_ISTRING_HASH_1 (((const struct hash_string *) key)->string); |
| 87 |
+} |
| 88 |
+ |
| 89 |
+static unsigned long |
| 90 |
+string_hash_2 (key) |
| 91 |
+ const void *key; |
| 92 |
+{ |
| 93 |
+ return_ISTRING_HASH_2 (((const struct hash_string *) key)->string); |
| 94 |
+} |
| 95 |
+ |
| 96 |
+static int |
| 97 |
+string_hash_cmp (x, y) |
| 98 |
+ const void *x; |
| 99 |
+ const void *y; |
| 100 |
+{ |
| 101 |
+ return_ISTRING_COMPARE (((const struct hash_string *) x)->string, |
| 102 |
+ ((const struct hash_string *) y)->string); |
| 103 |
+} |
| 104 |
+ |
| 105 |
+static struct hash_table strings; |
| 106 |
+ |
| 107 |
+void |
| 108 |
+init_hash_strings () |
| 109 |
+{ |
| 110 |
+ hash_init (&strings, 1000, string_hash_1, string_hash_2, |
| 111 |
+ string_hash_cmp); |
| 112 |
+} |
| 113 |
+ |
| 114 |
+/* Keep track duplicated string and return the old one if exists. */ |
| 115 |
+ |
| 116 |
+char * |
| 117 |
+hash_strdup (ptr) |
| 118 |
+ const char *ptr; |
| 119 |
+{ |
| 120 |
+ struct hash_string *h, key; |
| 121 |
+ |
| 122 |
+ if (*ptr == '\0') |
| 123 |
+ return ""; |
| 124 |
+ |
| 125 |
+ key.string = (char *) ptr; |
| 126 |
+ key.count = 0; |
| 127 |
+ h = (struct hash_string *) hash_find_item (&strings, &key); |
| 128 |
+ if (h == NULL) |
| 129 |
+ { |
| 130 |
+ char *result = (char *) malloc (strlen (ptr) + 1); |
| 131 |
+ |
| 132 |
+ if (result == NULL) |
| 133 |
+ fatal (NILF, _("virtual memory exhausted")); |
| 134 |
+ |
| 135 |
+ strcpy (result, ptr); |
| 136 |
+ |
| 137 |
+ h = (struct hash_string *) malloc (sizeof (struct hash_string)); |
| 138 |
+ if (h == NULL) |
| 139 |
+ fatal (NILF, _("virtual memory exhausted")); |
| 140 |
+ |
| 141 |
+ h->string = result; |
| 142 |
+ h->count = 1; |
| 143 |
+ hash_insert (&strings, h); |
| 144 |
+ } |
| 145 |
+ else |
| 146 |
+ { |
| 147 |
+ h->count++; |
| 148 |
+ assert (h->count != 0); |
| 149 |
+ } |
| 150 |
+ |
| 151 |
+ return h->string; |
| 152 |
+} |
| 153 |
+ |
| 154 |
+char * |
| 155 |
+hash_savestring (str, length) |
| 156 |
+ const char *str; |
| 157 |
+ unsigned int length; |
| 158 |
+{ |
| 159 |
+ struct hash_string *h, key; |
| 160 |
+ |
| 161 |
+ if (length == 0 || *str == '\0') |
| 162 |
+ return ""; |
| 163 |
+ |
| 164 |
+ key.string = alloca (length + 1); |
| 165 |
+ key.count = 0; |
| 166 |
+ bcopy (str, key.string, length); |
| 167 |
+ key.string [length] = '\0'; |
| 168 |
+ |
| 169 |
+ h = (struct hash_string *) hash_find_item (&strings, &key); |
| 170 |
+ if (h == NULL) |
| 171 |
+ { |
| 172 |
+ char *out = (char *) xmalloc (length + 1); |
| 173 |
+ bcopy (str, out, length); |
| 174 |
+ out[length] = '\0'; |
| 175 |
+ |
| 176 |
+ h = (struct hash_string *) malloc (sizeof (struct hash_string)); |
| 177 |
+ if (h == NULL) |
| 178 |
+ fatal (NILF, _("virtual memory exhausted")); |
| 179 |
+ |
| 180 |
+ h->string = out; |
| 181 |
+ h->count = 1; |
| 182 |
+ hash_insert (&strings, h); |
| 183 |
+ } |
| 184 |
+ else |
| 185 |
+ { |
| 186 |
+ h->count++; |
| 187 |
+ assert (h->count != 0); |
| 188 |
+ } |
| 189 |
+ |
| 190 |
+ return h->string; |
| 191 |
+} |
| 192 |
+ |
| 193 |
+void |
| 194 |
+hash_strfree (ptr) |
| 195 |
+ char *ptr; |
| 196 |
+{ |
| 197 |
+ struct hash_string *h, key; |
| 198 |
+ |
| 199 |
+ if (*ptr == '\0') |
| 200 |
+ return; |
| 201 |
+ |
| 202 |
+ key.string = ptr; |
| 203 |
+ key.count = 0; |
| 204 |
+ h = (struct hash_string *) hash_find_item (&strings, &key); |
| 205 |
+ |
| 206 |
+ /* Check if string comes from hash_strdup or hash_savestring. */ |
| 207 |
+ if (h == NULL || h->string != ptr) |
| 208 |
+ { |
| 209 |
+ free (ptr); |
| 210 |
+ return; |
| 211 |
+ } |
| 212 |
+ |
| 213 |
+ h->count--; |
| 214 |
+ if (h->count == 0) |
| 215 |
+ { |
| 216 |
+ struct hash_string *d; |
| 217 |
+ |
| 218 |
+ d = hash_delete (&strings, h); |
| 219 |
+ assert (d == h); |
| 220 |
+ free (h->string); |
| 221 |
+ free (h); |
| 222 |
+ } |
| 223 |
+} |
| 224 |
--- read.c.memory 2006-02-01 10:45:32.000000000 -0800 |
| 225 |
+++ read.c 2006-02-01 10:45:32.000000000 -0800 |
| 226 |
@@ -1871,8 +1871,8 @@ record_files (filenames, pattern, patter |
| 227 |
fatal (flocp, |
| 228 |
_("target `%s' leaves prerequisite pattern empty"), |
| 229 |
name); |
| 230 |
- free (d->name); |
| 231 |
- d->name = savestring (buffer, o - buffer); |
| 232 |
+ hash_strfree (d->name); |
| 233 |
+ d->name = hash_savestring (buffer, o - buffer); |
| 234 |
} |
| 235 |
} |
| 236 |
} |
| 237 |
@@ -2017,7 +2017,7 @@ record_files (filenames, pattern, patter |
| 238 |
while (d != 0) |
| 239 |
{ |
| 240 |
struct dep *nextd = d->next; |
| 241 |
- free (d->name); |
| 242 |
+ hash_strfree (d->name); |
| 243 |
free ((char *)d); |
| 244 |
d = nextd; |
| 245 |
} |