Index: /trunk/src/kmk/Makefile.am
===================================================================
--- /trunk/src/kmk/Makefile.am	(revision 1437)
+++ /trunk/src/kmk/Makefile.am	(revision 1438)
@@ -125,4 +125,5 @@
 	-DCONFIG_WITH_WHICH \
 	-DCONFIG_WITH_EVALCTX \
+	-DCONFIG_WITH_MAKE_STATS \
 	-DCONFIG_PRETTY_COMMAND_PRINTING \
 	\
Index: /trunk/src/kmk/Makefile.kmk
===================================================================
--- /trunk/src/kmk/Makefile.kmk	(revision 1437)
+++ /trunk/src/kmk/Makefile.kmk	(revision 1438)
@@ -125,4 +125,5 @@
 	CONFIG_WITH_WHICH \
 	CONFIG_WITH_EVALCTX \
+	CONFIG_WITH_MAKE_STATS \
 	CONFIG_PRETTY_COMMAND_PRINTING \
 	\
Index: /trunk/src/kmk/function.c
===================================================================
--- /trunk/src/kmk/function.c	(revision 1437)
+++ /trunk/src/kmk/function.c	(revision 1438)
@@ -116,4 +116,12 @@
 
 static struct hash_table function_table;
+
+#ifdef CONFIG_WITH_MAKE_STATS
+unsigned long make_stats_allocations = 0;
+unsigned long make_stats_allocated = 0;
+unsigned long make_stats_allocated_sum = 0;
+unsigned long make_stats_ht_lookups = 0;
+unsigned long make_stats_ht_collisions = 0;
+#endif
 
 
@@ -3460,4 +3468,57 @@
 #endif  /* CONFIG_WITH_OS2_LIBPATH */
 
+#ifdef CONFIG_WITH_MAKE_STATS
+/* Retrieve make statistics. */
+static char *
+func_make_stats (char *o, char **argv, const char *funcname)
+{
+  char buf[512];
+  int len;
+
+  if (!argv[0] || (!argv[0][0] && !argv[1]))
+    {
+      len = sprintf (buf, "alloc-cur: %5lu %6luKB (/%3luMB)  hash: %5lu %2lu%%", 
+                     make_stats_allocations, 
+                     make_stats_allocated / 1024, 
+                     make_stats_allocated_sum / (1024*1024), 
+                     make_stats_ht_lookups,
+                     (make_stats_ht_collisions * 100) / make_stats_ht_lookups);
+      o = variable_buffer_output (o, buf, len);
+    }
+  else
+    { 
+      /* selective */
+      int i;
+      for (i = 0; argv[i]; i++)
+        {
+          unsigned long val;
+          if (i != 0)
+            o = variable_buffer_output (o, " ", 1);
+          if (!strcmp(argv[i], "allocations"))
+            val = make_stats_allocations;
+          else if (!strcmp(argv[i], "allocated"))
+            val = make_stats_allocated;
+          else if (!strcmp(argv[i], "allocated_sum"))
+            val = make_stats_allocated_sum;
+          else if (!strcmp(argv[i], "ht_lookups"))
+            val = make_stats_ht_lookups;
+          else if (!strcmp(argv[i], "ht_collisions"))
+            val = make_stats_ht_collisions;
+          else if (!strcmp(argv[i], "ht_collisions_pct"))
+            val = (make_stats_ht_collisions * 100) / make_stats_ht_lookups;
+          else
+            {  
+              o = variable_buffer_output (o, argv[i], strlen (argv[i]));
+              continue;
+            }
+
+          len = sprintf (buf, "%ld", val);
+          o = variable_buffer_output (o, buf, len);
+        }
+    }
+  return o;
+}
+#endif
+
 /* Lookup table for builtin functions.
 
@@ -3576,4 +3637,7 @@
   { STRING_SIZE_TUPLE("libpath"),       1,  2,  1,  func_os2_libpath},
 #endif
+#ifdef CONFIG_WITH_MAKE_STATS
+  { STRING_SIZE_TUPLE("make-stats"),    0, ~0,  0,  func_make_stats},
+#endif
 #ifdef KMK_HELPERS
   { STRING_SIZE_TUPLE("kb-src-tool"),   1,  1,  0,  func_kbuild_source_tool},
Index: /trunk/src/kmk/hash.c
===================================================================
--- /trunk/src/kmk/hash.c	(revision 1437)
+++ /trunk/src/kmk/hash.c	(revision 1438)
@@ -92,4 +92,7 @@
 
   ht->ht_lookups++;
+#ifdef CONFIG_WITH_MAKE_STATS
+  make_stats_ht_lookups++;
+#endif
   for (;;)
     {
@@ -111,4 +114,7 @@
 	    return slot;
 	  ht->ht_collisions++;
+#ifdef CONFIG_WITH_MAKE_STATS
+    make_stats_ht_collisions++;
+#endif
 	}
       if (!hash_2)
Index: /trunk/src/kmk/make.h
===================================================================
--- /trunk/src/kmk/make.h	(revision 1437)
+++ /trunk/src/kmk/make.h	(revision 1438)
@@ -690,2 +690,33 @@
 
 #endif /* __EMX__ (bird) */
