[m-rev.] for review: stack frame size stats

Zoltan Somogyi zs at cs.mu.OZ.AU
Fri Dec 21 16:54:21 AEDT 2001


For review by anyone.

Estimated hours taken: 4
Branches: main

Add a capability for measuring statistics about the stack frame usage
of a program.

configure.in:
	Find out the symbolic names of the max values for the 16 and 32 bit
	integer types.

runtime/mercury_conf.h.in:
	Include MR_INT_LEAST{16,32}_{MAX,UMAX} among the macros whose values
	are determined by autoconfiguration.

runtime/mercury_conf_param.h:
	Document MR_STACK_FRAME_STATS as a macro whose definition causes the
	program to collect statistics on stack frame sizes.

runtime/mercury_stacks.h:
	If MR_STACK_FRAME_STATS is defined, then record statistics every time
	we create a stack frame.

runtime/mercury_stacks.c:
	Define the global variables and functions needed for stack frame
	statistics.

runtime/mercury_heap_profile.h:
runtime/mercury_dword.h:
	Move the macros for managing 64-bit counters from
	mercury_heap_profile.h to a new header file, mercury_dword.h,
	since mercury_stacks.h now needs such counters too.

	Rewrite the macros to make fewer assumptions, using MR_INT_LEAST64_TYPE
	instead of "long long" and MR_INT_LEAST32_TYPE instead of "int".

	Add expression-like forms of some of the macros for use in
	mercury_stacks.h.

runtime/mercury_heap_profile.c:
	#include the new header file.

runtime/Mmakefile:
	Add the new header file to the list of header files.

runtime/mercury_wrapper.c:
	If MR_STACK_FRAME_STATS is defined, initialize the stack frame stats
	before execution starts and write out the statistics when execution
	ends.

tools/speedtest:
	Add an option that when set, causes the script to report stack frame
	stats for each variant being tested.

Zoltan.

cvs diff: Diffing .
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.286
diff -u -b -r1.286 configure.in
--- configure.in	2001/12/21 04:04:52	1.286
+++ configure.in	2001/12/21 05:14:50
@@ -1055,6 +1055,19 @@
 AC_DEFINE_UNQUOTED(MR_INT_LEAST32_TYPE, $mercury_cv_int_least32_type)
 MR_INT_LEAST32_TYPE=$mercury_cv_int_least32_type
 AC_SUBST(MR_INT_LEAST32_TYPE)
