for review again: reorganize label table, reduce executable sizes
Zoltan Somogyi
zs at cs.mu.OZ.AU
Thu Jul 2 10:32:16 AEST 1998
Estimated hours taken: 24
Reorganize the label table to better fit the needs of accurate gc
and the tracer, and reduce the size of executables.
With these changes, the size of hello world, compiled with static
Mercury libraries but dynamic C libraries, goes from 150+ Kb to
138+ Kb, much of which is beyond our control (e.g. Boehm gc).
runtime/mercury_label.[ch]:
The old label table contained both entry labels and internal labels,
even though they had different kinds of layouts associated with them
(proc layouts and label layouts respectively). The two kinds of labels
have different usage patterns. Internal labels are needed for stack
walking, which requires random access by exact label address. Entry
labels are needed for finding which procedure a program counter is in
for accurate GC, which requires lower-bound inexact search.
The module now has two separate data structures for the two
different kinds of labels. Internal labels are in a hash table,
as before. Entry labels are in an array (resized on demand),
which is sorted for binary search. The entry label array and
its associated functions are present only if they are needed.
runtime/mercury_goto.h:
Call the new functions in mercury_label.c from the
init_{local,label,entry}{,_sl} macros.
runtime/mercury_misc.[ch]
Use the new functions in mercury_label. Fix some software rot,
so that the code now compiles with MR_DEBUG_GOTOS. (It still does not
compile with MR_LOWLEVEL_DEBUG, but the fix for that would conflict
with Tom's planned change to zone handling, so that fix should be
done after Tom is done.)
Note that mercury_misc.c still defines newmem() and oldmem()
although they are declared in mercury_std.h.
runtime/mercury_stack_trace.c:
Use the new functions in mercury_label. As a result, we also need
to make a few more pointers const.
runtime/mercury_table.[ch]:
Add a new traversal predicate to support a new function in
mercury_label.c. (That function is not used yet, but will be soon.)
runtime/mercury_trace.[ch]:
runtime/mercury_trace_base.[ch]:
Split the old mercury_trace module into two. The functions and
variables that will always be linked in (because they are referenced
from modules such as mercury_wrapper which are always needed) are
now in mercury_trace_base; the other functions and variables
stay in mercury_trace. This way, mercury_trace.o will be linked in
only if some module was compiled with execution tracing. Since
mercury_trace.o drags in mercury_trace_internal.o which drags in
everything needed for printing arbitrary terms (which is a lot),
this can be a significant win.
runtime/Mmakefile:
Include the new module in the library.
runtime/mercury_wrapper.c:
runtime/mercury_conf_param.h:
Remove some obsolete MERCURY_OPTIONS options, which would be
difficult to support with the new label table.
Replace the long help message for malformed MERCURY_OPTIONS
environment variables with a pointer to the user's guide.
This saves about 1 Kb on every executable.
runtime/mercury_conf_param.h:
Document MR_STACK_TRACE_THIS_MODULE.
util/mkinit.c:
Add a new flag, -i. If this flag is given, include the initialization
code regardless of grade. If it is not given, include the init code
only if the grade requires it.
The -i should be given if you want the executable to support stack
tracing, or uplevel printing in execution tracing, at the cost of
making the executable link in the init functions of all the modules
in the library.
Put the option handling code in alphabetical order.
Fix the wrong default name of the entry point. (It only worked because
c2init was always overriding the default.)
scripts/c2init.in:
Pass through the -i flag to mkinit.
Put the option handling code in alphabetical order.
compiler/mercury_compile.m:
If the trace level specifies any kind of tracing, pass -i to c2init.
tests/debugger/Mmakefile:
Add -i to the c2init flags.
tests/debugger/*
Update the other half the test cases (those which assume a traced
library) to conform to the changes in the debugger interface.
The first half were updated earlier.
doc/user_guide.texi:
In the environment variable section, modify the entry for
MERCURY_OPTIONS to document all the options it makes sense
for non-developers to use.
Slight changes to two other parts of the guide to reduce duplication
with the new material.
Zoltan.
cvs diff: Diffing .
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/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing bytecode
cvs diff: Diffing bytecode/test
cvs diff: Diffing compiler
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.101
diff -u -u -r1.101 mercury_compile.m
--- mercury_compile.m 1998/07/01 04:09:37 1.101
+++ mercury_compile.m 1998/07/01 04:41:41
@@ -2359,7 +2359,13 @@
% create the initialization C file
maybe_write_string(Verbose, "% Creating initialization file...\n"),
join_module_list(Modules, ".m", ["> ", InitCFileName], MkInitCmd0),
- { string__append_list(["c2init " | MkInitCmd0], MkInitCmd) },
+ globals__io_get_trace_level(TraceLevel),
+ { trace_level_trace_interface(TraceLevel, yes) ->
+ CmdPrefix = "c2init -i "
+ ;
+ CmdPrefix = "c2init "
+ },
+ { string__append_list([CmdPrefix | MkInitCmd0], MkInitCmd) },
invoke_system_command(MkInitCmd, MkInitOK),
maybe_report_stats(Stats),
( { MkInitOK = no } ->
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.127
diff -u -u -r1.127 user_guide.texi
--- user_guide.texi 1998/07/01 04:10:14 1.127
+++ user_guide.texi 1998/07/01 04:42:09
@@ -1185,30 +1185,24 @@
@node Time profiling methods
@section Time profiling methods
-By setting the environment variable MERCURY_OPTIONS,
-which is used for passing options to the Mercury runtime system,
-you can control how the Mercury profiler measures the time spent.
-The default (@samp{-Tp}) is to count time spent executing the process,
-including time spent by the system performing operations on behalf of
-the process, but not including time that the process was suspended
+You can control whether profiling measures
+real (elapsed) time, user time plus system time, or user time only,
+by including the options -Tr, -Tp, or -Tv respectively
+in the environment variable MERCURY_OPTIONS
+when you run the program to be profiled.
+ at c (See the environment variables section below.)
+
+The default is user time plus system time,
+which counts all time spent executing the process,
+including time spent by the operating system performing
+working on behalf of the process,
+but not including time that the process was suspended
(e.g. due to time slicing, or while waiting for input).
-Using @samp{-Tv} counts only time spent executing the process.
-Using @samp{-Tr} counts all elapsed time, even including time that
-the process was suspended.
+When measuring real time, profiling counts
+even periods during which the process was suspended.
+When measuring user time only, profiling does not count
+time inside the operating system at all.
- at table @asis
- at item @samp{-Tr}
-Profile real (elapsed) time (using ITIMER_REAL).
- at item @samp{-Tv}
-Profile user time (using ITIMER_VIRTUAL).
- at item @samp{-Tp}
-Profile user time plus system time (using ITIMER_PROF).
-This is the default.
- at end table
-
-Currently, the @samp{-Tv} and @samp{-Tp} options don't work on Windows,
-so on Windows you must explicitly specify @samp{-Tr}.
-
@node Creating the profile
@section Creating the profile
@@ -2713,14 +2707,6 @@
The default grade to use if no @samp{--grade} option is specified.
@sp 1
- at item MERCURY_OPTIONS
-A list of options for the Mercury runtime that gets
-linked into every Mercury program.
-Options are available to set the size of the different memory
-areas, and to enable various debugging traces.
-Set @samp{MERCURY_OPTIONS} to @samp{-h} for help.
-
- at sp 1
@item MERCURY_C_INCL_DIR
Directory for the C header files for the Mercury runtime system (@file{*.h}).
This environment variable is used
@@ -2809,6 +2795,82 @@
@sp 1
@item MERCURY_MKINIT
Filename of the program to create the @file{*_init.c} file.
+
+ at sp 1
+ at item MERCURY_OPTIONS
+A list of options for the Mercury runtime that gets
+linked into every Mercury program.
+Their meanings are as follows.
+
+ at sp 1
+ at table @code
+
+ at c @item -a
+ at c @item -c
+
+ at item -C @var{size}
+Tells the runtime system
+to optimize the locations of the starts of the various data areas
+for a primary data cache of @var{size} kilobytes.
+The optimization consists of arranging the starts of the areas
+to differ as much as possible modulo this size.
+
+ at c @item -d @var{debugflag}
+
+ at sp 1
+ at item -D @var{debugger}
+Enables execution tracing of the program,
+via the internal debugger if @var{debugger} is @samp{i}
+and via the external debugger if @var{debugger} is @samp{e}.
+ at c The mdb script works by including -Di in MERCURY_OPTIONS.
+
+ at sp 1
+ at item -p
+Disables profiling in an executable built in a profiling grade.
+
+ at sp 1
+ at item -P @var{num}
+Tells the runtime system to use @var{num} threads
+if the program was build in a parallel grade.
+
+ at c @item -r
+
+ at sp 1
+ at item -s @var{area} @var{size}
+Tells the runtime system to set the size of one area of the runtime system,
+where @var{area} must be one of @samp{h} (standing for heap),
+ at samp{d} (standing for deterministic stack),
+ at samp{n} (standing for nondeterministic stack)
+and, in grades with trailing, @samp{t} (standing for trail),
+to @var{size} kilobytes.
+
+ at c @item -t
+
+ at sp 1
+ at item -T @var{time_method}
+If the executable is in a grade that includes time profiling,
+specifies what time is counted in the profile.
+ at var{time_method} must have one of the following values:
+
+ at sp 1
+ at table @code
+ at item @samp{r}
+Profile real (elapsed) time (using ITIMER_REAL).
+ at item @samp{p}
+Profile user time plus system time (using ITIMER_PROF).
+This is the default.
+ at item @samp{v}
+Profile user time (using ITIMER_VIRTUAL).
+ at end table
+
+ at sp 1
+Currently, the @samp{-Tp} and @samp{-Tv} options don't work on Windows,
+so on Windows you must explicitly specify @samp{-Tr}.
+
+ at c @item -x
+ at c @item -z @var{area} @var{size}
+
+ at end table
@end table
cvs diff: Diffing extras
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/graphics
cvs diff: Diffing extras/graphics/Togl-1.2
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/odbc
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
Index: runtime/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/Mmakefile,v
retrieving revision 1.30
diff -u -u -r1.30 Mmakefile
--- Mmakefile 1998/06/09 02:07:45 1.30
+++ Mmakefile 1998/06/30 06:36:10
@@ -14,7 +14,7 @@
#-----------------------------------------------------------------------------#
CFLAGS = -I$(MERCURY_DIR)/runtime -I$(MERCURY_DIR)/boehm_gc -g \
- $(DLL_CFLAGS) $(EXTRA_CFLAGS)
+ $(DLL_CFLAGS) $(EXTRA_CFLAGS)
MGNUC = MERCURY_C_INCL_DIR=. $(SCRIPTS_DIR)/mgnuc
MGNUCFLAGS = --no-ansi $(EXTRA_MGNUCFLAGS) $(CFLAGS)
MOD2C = $(SCRIPTS_DIR)/mod2c
@@ -67,6 +67,7 @@
mercury_thread.h \
mercury_timing.h \
mercury_trace.h \
+ mercury_trace_base.h \
mercury_trace_external.h \
mercury_trace_internal.h \
mercury_trace_util.h \
@@ -118,6 +119,7 @@
mercury_table_type_info.c\
mercury_timing.c \
mercury_trace.c \
+ mercury_trace_base.c \
mercury_trace_external.c \
mercury_trace_internal.c \
mercury_trace_util.c \
Index: runtime/mercury_conf_param.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.5
diff -u -u -r1.5 mercury_conf_param.h
--- mercury_conf_param.h 1998/06/08 08:26:58 1.5
+++ mercury_conf_param.h 1998/07/01 10:31:18
@@ -47,7 +47,7 @@
** COMPACT_ARGS
** NO_TYPE_LAYOUT
** BOXED_FLOAT
-** USE_TRAIL
+** MR_USE_TRAIL
** See the documentation for
** --gcc-global-registers
** --gcc-non-local-gotos
@@ -91,8 +91,16 @@
** Debugging options:
**
** MR_STACK_TRACE
-** Enable stuff needed so that error/1 (and co.) can print out
-** stack traces.
+** Require the inclusion of the layout information needed by error/1
+** and the debugger to print stack traces. This effect is achieved by
+** including MR_STACK_TRACE in the mangled grade (see mercury_grade.h).
+**
+** MR_STACK_TRACE_THIS_MODULE
+** Include the layout information needed by error/1 and the debugger
+** to print stack traces. Unlike MR_STACK_TRACE, this does not affect
+** the mangled grade, so it can be specified on a module-by-module basis.
+** (When a stack trace encounters a stack frame created by code from a
+** module which does not have layout information, the trace stops.)
**
** MR_REQUIRE_TRACING
** Require that all Mercury procedures linked in should be compiled
@@ -143,16 +151,6 @@
**
** PROFILE_MEMORY
** Enables profiling of memory usage.
-*/
-
-/*
-** Miscellaneous options:
-**
-** MR_CHOOSE_ENTRY_POINT
-** Enables support for the `-w' (entry point) command
-** in the MERCURY_OPTIONS environment variable.
-** (`-w' also happens to work if you set certain other
-** options instead, include MR_LOWLEVEL_DEBUG.)
*/
/*---------------------------------------------------------------------------*/
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.10
diff -u -u -r1.10 mercury_goto.h
--- mercury_goto.h 1998/06/08 08:27:01 1.10
+++ mercury_goto.h 1998/06/30 06:38:48
@@ -12,6 +12,7 @@
#include "mercury_conf.h"
#include "mercury_types.h" /* for `Code *' */
#include "mercury_debug.h" /* for debuggoto() */
+#include "mercury_label.h" /* for insert_{entry,internal}_label() */
#define paste(a,b) a##b
#define stringify(string) #string
@@ -19,13 +20,15 @@
#define skip(label) paste(skip_,label)
#if defined(MR_USE_STACK_LAYOUTS)
- #define MR_STACK_LAYOUT(label) (Word *) (Word) \
+ #define MR_ENTRY_LAYOUT(label) (const MR_Stack_Layout_Entry *) (Word) \
&(paste(mercury_data__layout__,label))
+ #define MR_INTERNAL_LAYOUT(label) (const MR_Stack_Layout_Label *) (Word) \
+ &(paste(mercury_data__layout__,label))
#else
- #define MR_STACK_LAYOUT(label) (Word *) NULL
+ #define MR_ENTRY_LAYOUT(label) (const MR_Stack_Layout_Entry *) NULL
+ #define MR_INTERNAL_LAYOUT(label) (const MR_Stack_Layout_Label *) NULL
#endif
-
/*
** Taking the address of a label can inhibit gcc's optimization,
** because it assumes that anything can jump there.
@@ -40,25 +43,27 @@
*/
#if defined(MR_INSERT_LABELS)
- #define make_label(n, a, l) make_entry(n, a, l)
- #define make_label_sl(n, a, l) make_entry_sl(n, a, l)
+ #define make_label(n, a, l) MR_insert_internal_label(n, a, NULL)
+ #define make_label_sl(n, a, l) \
+ MR_insert_internal_label(n, a, MR_INTERNAL_LAYOUT(l))
#else
#define make_label(n, a, l) /* nothing */
#define make_label_sl(n, a, l) /* nothing */
#endif
#if defined(MR_INSERT_LABELS) || defined(PROFILE_CALLS)
- #define make_local(n, a, l) make_entry(n, a, l)
- #define make_local_sl(n, a, l) make_entry_sl(n, a, l)
+ #define make_local(n, a, l) MR_insert_internal_label(n, a, NULL)
+ #define make_local_sl(n, a, l) \
+ MR_insert_internal_label(n, a, MR_INTERNAL_LAYOUT(l))
#else
#define make_local(n, a, l) /* nothing */
#define make_local_sl(n, a, l) /* nothing */
#endif
-#if defined(MR_INSERT_LABELS) || defined(PROFILE_CALLS) \
- || defined(MR_CHOOSE_ENTRY_POINT)
- #define make_entry(n, a, l) insert_entry(n, a, NULL)
- #define make_entry_sl(n, a, l) insert_entry(n, a, MR_STACK_LAYOUT(l))
+#if defined(MR_INSERT_LABELS) || defined(PROFILE_CALLS)
+ #define make_entry(n, a, l) MR_insert_entry_label(n, a, NULL)
+ #define make_entry_sl(n, a, l) \
+ MR_insert_entry_label(n, a, MR_ENTRY_LAYOUT(l))
#else
#define make_entry(n, a, l) /* nothing */
#define make_entry_sl(n, a, l) /* nothing */
Index: runtime/mercury_label.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_label.c,v
retrieving revision 1.6
diff -u -u -r1.6 mercury_label.c
--- mercury_label.c 1998/03/16 12:23:30 1.6
+++ mercury_label.c 1998/07/01 04:09:29
@@ -23,44 +23,76 @@
#include "mercury_engine.h" /* for `progdebug' */
#include "mercury_wrapper.h" /* for do_init_modules() */
-static const void *entry_name(const void *entry);
-static const void *entry_addr(const void *entry);
-static bool equal_name(const void *name1, const void *name2);
+/*
+** We record information about entry labels in an array that
+** we sort by code address once all the entry labels have been inserted.
+** Space for the array is provided by malloc, and it is expanded when
+** needed.
+**
+** This array is needed only by accurate garbage collection and when
+** doing low-level debugging.
+*/
+
+#ifdef MR_NEED_ENTRY_LABEL_ARRAY
+
+/* the number of entries in the initial array */
+#define INIT_ENTRY_SIZE (1 << 8)
+
+static int compare_entry_by_addr(const void *e1, const void *e2);
+
+static MR_Entry *entry_array;
+static int entry_array_size; /* # of entries allocated */
+static int entry_array_next; /* # of entries used */
+static bool entry_array_sorted;
+
+#endif /* MR_NEED_ENTRY_LABEL_ARRAY */
+
+/*
+** We record information about internal labels in a hash table
+** that is indexed by the code address of the label.
+**
+** This table is used by stack tracing and execution tracing.
+** Since execution tracing and hence stack tracing can be required
+** in any grade, we always include this table.
+*/
+
+#define INTERNAL_SIZE (1 << 16) /* 64k */
+
+static const void *internal_addr(const void *internal);
static bool equal_addr(const void *addr1, const void *addr2);
-static int hash_name(const void *name);
static int hash_addr(const void *addr);
-int entry_table_size = (1 << 16); /* 64k */
+static Table internal_addr_table = {INTERNAL_SIZE, NULL,
+ internal_addr, hash_addr, equal_addr};
-Table entry_name_table =
- {0, NULL, entry_name, hash_name, equal_name};
-Table entry_addr_table =
- {0, NULL, entry_addr, hash_addr, equal_addr};
-
void
-do_init_entries(void)
+MR_do_init_label_tables(void)
{
- static bool done = FALSE;
+ static bool done = FALSE;
+
if (!done) {
- entry_name_table.ta_size = entry_table_size;
- entry_addr_table.ta_size = entry_table_size;
- init_table(entry_name_table);
- init_table(entry_addr_table);
+#ifdef MR_NEED_ENTRY_LABEL_ARRAY
+ entry_array_next = 0;
+ entry_array_size = INIT_ENTRY_SIZE;
+ entry_array_sorted = TRUE;
+ entry_array = malloc(entry_array_size * sizeof(MR_Entry));
+#endif
+
+ init_table(internal_addr_table);
+
done = TRUE;
}
}
-Label *
-insert_entry(const char *name, Code *addr, Word *entry_layout_info)
-{
- Label *entry;
+#ifdef MR_NEED_ENTRY_LABEL_INFO
- do_init_entries();
+static int compare_entry_addr(const void *e1, const void *e2);
- entry = make(Label);
- entry->e_name = name;
- entry->e_addr = addr;
- entry->e_layout = entry_layout_info;
+void
+MR_insert_entry_label(const char *name, Code *addr,
+ const MR_Stack_Layout_Entry *entry_layout)
+{
+ MR_do_init_label_tables();
#ifdef PROFILE_CALLS
if (MR_profiling) MR_prof_output_addr_decl(name, addr);
@@ -68,74 +100,132 @@
#ifdef MR_LOWLEVEL_DEBUG
if (progdebug) {
- printf("inserting label %s at %p\n", name, addr);
+ printf("recording entry label %s at %p\n", name, addr);
}
#endif
+
+#ifdef MR_NEED_ENTRY_LABEL_ARRAY
- if (insert_table(entry_name_table, entry)) {
- printf("duplicated label name %s\n", name);
+ if (entry_array_next >= entry_array_size) {
+ entry_array_size *= 2;
+ if (realloc(entry_array, entry_array_size * sizeof(MR_Entry))
+ == NULL) {
+ fatal_error("run out of memory for entry label array");
+ }
}
- /* two labels at same location will happen quite often */
- /* when the code generated between them turns out to be empty */
+ entry_array[entry_array_next].e_addr = addr;
+ entry_array[entry_array_next].e_name = name;
+ entry_array[entry_array_next].e_layout = entry_layout;
+ entry_array_next++;
+ entry_array_sorted = FALSE;
+#endif
+}
+
+#endif
- (void) insert_table(entry_addr_table, entry);
+#ifdef MR_NEED_ENTRY_LABEL_ARRAY
- return entry;
+static int
+compare_entry_addr(const void *e1, const void *e2)
+{
+ const MR_Entry *entry1;
+ const MR_Entry *entry2;
+
+ entry1 = (const MR_Entry *) e1;
+ entry2 = (const MR_Entry *) e2;
+
+ if (entry1->e_addr > entry2->e_addr) {
+ return 1;
+ } else if (entry1->e_addr < entry2->e_addr) {
+ return -1;
+ } else {
+ return 0;
+ }
}
-Label *
-lookup_label_addr(const Code *addr)
+MR_Entry *
+MR_prev_entry_by_addr(const Code *addr)
{
- do_init_entries();
- do_init_modules();
-#ifdef MR_LOWLEVEL_DEBUG
- if (progdebug) {
- printf("looking for label at %p\n", addr);
+ int lo;
+ int hi;
+ int mid;
+ int i;
+
+ if (!entry_array_sorted) {
+ qsort(entry_array, entry_array_next, sizeof(MR_Entry),
+ compare_entry_addr);
+
+ entry_array_sorted = TRUE;
}
-#endif
+
+ lo = 0;
+ hi = entry_array_next-1;
- return (Label *) lookup_table(entry_addr_table, addr);
+ while (lo <= hi) {
+ mid = (lo + hi) / 2;
+ if (entry_array[mid].e_addr == addr) {
+ return &entry_array[mid];
+ } else if (entry_array[mid].e_addr < addr) {
+ lo = mid + 1;
+ } else {
+ hi = mid - 1;
+ }
+ }
+
+ if (entry_array[lo].e_addr < addr) {
+ return &entry_array[lo];
+ } else {
+ return &entry_array[lo-1];
+ }
}
-Label *
-lookup_label_name(const char *name)
-{
- do_init_entries();
- do_init_modules();
+#endif
+
+void
+MR_insert_internal_label(const char *name, Code *addr,
+ const MR_Stack_Layout_Label *label_layout)
+{
+ MR_Internal *internal;
+
+ MR_do_init_label_tables();
+
+ internal = make(MR_Internal);
+ internal->i_addr = addr;
+ internal->i_layout = label_layout;
+ internal->i_name = name;
+
#ifdef MR_LOWLEVEL_DEBUG
if (progdebug) {
- printf("looking for label %s\n", name);
+ printf("inserting internal label %s at %p\n", name, addr);
}
#endif
- return (Label *) lookup_table(entry_name_table, name);
+ /* two labels at same location will happen quite often */
+ /* when the code generated between them turns out to be empty */
+
+ (void) insert_table(internal_addr_table, internal);
}
-List *
-get_all_labels(void)
+MR_Internal *
+MR_lookup_internal_by_addr(const Code *addr)
{
- do_init_entries();
+ MR_do_init_label_tables();
do_init_modules();
- return get_all_entries(entry_name_table);
-}
-static const void *
-entry_name(const void *entry)
-{
- return (const void *) (((const Label *) entry)->e_name);
-}
+#ifdef MR_LOWLEVEL_DEBUG
+ if (progdebug) {
+ printf("looking for internal label at %p\n", addr);
+ }
+#endif
-static const void *
-entry_addr(const void *entry)
-{
- return (const void *) (((const Label *) entry)->e_addr);
+ return (MR_Internal *) lookup_table(internal_addr_table, addr);
}
-static bool
-equal_name(const void *name1, const void *name2)
+static const void *
+internal_addr(const void *internal)
{
- return streq(((const char *) name1), ((const char *) name2));
+ return (const void *) (((const MR_Internal *) internal)->i_addr);
}
static bool
@@ -145,13 +235,13 @@
}
static int
-hash_name(const void *name)
+hash_addr(const void *addr)
{
- return str_to_int(((const char *) name)) % entry_table_size;
+ return (((Unsigned) addr) >> 3) % INTERNAL_SIZE;
}
-static int
-hash_addr(const void *addr)
+void
+MR_process_all_internal_labels(void f(const void *))
{
- return (((Unsigned) addr) >> 3) % entry_table_size;
+ process_all_entries(internal_addr_table, f);
}
Index: runtime/mercury_label.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_label.h,v
retrieving revision 1.4
diff -u -u -r1.4 mercury_label.h
--- mercury_label.h 1998/04/21 05:51:37 1.4
+++ mercury_label.h 1998/07/01 04:09:15
@@ -15,24 +15,63 @@
#ifndef MERCURY_LABEL_H
#define MERCURY_LABEL_H
-#include "mercury_types.h" /* for `Code *' */
-#include "mercury_dlist.h" /* for `List' */
+#include "mercury_types.h" /* for `Code *' */
+#include "mercury_dlist.h" /* for `List' */
+#include "mercury_stack_layout.h" /* for `MR_Stack_Layout_*' */
-typedef struct s_label {
- const char *e_name; /* name of the procedure */
- Code *e_addr; /* address of the code */
- Word *e_layout; /* layout info for the label */
-} Label;
-
-extern void do_init_entries(void);
-extern Label *insert_entry(const char *name, Code *addr,
- Word * entry_layout_info);
-extern Label *lookup_label_name(const char *name);
-extern Label *lookup_label_addr(const Code *addr);
-extern List *get_all_labels(void);
-
-extern int entry_table_size;
- /* expected number of entries in the table */
- /* we allocate 8 bytes per entry */
+#if defined(NATIVE_GC) || defined(MR_DEBUG_GOTOS)
+ #define MR_NEED_ENTRY_LABEL_ARRAY
+#endif
+
+#if defined(MR_NEED_ENTRY_LABEL_ARRAY) || defined(PROFILE_CALLS)
+ #define MR_NEED_ENTRY_LABEL_INFO
+#endif
+
+/*
+** This struct records information about entry labels. Elements in the
+** entry label array are of this type. The table is sorted on address,
+** to allow the garbage collector to locate the entry label of the procedure
+** to which an internal label belongs by a variant of binary search.
+**
+** The name field is needed only for low-level debugging.
+*/
+
+typedef struct s_entry {
+ const Code *e_addr;
+ const MR_Stack_Layout_Entry *e_layout;
+ const char *e_name;
+} MR_Entry;
+
+/*
+** This struct records information about internal (non-entry) labels.
+** The internal label table is organized as a hash table, with the address
+** being the key.
+**
+** The name field is needed only for low-level debugging.
+*/
+
+typedef struct s_internal {
+ const Code *i_addr;
+ const MR_Stack_Layout_Label *i_layout;
+ const char *i_name;
+} MR_Internal;
+
+extern void MR_do_init_label_tables(void);
+
+#ifdef MR_NEED_ENTRY_LABEL_INFO
+extern void MR_insert_entry_label(const char *name, Code *addr,
+ const MR_Stack_Layout_Entry *entry_layout);
+#else
+#define MR_insert_entry_label(n, a, l) /* nothing */
+#endif /* not MR_NEED_ENTRY_LABEL_INFO */
+
+#ifdef MR_NEED_ENTRY_LABEL_ARRAY
+extern MR_Entry *MR_prev_entry_by_addr(const Code *addr);
+#endif /* MR_NEED_ENTRY_LABEL_ARRAY */
+
+extern void MR_insert_internal_label(const char *name, Code *addr,
+ const MR_Stack_Layout_Label *label_layout);
+extern MR_Internal *MR_lookup_internal_by_addr(const Code *addr);
+extern void MR_process_all_internal_labels(void f(const void *));
#endif /* not MERCURY_LABEL_H */
Index: runtime/mercury_misc.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_misc.c,v
retrieving revision 1.7
diff -u -u -r1.7 mercury_misc.c
--- mercury_misc.c 1998/06/09 02:08:11 1.7
+++ mercury_misc.c 1998/06/23 07:34:23
@@ -8,6 +8,7 @@
#include "mercury_dlist.h"
#include "mercury_regs.h"
#include "mercury_trace.h"
+#include "mercury_label.h"
#include "mercury_misc.h"
#include <stdio.h>
@@ -214,19 +215,13 @@
#endif /* defined(MR_LOWLEVEL_DEBUG) */
-#if defined(MR_DEBUG_GOTOS)
+#ifdef MR_DEBUG_GOTOS
void
goto_msg(/* const */ Code *addr)
{
printf("\ngoto ");
printlabel(addr);
-
- if (detaildebug) {
- printregs("registers at goto");
- }
-
- return;
}
void
@@ -254,7 +249,7 @@
/*--------------------------------------------------------------------*/
-#if defined(MR_DEBUG_GOTOS)
+#ifdef MR_LOWLEVEL_DEBUG
/* debugging printing tools */
@@ -410,16 +405,25 @@
void
printlabel(/* const */ Code *w)
{
- Label *label;
+ MR_Internal *internal;
- label = lookup_label_addr(w);
- if (label != NULL) {
- printf("label %s (0x%p)\n", label->e_name, w);
+ internal = MR_lookup_internal_by_addr(w);
+ if (internal != NULL) {
+ printf("label %s (0x%p)\n", internal->i_name, w);
} else {
+#ifdef MR_DEBUG_GOTOS
+ MR_Entry *entry;
+ entry = MR_prev_entry_by_addr(w);
+ if (entry->e_addr == w) {
+ printf("label %s (0x%p)\n", entry->e_name, w);
+ } else {
+ printf("label UNKNOWN (0x%p)\n", w);
+ }
+#else
printf("label UNKNOWN (0x%p)\n", w);
+#endif /* not MR_DEBUG_GOTOS */
}
}
-
void *
newmem(size_t n)
Index: runtime/mercury_misc.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_misc.h,v
retrieving revision 1.6
diff -u -u -r1.6 mercury_misc.h
--- mercury_misc.h 1998/06/09 02:08:12 1.6
+++ mercury_misc.h 1998/06/30 06:38:48
@@ -17,7 +17,6 @@
#include "mercury_types.h" /* for `Code *' */
#ifdef MR_LOWLEVEL_DEBUG
-
extern void mkframe_msg(void);
extern void modframe_msg(void);
extern void succeed_msg(void);
@@ -35,16 +34,13 @@
extern void push_msg(Word val, const Word *addr);
extern void pop_msg(Word val, const Word *addr);
#endif
-
-#if defined(MR_DEBUG_GOTOS)
+#ifdef MR_DEBUG_GOTOS
extern void goto_msg(/* const */ Code *addr);
extern void reg_msg(void);
-
#endif
#ifdef MR_LOWLEVEL_DEBUG
-
extern void printint(Word n);
extern void printstring(const char *s);
extern void printheap(const Word *h);
@@ -55,12 +51,10 @@
extern void printlist(Word p);
extern void printframe(const char *);
extern void printregs(const char *msg);
-
#endif
extern void printlabel(/* const */ Code *w);
-
#if __GNUC__
#define NO_RETURN __attribute__((noreturn))
#else
@@ -76,6 +70,6 @@
** XXX We should fix this eventually by using -fno-builtin since pragma
** c_code may call the builtin functions.
*/
-void MR_memcpy(char *dest, const char *src, size_t nbytes);
+extern void MR_memcpy(char *dest, const char *src, size_t nbytes);
#endif /* not MERCURY_MISC_H */
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.9
diff -u -u -r1.9 mercury_stack_trace.c
--- mercury_stack_trace.c 1998/06/18 06:08:05 1.9
+++ mercury_stack_trace.c 1998/06/29 06:36:17
@@ -39,15 +39,17 @@
"cc_multi" /* 14 */
};
-static MR_Stack_Walk_Step_Result MR_stack_walk_step(MR_Stack_Layout_Entry *,
- MR_Stack_Layout_Label **, Word **, Word **,
- const char **);
+static MR_Stack_Walk_Step_Result MR_stack_walk_step(
+ const MR_Stack_Layout_Entry *,
+ const MR_Stack_Layout_Label **,
+ Word **, Word **, const char **);
static void MR_dump_stack_record_init(void);
-static void MR_dump_stack_record_frame(FILE *fp, MR_Stack_Layout_Entry *);
+static void MR_dump_stack_record_frame(FILE *fp,
+ const MR_Stack_Layout_Entry *);
static void MR_dump_stack_record_flush(FILE *fp);
-static void MR_dump_stack_record_print(FILE *fp, MR_Stack_Layout_Entry *,
- int, int);
+static void MR_dump_stack_record_print(FILE *fp,
+ const MR_Stack_Layout_Entry *, int, int);
void
MR_dump_stack(Code *success_pointer, Word *det_stack_pointer,
@@ -80,11 +82,11 @@
}
const char *
-MR_dump_stack_from_layout(FILE *fp, MR_Stack_Layout_Entry *entry_layout,
+MR_dump_stack_from_layout(FILE *fp, const MR_Stack_Layout_Entry *entry_layout,
Word *det_stack_pointer, Word *current_frame)
{
MR_Stack_Walk_Step_Result result;
- MR_Stack_Layout_Label *return_label_layout;
+ const MR_Stack_Layout_Label *return_label_layout;
const char *problem;
Word *stack_trace_sp;
Word *stack_trace_curfr;
@@ -125,7 +127,7 @@
const char **problem)
{
MR_Stack_Walk_Step_Result result;
- MR_Stack_Layout_Label *return_label_layout;
+ const MR_Stack_Layout_Label *return_label_layout;
int i;
*problem = NULL;
@@ -144,17 +146,17 @@
}
-static MR_Stack_Walk_Step_Result
-MR_stack_walk_step(MR_Stack_Layout_Entry *entry_layout,
- MR_Stack_Layout_Label **return_label_layout,
+static MR_Stack_Walk_Step_Result
+MR_stack_walk_step(const MR_Stack_Layout_Entry *entry_layout,
+ const MR_Stack_Layout_Label **return_label_layout,
Word **stack_trace_sp_ptr, Word **stack_trace_curfr_ptr,
const char **problem_ptr)
{
- Label *label;
+ MR_Internal *label;
MR_Live_Lval location;
- MR_Stack_Layout_Label *label_layout;
MR_Lval_Type type;
- int number, determinism;
+ int number;
+ int determinism;
Code *success;
*return_label_layout = NULL;
@@ -192,26 +194,25 @@
return STEP_OK;
}
- label = lookup_label_addr(success);
+ label = MR_lookup_internal_by_addr(success);
if (label == NULL) {
*problem_ptr = "reached label with no stack trace info";
return STEP_ERROR_AFTER;
}
- label_layout = (MR_Stack_Layout_Label *) label->e_layout;
- if (label_layout == NULL) {
+ if (label->i_layout == NULL) {
*problem_ptr = "reached label with no stack layout info";
return STEP_ERROR_AFTER;
}
- *return_label_layout = label_layout;
+ *return_label_layout = label->i_layout;
return STEP_OK;
}
-static MR_Stack_Layout_Entry *prev_entry_layout;
-static int prev_entry_layout_count;
-static int prev_entry_start_level;
-static int current_level;
+static const MR_Stack_Layout_Entry *prev_entry_layout;
+static int prev_entry_layout_count;
+static int prev_entry_start_level;
+static int current_level;
static void
MR_dump_stack_record_init(void)
@@ -223,7 +224,7 @@
}
static void
-MR_dump_stack_record_frame(FILE *fp, MR_Stack_Layout_Entry *entry_layout)
+MR_dump_stack_record_frame(FILE *fp, const MR_Stack_Layout_Entry *entry_layout)
{
if (entry_layout == prev_entry_layout) {
prev_entry_layout_count++;
@@ -247,7 +248,7 @@
}
static void
-MR_dump_stack_record_print(FILE *fp, MR_Stack_Layout_Entry *entry_layout,
+MR_dump_stack_record_print(FILE *fp, const MR_Stack_Layout_Entry *entry_layout,
int count, int start_level)
{
fprintf(fp, "%9d ", start_level);
Index: runtime/mercury_stack_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.h,v
retrieving revision 1.6
diff -u -u -r1.6 mercury_stack_trace.h
--- mercury_stack_trace.h 1998/06/18 06:08:07 1.6
+++ mercury_stack_trace.h 1998/06/30 06:38:48
@@ -52,7 +52,7 @@
*/
extern const char *MR_dump_stack_from_layout(FILE *fp,
- MR_Stack_Layout_Entry *entry_layout,
+ const MR_Stack_Layout_Entry *entry_layout,
Word *det_stack_pointer, Word *current_frame);
extern const MR_Stack_Layout_Label *MR_find_nth_ancestor(
Index: runtime/mercury_table.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_table.c,v
retrieving revision 1.3
diff -u -u -r1.3 mercury_table.c
--- mercury_table.c 1997/11/23 09:31:50 1.3
+++ mercury_table.c 1998/06/23 07:50:07
@@ -120,6 +120,23 @@
}
/*
+** Process all table entries with the specified function.
+*/
+
+void
+tab_process_all_entries(const Table *table, void f(const void *))
+{
+ reg List *ptr;
+ reg int i;
+
+ for (i = 0; i < table->ta_size; i++) {
+ for_list (ptr, table->ta_store[i]) {
+ (*f)(ldata(ptr));
+ }
+ }
+}
+
+/*
** Convert a string to a positive int. The return value
** mod the table size is a good hash value.
*/
Index: runtime/mercury_table.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_table.h,v
retrieving revision 1.4
diff -u -u -r1.4 mercury_table.h
--- mercury_table.h 1998/05/17 07:03:14 1.4
+++ mercury_table.h 1998/06/30 06:38:48
@@ -28,20 +28,22 @@
/* applied to two keys */
} Table;
-#define init_table(t) tab_init_table(&t)
-#define lookup_table(t, k) tab_lookup_table(&t, (const void *) k)
-#define insert_table(t, e) tab_insert_table(&t, (void *) e)
-#define get_all_entries(t) tab_get_all_entries(&t)
-#define str_to_int(val) tab_str_to_int(val)
+#define init_table(t) tab_init_table(&t)
+#define lookup_table(t, k) tab_lookup_table(&t, (const void *) k)
+#define insert_table(t, e) tab_insert_table(&t, (void *) e)
+#define get_all_entries(t) tab_get_all_entries(&t)
+#define process_all_entries(t, f) tab_process_all_entries(&t, f)
+#define str_to_int(val) tab_str_to_int(val)
-#define tablekey(table) (*(table->ta_key))
-#define tablehash(table) (*(table->ta_hash))
-#define tableequal(table) (*(table->ta_equal))
+#define tablekey(table) (*(table->ta_key))
+#define tablehash(table) (*(table->ta_hash))
+#define tableequal(table) (*(table->ta_equal))
extern void tab_init_table(Table *);
extern void * tab_lookup_table(const Table *, const void *);
extern bool tab_insert_table(const Table *, void *);
extern List *tab_get_all_entries(const Table *);
+extern void tab_process_all_entries(const Table *, void f(const void *));
extern int tab_str_to_int(const char *);
#endif /* not MERCURY_TABLE_H */
Index: runtime/mercury_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace.c,v
retrieving revision 1.13
diff -u -u -r1.13 mercury_trace.c
--- mercury_trace.c 1998/05/16 07:28:21 1.13
+++ mercury_trace.c 1998/06/23 08:33:07
@@ -31,71 +31,6 @@
#include <stdio.h>
#include <unistd.h> /* for the write system call */
-/*
-** Do we want to use the debugger within this process, or do want to use
-** the Opium-style trace analyzer debugger implemented by an external process.
-** This variable is set in mercury_wrapper.c and never modified afterwards.
-*/
-
-MR_trace_type MR_trace_handler = MR_TRACE_INTERNAL;
-
-/*
-** Compiler generated tracing code will check whether MR_trace_enabled is true,
-** before calling MR_trace. For now, and until we implement interface tracing,
-** MR_trace_enabled should keep the same value throughout the execution of
-** the entire program after being set in mercury_wrapper.c. There is one
-** exception to this: the Mercury routines called as part of the functionality
-** of the tracer itself (e.g. the term browser) should always be executed
-** with MR_trace_enabled set to FALSE.
-*/
-
-bool MR_trace_enabled = FALSE;
-
-/*
-** MR_trace_call_seqno counts distinct calls. The prologue of every
-** procedure assigns the current value of this counter as the sequence number
-** of that invocation and increments the counter. This is the only way that
-** MR_trace_call_seqno is modified.
-**
-** MR_trace_call_depth records the current depth of the call tree. The prologue
-** of every procedure assigns the current value of this variable plus one
-** as the depth of that invocation. Just before making a call, the caller
-** will set MR_trace_call_depth to its own remembered depth value.
-** These are the only ways in which MR_trace_call_depth is modified.
-**
-** Although neither MR_trace_call_seqno nor MR_trace_call_depth are used
-** directly in this module, the seqno and depth arguments of MR_trace
-** always derive their values from the saved values of these two global
-** variables.
-*/
-
-Unsigned MR_trace_call_seqno = 0;
-Unsigned MR_trace_call_depth = 0;
-
-/*
-** MR_trace_event_number is a simple counter of events. This is used in
-** two places: here, for display to the user and for skipping a given number
-** of events, and when printing an abort message, so that the programmer
-** can zero in on the source of the problem more quickly.
-*/
-
-Unsigned MR_trace_event_number = 0;
-
-/*
-** MR_trace_from_full is a boolean that is set before every call;
-** it states whether the caller is being fully traced, or only interface
-** traced. If the called code is interface traced, it will generate
-** call, exit and fail trace events only if MR_trace_from_full is true.
-** (It will never generate internal events.) If the called code is fully
-** traced, it will always generate all trace events, external and internal,
-** regardless of the setting of this variable on entry.
-**
-** The initial value is set to TRUE to allow the programmer to gain
-** control in the debugger when main/2 is called.
-*/
-
-Bool MR_trace_from_full = 1;
-
static MR_trace_cmd_info MR_trace_ctrl = { MR_CMD_GOTO, 0, 0, FALSE };
static void MR_trace_event(MR_trace_cmd_info *cmd,
@@ -107,40 +42,6 @@
MR_trace_port port, Unsigned seqno, Unsigned depth,
const char *path, int max_r_num);
-void
-MR_trace_init(void)
-{
-#ifdef MR_USE_EXTERNAL_DEBUGGER
- if (MR_trace_handler == MR_TRACE_EXTERNAL)
- MR_trace_init_external();
-#endif
-}
-
-void
-MR_trace_final(void)
-{
-#ifdef MR_USE_EXTERNAL_DEBUGGER
- if (MR_trace_handler == MR_TRACE_EXTERNAL)
- MR_trace_final_external();
-#endif
-}
-
-void
-MR_trace_start(bool enabled)
-{
- MR_trace_event_number = 0;
- MR_trace_call_seqno = 0;
- MR_trace_call_depth = 0;
- MR_trace_from_full = TRUE;
- MR_trace_enabled = enabled;
-}
-
-void
-MR_trace_end(void)
-{
- MR_trace_enabled = FALSE;
-}
-
/*
** This function is called from compiled code whenever an event to be traced
** occurs.
@@ -261,35 +162,4 @@
MR_trace_event_internal_report(layout, port, seqno, depth, path);
#endif
-}
-
-void
-MR_trace_report(FILE *fp)
-{
- if (MR_trace_event_number > 0) {
- /*
- ** This means that the executable was compiled with tracing,
- ** which implies that the user wants trace info on abort.
- */
-
- fprintf(fp, "Last trace event was event #%ld.\n",
- (long) MR_trace_event_number);
- }
-}
-
-void
-MR_trace_report_raw(int fd)
-{
- char buf[80]; /* that ought to be more than long enough */
-
- if (MR_trace_event_number > 0) {
- /*
- ** This means that the executable was compiled with tracing,
- ** which implies that the user wants trace info on abort.
- */
-
- sprintf(buf, "Last trace event was event #%ld.\n",
- (long) MR_trace_event_number);
- write(fd, buf, strlen(buf));
- }
}
Index: runtime/mercury_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace.h,v
retrieving revision 1.8
diff -u -u -r1.8 mercury_trace.h
--- mercury_trace.h 1998/05/16 07:28:23 1.8
+++ mercury_trace.h 1998/06/30 08:44:57
@@ -13,23 +13,28 @@
** (b) It defines the interface by which the internal and external debuggers
** can control how the tracing subsystem treats events.
**
-** The macros and functions defined in this module are intended to be called
-** only from code generated by the Mercury compiler, and from hand-written
-** code in the Mercury runtime or the Mercury standard library.
+** The macros, functions and variables of this module are intended to be
+** referred to only from code generated by the Mercury compiler, and from
+** hand-written code in the Mercury runtime or the Mercury standard library,
+** and even then only if at least some part of the program was compiled
+** with some form of execution tracing.
+**
+** The parts of the tracing system that need to be present even when no
+** part of the program is compiled with execution tracing are in the module
+** mercury_trace_base.
*/
#ifndef MERCURY_TRACE_H
#define MERCURY_TRACE_H
+#include "mercury_trace_base.h"
+
/* The interface between the tracing subsystem and compiled code. */
#define MR_trace_incr_seq() (++MR_trace_call_seqno)
#define MR_trace_incr_depth() (++MR_trace_call_depth)
#define MR_trace_reset_depth(d) do { MR_trace_call_depth = (d); } while (0)
-extern Word MR_trace_call_seqno;
-extern Word MR_trace_call_depth;
-
/*
** This enum should exactly match the definition of the `trace_port' type in
** library/debugger_interface.
@@ -55,51 +60,6 @@
const char *, /* path to event goal within procedure */
int, /* highest numbered rN register in use */
bool); /* is this event supposed to be traced */
-
-/*
-** These functions will report the number of the last event,
-** if there have been some events, and will do nothing otherwise.
-*/
-
-extern void MR_trace_report(FILE *fp);
-extern void MR_trace_report_raw(int fd);
-
-/*
-** MR_trace_init() is called from mercury_runtime_init()
-** when the debuggee programs begins, to perform any initialization
-** that must be done before any traced Mercury code is executed.
-** This includes the initialization code written in Mercury as well as main.
-**
-** MR_trace_start(enabled) is called from mercury_runtime_init()
-** after the initialization code written in Mercury is executed,
-** when we are about to start executing main. The argument says
-** whether tracing is enabled for main (it is never enabled for
-** initialization and finalization routines).
-**
-** MR_trace_end() is called from mercury_runtime_terminate() just
-** after main has terminated and just before we call the finalization
-** code written in Mercury.
-**
-** MR_trace_final() is called from mercury_runtime_terminate()
-** after all Mercury code, including finalization code, has terminated.
-*/
-
-extern void MR_trace_init(void);
-extern void MR_trace_start(bool enabled);
-extern void MR_trace_end(void);
-extern void MR_trace_final(void);
-
-typedef enum {
- MR_TRACE_INTERNAL,
- MR_TRACE_EXTERNAL
-} MR_trace_type;
-
-extern MR_trace_type MR_trace_handler;
-extern bool MR_trace_enabled;
-
-extern Unsigned MR_trace_event_number;
-
-extern Bool MR_trace_from_full;
/* The interface between the debuggers and the tracing subsystem. */
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.14
diff -u -u -r1.14 mercury_wrapper.c
--- mercury_wrapper.c 1998/06/18 04:30:47 1.14
+++ mercury_wrapper.c 1998/07/01 09:06:04
@@ -479,7 +479,7 @@
unsigned long size;
int c;
- while ((c = getopt(argc, argv, "acC:d:D:hLlP:pr:s:tT:w:xz:")) != EOF)
+ while ((c = getopt(argc, argv, "acC:d:D:P:pr:s:tT:xz:")) != EOF)
{
switch (c)
{
@@ -563,31 +563,6 @@
break;
- case 'h':
- usage();
- break;
-
- case 'L':
- do_init_modules();
- break;
-
- case 'l': {
- List *ptr;
- List *label_list;
-
- label_list = get_all_labels();
- for_list (ptr, label_list) {
- Label *label;
- label = (Label *) ldata(ptr);
- printf("%lu %lx %s\n",
- (unsigned long) label->e_addr,
- (unsigned long) label->e_addr,
- label->e_name);
- }
-
- exit(0);
- }
-
case 'p':
MR_profiling = FALSE;
break;
@@ -619,9 +594,6 @@
detstack_size = size;
else if (optarg[0] == 'n')
nondstack_size = size;
- else if (optarg[0] == 'l')
- entry_table_size = size *
- 1024 / (2 * sizeof(List *));
#ifdef MR_USE_TRAIL
else if (optarg[0] == 't')
trail_size = size;
@@ -656,22 +628,6 @@
}
break;
- case 'w': {
- Label *which_label;
-
- which_label = lookup_label_name(optarg);
- if (which_label == NULL)
- {
- fprintf(stderr, "Mercury runtime: "
- "label name `%s' unknown\n",
- optarg);
- exit(1);
- }
-
- program_entry_point = which_label->e_addr;
-
- break;
- }
case 'x':
#ifdef CONSERVATIVE_GC
GC_dont_gc = TRUE;
@@ -708,54 +664,10 @@
static void
usage(void)
{
- printf("Mercury runtime usage:\n"
- "MERCURY_OPTIONS=\"[-hclLtxp] [-T[rvp]] [-d[abcdghs]]\n"
- " [-[szt][hdn]#] [-C#] [-r#] [-w name] [-[123]#]\"\n"
- "-h \t\tprint this usage message\n"
- "-c \t\tcheck cross-function stack usage\n"
- "-l \t\tprint all labels\n"
- "-L \t\tcheck for duplicate labels\n"
- "-t \t\ttime program execution\n"
- "-x \t\tdisable garbage collection\n"
- "-p \t\tdisable profiling\n"
- "-Tr \t\tprofile real time (using ITIMER_REAL)\n"
- "-Tv \t\tprofile user time (using ITIMER_VIRTUAL)\n"
- "-Tp \t\tprofile user + system time (using ITIMER_PROF)\n"
- "-dg \t\tdebug gotos\n"
- "-dc \t\tdebug calls\n"
- "-db \t\tdebug backtracking\n"
- "-dh \t\tdebug heap\n"
- "-ds \t\tdebug detstack\n"
- "-df \t\tdebug final success/failure\n"
- "-da \t\tdebug all\n"
- "-dm \t\tdebug memory allocation\n"
- "-dG \t\tdebug garbage collection\n"
- "-dd \t\tdetailed debug\n"
- "-Di \t\tdebug the program using the internal debugger\n"
-#ifdef MR_USE_EXTERNAL_DEBUGGER
- "-De \t\tdebug the program using the external debugger\n"
-#endif
- "-sh<n> \t\tallocate n kb for the heap\n"
- "-sd<n> \t\tallocate n kb for the det stack\n"
- "-sn<n> \t\tallocate n kb for the nondet stack\n"
-#ifdef MR_USE_TRAIL
- "-st<n> \t\tallocate n kb for the trail\n"
-#endif
- "-sl<n> \t\tallocate n kb for the label table\n"
- "-zh<n> \t\tallocate n kb for the heap redzone\n"
- "-zd<n> \t\tallocate n kb for the det stack redzone\n"
- "-zn<n> \t\tallocate n kb for the nondet stack redzone\n"
-#ifdef MR_USE_TRAIL
- "-zt<n> \t\tallocate n kb for the trail redzone\n"
-#endif
- "-C<n> \t\tprimary cache size in kbytes\n"
-#ifdef PARALLEL
- "-P<n> \t\tnumber of processes to use for parallel execution\n"
- "\t\tapplies only if Mercury is configured with --enable-parallel\n"
-#endif
- "-r<n> \t\trepeat n times\n"
- "-w<name> \tcall predicate with given name (default: main/2)\n"
- );
+ printf("The MERCURY_OPTIONS environment variable "
+ "contains an invalid option.\n"
+ "Please refer to the Environment Variables section of "
+ "the Mercury\nuser's guide for details.\n");
fflush(stdout);
exit(1);
} /* end usage() */
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 scripts
Index: scripts/c2init.in
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/c2init.in,v
retrieving revision 1.15
diff -u -u -r1.15 c2init.in
--- c2init.in 1998/05/30 13:34:09 1.15
+++ c2init.in 1998/07/01 09:04:43
@@ -19,6 +19,16 @@
Name: c2init - Create Mercury initialization file.
Usage: c2init [options] *.c *.init ...
Options:
+ -c <n>, --max-calls <n>
+ Break up the initialization into groups of at most <n> function
+ calls. (Default value of <n> is 40.)
+ -i, --include-initialization-code
+ Always include code that calls the initialization functions
+ of the various modules. With this option, the debugger can use
+ information from any modules that were compiled with execution
+ tracing to print (partial) stack traces, and to print the
+ values of variables in ancestors of the current call, even
+ in grades in which this not normally possible.
-l, --library
Don't generate a \`main()' function.
Instead, generate a function
@@ -26,18 +36,15 @@
(declared in \"init.h\") that can be called from C code.
(A more fine-grained interface is also available;
see \"init.h\" for details.)
+ -w <label>, --entry-point <label>
+ Set entry point to <label>.
+ (Default value is \`mercury__main_2_0'.)
-x, --extra-inits
Search \`.c' files for extra initialization functions.
(This may be necessary if the C files contain
hand-coded C code with \`INIT' comments, rather than
containing only C code that was automatically generated
by the Mercury compiler.)
- -c <n>, --max-calls <n>
- Break up the initialization into groups of at most <n> function
- calls. (Default value of <n> is 40.)
- -w <label>, --entry-point <label>
- Set entry point to <label>.
- (Default value is \`mercury__main_2_0'.)
Environment variables:
MERCURY_MOD_LIB_DIR, MERCURY_MOD_LIB_MODS, MERCURY_MKINIT.
"
@@ -52,18 +59,21 @@
# maximum number of calls to put in a single function
maxcalls=40
defentry=mercury__main_2_0
+init_opt=""
library_opt=""
extra_inits_opt=""
while true; do
case "$1" in
-c|--max-calls)
maxcalls="$2"; shift; shift;;
- -w|--entry-point)
- defentry="$2"; shift; shift;;
+ -i|--include-initialization-code)
+ init_opt="-i"; shift;;
-l|--library)
library_opt="-l"; shift;;
-l-|--no-library)
library_opt=""; shift;;
+ -w|--entry-point)
+ defentry="$2"; shift; shift;;
-x|--extra-inits)
extra_inits_opt="-x"; shift;;
-x-|--no-extra-inits)
@@ -83,10 +93,10 @@
done
case $# in
- 0) exec $MKINIT -w"$defentry" -c"$maxcalls" $library_opt \
- $extra_inits_opt $MERCURY_MOD_LIB_MODS
+ 0) exec $MKINIT -c"$maxcalls" $init_opt $library_opt \
+ -w"$defentry" $extra_inits_opt $MERCURY_MOD_LIB_MODS
;;
- *) exec $MKINIT -w"$defentry" -c"$maxcalls" $library_opt \
- $extra_inits_opt "$@" $MERCURY_MOD_LIB_MODS
+ *) exec $MKINIT -c"$maxcalls" $init_opt $library_opt \
+ -w"$defentry" $extra_inits_opt "$@" $MERCURY_MOD_LIB_MODS
;;
esac
cvs diff: Diffing tests
cvs diff: [22:47:49] waiting for zs's lock in /home/mercury1/repository/tests
cvs diff: [22:48:19] obtained lock in /home/mercury1/repository/tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.5
diff -u -u -r1.5 Mmakefile
--- Mmakefile 1998/05/18 02:05:11 1.5
+++ Mmakefile 1998/06/24 10:45:42
@@ -14,6 +14,7 @@
queens
MCFLAGS = --trace all $(EXTRA_MCFLAGS)
+EXTRA_C2INITFLAGS = -i
# Not all grades can be used with stack layouts
#
Index: tests/debugger/debugger_regs_lib.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/debugger_regs_lib.exp,v
retrieving revision 1.1
diff -u -u -r1.1 debugger_regs_lib.exp
--- debugger_regs_lib.exp 1998/05/16 07:31:04 1.1
+++ debugger_regs_lib.exp 1998/06/25 06:27:19
@@ -2,14 +2,6 @@
mtrace> 2: 2 2 CALL DET debugger_regs_lib:data/41-0
mtrace> 3: 2 2 EXIT DET debugger_regs_lib:data/41-0
mtrace> HeadVar__1 [1, 2, 3, 4, 5]
- HeadVar__2 a0
- HeadVar__3 a1
- HeadVar__4 a2
- HeadVar__5 a3
- HeadVar__6 a4
- HeadVar__7 a5
- HeadVar__8 a6
- HeadVar__9 a7
HeadVar__10 a8
HeadVar__11 a9
HeadVar__12 b0
@@ -20,6 +12,7 @@
HeadVar__17 b5
HeadVar__18 b6
HeadVar__19 b7
+ HeadVar__2 a0
HeadVar__20 b8
HeadVar__21 b9
HeadVar__22 c0
@@ -30,6 +23,7 @@
HeadVar__27 c5
HeadVar__28 c6
HeadVar__29 c7
+ HeadVar__3 a1
HeadVar__30 c8
HeadVar__31 c9
HeadVar__32 d0
@@ -40,8 +34,14 @@
HeadVar__37 d5
HeadVar__38 d6
HeadVar__39 d7
+ HeadVar__4 a2
HeadVar__40 d8
HeadVar__41 d9
+ HeadVar__5 a3
+ HeadVar__6 a4
+ HeadVar__7 a5
+ HeadVar__8 a6
+ HeadVar__9 a7
mtrace> a0a1a2a3a4a5a6a7a8a9
b0b1b2b3b4b5b6b7b8b9
c0c1c2c3c4c5c6c7c8c9
Index: tests/debugger/debugger_regs_lib.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/debugger_regs_lib.inp,v
retrieving revision 1.1
diff -u -u -r1.1 debugger_regs_lib.inp
--- debugger_regs_lib.inp 1998/05/16 07:31:08 1.1
+++ debugger_regs_lib.inp 1998/06/25 06:26:14
@@ -1,4 +1,4 @@
-p
+p *
c
Index: tests/debugger/interpreter_lib.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/interpreter_lib.exp,v
retrieving revision 1.1
diff -u -u -r1.1 interpreter_lib.exp
--- interpreter_lib.exp 1998/05/16 07:31:15 1.1
+++ interpreter_lib.exp 1998/06/25 06:37:34
@@ -9,23 +9,36 @@
F: finish this call, printing the trace.
<N> g: go to event #N, not printing the trace.
<N> G: go to event #N, printing the trace.
-p: print the variables live at this point.
+v: list the names of the variables live at this point.
+l <n>: set ancestor level to <n>
+p <n>: print variable #n (or all vars if <n> is '*')
r: continue until forward execution is resumed.
[<N>] [s]: skip N events, not printing the trace (default: N=1).
[<N>] S: skip N events, printing the trace (default: N=1).
?: list all the breakpoints.
+ <N>: enable breakpoint #N.
- <N>: disable breakpoint #N.
-mtrace> mtrace> Pure Prolog Interpreter.
+mtrace> Pure Prolog Interpreter.
Consulting file `interpreter_lib.m'...
- 45: 20 4 CALL DET interpreter_lib:consult_until_eof/4-0
-mtrace> HeadVar__1 []
- HeadVar__3 state('<<c_pointer>>')
-mtrace> 47: 22 6 CALL DET parser:read_term/3-0
+ 46: 21 5 CALL DET term_io:read_term/3-0
+mtrace> 0 HeadVar__2
mtrace> HeadVar__2 state('<<c_pointer>>')
-mtrace> 13300: 22 6 EXIT DET parser:read_term/3-0
-mtrace> HeadVar__1 term(varset(0, empty, empty), functor(atom(":-"), [functor(atom("module"), [functor(atom("interpreter"), [], context("interpreter_lib.m", 22))], context("interpreter_lib.m", 22))], context("interpreter_lib.m", 22)))
- HeadVar__3 state('<<c_pointer>>')
-mtrace> 0: + interpreter_lib:consult_until_eof
-mtrace> mtrace> ?-
\ No newline at end of file
+mtrace> 0: + interpreter_lib:database_assert_clause
+mtrace> 13446: 5011 6 CALL DET interpreter_lib:database_assert_clause/4-0
+mtrace> HeadVar__1 []
+ HeadVar__2 varset(0, empty, empty)
+ HeadVar__3 functor(atom(":-"), [functor(atom("module"), [functor(atom("interpreter_lib"), [], context("interpreter_lib.m", 22))], context("interpreter_lib.m", 22))], context("interpreter_lib.m", 22))
+mtrace> 13447: 5011 6 ELSE DET interpreter_lib:database_assert_clause/4-0 e;
+ 13448: 5012 7 CALL DET term:context_init/1-0
+ 13449: 5012 7 EXIT DET term:context_init/1-0
+ 13450: 5011 6 EXIT DET interpreter_lib:database_assert_clause/4-0
+mtrace> HeadVar__1 []
+ HeadVar__2 varset(0, empty, empty)
+ HeadVar__3 functor(atom(":-"), [functor(atom("module"), [functor(atom("interpreter_lib"), [], context("interpreter_lib.m", 22))], context("interpreter_lib.m", 22))], context("interpreter_lib.m", 22))
+ HeadVar__4 [clause(varset(0, empty, empty), functor(atom(":-"), [functor(atom("module"), [functor(atom("interpreter_lib"), [], context("interpreter_lib.m", 22))], context("interpreter_lib.m", 22))], context("interpreter_lib.m", 22)), functor(atom("true"), [], context("", 0)))]
+mtrace> 13451: 5013 6 CALL DET interpreter_lib:consult_until_eof/4-0
+mtrace> 368828: 5013 6 EXIT DET interpreter_lib:consult_until_eof/4-0
+mtrace> 368829: 5010 5 EXIT DET interpreter_lib:consult_until_eof_2/5-0
+mtrace> 368830: 20 4 EXIT DET interpreter_lib:consult_until_eof/4-0
+mtrace> ?-
\ No newline at end of file
Index: tests/debugger/interpreter_lib.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/interpreter_lib.inp,v
retrieving revision 1.1
diff -u -u -r1.1 interpreter_lib.inp
--- interpreter_lib.inp 1998/05/16 07:31:19 1.1
+++ interpreter_lib.inp 1998/06/25 06:36:12
@@ -1,11 +1,14 @@
h
-b interpreter_lib consult_until_eof
+45s
+v
+p *
+b interpreter_lib database_assert_clause
c
-p
-2s
-p
+p *
+F
+p *
+
f
-p
-?
-- 0
+
+
c
Index: tests/debugger/queens_lib.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/queens_lib.exp,v
retrieving revision 1.1
diff -u -u -r1.1 queens_lib.exp
--- queens_lib.exp 1998/05/16 07:31:26 1.1
+++ queens_lib.exp 1998/06/25 06:27:48
@@ -1,7 +1,7 @@
1: 1 1 CALL CCMUL queens_lib:main/2-0
mtrace> HeadVar__1 state('<<c_pointer>>')
mtrace> 2: 2 2 CALL DET queens_lib:data/1-0
-mtrace> mtrace: no live variables
+mtrace> mtrace: there are no live variables
mtrace> 3: 2 2 EXIT DET queens_lib:data/1-0
mtrace> HeadVar__1 [1, 2, 3, 4, 5]
mtrace> 4: 3 2 CALL NON queens_lib:queen/2-0
@@ -14,12 +14,17 @@
mtrace> HeadVar__2 [1, 2, 3, 4, 5]
mtrace> 8: 5 4 DISJ NON queens_lib:qdelete/3-0 c2;d1;
mtrace> HeadVar__2 [1, 2, 3, 4, 5]
- V_11 1
V_10 [2, 3, 4, 5]
+ V_11 1
+mtrace> Ancestor level set to 1
+mtrace> HeadVar__1 [1, 2, 3, 4, 5]
+mtrace> Ancestor level set to 2
+mtrace> 0 HeadVar__1
+mtrace> HeadVar__1 [1, 2, 3, 4, 5]
mtrace> 9: 5 4 EXIT NON queens_lib:qdelete/3-0
mtrace> HeadVar__1 1
- HeadVar__3 [2, 3, 4, 5]
HeadVar__2 [1, 2, 3, 4, 5]
+ HeadVar__3 [2, 3, 4, 5]
mtrace> 10: 6 4 CALL NON queens_lib:qperm/2-0
mtrace> HeadVar__1 [2, 3, 4, 5]
mtrace> 11: 6 4 SWTC NON queens_lib:qperm/2-0 s1;
@@ -28,12 +33,12 @@
mtrace> HeadVar__2 [2, 3, 4, 5]
mtrace> 13: 7 5 DISJ NON queens_lib:qdelete/3-0 c2;d1;
mtrace> HeadVar__2 [2, 3, 4, 5]
- V_11 2
V_10 [3, 4, 5]
+ V_11 2
mtrace> 14: 7 5 EXIT NON queens_lib:qdelete/3-0
mtrace> HeadVar__1 2
- HeadVar__3 [3, 4, 5]
HeadVar__2 [2, 3, 4, 5]
+ HeadVar__3 [3, 4, 5]
mtrace> 15: 8 5 CALL NON queens_lib:qperm/2-0
mtrace> HeadVar__1 [3, 4, 5]
mtrace> 16: 8 5 SWTC NON queens_lib:qperm/2-0 s1;
@@ -42,12 +47,12 @@
mtrace> HeadVar__2 [3, 4, 5]
mtrace> 18: 9 6 DISJ NON queens_lib:qdelete/3-0 c2;d1;
mtrace> HeadVar__2 [3, 4, 5]
- V_11 3
V_10 [4, 5]
+ V_11 3
mtrace> 19: 9 6 EXIT NON queens_lib:qdelete/3-0
mtrace> HeadVar__1 3
- HeadVar__3 [4, 5]
HeadVar__2 [3, 4, 5]
+ HeadVar__3 [4, 5]
mtrace> 20: 10 6 CALL NON queens_lib:qperm/2-0
mtrace> HeadVar__1 [4, 5]
mtrace> 21: 10 6 SWTC NON queens_lib:qperm/2-0 s1;
@@ -56,12 +61,12 @@
mtrace> HeadVar__2 [4, 5]
mtrace> 23: 11 7 DISJ NON queens_lib:qdelete/3-0 c2;d1;
mtrace> HeadVar__2 [4, 5]
- V_11 4
V_10 [5]
+ V_11 4
mtrace> 24: 11 7 EXIT NON queens_lib:qdelete/3-0
mtrace> HeadVar__1 4
- HeadVar__3 [5]
HeadVar__2 [4, 5]
+ HeadVar__3 [5]
mtrace> 25: 12 7 CALL NON queens_lib:qperm/2-0
mtrace> HeadVar__1 [5]
mtrace> 26: 12 7 SWTC NON queens_lib:qperm/2-0 s1;
@@ -70,33 +75,33 @@
mtrace> HeadVar__2 [5]
mtrace> 28: 13 8 DISJ NON queens_lib:qdelete/3-0 c2;d1;
mtrace> HeadVar__2 [5]
- V_11 5
V_10 []
+ V_11 5
mtrace> 29: 13 8 EXIT NON queens_lib:qdelete/3-0
mtrace> HeadVar__1 5
- HeadVar__3 []
HeadVar__2 [5]
+ HeadVar__3 []
mtrace> 30: 14 8 CALL NON queens_lib:qperm/2-0
mtrace> HeadVar__1 []
mtrace> 31: 14 8 SWTC NON queens_lib:qperm/2-0 s2;
mtrace> mtrace> 32: 14 8 EXIT NON queens_lib:qperm/2-0
-mtrace> HeadVar__2 []
- HeadVar__1 []
+mtrace> HeadVar__1 []
+ HeadVar__2 []
mtrace> 33: 12 7 EXIT NON queens_lib:qperm/2-0
-mtrace> HeadVar__2 [5]
- HeadVar__1 [5]
+mtrace> HeadVar__1 [5]
+ HeadVar__2 [5]
mtrace> 34: 10 6 EXIT NON queens_lib:qperm/2-0
-mtrace> HeadVar__2 [4, 5]
- HeadVar__1 [4, 5]
+mtrace> HeadVar__1 [4, 5]
+ HeadVar__2 [4, 5]
mtrace> 35: 8 5 EXIT NON queens_lib:qperm/2-0
-mtrace> HeadVar__2 [3, 4, 5]
- HeadVar__1 [3, 4, 5]
+mtrace> HeadVar__1 [3, 4, 5]
+ HeadVar__2 [3, 4, 5]
mtrace> 36: 6 4 EXIT NON queens_lib:qperm/2-0
-mtrace> HeadVar__2 [2, 3, 4, 5]
- HeadVar__1 [2, 3, 4, 5]
+mtrace> HeadVar__1 [2, 3, 4, 5]
+ HeadVar__2 [2, 3, 4, 5]
mtrace> 37: 4 3 EXIT NON queens_lib:qperm/2-0
-mtrace> HeadVar__2 [1, 2, 3, 4, 5]
- HeadVar__1 [1, 2, 3, 4, 5]
+mtrace> HeadVar__1 [1, 2, 3, 4, 5]
+ HeadVar__2 [1, 2, 3, 4, 5]
mtrace> 38: 15 3 CALL SEMI queens_lib:safe/1-0
mtrace> HeadVar__1 [1, 2, 3, 4, 5]
mtrace> 39: 15 3 SWTC SEMI queens_lib:safe/1-0 s1;
cvs diff: Diffing tests/general
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trial
cvs diff: Diffing util
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.33
diff -u -u -r1.33 mkinit.c
--- mkinit.c 1998/06/08 08:29:17 1.33
+++ mkinit.c 1998/07/01 09:15:15
@@ -37,12 +37,13 @@
static const char *progname = NULL;
/* options and arguments, set by parse_options() */
-static const char *entry_point = "mercury__io__main_2_0";
+static const char *entry_point = "mercury__main_2_0";
static int maxcalls = MAXCALLS;
static int num_files;
static char **files;
static bool output_main_func = TRUE;
static bool c_files_contain_extra_inits = FALSE;
+static bool need_initialization_code = FALSE;
static int num_modules = 0;
static int num_errors = 0;
@@ -178,6 +179,12 @@
"}\n"
;
+
+static const char if_need_to_init[] =
+ "#if defined(MR_NEED_INITIALIZATION_CODE)\n\n"
+ ;
+
+
/* --- function prototypes --- */
static void parse_options(int argc, char *argv[]);
static void usage(void);
@@ -249,21 +256,25 @@
parse_options(int argc, char *argv[])
{
int c;
- while ((c = getopt(argc, argv, "c:w:lx")) != EOF) {
+ while ((c = getopt(argc, argv, "c:ilw:x")) != EOF) {
switch (c) {
case 'c':
if (sscanf(optarg, "%d", &maxcalls) != 1)
usage();
break;
- case 'w':
- entry_point = optarg;
+ case 'i':
+ need_initialization_code = TRUE;
break;
case 'l':
output_main_func = FALSE;
break;
+ case 'w':
+ entry_point = optarg;
+ break;
+
case 'x':
c_files_contain_extra_inits = TRUE;
break;
@@ -309,6 +320,10 @@
{
int filenum;
+ if (! need_initialization_code) {
+ fputs(if_need_to_init, stdout);
+ }
+
fputs("static void init_modules_0(void)\n", stdout);
fputs("{\n", stdout);
@@ -316,7 +331,10 @@
process_file(files[filenum]);
}
- fputs("}\n\n", stdout);
+ fputs("}\n", stdout);
+ if (! need_initialization_code) {
+ fputs("\n#endif\n\n", stdout);
+ }
}
static void
@@ -327,8 +345,16 @@
fputs("static void init_modules(void)\n", stdout);
fputs("{\n", stdout);
+ if (! need_initialization_code) {
+ fputs(if_need_to_init, stdout);
+ }
+
for (i = 0; i <= num_modules; i++) {
printf("\tinit_modules_%d();\n", i);
+ }
+
+ if (! need_initialization_code) {
+ fputs("\n#endif\n", stdout);
}
fputs("}\n", stdout);
More information about the developers
mailing list