+
+#ifdef CONFIG_WITH_MAKE_STATS
+extern unsigned long make_stats_allocations;
+extern unsigned long make_stats_allocated;
+extern unsigned long make_stats_allocated_sum;
+extern unsigned long make_stats_ht_lookups;
+extern unsigned long make_stats_ht_collisions;
+
+# ifdef __APPLE__
+#  include <malloc/malloc.h>
+#  define SIZE_OF_HEAP_BLOCK(ptr)   malloc_size(ptr)
+
+# elif defined(__linux__) /* glibc */
+#  include <malloc.h>
+#  define SIZE_OF_HEAP_BLOCK(ptr)   malloc_usable_size(ptr)
+
+# elif defined(_MSC_VER) || defined(__OS2__)
+#  define SIZE_OF_HEAP_BLOCK(ptr)   _msize(ptr)
+
+# else
+#  include <stdlib.h>
+#  define SIZE_OF_HEAP_BLOCK(ptr)   0
+#endif
+
+# if defined(CONFIG_WITH_MAKE_STATS) && !defined(ELECTRIC_HEAP)
+#  define free xfree
+extern void xfree (void *);
+# endif
+
+#endif
+
Index: /trunk/src/kmk/misc.c
===================================================================
--- /trunk/src/kmk/misc.c	(revision 1437)
+++ /trunk/src/kmk/misc.c	(revision 1438)
@@ -361,4 +361,9 @@
   if (result == 0)
     fatal (NILF, _("virtual memory exhausted"));
+#ifdef CONFIG_WITH_MAKE_STATS
+  make_stats_allocations++;
+  make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
+  make_stats_allocated_sum += SIZE_OF_HEAP_BLOCK (result);
+#endif
   return result;
 }
@@ -369,4 +374,8 @@
 {
   void *result;
+#ifdef CONFIG_WITH_MAKE_STATS
+  make_stats_allocated -= SIZE_OF_HEAP_BLOCK (ptr);
+  make_stats_allocated_sum -= SIZE_OF_HEAP_BLOCK (ptr);
+#endif
 
   /* Some older implementations of realloc() don't conform to ANSI.  */
@@ -376,4 +385,8 @@
   if (result == 0)
     fatal (NILF, _("virtual memory exhausted"));
+#ifdef CONFIG_WITH_MAKE_STATS
+  make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
+  make_stats_allocated_sum += SIZE_OF_HEAP_BLOCK (result);
+#endif
   return result;
 }
@@ -394,4 +407,9 @@
     fatal (NILF, _("virtual memory exhausted"));
 
+#ifdef CONFIG_WITH_MAKE_STATS
+  make_stats_allocations++;
+  make_stats_allocated += SIZE_OF_HEAP_BLOCK (result);
+  make_stats_allocated_sum += SIZE_OF_HEAP_BLOCK (result);
+#endif
 #ifdef HAVE_STRDUP
   return result;
@@ -924,2 +942,16 @@
     }
 }
+
+#if defined(CONFIG_WITH_MAKE_STATS) && !defined(ELECTRIC_HEAP)
+#undef free
+void xfree(void *ptr)
+{
+  if (ptr) 
+    {
+      make_stats_allocations--;
+      make_stats_allocated -= SIZE_OF_HEAP_BLOCK (ptr);
+      free (ptr);
+    }
+}
+#endif
+
Index: /trunk/src/kmk/variable.c
===================================================================
--- /trunk/src/kmk/variable.c	(revision 1437)
+++ /trunk/src/kmk/variable.c	(revision 1438)
@@ -1042,4 +1042,6 @@
   && defined (CONFIG_WITH_FILE_SIZE) \
   && defined (CONFIG_WITH_WHICH) \
+  && defined (CONFIG_WITH_EVALCTX) \
+  && defined (CONFIG_WITH_MAKE_STATS) \
   && defined (KMK_HELPERS)
   (void) define_variable ("KMK_FEATURES", 12,
@@ -1058,4 +1060,6 @@
                           " file-size"
                           " which"
+                          " evalctx"
+                          " make-stats"
                           " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one "
                           , o_default, 0);
@@ -1102,4 +1106,10 @@
   strcat (buf, " which");
 #  endif
+#  if defined (CONFIG_WITH_EVALCTX)
+  strcat (buf, " evalctx");
+#  endif
+#  if defined (CONFIG_WITH_MAKE_STATS)
+  strcat (buf, " make-stats");
+#  endif
 #  if defined (KMK_HELPERS)
   strcat (buf, " kb-src-tool kb-obj-base kb-obj-suff kb-src-prop kb-src-one");