+
+if test "$mercury_cv_int_least32_type" = int; then
+	AC_DEFINE_UNQUOTED(MR_INT_LEAST32_MAX, INT_MAX)
+	AC_DEFINE_UNQUOTED(MR_INT_LEAST32_UMAX, UINT_MAX)
+elif test "$mercury_cv_int_least32_type" = long; then
+	AC_DEFINE_UNQUOTED(MR_INT_LEAST32_MAX, LONG_MAX)
+	AC_DEFINE_UNQUOTED(MR_INT_LEAST32_UMAX, ULONG_MAX)
+else
+	AC_MSG_ERROR("Cannot find the name of the max values for MR_INT_LEAST32_TYPE.")
+fi
+AC_SUBST(MR_INT_LEAST32_MAX)
+AC_SUBST(MR_INT_LEAST32_UMAX)
+
 #-----------------------------------------------------------------------------#
 AC_MSG_CHECKING(for an integer type of at least 16 bits)
 AC_CACHE_VAL(mercury_cv_int_least16_type,
@@ -1091,6 +1104,19 @@
 AC_DEFINE_UNQUOTED(MR_INT_LEAST16_TYPE, $mercury_cv_int_least16_type)
 MR_INT_LEAST16_TYPE=$mercury_cv_int_least16_type
 AC_SUBST(MR_INT_LEAST16_TYPE)
+
+if test "$mercury_cv_int_least16_type" = short; then
+	AC_DEFINE_UNQUOTED(MR_INT_LEAST16_MAX, SHRT_MAX)
+	AC_DEFINE_UNQUOTED(MR_INT_LEAST16_UMAX, USHRT_MAX)
+elif test "$mercury_cv_int_least16_type" = int; then
+	AC_DEFINE_UNQUOTED(MR_INT_LEAST16_MAX, INT_MAX)
+	AC_DEFINE_UNQUOTED(MR_INT_LEAST16_UMAX, UINT_MAX)
+else
+	AC_MSG_ERROR("Cannot find the name of the max value for MR_INT_LEAST16_TYPE.")
+fi
+AC_SUBST(MR_INT_LEAST16_MAX)
+AC_SUBST(MR_INT_LEAST16_UMAX)
+
 #-----------------------------------------------------------------------------#
 AC_MSG_CHECKING(the number of low tag bits available)
 AC_CACHE_VAL(mercury_cv_low_tag_bits,
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing library
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/Mmakefile,v
retrieving revision 1.77
diff -u -b -r1.77 Mmakefile
--- runtime/Mmakefile	2001/08/14 10:19:01	1.77
+++ runtime/Mmakefile	2001/12/20 15:15:45
@@ -47,6 +47,7 @@
 			mercury_deep_profiling_hand.h \
 			mercury_dummy.h		\
 			mercury_dlist.h		\
+			mercury_dword.h		\
 		  	mercury_engine.h	\
 			mercury_file.h		\
 			mercury_float.h		\
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.39
diff -u -b -r1.39 mercury_conf.h.in
--- runtime/mercury_conf.h.in	2001/12/11 09:01:19	1.39
+++ runtime/mercury_conf.h.in	2001/12/20 15:14:14
@@ -78,6 +78,16 @@
 #undef	MR_INT_LEAST16_TYPE
 
 /*
+** MR_INT_LEAST{16,32}_{MAX,UMAX}:
+** The symbolic names (defined in limits.h) of the maximum values for the
+** signed and unsigned forms of MR_INT_LEAST16_TYPE and MR_INT_LEAST32_TYPE.
+*/
+#undef	MR_INT_LEAST16_MAX
+#undef	MR_INT_LEAST16_UMAX
+#undef	MR_INT_LEAST32_MAX
+#undef	MR_INT_LEAST32_UMAX
+
+/*
 ** LOW_TAG_BITS: an integer, specifying the number of low-order tag bits
 ** we can use.  Normally this is the base-2 log of the word size in bytes.
 */
Index: runtime/mercury_conf_param.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.50
diff -u -b -r1.50 mercury_conf_param.h
--- runtime/mercury_conf_param.h	2001/12/10 06:50:10	1.50
+++ runtime/mercury_conf_param.h	2001/12/20 15:14:22
@@ -255,6 +255,11 @@
 ** MR_TABLE_STATISTICS
 ** Enable this if you want to gather statistics about the operation of the
 ** tabling system. The results are reported via io__report_tabling_stats.
+** 
+** MR_STACK_FRAME_STATS
+** If you want to gather statistics about the number and size of stack frames,
+** then set this macro to a string giving the name of the file to which which
+** the statistics should be appended when the program exits.
 */
 
 /*---------------------------------------------------------------------------*/
Index: runtime/mercury_dword.h
===================================================================
RCS file: mercury_dword.h
diff -N mercury_dword.h
--- /dev/null	Fri Dec  1 02:25:58 2000
+++ mercury_dword.h	Fri Dec 21 16:51:46 2001
@@ -0,0 +1,120 @@
+/*
+** Copyright (C) 1998, 2000-2001 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** File: mercury_dword.h
+** Author: zs.
+**
+** This module provides facilities for maintaining unsigned counters (dwords)
+** whose size is at least 64 bits. The reason why we need such counters is that
+** e.g. the amount of memory allocated by a program may be too big to be
+** represented using 32 bits, even on 32 bit platforms, in the presence of
+** e.g. garbage collection.
+*/
+
+/*---------------------------------------------------------------------------*/
+
+#ifndef MERCURY_DWORD_H
+#define MERCURY_DWORD_H
+
+/*---------------------------------------------------------------------------*/
+
+#ifdef MR_INT_LEAST64_TYPE
+
+  /*
+  ** This case is nice and simple.
+  */
+
+  typedef unsigned MR_INT_LEAST64_TYPE MR_dword;
+
+  #define MR_convert_dword_to_double(dword_form, double_form) \
+		((double_form) = (double) (dword_form))
+
+  #define MR_zero_dword(dword) \
+		((dword) = 0)
+
+  #define MR_increment_dword(dword, inc) \
+		((dword) += (inc))
+
+  #define MR_increment_dword_tmp(dword, inc, tmp) \
+		((dword) += (inc))
+
+  #define MR_add_two_dwords(src_dest_dword, src_dword) \
+		((src_dest_dword) += (src_dword))
+
+  #define MR_add_two_dwords_tmp(src_dest_dword, src_dword, tmp) \
+		((src_dest_dword) += (src_dword))
+
+#elif MR_INT_LEAST32_TYPE
+
+  /*
+  ** oh well, guess we have to do it the hard way :-(
+  */
+
+  typedef struct MR_dword
+  {
+	unsigned MR_INT_LEAST32_TYPE	MR_dword_low;
+	unsigned MR_INT_LEAST32_TYPE	MR_dword_high;
+  } MR_dword;
+
+  #include <limits.h>
+
+  #define MR_HIGHWORD_TO_DOUBLE	(((double) MR_INT_LEAST32_UMAX) + 1.0)
+
+  #define MR_convert_dword_to_double(dword_form, double_form) 		\
+	do {								\
+		double_form = (MR_HIGHWORD_TO_DOUBLE			\
+			* (double) (dword_form).MR_dword_high) 		\
+			+ (double) (dword_form).MR_dword_low;		\
+	} while (0)
+
+  #define MR_zero_dword(dword) 						\
+	do { 								\
+		(dword).MR_dword_low = 0;				\
+		(dword).MR_dword_high = 0;				\
+	} while (0)
+
+  #define MR_increment_dword(dword, inc) 				\
+	do { 								\
+		unsigned long	old_low_word = (dword).low_word;	\
+		(dword).low_word += (inc);				\
+		if ((dword).low_word < old_low_word) {			\
+			(dword).high_word += 1;				\
+		}							\
+	} while (0)
+
+  #define MR_increment_dword_tmp(dword, inc, low_tmp)			\
+	( 								\
+		low_tmp = (dword).MR_dword_low,				\
+		(dword).MR_dword_low += (inc),				\
+		((dword).MR_dword_low < low_tmp) ?			\
+			(dword).MR_dword_high += 1 : (void) 0		\
+	)
+
+  #define MR_add_two_dwords(src_dest_dword, src_dword) 			\
+	do { 								\
+		unsigned long	old_low_word = (src_dest_dword).low_word; \
+		(src_dest_dword).low_word += (src_dword).low_word;	\
+		if ((src_dest_dword).low_word < old_low_word) {		\
+			(src_dest_dword).high_word += 1;		\
+		}							\
+		(src_dest_dword).high_word += (src_dword).high_word;	\
+	} while (0)
+
+  #define MR_add_two_dwords_tmp(src_dest_dword, src_dword, low_tmp)	\
+	( 								\
+		low_tmp = (src_dest_dword).MR_dword_low; 		\
+		(src_dest_dword).MR_dword_low += (src_dword).MR_dword_low;\
+		((src_dest_dword).MR_dword_low < low_tmp) ?		\
+			(src_dest_dword).MR_dword_high += 1 : (void) 0,	\
+		(src_dest_dword).MR_dword_high += (src_dword).MR_dword_high\
+	)
+
+#else /* not MR_INT_LEAST32_TYPE */
+  #error "mercury_dword.h: neither MR_INT_LEAST64_TYPE nor MR_INT_LEAST32_TYPE"
+#endif /* not MR_INT_LEAST32_TYPE */
+
+#endif /* MERCURY_DWORD_H */
Index: runtime/mercury_heap_profile.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_heap_profile.c,v
retrieving revision 1.3
diff -u -b -r1.3 mercury_heap_profile.c
--- runtime/mercury_heap_profile.c	2000/08/03 06:18:44	1.3
+++ runtime/mercury_heap_profile.c	2001/12/20 15:14:27
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 1997, 1999-2000 The University of Melbourne.
+** Copyright (C) 1997, 1999-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 */
@@ -22,6 +22,7 @@
 #include <string.h>
 
 #include "mercury_prof_mem.h"
+#include "mercury_dword.h"
 #include "mercury_heap_profile.h"
 
 /* all fields of these variables are initialized to 0 */
Index: runtime/mercury_heap_profile.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_heap_profile.h,v
retrieving revision 1.3
diff -u -b -r1.3 mercury_heap_profile.h
--- runtime/mercury_heap_profile.h	2000/08/03 06:18:44	1.3
+++ runtime/mercury_heap_profile.h	2001/12/20 15:14:32
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 1998, 2000 The University of Melbourne.
+** Copyright (C) 1998, 2000-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 */
@@ -19,86 +19,10 @@
 #define MERCURY_HEAP_PROFILE_H
 
 #include "mercury_types.h"	/* for `MR_Code' */
+#include "mercury_dword.h"	/* for `MR_dword' */
 
 /*---------------------------------------------------------------------------*/
 
-/*
-** Due to garbage collection, the total amount of memory allocated can
-** exceed the amount of real or even virtual memory available.  Hence
-** the total amount of memory allocated by a long-running Mercury program
-** might not fit into a single 32-bit `unsigned long'.
-** Hence we record memory usage counts using either `unsigned long long',
-** if available, or otherwise using a pair of unsigned longs (ugh).
-*/
-
-#ifdef MR_HAVE_LONG_LONG
-
-  /* nice and simple */
-
-  typedef unsigned long long MR_dword;
-
-  #define MR_convert_dword_to_double(dword_form, double_form) \
-		((double_form) = (double) (dword_form))
-
-  #define MR_zero_dword(dword) \
-		((dword) = 0)
-
-  #define MR_increment_dword(dword, inc) \
-		((dword) += (inc))
-
-  #define MR_add_two_dwords(src_dest_dword, src_dword) \
-		((src_dest_dword) += (src_dword))
-
-#else /* not MR_HAVE_LONG_LONG */
-
-  /* oh well, guess we have to do it the hard way :-( */
-
-  typedef struct MR_dword
-  {
-	unsigned long	low_word;
-	unsigned long	high_word;
-  } MR_dword;
-
-  #include <limits.h>
-
-  #define MR_HIGHWORD_TO_DOUBLE	(((double) ULONG_MAX) + 1.0)
-
-  #define MR_convert_dword_to_double(dword_form, double_form) 		\
-	do {								\
-		double_form = (MR_HIGHWORD_TO_DOUBLE			\
-			* (double) (dword_form).high_word) 		\
-			+ (double) (dword_form).low_word;		\
-	} while (0)
-
-  #define MR_zero_dword(dword) 						\
-	do { 								\
-		(dword).low_word = 0;					\
-		(dword).high_word = 0;					\
-	} while (0)
-
-  #define MR_increment_dword(dword, inc) 				\
-	do { 								\
-		unsigned long	old_low_word = (dword).low_word;	\
-		(dword).low_word += (inc);				\
-		if ((dword).low_word < old_low_word) {			\
-			(dword).high_word += 1;				\
-		}							\
-	} while (0)
-
-  #define MR_add_two_dwords(src_dest_dword, src_dword) 			\
-	do { 								\
-		unsigned long	old_low_word = (src_dest_dword).low_word; \
-		(src_dest_dword).low_word += (src_dword).low_word;	\
-		if ((src_dest_dword).low_word < old_low_word) {		\
-			(src_dest_dword).high_word += 1;		\
-		}							\
-		(src_dest_dword).high_word += (src_dword).high_word;	\
-	} while (0)
-
-#endif /* not MR_HAVE_LONG_LONG */
-
-/*---------------------------------------------------------------------------*/
-
 /* type declarations */
 
 /*
@@ -119,6 +43,12 @@
 ** The tables of counters for each procedure is represented
 ** as a binary search tree.  Similarly for the table of counters
 ** for each type.
+**
+** Due to garbage collection, the total amount of memory allocated can exceed
+** the amount of real or even virtual memory available. Hence the total amount
+** of memory allocated by a long-running Mercury program might not fit into a
+** single 32-bit `unsigned long'. This is why we use MR_dwords, which are
+** at least 64 bits in size.
 */
 
 typedef	struct MR_memprof_counter
Index: runtime/mercury_stacks.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stacks.c,v
retrieving revision 1.7
diff -u -b -r1.7 mercury_stacks.c
--- runtime/mercury_stacks.c	2000/11/23 02:00:41	1.7
+++ runtime/mercury_stacks.c	2001/12/21 05:43:48
@@ -1,12 +1,12 @@
 /*
-** Copyright (C) 1998-2000 The University of Melbourne.
+** Copyright (C) 1998-2001 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 */
 
 /*
-** This file contains code for manipulating the generator stack and the cut
-** stack.
+** This file contains code for printing statistics about stack frame sizes,
+** and for manipulating the generator stack and the cut stack.
 **
 ** The generator stack has one entry for each call to a minimal model tabled
 ** procedure that is (a) acting as the generator for its subgoal and (b) is
@@ -32,6 +32,78 @@
 #include "mercury_imp.h"
 #include <stdio.h>
 
+#ifdef	MR_STACK_FRAME_STATS
+
+#include "mercury_dword.h"
+
+MR_dword			MR_det_frame_count;
+MR_dword			MR_det_frame_total_size;
+MR_Word				*MR_det_frame_max;
+MR_dword			MR_non_frame_count;
+MR_dword			MR_non_frame_total_size;
+MR_Word				*MR_non_frame_max;
+
+unsigned MR_INT_LEAST32_TYPE	MR_old_low_tmp;
+
+void
+MR_init_stack_frame_stats(void)
+{
+	MR_zero_dword(MR_det_frame_count);
+	MR_zero_dword(MR_det_frame_total_size);
+	MR_zero_dword(MR_non_frame_count);
+	MR_zero_dword(MR_non_frame_total_size);
+	MR_det_frame_max = MR_CONTEXT(MR_ctxt_detstack_zone)->min;
+	MR_non_frame_max = MR_CONTEXT(MR_ctxt_nondetstack_zone)->min;
+}
+
+void
+MR_print_stack_frame_stats(void)
+{
+	FILE	*fp;
+	double	det_frame_count;
+	double	det_frame_total_size;
+	double	non_frame_count;
+	double	non_frame_total_size;
+
+	fp = fopen(MR_STACK_FRAME_STATS, "a");
+	if (fp == NULL) {
+		return;
+	}
+
+	MR_convert_dword_to_double(MR_det_frame_count,
+		det_frame_count);
+	MR_convert_dword_to_double(MR_det_frame_total_size,
+		det_frame_total_size);
+	MR_convert_dword_to_double(MR_non_frame_count,
+		non_frame_count);
+	MR_convert_dword_to_double(MR_non_frame_total_size,
+		non_frame_total_size);
+
+	fprintf(fp, "number of det stack frames created:  %.0f\n",
+		det_frame_count);
+	fprintf(fp, "number of words in det stack frames: %.0f\n",
+		det_frame_total_size);
+	fprintf(fp, "average size of a det stack frame:   %.3f\n",
+		det_frame_total_size / det_frame_count);
+	fprintf(fp, "max size of det stack:               %ld\n",
+		(long) (MR_det_frame_max
+		       - MR_CONTEXT(MR_ctxt_detstack_zone)->min));
+
+	fprintf(fp, "number of non stack frames created:  %.0f\n",
+		non_frame_count);
+	fprintf(fp, "number of words in non stack frames: %.0f\n",
+		non_frame_total_size);
+	fprintf(fp, "average size of a non stack frame:   %.3f\n",
+		non_frame_total_size / non_frame_count);
+	fprintf(fp, "max size of non stack:               %ld\n",
+		(long) (MR_non_frame_max
+			- MR_CONTEXT(MR_ctxt_nondetstack_zone)->min));
+
+	(void) fclose(fp);
+}
+
+#endif	/* MR_STACK_FRAME_STATS */
+
 #ifdef	MR_USE_MINIMAL_MODEL
 
 static	void	MR_print_gen_stack_entry(FILE *fp, MR_Integer i);
@@ -208,4 +280,4 @@
 	}
 }
 
