Index: trunk/src/kmk/incdep.c
===================================================================
--- trunk/src/kmk/incdep.c	(revision 1853)
+++ trunk/src/kmk/incdep.c	(revision 1854)
@@ -85,4 +85,12 @@
 *   Structures and Typedefs                                                    *
 *******************************************************************************/
+struct incdep_strcache_entry
+{
+    unsigned int length;
+    unsigned int alignment;
+    unsigned long hash1;
+    unsigned long hash2;
+    char str[1];
+};
 
 struct incdep_variable_in_set
@@ -90,6 +98,5 @@
     struct incdep_variable_in_set *next;
     /* the parameters */
-    char *name;                     /* xmalloc'ed -> strcache */
-    unsigned int name_length;
+    struct incdep_strcache_entry *name_entry;
     const char *value;              /* xmalloc'ed */
     unsigned int value_length;
@@ -106,6 +113,5 @@
     /* the parameters */
     const struct floc *flocp;       /* NILF */
-    char *name;                     /* xmalloc'ed -> strcache */
-    unsigned int name_length;       /* (not an actual parameter) */
+    struct incdep_strcache_entry *name_entry;
     char *value;                    /* xmalloc'ed, free it */
     unsigned int value_length;
@@ -120,8 +126,8 @@
 
     /* the parameters */
-    struct nameseq *filenames;      /* only one file? its name needs be strcache'ed */
+    struct nameseq *filenames;      /* One only, its name is a strcache entry. */
     const char *pattern;            /* NULL */
     const char *pattern_percent;    /* NULL */
-    struct dep *deps;               /* names need to be strcache'ed */
+    struct dep *deps;               /* All the names are strcache entries. */
     unsigned int cmds_started;      /* 0 */
     char *commands;                 /* NULL */
@@ -665,4 +671,16 @@
 
 #ifdef PARSE_IN_WORKER
+/* Flushes a strcache entry returning the actual string cache entry.
+   The input is freed! */
+static const char *
+incdep_flush_strcache_entry (const void *pv_entry)
+{
+  struct incdep_strcache_entry *entry = (struct incdep_strcache_entry *)pv_entry;
+  const char *result;
+  result = strcache_add_prehashed (entry->str, entry->length, entry->hash1, entry->hash2);
+  free (entry);
+  return result;
+}
+
 /* Flushes the recorded instructions. */
 static void