-#endif
+#endif	/* MR_USE_MINIMAL_MODEL */
Index: runtime/mercury_stacks.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stacks.h,v
retrieving revision 1.30
diff -u -b -r1.30 mercury_stacks.h
--- runtime/mercury_stacks.h	2001/05/31 06:00:16	1.30
+++ runtime/mercury_stacks.h	2001/12/21 05:46:15
@@ -17,6 +17,53 @@
 #include "mercury_tabling.h"
 #include "mercury_engine.h"
 
+#ifdef	MR_STACK_FRAME_STATS
+  #include "mercury_dword.h"
+
+  extern MR_dword	MR_det_frame_count;
+  extern MR_dword	MR_det_frame_total_size;
+  extern MR_Word	*MR_det_frame_max;
+  extern MR_dword	MR_non_frame_count;
+  extern MR_dword	MR_non_frame_total_size;
+  extern MR_Word	*MR_non_frame_max;
+
+  /*
+  ** This temporary is for use in the MR_increment_dword_tmp macro only.
+  ** Making the temporary variable global (nonlocal to the macro) allows
+  ** the macro have the form of an expression, instead of a statement,
+  ** without relying on GNU extensions to C.
+  */
+  extern unsigned MR_INT_LEAST32_TYPE	MR_old_low_tmp;
+
+  extern void		MR_init_stack_frame_stats(void);
+  extern void		MR_print_stack_frame_stats(void);
+
+  #define MR_collect_det_frame_stats(size)				\
+	(								\
+		MR_increment_dword_tmp(MR_det_frame_count, 		\
+			1, MR_old_low_tmp),				\
+		MR_increment_dword_tmp(MR_det_frame_total_size,		\
+			(size), MR_old_low_tmp),			\
+		((MR_sp > MR_det_frame_max) ?				\
+		 	(MR_det_frame_max = MR_sp) : (void) 0)		\
+	)
+  #define MR_collect_non_frame_stats(slots)				\
+	(								\
+		MR_increment_dword_tmp(MR_non_frame_count,		\
+			1, MR_old_low_tmp),				\
+		MR_increment_dword_tmp(MR_non_frame_total_size, 	\
+			(slots) + MR_NONDET_FIXED_SIZE, MR_old_low_tmp),\
+		((MR_maxfr > MR_non_frame_max) ?			\
+		 	(MR_non_frame_max = MR_maxfr) : (void) 0)	\
+	)
+
+#else	/* !MR_STACK_FRAME_STATS */
+
+  #define MR_collect_det_frame_stats(size)		((void) 0)
+  #define MR_collect_non_frame_stats(slots)		((void) 0)
+
+#endif	/* !MR_STACK_FRAME_STATS */
+
 /*---------------------------------------------------------------------------*/
 
 /* DEFINITIONS FOR MANIPULATING THE DET STACK */
@@ -30,6 +77,7 @@
 				MR_debugincrsp(n, MR_sp),	\
 				MR_sp = MR_sp + (n),		\
 				MR_detstack_overflow_check(),	\
+				MR_collect_det_frame_stats(n),	\
 				(void)0				\
 			)
 
@@ -45,6 +93,7 @@
 				MR_debugincrsp(n, MR_sp),	\
 				MR_sp = MR_sp + (n),		\
 				MR_detstack_overflow_check(),	\
+				MR_collect_det_frame_stats(n),	\
 				(void)0				\
 			)
 
@@ -124,6 +173,7 @@
 				MR_redofr_slot(MR_curfr) = MR_curfr;	\
 				MR_debugmkframe(predname);		\
 				MR_nondstack_overflow_check();		\
+				MR_collect_non_frame_stats(numslots);	\
 			} while (0)
 
 /* just like mkframe, but also reserves space for a struct     */
@@ -145,6 +195,7 @@
 		MR_redofr_slot(MR_curfr) = MR_curfr;			\
 		MR_debugmkframe(predname);				\
 		MR_nondstack_overflow_check();				\
+		MR_collect_non_frame_stats(numslots);			\
 	} while (0)
 
 #define	MR_mktempframe(redoip)						\
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.92
diff -u -b -r1.92 mercury_wrapper.c
--- runtime/mercury_wrapper.c	2001/12/04 00:44:35	1.92
+++ runtime/mercury_wrapper.c	2001/12/21 05:44:07
@@ -328,6 +328,10 @@
 	process_args(argc, argv);
 	process_environment_options();
 