@@ -681,6 +699,7 @@
       {
         void *free_me = rec_vis;
-        define_variable_in_set (strcache_add_len (rec_vis->name, rec_vis->name_length),
-                                rec_vis->name_length,
+        unsigned int name_length = rec_vis->name_entry->length;
+        define_variable_in_set (incdep_flush_strcache_entry (rec_vis->name_entry),
+                                name_length,
                                 rec_vis->value,
                                 rec_vis->value_length,
@@ -690,5 +709,4 @@
                                 rec_vis->set,
                                 rec_vis->flocp);
-        incdep_xfree (cur, rec_vis->name);
         rec_vis = rec_vis->next;
         incdep_xfree (cur, free_me);
@@ -705,5 +723,5 @@
         void *free_me = rec_vd;
         do_variable_definition_2 (rec_vd->flocp,
-                                  strcache_add_len(rec_vd->name, rec_vd->name_length),
+                                  incdep_flush_strcache_entry (rec_vd->name_entry),
                                   rec_vd->value,
                                   rec_vd->value_length,
@@ -713,5 +731,4 @@
                                   rec_vd->flavor,
                                   rec_vd->target_var);
-        incdep_xfree (cur, rec_vd->name);
         rec_vd = rec_vd->next;
         incdep_xfree (cur, free_me);
@@ -728,16 +745,8 @@
         void *free_me = rec_f;
         struct dep *dep;
-        const char *newname;
 
         for (dep = rec_f->deps; dep; dep = dep->next)
-          {
-            newname = strcache_add (dep->name);
-            free ((char *)dep->name);
-            dep->name = newname;
-          }
-
-        newname = strcache_add (rec_f->filenames->name);
-        incdep_xfree (cur, (char *)rec_f->filenames->name);
-        rec_f->filenames->name = newname;
+          dep->name = incdep_flush_strcache_entry (dep->name);
+        rec_f->filenames->name = incdep_flush_strcache_entry (rec_f->filenames->name);
 
         record_files (rec_f->filenames,
@@ -790,10 +799,13 @@
   else
     {
-      /* Duplicate the string. The other recorders knows which arguments
-         needs to be added to the string cache later. */
-      char *newstr = incdep_xmalloc (cur, len + 1);
-      memcpy (newstr, str, len);
-      newstr[len] = '\0';
-      ret = newstr;
+      /* Allocate a strcache record for it, pre-hashing the string to save
+         time later on in the main thread. */
+      struct incdep_strcache_entry *entry = incdep_xmalloc (cur, sizeof (*entry) + len);
+      memcpy (entry->str, str, len);
+      entry->str[len] = '\0';
+      entry->length = len;
+      strcache_prehash_str (entry->str, &entry->hash1, &entry->hash2);
+
+      ret = (const char *)entry;
     }
   return ret;
@@ -823,6 +835,5 @@
     {
       struct incdep_variable_in_set *rec = incdep_xmalloc (cur, sizeof (*rec));
-      rec->name = (char *)name;
-      rec->name_length = name_length;
+      rec->name_entry = (struct incdep_strcache_entry *)name;
       rec->value = value;
       rec->value_length = value_length;
@@ -863,6 +874,5 @@
       struct incdep_variable_def *rec = incdep_xmalloc (cur, sizeof (*rec));
       rec->flocp = flocp;
-      rec->name = (char *)name;
-      rec->name_length = name_length;
+      rec->name_entry = (struct incdep_strcache_entry *)name;
       rec->value = value;
       rec->value_length = value_length;
Index: trunk/src/kmk/make.h
===================================================================
--- trunk/src/kmk/make.h	(revision 1853)
+++ trunk/src/kmk/make.h	(revision 1854)
@@ -504,4 +504,10 @@
 const char *strcache_add_len (const char *str, int len);
 int strcache_setbufsize (int size);
+#ifdef CONFIG_WITH_INCLUDEDEP
+const char *strcache_add_prehashed (const char *str, int len,
+                                    unsigned long hash1, unsigned long hash2);
+void strcache_prehash_str (const char *str, unsigned long *hash1p,
+                           unsigned long *hash2p);
+#endif
 #ifdef CONFIG_WITH_VALUE_LENGTH
 MY_INLINE unsigned int strcache_get_len (const char *str)
Index: trunk/src/kmk/strcache.c
===================================================================
--- trunk/src/kmk/strcache.c	(revision 1853)
+++ trunk/src/kmk/strcache.c	(revision 1854)
@@ -131,11 +131,22 @@
 
 #ifdef CONFIG_WITH_VALUE_LENGTH
+/* Hackish globals for passing data to the hash functions.
+   There isn't really any other way without running the
+   risk of breaking rehashing. */
 static const char *lookup_string;
 static unsigned int lookup_string_len;
-#endif
+# ifdef CONFIG_WITH_INCLUDEDEP
+static unsigned long lookup_string_hash1;
+static unsigned long lookup_string_hash2;
+# endif /* CONFIG_WITH_INCLUDEDEP */
+#endif /* CONFIG_WITH_VALUE_LENGTH */
 
 static unsigned long
 str_hash_1 (const void *key)
 {
+#ifdef CONFIG_WITH_INCLUDEDEP
+  if ((const char *) key == lookup_string && lookup_string_hash1)
+    return lookup_string_hash1;
+#endif
   return_ISTRING_HASH_1 ((const char *) key);
 }
@@ -144,4 +155,8 @@
 str_hash_2 (const void *key)
 {
+#ifdef CONFIG_WITH_INCLUDEDEP
+  if ((const char *) key == lookup_string && lookup_string_hash2)
+    return lookup_string_hash2;
+#endif
   return_ISTRING_HASH_2 ((const char *) key);
 }
@@ -157,5 +172,5 @@
      kBuild scenario.  */
 
-  if (x == lookup_string)
+  if ((const char *) x == lookup_string)
     {
       assert (lookup_string_len == strlen ((const char *)x));
@@ -237,4 +252,39 @@
 }
 
+#ifdef CONFIG_WITH_INCLUDEDEP
+
+/* A special variant used by the includedep worker threads, it off loads
+   the main thread when it adds the strings to the cache later. */
+const char *
+strcache_add_prehashed (const char *str, int len, unsigned long hash1,
+                        unsigned long hash2)
+{
+  const char *retstr;
+
+  assert (hash1 == str_hash_1 (str));
+  assert (hash2 == str_hash_2 (str));
+
+  lookup_string_hash1 = hash1;
+  lookup_string_hash2 = hash2;
+
+  retstr = add_hash (str, len);
+
+  lookup_string_hash1 = 0;
+  lookup_string_hash2 = 0;
+
+  return retstr;
+}
+
+/* Performs the prehashing for use with strcache_add_prehashed(). */
+void
+strcache_prehash_str (const char *str, unsigned long *hash1p,
+                      unsigned long *hash2p)
+{
+  *hash1p = str_hash_1 (str);
+  *hash2p = str_hash_2 (str);
+}
+
+#endif /* CONFIG_WITH_INCLUDEDEP */
+
 int
 strcache_setbufsize(int size)