+#ifdef	MR_STACK_FRAME_STATS
+	MR_init_stack_frame_stats();
+#endif	/* MR_STACK_FRAME_STATS */
+
 	/*
 	** Some of the rest of this function may call Mercury code
 	** that may have been compiled with tracing (e.g. the initialization
@@ -1193,6 +1197,10 @@
 #ifdef	MR_TYPE_CTOR_STATS
 	MR_print_type_ctor_stats();
 #endif
+
+#ifdef	MR_STACK_FRAME_STATS
+	MR_print_stack_frame_stats();
+#endif	/* MR_STACK_FRAME_STATS */
 
 	/*
 	** Save the Mercury registers and
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
Index: tools/speedtest
===================================================================
RCS file: /home/mercury1/repository/mercury/tools/speedtest,v
retrieving revision 1.12
diff -u -b -r1.12 speedtest
--- tools/speedtest	2001/08/09 05:31:46	1.12
+++ tools/speedtest	2001/12/20 23:42:22
@@ -7,6 +7,7 @@
 cmd="mmc -C -O2 -I../compiler --no-lazy-code make_hlds.m"
 debug=false
 size=false
+framesizefile=""
 
 while test $# -gt 0
 do
@@ -20,6 +21,11 @@
 	-d)
 		debug=true ;;
 
+	-f)
+		framesizefile="$2" ; shift ;;
+	-f*)
+		framesizefile="` expr $1 : '-f\(.*\)' `" ;;
+
 	-n)
 		limit="$2" ; shift ;;
 	-n*)
@@ -84,6 +90,11 @@
 	count=1
 	while test $count -le $limit
 	do
+		if test "$framesizefile" != ""
+		then
+			rm $framesizefile > /dev/null 2>&1
+		fi
+
 		briefname=`echo "$file" | sed "s:batch/$batch.::"`
 		$ECHO -n "$briefname "
 		if $debug
@@ -98,8 +109,16 @@
 			mv Deep.data ../batch/Deep.data.`basename $file .gz`.run$count
 		fi
 
+		if test "$count" -eq 1 -a "$framesizefile" != ""
+		then
+			echo
+			cat $framesizefile
+			echo
+		fi
+
 		count=`expr $count + 1`
 	done
+
 	cd $root
 	gzip $file
 done
cvs diff: Diffing trace
cvs diff: Diffing util
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list