[m-rev.] for review: stack segments

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Oct 31 11:29:24 AEDT 2006


For review by anyone.

Zoltan.

Add a mechanism for growing the stacks on demand by adding new segments
to them. You can ask for the new mechanism via a new grade component, stseg
(short for "stack segments").

The mechanism works by adding a test to each increment of a stack pointer (sp
or maxfr). If the test indicates that we are about to run out of stack, we
allocate a new stack segment, allocate a placeholder frame on the new segment,
and then allocate the frame we wanted in the first place on top of the
placeholder. We also override succip to make it point code that will (1)
release the new segment when the newly created stack frame returns, and then
(2) go to the place indicated by the original, overridden succip.

For leaf procedures on the det stack, we optimize away the check of the stack
pointer. We can do this because we reserve some space on each stack for the
use of such stack frames.

My intention is that doc/user_guide.texi and NEWS will be updated once we have
used the feature ourselves for a while and it seems to be stable.

runtime/mercury_grade.h:
	Add the new grade component.

runtime/mercury_conf_param.h:
	Document the new grade component, and the option used to debug stack
	segments.

runtime/mercury_context.[ch]:
	Add new fields to contexts to hold the list of previous segments of the
	det and nondet stacks.

runtime/mercury_memory_zones.[ch]:
	Include a threshold in all zones, for use in stack segments.
	Set it when a zone is allocated.

	Restore the previous #ifdef'd out function MR_unget_zone, for use
	when freeing stack segments execution has fallen out of.

runtime/mercury_debug.[ch]:
	When printing the offsets of pointers into the det and nondet stacks,
	print the number of the segment the pointer points into (unless it is
	the first, in which case we suppress this in the interest of brevity
	and simplicity).

	Make all the functions in this module take a FILE * as an input
	argument; don't print to stdout by default.

runtime/mercury_stacks.[ch]:
	Modify the macros that allocate stack frames to invoke the code for
	adding new stack segments when we are about to run out of stack.

	Standardize on "nondet" over "nond" as the abbreviation referring to
	the nondet stack.

	Conform to the changes in mercury_debug.c.

runtime/mercury_stack_trace.c:
	When traversing the stack, step over the placeholder stack frames
	at the bottoms of stack segments.

	Conform to the changes in mercury_debug.c.

runtime/mercury_wrapper.[ch]:
	Make the default stack size small in grades that support stack
	segments.

	Standardize on "nondet" over "nond" as the abbreviation referring to
	the nondet stack.

	Conform to the changes in mercury_debug.c.

runtime/mercury_memory.c:
	Standardize on "nondet" over "nond" as the abbreviation referring to
	the nondet stack.

runtime/mercury_engine.[ch]:
runtime/mercury_overflow.h:
	Standardize on "nondet" over "nond" as the abbreviation referring to
	the nondet stack.

	Convert these files to four-space indentation.

runtime/mercury_minimal_model.c:
trace/mercury_trace.c:
trace/mercury_trace_util.c:
	Conform to the changes in mercury_debug.c.

compiler/options.m:
	Add the new grade option for stack segments.

compiler/compile_target_code.m:
compiler/handle_options.m:
	Add the new grade component, and handle its exclusions with other grade
	components and optimizations.

compiler/llds.m:
	Extend the incr_sp instruction to record whether the stack frame
	is for a leaf procedure.

compiler/llds_out.m:
	Output the extended incr_sp instruction.

compiler/proc_gen.m:
	Fill in the extra slot in incr_sp instructions.

compiler/goal_util.m:
	Provide a predicate for testing whether a procedure body is a leaf.

compiler/delay_slot.m:
compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/frameopt.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/peephole.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Conform to the change in llds.m.

scripts/canonicate_grade.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/parse_grade_options.sh-subr:
scripts/final_grade_options.sh-subr:
scripts/mgnuc.in:
	Handle the new grade component.

	Convert parse_grade_options.sh-subr to four-space indentation.

Mmake.workspace:
	Fix an old bug that prevented bootcheck from working in the new grade:
	when computing the gc grade, use the workspace's version of ml (which
	in this case understands the new grade components), rather than the
	installed ml (which does not).

	(This was a devil to track down, because neither make --debug nor
	strace on make revealed how the installed ml was being invoked,
	and there was no explicit invocation in the Makefile either; the error
	message appeared to come out of thin air just before the completion
	of the stage 2 library. It turned out the invocation happened
	implicitly, as a result of expanding a make variable.)

cvs diff: Diffing .
Index: Mmake.workspace
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/Mmake.workspace,v
retrieving revision 1.24
diff -u -b -r1.24 Mmake.workspace
--- Mmake.workspace	17 Oct 2006 06:07:52 -0000	1.24
+++ Mmake.workspace	30 Oct 2006 13:17:31 -0000
@@ -155,7 +155,7 @@
 # passed to echo in order to preserve double-quotes (e.g. for
 # file names containing spaces).
 #
-GC_LIBS_0=`ml --grade $(GRADE) --print-gc-grade`
+GC_LIBS_0=`$(ML) --grade $(GRADE) --print-gc-grade`
 GC_LIBS=$(shell echo $(GC_LIBS_0))
 
 STATIC_GC_LIBS_0 = 						\
cvs diff: Diffing analysis
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/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/compile_target_code.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/compile_target_code.m,v
retrieving revision 1.96
diff -u -b -r1.96 compile_target_code.m
--- compiler/compile_target_code.m	5 Oct 2006 04:45:31 -0000	1.96
+++ compiler/compile_target_code.m	20 Oct 2006 03:51:59 -0000
@@ -581,12 +581,24 @@
         ExecTraceOpt = ""
     ),
     globals.io_lookup_bool_option(extend_stacks_when_needed, Extend, !IO),
+    globals.io_lookup_bool_option(stack_segments, StackSegments, !IO),
     (
         Extend = yes,
+        StackSegments = no,
         ExtendOpt = "-DMR_EXTEND_STACKS_WHEN_NEEDED "
     ;
         Extend = no,
+        StackSegments = yes,
+        ExtendOpt = "-DMR_STACK_SEGMENTS "
+    ;
+        Extend = no,
+        StackSegments = no,
         ExtendOpt = ""
+    ;
+        Extend = yes,
+        StackSegments = yes,
+        ExtendOpt = unexpected(this_file,
+            "compile_c_file: --extend-stacks-when-needed and --stack-segments")
     ),
     globals.io_lookup_bool_option(target_debug, Target_Debug, !IO),
     (
Index: compiler/delay_slot.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/delay_slot.m,v
retrieving revision 1.18
diff -u -b -r1.18 delay_slot.m
--- compiler/delay_slot.m	31 Jul 2006 08:31:34 -0000	1.18
+++ compiler/delay_slot.m	26 Oct 2006 12:41:45 -0000
@@ -75,7 +75,7 @@
         Instr0 = label(_) - _,
         Instrs0 = [Instr1, Instr2, Instr3 | Tail0],
         Instr1 = if_val(_, _) - _,
-        Instr2 = incr_sp(Size, _) - _,
+        Instr2 = incr_sp(Size, _, _) - _,
         Instr3 = assign(stackvar(Size), lval(succip)) - C2
     ->
         fill_branch_delay_slot(Tail0, Tail1),
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.85
diff -u -b -r1.85 dupelim.m
--- compiler/dupelim.m	15 Oct 2006 23:26:39 -0000	1.85
+++ compiler/dupelim.m	26 Oct 2006 12:42:10 -0000
@@ -407,7 +407,7 @@
         standardize_rval(Rval1, Rval),
         Instr = prune_tickets_to(Rval)
     ;
-        Instr1 = incr_sp(_, _),
+        Instr1 = incr_sp(_, _, _),
         Instr = Instr1
     ;
         Instr1 = decr_sp(_),
@@ -729,7 +729,7 @@
         ; Instr1 = restore_maxfr(_)
         ; Instr1 = discard_ticket
         ; Instr1 = prune_ticket
-        ; Instr1 = incr_sp(_, _)
+        ; Instr1 = incr_sp(_, _, _)
         ; Instr1 = decr_sp(_)
         ; Instr1 = decr_sp_and_return(_)
         ; Instr1 = pragma_c(_, _, _, _, _, _, _, _, _)
Index: compiler/dupproc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupproc.m,v
retrieving revision 1.14
diff -u -b -r1.14 dupproc.m
--- compiler/dupproc.m	15 Oct 2006 23:26:39 -0000	1.14
+++ compiler/dupproc.m	26 Oct 2006 12:42:30 -0000
@@ -259,8 +259,8 @@
         Instr = prune_tickets_to(_),
         StdInstr = Instr
     ;
-        Instr = incr_sp(NumSlots, _),
-        StdInstr = incr_sp(NumSlots, "")
+        Instr = incr_sp(NumSlots, _, Kind),
+        StdInstr = incr_sp(NumSlots, "", Kind)
     ;
         Instr = decr_sp(_),
         StdInstr = Instr
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.77
diff -u -b -r1.77 exprn_aux.m
--- compiler/exprn_aux.m	15 Oct 2006 23:26:39 -0000	1.77
+++ compiler/exprn_aux.m	26 Oct 2006 12:42:40 -0000
@@ -349,7 +349,7 @@
         ; Uinstr0 = goto(_)
         ; Uinstr0 = prune_ticket
         ; Uinstr0 = discard_ticket
-        ; Uinstr0 = incr_sp(_, _)
+        ; Uinstr0 = incr_sp(_, _, _)
         ; Uinstr0 = decr_sp(_)
         ; Uinstr0 = decr_sp_and_return(_)
         ; Uinstr0 = fork(_)
Index: compiler/frameopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/frameopt.m,v
retrieving revision 1.106
diff -u -b -r1.106 frameopt.m
--- compiler/frameopt.m	15 Oct 2006 23:26:40 -0000	1.106
+++ compiler/frameopt.m	26 Oct 2006 12:54:41 -0000
@@ -437,8 +437,9 @@
 
 :- type det_entry_info
     --->    det_entry(
+                int,            % The frame size.
                 string,         % The msg of the incr_sp instruction.
-                int             % The frame size.
+                stack_incr_kind
             ).
 
 :- type det_exit_info
@@ -777,10 +778,10 @@
 detect_det_entry(Instrs0, Setup, Others ++ Remain, EntryInfo) :-
     opt_util.gather_comments(Instrs0, Others0, Instrs1),
     Instrs1 = [SetupInstr1 | Instrs2],
-    SetupInstr1 = incr_sp(FrameSize, Msg) - _,
+    SetupInstr1 = incr_sp(FrameSize, Msg, Kind) - _,
     detstack_setup(Instrs2, FrameSize, SetupInstr2, Others0, Others, Remain),
     Setup = [SetupInstr1, SetupInstr2],
-    EntryInfo = det_entry(Msg, FrameSize).
+    EntryInfo = det_entry(FrameSize, Msg, Kind).
 
 :- pred detstack_setup(list(instruction)::in, int::in, instruction::out,
     list(instruction)::in, list(instruction)::out, list(instruction)::out)
@@ -833,7 +834,7 @@
     det_exit_info::out) is semidet.
 
 detect_det_exit(Instrs0, EntryInfo, Extra, ExitInstrs, Remain, ExitInfo) :-
-    EntryInfo = det_entry(_Msg, FrameSize),
+    EntryInfo = det_entry(FrameSize, _Msg, _),
     detstack_teardown(Instrs0, FrameSize, Extra, SuccipRestore, Decrsp,
         Livevals, Goto, Remain),
     ExitInstrs = SuccipRestore ++ Decrsp ++ Livevals ++ [Goto],
@@ -2148,8 +2149,8 @@
 
 :- func det_late_setup(det_entry_info) = list(instruction).
 
-det_late_setup(det_entry(Msg, FrameSize)) =
-    [incr_sp(FrameSize, Msg) - "late setup",
+det_late_setup(det_entry(FrameSize, Msg, Kind)) =
+    [incr_sp(FrameSize, Msg, Kind) - "late setup",
     assign(stackvar(FrameSize), lval(succip)) - "late save"].
 
 :- func det_non_teardown_exit_code(det_exit_info) = list(instruction).
@@ -2313,8 +2314,11 @@
 
 :- func describe_det_entry(det_entry_info) = string.
 
-describe_det_entry(det_entry(Msg, Size)) =
-    "msg: " ++ Msg ++ ", size: " ++ int_to_string(Size) ++ "\n".
+describe_det_entry(det_entry(Size, Msg, Kind)) =
+    "size: " ++ int_to_string(Size) ++
+    ", msg: " ++ Msg ++
+    ", kind: " ++ dump_stack_incr_kind(Kind) ++
+    "\n".
 
 :- func describe_det_exit(proc_label, det_exit_info) = string.
 
Index: compiler/global_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/global_data.m,v
retrieving revision 1.26
diff -u -b -r1.26 global_data.m
--- compiler/global_data.m	29 Sep 2006 06:34:48 -0000	1.26
+++ compiler/global_data.m	26 Oct 2006 12:44:59 -0000
@@ -944,7 +944,7 @@
         ; Instr0 = discard_ticket
         ; Instr0 = mark_ticket_stack(_)
         ; Instr0 = prune_tickets_to(_)
-        ; Instr0 = incr_sp(_, _)
+        ; Instr0 = incr_sp(_, _, _)
         ; Instr0 = decr_sp(_)
         ; Instr0 = decr_sp_and_return(_)
         ; Instr0 = init_sync_term(_, _)
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.139
diff -u -b -r1.139 goal_util.m
--- compiler/goal_util.m	15 Oct 2006 23:26:40 -0000	1.139
+++ compiler/goal_util.m	26 Oct 2006 12:40:32 -0000
@@ -152,6 +152,14 @@
 :- pred extra_nonlocal_typeinfos(rtti_varmaps::in, vartypes::in,
     existq_tvars::in, set(prog_var)::in, set(prog_var)::out) is det.
 
+:- type is_leaf
+    --->    is_leaf
+    ;       is_not_leaf.
+
+    % See whether the given procedure body is that of a leaf procedure.
+    %
+:- func proc_body_is_leaf(hlds_goal) = is_leaf.
+
     % See whether the goal is a branched structure.
     %
 :- pred goal_is_branched(hlds_goal_expr::in) is semidet.
@@ -1005,6 +1013,92 @@
 
 %-----------------------------------------------------------------------------%
 
+proc_body_is_leaf(GoalExpr - _) = IsLeaf :-
+    (
+        GoalExpr = unify(_, _, _, UnifyKind, _),
+        (
+            UnifyKind = complicated_unify(_, _, _),
+            IsLeaf = is_not_leaf
+        ;
+            ( UnifyKind = construct(_, _, _, _, _, _, _)
+            ; UnifyKind = deconstruct(_, _, _, _, _, _)
+            ; UnifyKind = assign(_, _)
+            ; UnifyKind = simple_test(_, _)
+            ),
+            IsLeaf = is_leaf
+        )
+    ;
+        ( GoalExpr = plain_call(_, _, _, _, _, _)
+        ; GoalExpr = generic_call(_, _, _, _)
+        ; GoalExpr = call_foreign_proc(_, _, _, _, _, _, _)
+        ),
+        IsLeaf = is_not_leaf
+    ;
+        ( GoalExpr = conj(_, Goals)
+        ; GoalExpr = disj(Goals)
+        ),
+        IsLeaf = proc_body_is_leaf_goals(Goals)
+    ;
+        ( GoalExpr = negation(Goal)
+        ; GoalExpr = scope(_, Goal)
+        ),
+        IsLeaf = proc_body_is_leaf(Goal)
+    ;
+        GoalExpr = switch(_, _, Cases),
+        IsLeaf = proc_body_is_leaf_cases(Cases)
+    ;
+        GoalExpr = if_then_else(_, Cond, Then, Else),
+        ( 
+            proc_body_is_leaf(Cond) = is_leaf,
+            proc_body_is_leaf(Then) = is_leaf,
+            proc_body_is_leaf(Else) = is_leaf
+        ->
+            IsLeaf = is_leaf
+        ;
+            IsLeaf = is_not_leaf
+        )
+    ;
+        GoalExpr = shorthand(ShortHand),
+        ShortHand = bi_implication(GoalA, GoalB),
+        ( 
+            proc_body_is_leaf(GoalA) = is_leaf,
+            proc_body_is_leaf(GoalB) = is_leaf
+        ->
+            IsLeaf = is_leaf
+        ;
+            IsLeaf = is_not_leaf
+        )
+    ).
+
+:- func proc_body_is_leaf_goals(list(hlds_goal)) = is_leaf.
+
+proc_body_is_leaf_goals([]) = is_leaf.
+proc_body_is_leaf_goals([Goal | Goals]) = IsLeaf :-
+    ( 
+        proc_body_is_leaf(Goal) = is_leaf,
+        proc_body_is_leaf_goals(Goals) = is_leaf
+    ->
+        IsLeaf = is_leaf
+    ;
+        IsLeaf = is_not_leaf
+    ).
+
+:- func proc_body_is_leaf_cases(list(case)) = is_leaf.
+
+proc_body_is_leaf_cases([]) = is_leaf.
+proc_body_is_leaf_cases([Case | Cases]) = IsLeaf :-
+    Case = case(_, Goal),
+    ( 
+        proc_body_is_leaf(Goal) = is_leaf,
+        proc_body_is_leaf_cases(Cases) = is_leaf
+    ->
+        IsLeaf = is_leaf
+    ;
+        IsLeaf = is_not_leaf
+    ).
+
+%-----------------------------------------------------------------------------%
+
 goal_is_branched(if_then_else(_, _, _, _)).
 goal_is_branched(switch(_, _, _)).
 goal_is_branched(disj(_)).
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.276
diff -u -b -r1.276 handle_options.m
--- compiler/handle_options.m	5 Oct 2006 04:45:32 -0000	1.276
+++ compiler/handle_options.m	29 Oct 2006 01:03:53 -0000
@@ -1362,6 +1362,13 @@
         % negation, disjunction, or commit.
         option_implies(use_trail, middle_rec, bool(no), !Globals),
 
+        % The cut-down stack frames used by middle recursion optimization
+        % don't include return addresses. Since stack extension arranges for
+        % the return to the old stack segments by overriding the return
+        % address, stack extension via stack segments and middle recursion
+        % optimization are incompatible.
+        option_implies(stack_segments, middle_rec, bool(no), !Globals),
+
         % Stack copy minimal model tabling needs to be able to rewrite all
         % the redoips in a given nondet stack segments. If we allow hijacks,
         % some of these redoips may have been saved in ordinary framevars,
@@ -1986,17 +1993,16 @@
     set.init(NoComps),
     list.foldl2((pred(CompStr::in, Opts0::in, Opts::out,
             CompSet0::in, CompSet::out) is semidet :-
-        grade_component_table(CompStr, Comp, CompOpts, MaybeTargets,
-            _),
-            % Check that the component isn't mentioned
-            % more than once.
+        grade_component_table(CompStr, Comp, CompOpts, MaybeTargets, _),
+
+        % Check that the component isn't mentioned more than once.
         \+ set.member(Comp, CompSet0),
         set.insert(CompSet0, Comp, CompSet),
         add_option_list(CompOpts, Opts0, Opts1),
 
-            % XXX Here the behaviour matches what used to happen
-            % and that is to only set the target option iff there
-            % was only one possible target.  Is this a bug?
+        % XXX Here the behaviour matches what used to happen and that is
+        % to only set the target option iff there was only one possible target.
+        % Is this a bug?
         ( MaybeTargets = yes([Target]) ->
             add_option_list([target - Target], Opts1, Opts)
         ;
@@ -2060,28 +2066,23 @@
     solutions.solutions((pred(CompData::out) is nondet :-
         grade_component_table(Name, Comp, CompOpts, MaybeTargets,
             IncludeInGradeString),
-            % For possible component of the grade string
-            % include it in the actual grade string if all
-            % the option setting that it implies are true.
-            % ie
-            %   all [Opt, Value] (
-            %       member(Opt - Value, CompOpts) =>
-            %       map.search(Options, Opt, Value)
-            %   )
-        \+ (
-            list.member(Opt - Value, CompOpts),
-            \+ map.search(Options, Opt, Value)
+
+        % For a possible component of the grade string include, it in the
+        % actual grade string if all the option settings that it implies
+        % are true.
+        all [Opt, Value] (
+            member(Opt - Value, CompOpts)
+        =>
+            map.search(Options, Opt, Value)
         ),
-            % Don't include `.mm' or `.dmm' in grade strings
-            % because they are just synonyms for `.mmsc' and
-            % `.dmmsc' respectively.
-            %
+
+        % Don't include `.mm' or `.dmm' in grade strings because they are just
+        % synonyms for `.mmsc' and `.dmmsc' respectively.
         IncludeInGradeString = yes,
 
-            % When checking gcc_ext there exist grades which
-            % can have more then one possible target, ensure that
-            % the target in the options table matches one of the
-            % possible targets.
+        % When checking gcc_ext there exist grades which can have more than one
+        % possible target, ensure that the target in the options table matches
+        % one of the possible targets.
         (
             MaybeTargets = yes(Targets),
             list.member(Target, Targets),
@@ -2108,7 +2109,7 @@
 :- mode grade_component_table(out, in, out, out, out) is multi.
 :- mode grade_component_table(out, out, out, out, out) is multi.
 
-    % Base components
+    % Base components.
     % These specify the basic compilation model we use,
     % including the choice of back-end and the use of gcc extensions.
 grade_component_table("none", comp_gcc_ext, [
@@ -2219,13 +2220,13 @@
     % Parallelism/multithreading components.
 grade_component_table("par", comp_par, [parallel - bool(yes)], no, yes).
 
-    % GC components
+    % GC components.
 grade_component_table("gc", comp_gc, [gc - string("boehm")], no, yes).
 grade_component_table("gcd", comp_gc, [gc - string("boehm_debug")], no, yes).
 grade_component_table("mps", comp_gc, [gc - string("mps")], no, yes).
 grade_component_table("agc", comp_gc, [gc - string("accurate")], no, yes).
 
-    % Profiling components
+    % Profiling components.
 grade_component_table("prof", comp_prof,
     [profile_time - bool(yes), profile_calls - bool(yes),
     profile_memory - bool(no), profile_deep - bool(no)], no, yes).
@@ -2245,7 +2246,7 @@
     [profile_time - bool(no), profile_calls - bool(no),
     profile_memory - bool(no), profile_deep - bool(yes)], no, yes).
 
-    % Term size components
+    % Term size components.
 grade_component_table("tsw", comp_term_size,
     [record_term_sizes_as_words - bool(yes),
     record_term_sizes_as_cells - bool(no)], no, yes).
@@ -2253,13 +2254,13 @@
     [record_term_sizes_as_words - bool(no),
     record_term_sizes_as_cells - bool(yes)], no, yes).
 
-    % Trailing components
+    % Trailing components.
 grade_component_table("tr", comp_trail, [use_trail - bool(yes)], no, yes).
 
-    % Tag reservation components
+    % Tag reservation components.
 grade_component_table("rt", comp_tag, [reserve_tag - bool(yes)], no, yes).
 
-    % Minimal model tabling components
+    % Minimal model tabling components.
     % NOTE: we do not include `.mm' and `.dmm' in grade strings
     % because they are just synonyms for `.mmsc' and `.dmmsc'.
     %
@@ -2288,22 +2289,26 @@
     use_minimal_model_own_stacks - bool(yes),
     minimal_model_debug - bool(yes)], no, yes).
 
-    % Pic reg components
+    % Pic reg components.
 grade_component_table("picreg", comp_pic, [pic_reg - bool(yes)], no, yes).
 
-    % Debugging/Tracing components
+    % Debugging/Tracing components.
 grade_component_table("decldebug", comp_trace,
     [exec_trace - bool(yes), decl_debug - bool(yes)], no, yes).
 grade_component_table("debug", comp_trace,
     [exec_trace - bool(yes), decl_debug - bool(no)], no, yes).
 
-    % Stack extension components
+    % Low (target) level debugging components.
 grade_component_table("ll_debug", comp_lowlevel,
     [target_debug - bool(yes)], no, yes).
 
-    % Stack extension components
+    % Stack extension components.
 grade_component_table("exts", comp_stack_extend,
-    [extend_stacks_when_needed - bool(yes)], no, yes).
+    [extend_stacks_when_needed - bool(yes), stack_segments - bool(no)],
+    no, yes).
+grade_component_table("stseg", comp_stack_extend,
+    [extend_stacks_when_needed - bool(no), stack_segments - bool(yes)],
+    no, yes).
 
 :- pred reset_grade_options(option_table::in, option_table::out) is det.
 
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.94
diff -u -b -r1.94 jumpopt.m
--- compiler/jumpopt.m	15 Oct 2006 23:26:41 -0000	1.94
+++ compiler/jumpopt.m	26 Oct 2006 12:45:11 -0000
@@ -786,7 +786,7 @@
         ; Uinstr0 = label(_)
         ; Uinstr0 = save_maxfr(_)
         ; Uinstr0 = restore_maxfr(_)
-        ; Uinstr0 = incr_sp(_, _)
+        ; Uinstr0 = incr_sp(_, _, _)
         ; Uinstr0 = decr_sp(_)
         ; Uinstr0 = decr_sp_and_return(_)
         ; Uinstr0 = store_ticket(_)
Index: compiler/livemap.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/livemap.m,v
retrieving revision 1.81
diff -u -b -r1.81 livemap.m
--- compiler/livemap.m	15 Oct 2006 23:26:43 -0000	1.81
+++ compiler/livemap.m	26 Oct 2006 12:45:15 -0000
@@ -273,7 +273,7 @@
         Uinstr0 = prune_tickets_to(Rval),
         livemap.make_live_in_rval(Rval, !Livevals)
     ;
-        Uinstr0 = incr_sp(_, _)
+        Uinstr0 = incr_sp(_, _, _)
     ;
         Uinstr0 = decr_sp(_)
     ;
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.341
diff -u -b -r1.341 llds.m
--- compiler/llds.m	15 Oct 2006 23:26:43 -0000	1.341
+++ compiler/llds.m	27 Oct 2006 04:06:57 -0000
@@ -411,7 +411,7 @@
             %   MR_ticket_counter = rval;
             %   MR_ticket_high_water = MR_ticket_counter;
 
-    ;       incr_sp(int, string)
+    ;       incr_sp(int, string, stack_incr_kind)
             % Increment the det stack pointer. The string is the name of the
             % procedure, for use in collecting statistics about stack frame
             % sizes.
@@ -493,6 +493,12 @@
             % The label gives the address of the code following the parallel
             % conjunction. 
 
+:- type stack_incr_kind
+    --->    stack_incr_leaf         % The incr_sp creates the stack frame
+                                    % of a leaf procedure.
+    ;       stack_incr_nonleaf.     % The incr_sp creates the stack frame
+                                    % of a nonleaf procedure.
+
 :- type nondet_frame_info
     --->    temp_frame(
                 temp_frame_type
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.295
diff -u -b -r1.295 llds_out.m
--- compiler/llds_out.m	15 Oct 2006 23:26:43 -0000	1.295
+++ compiler/llds_out.m	27 Oct 2006 09:15:10 -0000
@@ -1967,7 +1967,7 @@
     output_lval_decls(Lval, !DeclSet, !IO).
 output_instr_decls(_, prune_tickets_to(Rval), !DeclSet, !IO) :-
     output_rval_decls(Rval, !DeclSet, !IO).
-output_instr_decls(_, incr_sp(_, _), !DeclSet, !IO).
+output_instr_decls(_, incr_sp(_, _, _), !DeclSet, !IO).
 output_instr_decls(_, decr_sp(_), !DeclSet, !IO).
 output_instr_decls(_, decr_sp_and_return(_), !DeclSet, !IO).
 output_instr_decls(StackLayoutLabels, pragma_c(_, Comps, _, _,
@@ -2523,8 +2523,18 @@
     output_rval_as_type(Rval, word, !IO),
     io.write_string(");\n", !IO).
 
-output_instruction(incr_sp(N, _Msg), _, !IO) :-
-    io.write_string("\tMR_incr_sp(", !IO),
+output_instruction(incr_sp(N, _Msg, Kind), _, !IO) :-
+    (
+        Kind = stack_incr_leaf,
+        ( N < max_leaf_stack_frame_size ->
+            io.write_string("\tMR_incr_sp_leaf(", !IO)
+        ;
+            io.write_string("\tMR_incr_sp(", !IO)
+        )
+    ;
+        Kind = stack_incr_nonleaf,
+        io.write_string("\tMR_incr_sp(", !IO)
+    ),
     io.write_int(N, !IO),
     io.write_string(");\n", !IO).
     % Use the code below instead of the code above if you want to run
@@ -2570,6 +2580,12 @@
     output_label_as_code_addr(Label, !IO),
     io.write_string(");\n", !IO).
 
+:- func max_leaf_stack_frame_size = int.
+
+% This should be kept in sync with the value of MR_stack_margin_size
+% in runtime/mercury_wrapper.c. See the documentation there.
+max_leaf_stack_frame_size = 128.
+
 :- pred output_pragma_c_component(pragma_c_component::in, io::di, io::uo)
     is det.
 
Index: compiler/middle_rec.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/middle_rec.m,v
retrieving revision 1.124
diff -u -b -r1.124 middle_rec.m
--- compiler/middle_rec.m	15 Oct 2006 23:26:46 -0000	1.124
+++ compiler/middle_rec.m	26 Oct 2006 12:46:00 -0000
@@ -306,7 +306,7 @@
                 - "test on upward loop"]
     ;
         PushMsg = proc_gen.push_msg(ModuleInfo, PredId, ProcId),
-        MaybeIncrSp = [incr_sp(FrameSize, PushMsg) - ""],
+        MaybeIncrSp = [incr_sp(FrameSize, PushMsg, stack_incr_nonleaf) - ""],
         MaybeDecrSp = [decr_sp(FrameSize) - ""],
         InitAuxReg =  [assign(AuxReg, lval(sp))
             - "initialize counter register"],
@@ -529,7 +529,7 @@
     find_used_registers_lval(Lval, !Used).
 find_used_registers_instr(prune_tickets_to(Rval), !Used) :-
     find_used_registers_rval(Rval, !Used).
-find_used_registers_instr(incr_sp(_, _), !Used).
+find_used_registers_instr(incr_sp(_, _, _), !Used).
 find_used_registers_instr(decr_sp(_), !Used).
 find_used_registers_instr(decr_sp_and_return(_), !Used).
 find_used_registers_instr(pragma_c(_, Components, _, _, _, _, _, _, _),
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.179
diff -u -b -r1.179 opt_debug.m
--- compiler/opt_debug.m	15 Oct 2006 23:26:46 -0000	1.179
+++ compiler/opt_debug.m	27 Oct 2006 06:37:33 -0000
@@ -108,14 +108,16 @@
 
 :- func dump_bool(bool) = string.
 
+:- func dump_code_model(code_model) = string.
+
+:- func dump_stack_incr_kind(stack_incr_kind) = string.
+
 :- func dump_instr(proc_label, bool, instr) = string.
 
 :- func dump_fullinstr(proc_label, bool, instruction) = string.
 
 :- func dump_fullinstrs(proc_label, bool, list(instruction)) = string.
 
-:- func dump_code_model(code_model) = string.
-
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -636,6 +638,9 @@
 dump_code_model(model_semi) = "model_semi".
 dump_code_model(model_non) = "model_non".
 
+dump_stack_incr_kind(stack_incr_leaf) = "leaf".
+dump_stack_incr_kind(stack_incr_nonleaf) = "nonleaf".
+
 dump_instr(ProcLabel, PrintComments, Instr) = Str :-
     (
         Instr = comment(Comment),
@@ -774,8 +779,9 @@
         Instr = prune_tickets_to(Rval),
         Str = "prune_tickets_to(" ++ dump_rval(Rval) ++ ")"
     ;
-        Instr = incr_sp(Size, _),
-        Str = "incr_sp(" ++ int_to_string(Size) ++ ")"
+        Instr = incr_sp(Size, _, Kind),
+        Str = "incr_sp(" ++ int_to_string(Size) ++ ", " ++
+            dump_stack_incr_kind(Kind) ++ ")"
     ;
         Instr = decr_sp(Size),
         Str = "decr_sp(" ++ int_to_string(Size) ++ ")"
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.155
diff -u -b -r1.155 opt_util.m
--- compiler/opt_util.m	15 Oct 2006 23:26:47 -0000	1.155
+++ compiler/opt_util.m	26 Oct 2006 12:51:56 -0000
@@ -847,7 +847,7 @@
         Uinstr = prune_tickets_to(Rval),
         Refers = rval_refers_stackvars(Rval)
     ;
-        Uinstr = incr_sp(_, _),
+        Uinstr = incr_sp(_, _, _),
         Refers = yes
     ;
         Uinstr = decr_sp(_),
@@ -1000,7 +1000,7 @@
 can_instr_branch_away(prune_ticket, no).
 can_instr_branch_away(mark_ticket_stack(_), no).
 can_instr_branch_away(prune_tickets_to(_), no).
-can_instr_branch_away(incr_sp(_, _), no).
+can_instr_branch_away(incr_sp(_, _, _), no).
 can_instr_branch_away(decr_sp(_), no).
 can_instr_branch_away(decr_sp_and_return(_), yes).
 can_instr_branch_away(init_sync_term(_, _), no).
@@ -1076,7 +1076,7 @@
 can_instr_fall_through(prune_ticket, yes).
 can_instr_fall_through(mark_ticket_stack(_), yes).
 can_instr_fall_through(prune_tickets_to(_), yes).
-can_instr_fall_through(incr_sp(_, _), yes).
+can_instr_fall_through(incr_sp(_, _, _), yes).
 can_instr_fall_through(decr_sp(_), yes).
 can_instr_fall_through(decr_sp_and_return(_), no).
 can_instr_fall_through(init_sync_term(_, _), yes).
@@ -1122,7 +1122,7 @@
 can_use_livevals(prune_ticket, no).
 can_use_livevals(mark_ticket_stack(_), no).
 can_use_livevals(prune_tickets_to(_), no).
-can_use_livevals(incr_sp(_, _), no).
+can_use_livevals(incr_sp(_, _, _), no).
 can_use_livevals(decr_sp(_), no).
 can_use_livevals(decr_sp_and_return(_), yes).
 can_use_livevals(init_sync_term(_, _), no).
@@ -1185,7 +1185,7 @@
 instr_labels_2(prune_ticket, [], []).
 instr_labels_2(mark_ticket_stack(_), [], []).
 instr_labels_2(prune_tickets_to(_), [], []).
-instr_labels_2(incr_sp(_, _), [], []).
+instr_labels_2(incr_sp(_, _, _), [], []).
 instr_labels_2(decr_sp(_), [], []).
 instr_labels_2(decr_sp_and_return(_), [], []) :-
     % XXX decr_sp_and_return does refer to a code addr, but the code addr it
@@ -1246,7 +1246,7 @@
 possible_targets(prune_ticket, [], []).
 possible_targets(mark_ticket_stack(_), [], []).
 possible_targets(prune_tickets_to(_), [], []).
-possible_targets(incr_sp(_, _), [], []).
+possible_targets(incr_sp(_, _, _), [], []).
 possible_targets(decr_sp(_), [], []).
 possible_targets(decr_sp_and_return(_), [], []) :-
     % See the comment in instr_labels_2.
@@ -1319,7 +1319,7 @@
 instr_rvals_and_lvals(prune_ticket, [], []).
 instr_rvals_and_lvals(mark_ticket_stack(Lval), [], [Lval]).
 instr_rvals_and_lvals(prune_tickets_to(Rval), [Rval], []).
-instr_rvals_and_lvals(incr_sp(_, _), [], []).
+instr_rvals_and_lvals(incr_sp(_, _, _), [], []).
 instr_rvals_and_lvals(decr_sp(_), [], []).
 instr_rvals_and_lvals(decr_sp_and_return(_), [], []).
 instr_rvals_and_lvals(init_sync_term(Lval, _), [], [Lval]).
@@ -1463,7 +1463,7 @@
     count_temps_lval(Lval, !R, !F).
 count_temps_instr(prune_tickets_to(Rval), !R, !F) :-
     count_temps_rval(Rval, !R, !F).
-count_temps_instr(incr_sp(_, _), !R, !F).
+count_temps_instr(incr_sp(_, _, _), !R, !F).
 count_temps_instr(decr_sp(_), !R, !F).
 count_temps_instr(decr_sp_and_return(_), !R, !F).
 count_temps_instr(init_sync_term(Lval, _), !R, !F) :-
@@ -1520,7 +1520,7 @@
 
 has_both_incr_decr_sp_2([], !HasIncr, !HasDecr).
 has_both_incr_decr_sp_2([Uinstr - _ | Instrs], !HasIncr, !HasDecr) :-
-    ( Uinstr = incr_sp(_, _) ->
+    ( Uinstr = incr_sp(_, _, _) ->
         !:HasIncr = yes
     ;
         true
@@ -1556,7 +1556,7 @@
         ; Uinstr = discard_ticket
         ; Uinstr = prune_tickets_to(_)
         ; Uinstr = mark_ticket_stack(_)
-        ; Uinstr = incr_sp(_, _)
+        ; Uinstr = incr_sp(_, _, _)
         ; Uinstr = decr_sp(_)
         ; Uinstr = decr_sp_and_return(_)
         ),
@@ -1954,7 +1954,7 @@
         ReplData = no,
         Rval = Rval0
     ).
-replace_labels_instr(incr_sp(Size, Msg), _, _, incr_sp(Size, Msg)).
+replace_labels_instr(incr_sp(Size, Msg, Kind), _, _, incr_sp(Size, Msg, Kind)).
 replace_labels_instr(decr_sp(Size), _, _, decr_sp(Size)).
 replace_labels_instr(decr_sp_and_return(Size), _, _, decr_sp_and_return(Size)).
 replace_labels_instr(init_sync_term(T, N), _, _, init_sync_term(T, N)).
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.532
diff -u -b -r1.532 options.m
--- compiler/options.m	5 Oct 2006 04:59:21 -0000	1.532
+++ compiler/options.m	27 Oct 2006 15:58:23 -0000
@@ -296,6 +296,7 @@
     ;       type_layout
     ;       maybe_thread_safe_opt
     ;       extend_stacks_when_needed
+    ;       stack_segments
 
     % Data representation compilation model options
     ;       reserve_tag
@@ -1040,6 +1041,7 @@
     use_trail                           -   bool(no),
     maybe_thread_safe_opt               -   string("no"),
     extend_stacks_when_needed           -   bool(no),
+    stack_segments                      -   bool(no),
     use_minimal_model_stack_copy        -   bool(no),
     use_minimal_model_own_stacks        -   bool(no),
     minimal_model_debug                 -   bool(no),
@@ -1774,6 +1776,7 @@
 long_option("type-layout",          type_layout).
 long_option("maybe-thread-safe",    maybe_thread_safe_opt).
 long_option("extend-stacks-when-needed",    extend_stacks_when_needed).
+long_option("stack-segments",       stack_segments).
 % Data representation options
 long_option("reserve-tag",          reserve_tag).
 long_option("use-minimal-model-stack_copy", use_minimal_model_stack_copy).
@@ -3575,7 +3578,10 @@
         "\tattribute.  The default is no.",
         "--extend-stacks-when-needed",
         "\tSpecify that code that increments a stack pointer must",
-        "\textend the stack when this is needed."
+        "\textend the stack when this is needed.",
+        "--stack-segments-needed",
+        "\tSpecify that code that increments a stack pointer must allocate",
+        "\ta new stack segment when the limit on the old one is reached."
     ]),
 
     io.write_string("\n    LLDS back-end compilation model options:\n"),
Index: compiler/peephole.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/peephole.m,v
retrieving revision 1.93
diff -u -b -r1.93 peephole.m
--- compiler/peephole.m	15 Oct 2006 23:26:49 -0000	1.93
+++ compiler/peephole.m	26 Oct 2006 12:48:18 -0000
@@ -387,7 +387,7 @@
     %   succip = detstackvar(N)
     %   decr_sp N
     %
-peephole.match(incr_sp(N, _), _, InvalidPatterns, Instrs0, Instrs) :-
+peephole.match(incr_sp(N, _, _), _, InvalidPatterns, Instrs0, Instrs) :-
     \+ list.member(incr_sp, InvalidPatterns),
     ( opt_util.no_stackvars_til_decr_sp(Instrs0, N, Between, Remain) ->
         Instrs = Between ++ Remain
Index: compiler/proc_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_gen.m,v
retrieving revision 1.9
diff -u -b -r1.9 proc_gen.m
--- compiler/proc_gen.m	15 Oct 2006 23:26:50 -0000	1.9
+++ compiler/proc_gen.m	26 Oct 2006 12:48:48 -0000
@@ -910,7 +910,8 @@
     Arity = pred_info_orig_arity(PredInfo),
 
     PushMsg = push_msg(ModuleInfo, PredId, ProcId),
-    ( CodeModel = model_non ->
+    (
+        CodeModel = model_non,
         code_info.resume_point_stack_addr(OutsideResumePoint,
             OutsideResumeAddress),
         (
@@ -941,13 +942,26 @@
             ]),
             NondetPragma = no
         )
-    ; TotalSlots > 0 ->
+    ;
+        ( CodeModel = model_det
+        ; CodeModel = model_semi
+        ),
+        IsLeaf = proc_body_is_leaf(Goal),
+        (
+            IsLeaf = is_not_leaf,
+            StackIncrKind = stack_incr_nonleaf
+        ;
+            IsLeaf = is_leaf,
+            StackIncrKind = stack_incr_leaf
+        ),
+        ( TotalSlots > 0 ->
         AllocCode = node([
-            incr_sp(TotalSlots, PushMsg) - "Allocate stack frame"
-        ]),
-        NondetPragma = no
+                incr_sp(TotalSlots, PushMsg, StackIncrKind)
+                    - "Allocate stack frame"
+            ])
     ;
-        AllocCode = empty,
+            AllocCode = empty
+        ),
         NondetPragma = no
     ),
     FrameInfo = frame(TotalSlots, MaybeSuccipSlot, NondetPragma),
Index: compiler/reassign.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/reassign.m,v
retrieving revision 1.20
diff -u -b -r1.20 reassign.m
--- compiler/reassign.m	26 Sep 2006 03:53:18 -0000	1.20
+++ compiler/reassign.m	26 Oct 2006 12:48:36 -0000
@@ -264,7 +264,7 @@
 %       Uinstr0 = discard_tickets_to(_),
 %       !:RevInstrs = [Instr0 | !.RevInstrs]
     ;
-        Uinstr0 = incr_sp(_, _),
+        Uinstr0 = incr_sp(_, _, _),
         !:RevInstrs = [Instr0 | !.RevInstrs],
         % All stackvars now refer to new locations. Rather than delete
         % only stackvars from KnownContentsMap, we delete everything.
Index: compiler/use_local_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/use_local_vars.m,v
retrieving revision 1.27
diff -u -b -r1.27 use_local_vars.m
--- compiler/use_local_vars.m	26 Sep 2006 03:53:19 -0000	1.27
+++ compiler/use_local_vars.m	26 Oct 2006 12:41:12 -0000
@@ -512,7 +512,7 @@
     ;
         Uinstr0 = prune_tickets_to(_)
     ;
-        Uinstr0 = incr_sp(_, _)
+        Uinstr0 = incr_sp(_, _, _)
     ;
         Uinstr0 = decr_sp(_)
     ;
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
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/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/error
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
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/gears
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/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
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/solver_types
cvs diff: Diffing extras/solver_types/library
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/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_conf_param.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.89
diff -u -b -r1.89 mercury_conf_param.h
--- runtime/mercury_conf_param.h	4 Oct 2006 06:59:22 -0000	1.89
+++ runtime/mercury_conf_param.h	30 Oct 2006 06:46:50 -0000
@@ -56,7 +56,8 @@
 ** MR_USE_MINIMAL_MODEL_STACK_COPY
 ** MR_USE_MINIMAL_MODEL_OWN_STACKS
 ** MR_MINIMAL_MODEL_DEBUG
-** MR_SPLIT_C_FILES
+** MR_EXTEND_STACKS_WHEN_NEEDED
+** MR_STACK_SEGMENTS
 ** MR_INLINE_ALLOC
 ** MR_PIC_REG
 ** MR_HIGHTAGS
@@ -76,7 +77,8 @@
 **		--reserve-tag
 **		--use-minimal-model
 **		--minimal-model-debug
-**		--split-c-files
+**		--extend-stacks-when-needed
+**		--stack-segments
 **		--inline-alloc
 **		--pic-reg
 **		--tags
@@ -280,6 +282,10 @@
 ** MR_STACK_EXTEND_DEBUG
 **	Enables low-level debugging messages when extending the stacks.
 **
+** MR_DEBUG_STACK_SEGMENTS
+**	Enables low-level debugging messages when updating the list of
+**	stack segments.
+**
 ** MR_TRACE_CHECK_INTEGRITY
 **	Enables the -i and --integrity options on mdb's forward movement
 **	commands, which cause the debugger to check the integrity of the
Index: runtime/mercury_context.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_context.c,v
retrieving revision 1.50
diff -u -b -r1.50 mercury_context.c
--- runtime/mercury_context.c	3 Oct 2006 11:41:46 -0000	1.50
+++ runtime/mercury_context.c	29 Oct 2006 02:05:02 -0000
@@ -107,9 +107,9 @@
     MR_Generator *gen)
 {
     const char  *detstack_name;
-    const char  *nondstack_name;
+    const char  *nondetstack_name;
     size_t      detstack_size;
-    size_t      nondstack_size;
+    size_t      nondetstack_size;
 
     c->MR_ctxt_id = id;
     c->MR_ctxt_next = NULL;
@@ -124,15 +124,15 @@
     switch (c->MR_ctxt_size) {
         case MR_CONTEXT_SIZE_REGULAR:
             detstack_name  = "detstack";
-            nondstack_name = "nondetstack";
+            nondetstack_name = "nondetstack";
             detstack_size  = MR_detstack_size;
-            nondstack_size = MR_nondstack_size;
+            nondetstack_size = MR_nondetstack_size;
             break;
         case MR_CONTEXT_SIZE_SMALL:
             detstack_name  = "small_detstack";
-            nondstack_name = "small_nondetstack";
+            nondetstack_name = "small_nondetstack";
             detstack_size  = MR_small_detstack_size;
-            nondstack_size = MR_small_nondstack_size;
+            nondetstack_size = MR_small_nondetstack_size;
             break;
     }
 
@@ -146,7 +146,16 @@
                     0, detstack_size, MR_next_offset(),
                     MR_detstack_zone_size, MR_default_handler);
         }
+
+        if (c->MR_ctxt_prev_detstack_zones != NULL) {
+            /*
+            ** We may be able to reuse a previously allocated stack, but
+            ** a context should be reused only when its stacks are empty.
+            */
+            MR_fatal_error("MR_init_context_maybe_generator: prev det stack");
+        }
     }
+    c->MR_ctxt_prev_detstack_zones = NULL;
     c->MR_ctxt_sp = c->MR_ctxt_detstack_zone->MR_zone_min;
 
     if (c->MR_ctxt_nondetstack_zone == NULL) {
@@ -155,11 +164,21 @@
                     0, MR_gen_nonstack_size, MR_next_offset(),
                     MR_gen_nonstack_zone_size, MR_default_handler);
         } else {
-            c->MR_ctxt_nondetstack_zone = MR_create_zone(nondstack_name,
-                    0, nondstack_size, MR_next_offset(),
-                    MR_nondstack_zone_size, MR_default_handler);
+            c->MR_ctxt_nondetstack_zone = MR_create_zone(nondetstack_name,
+                    0, nondetstack_size, MR_next_offset(),
+                    MR_nondetstack_zone_size, MR_default_handler);
+        }
+
+        if (c->MR_ctxt_prev_nondetstack_zones != NULL) {
+            /*
+            ** We may be able to reuse a previously allocated stack, but
+            ** a context should be reused only when its stacks are empty.
+            */
+            MR_fatal_error(
+                "MR_init_context_maybe_generator: prev nondet stack");
         }
     }
+    c->MR_ctxt_prev_nondetstack_zones = NULL;
     /*
     ** Note that maxfr and curfr point to the last word in the frame,
     ** not to the first word, so we need to add the size of the frame,
@@ -250,9 +269,9 @@
     MR_num_outstanding_contexts_and_sparks++;
 
     /*
-    ** Regular contexts have stacks at least as big as
-    ** small contexts, so we can return a regular context in place of
-    ** a small context if one is already available.
+    ** Regular contexts have stacks at least as big as small contexts,
+    ** so we can return a regular context in place of a small context
+    ** if one is already available.
     */
     if (ctxt_size == MR_CONTEXT_SIZE_SMALL && free_small_context_list) {
         c = free_small_context_list;
Index: runtime/mercury_context.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_context.h,v
retrieving revision 1.34
diff -u -b -r1.34 mercury_context.h
--- runtime/mercury_context.h	11 Oct 2006 22:42:09 -0000	1.34
+++ runtime/mercury_context.h	30 Oct 2006 06:19:37 -0000
@@ -11,12 +11,12 @@
 ** mercury_context.h - defines Mercury multithreading stuff.
 **
 ** A "context" is a Mercury thread.  (We use a different term than "thread"
-** to avoid confusing Mercury threads and Posix threads.) 
+** to avoid confusing Mercury threads and POSIX threads.)
 ** Each context is represented by a value of type MR_Context,
 ** which contains a detstack, a nondetstack, a trail (if needed), the various
 ** pointers that refer to them, a succip, and a thread-resumption continuation. 
 ** Contexts are initally stored in a free-list.
-** When one is running, the Posix thread that is executing it has a pointer
+** When one is running, the POSIX thread that is executing it has a pointer
 ** to its context structure `this_context'. When a context suspends, it
 ** calls `MR_save_context(context_ptr)' which copies the context from the
 ** various registers and global variables into the structure referred to
@@ -28,18 +28,18 @@
 ** parallel conjunction. The code of a parallel conjunct has access
 ** to the procedure's stack frame via the `parent_sp' register.
 **
-** Contexts can migrate transparently between multiple Posix threads.
+** Contexts can migrate transparently between multiple POSIX threads.
 **
-** Each Posix thread has its own heap and solutions heap (both allocated
+** Each POSIX thread has its own heap and solutions heap (both allocated
 ** in shared memory). This makes GC harder, but enables heap allocation
 ** to be done without locking which is very important for performance.
 ** Each context has a copy of the heap pointer that is taken when it is
-** switched out. If the Posix thread's heap pointer is the same as the
+** switched out. If the POSIX thread's heap pointer is the same as the
 ** copied one when the context is switched back in, then it is safe for
 ** the context to do heap reclamation on failure.
 **
 ** If MR_THREAD_SAFE is not defined, then everything gets executed within a
-** single Posix thread. No locking is required.
+** single POSIX thread. No locking is required.
 */
 
 #ifndef MERCURY_CONTEXT_H
@@ -92,10 +92,14 @@
 **
 ** succip           The succip for this context.
 **
-** detstack_zone    The detstack zone for this context.
+** detstack_zone    The current detstack zone for this context.
+** prev_detstack_zones
+**                  A list of any previous detstack zones for this context.
 ** sp               The saved sp for this context.
 **
-** nondetstack_zone The nondetstack zone for this context.
+** nondetstack_zone The current nondetstack zone for this context.
+** prev_nondetstack_zones
+**                  A list of any previous nondetstack zones for this context.
 ** curfr            The saved curfr for this context.
 ** maxfr            The saved maxfr for this context.
 **
@@ -131,6 +135,13 @@
     MR_CONTEXT_SIZE_SMALL
 } MR_ContextSize;
 
+typedef struct MR_MemoryZones_Struct    MR_MemoryZones;
+
+struct MR_MemoryZones_Struct {
+    MR_MemoryZone       *MR_zones_head;
+    MR_MemoryZones      *MR_zones_tail;
+};
+
 struct MR_Context_Struct {
     const char          *MR_ctxt_id;
     MR_ContextSize      MR_ctxt_size;
@@ -144,9 +155,11 @@
     MR_Code             *MR_ctxt_succip;
 
     MR_MemoryZone       *MR_ctxt_detstack_zone;
+    MR_MemoryZones      *MR_ctxt_prev_detstack_zones;
     MR_Word             *MR_ctxt_sp;
 
     MR_MemoryZone       *MR_ctxt_nondetstack_zone;
+    MR_MemoryZones      *MR_ctxt_prev_nondetstack_zones;
     MR_Word             *MR_ctxt_maxfr;
     MR_Word             *MR_ctxt_curfr;
 
@@ -492,8 +505,12 @@
         MR_IF_NOT_HIGHLEVEL_CODE(                                             \
             MR_ENGINE(MR_eng_context).MR_ctxt_detstack_zone =                 \
                 load_context_c->MR_ctxt_detstack_zone;                        \
+            MR_ENGINE(MR_eng_context).MR_ctxt_prev_detstack_zones =           \
+                load_context_c->MR_ctxt_prev_detstack_zones;                  \
             MR_ENGINE(MR_eng_context).MR_ctxt_nondetstack_zone =              \
                 load_context_c->MR_ctxt_nondetstack_zone;                     \
+            MR_ENGINE(MR_eng_context).MR_ctxt_prev_nondetstack_zones =        \
+                load_context_c->MR_ctxt_prev_nondetstack_zones;               \
             MR_IF_USE_MINIMAL_MODEL_STACK_COPY(                               \
                 MR_ENGINE(MR_eng_context).MR_ctxt_genstack_zone =             \
                     load_context_c->MR_ctxt_genstack_zone;                    \
@@ -545,8 +562,12 @@
         MR_IF_NOT_HIGHLEVEL_CODE(                                             \
             save_context_c->MR_ctxt_detstack_zone =                           \
                 MR_ENGINE(MR_eng_context).MR_ctxt_detstack_zone;              \
+            save_context_c->MR_ctxt_prev_detstack_zones =                     \
+                MR_ENGINE(MR_eng_context).MR_ctxt_prev_detstack_zones;        \
             save_context_c->MR_ctxt_nondetstack_zone =                        \
                 MR_ENGINE(MR_eng_context).MR_ctxt_nondetstack_zone;           \
+            save_context_c->MR_ctxt_prev_nondetstack_zones =                  \
+                MR_ENGINE(MR_eng_context).MR_ctxt_prev_nondetstack_zones;     \
             MR_IF_USE_MINIMAL_MODEL_STACK_COPY(                               \
                 save_context_c->MR_ctxt_genstack_zone =                       \
                     MR_ENGINE(MR_eng_context).MR_ctxt_genstack_zone;          \
Index: runtime/mercury_debug.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_debug.c,v
retrieving revision 1.26
diff -u -b -r1.26 mercury_debug.c
--- runtime/mercury_debug.c	30 Oct 2006 01:31:46 -0000	1.26
+++ runtime/mercury_debug.c	30 Oct 2006 05:58:18 -0000
@@ -17,32 +17,18 @@
 #include    <stdio.h>
 #include    <stdarg.h>
 
-#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
-  #define   MR_in_ctxt_det_zone(ptr, ctxt)          \
-                MR_in_zone(ptr, ctxt->MR_ctxt_detstack_zone)
-  #define   MR_in_ctxt_non_zone(ptr, ctxt)          \
-                MR_in_zone(ptr, ctxt->MR_ctxt_nondetstack_zone)
-
-  extern  const MR_Context  *MR_find_ctxt_for_det_ptr(const MR_Word *ptr);
-  extern  const MR_Context  *MR_find_ctxt_for_non_ptr(const MR_Word *ptr);
-
-  extern  MR_MemoryZone     *MR_find_zone_for_det_ptr(const MR_Word *ptr);
-  extern  MR_MemoryZone     *MR_find_zone_for_non_ptr(const MR_Word *ptr);
-
-  extern  MR_Generator      *MR_find_gen_for_det_ptr(const MR_Word *ptr);
-  extern  MR_Generator      *MR_find_gen_for_non_ptr(const MR_Word *ptr);
-
-  #define MR_det_zone(fr)   (MR_find_zone_for_det_ptr(fr))
-  #define MR_non_zone(fr)   (MR_find_zone_for_non_ptr(fr))
-#else
-  #define MR_det_zone(fr)   (MR_CONTEXT(MR_ctxt_detstack_zone))
-  #define MR_non_zone(fr)   (MR_CONTEXT(MR_ctxt_nondetstack_zone))
-#endif
-
-#define MR_det_stack_min(fr)    (MR_det_zone(fr)->MR_zone_min)
-#define MR_det_stack_offset(fr) (fr - MR_det_stack_min(fr))
-#define MR_non_stack_min(fr)    (MR_non_zone(fr)->MR_zone_min)
-#define MR_non_stack_offset(fr) (fr - MR_non_stack_min(fr))
+static  MR_bool MR_find_zone_for_det_ptr_in_context(const MR_Word *ptr,
+                    MR_Context *ctxt,
+                    MR_MemoryZone **zone_ptr, int *zone_num_ptr);
+static  MR_bool MR_find_zone_for_nondet_ptr_in_context(const MR_Word *ptr,
+                    MR_Context *ctxt,
+                    MR_MemoryZone **zone_ptr, int *zone_num_ptr);
+static  MR_bool MR_find_zone_for_det_ptr(const MR_Word *ptr,
+                    MR_Context **ctxt_ptr,
+                    MR_MemoryZone **zone_ptr, int *zone_num_ptr);
+static  MR_bool MR_find_zone_for_nondet_ptr(const MR_Word *ptr,
+                    MR_Context **ctxt_ptr,
+                    MR_MemoryZone **zone_ptr, int *zone_num_ptr);
 
 /*--------------------------------------------------------------------*/
 
@@ -54,10 +40,10 @@
                     const MR_CallSiteDynamic *csd2);
 #endif
 
-static void     MR_count_call(MR_Code *proc);
-static void     MR_print_ordinary_regs(void);
-static void     MR_do_watches(void);
-static MR_bool  MR_proc_matches_name(MR_Code *proc, const char *name);
+static void     MR_count_call(FILE *fp, const MR_Code *proc);
+static void     MR_print_ordinary_regs(FILE *fp);
+static void     MR_do_watches(FILE *fp);
+static MR_bool  MR_proc_matches_name(const MR_Code *proc, const char *name);
 
 #ifdef  MR_LOWLEVEL_ADDR_DEBUG
   #define   MR_PRINT_RAW_ADDRS  MR_TRUE
@@ -67,137 +53,41 @@
 
 static  MR_bool MR_print_raw_addrs = MR_PRINT_RAW_ADDRS;
 
-/* auxiliary routines for the code that prints debugging messages */
-
-#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
-
-const MR_Context *
-MR_find_ctxt_for_det_ptr(const MR_Word *ptr)
-{
-    const MR_Dlist      *item;
-    const MR_Context    *ctxt;
-
-    if (MR_in_ctxt_det_zone(ptr, MR_ENGINE(MR_eng_main_context))) {
-        return MR_ENGINE(MR_eng_main_context);
-    }
-
-    MR_for_dlist(item, MR_ENGINE(MR_eng_gen_contexts)) {
-        ctxt = (MR_Context *) MR_dlist_data(item);
-        if (MR_in_ctxt_det_zone(ptr, ctxt)) {
-            return ctxt;
-        }
-    }
-
-    return NULL;
-}
-
-const MR_Context *
-MR_find_ctxt_for_non_ptr(const MR_Word *ptr)
-{
-    const MR_Dlist      *item;
-    const MR_Context    *ctxt;
-
-    if (MR_in_ctxt_non_zone(ptr, MR_ENGINE(MR_eng_main_context))) {
-        return MR_ENGINE(MR_eng_main_context);
-    }
-
-    MR_for_dlist(item, MR_ENGINE(MR_eng_gen_contexts)) {
-        ctxt = (MR_Context *) MR_dlist_data(item);
-        if (MR_in_ctxt_non_zone(ptr, ctxt)) {
-            return ctxt;
-        }
-    }
-
-    return NULL;
-}
-
-MR_MemoryZone *
-MR_find_zone_for_det_ptr(const MR_Word *ptr)
-{
-    const MR_Context    *ctxt;
-
-    ctxt = MR_find_ctxt_for_det_ptr(ptr);
-    if (ctxt != NULL) {
-        return ctxt->MR_ctxt_detstack_zone;
-    }
-
-    MR_fatal_error("MR_find_zone_for_det_ptr: not in any context");
-}
-
-MR_MemoryZone *
-MR_find_zone_for_non_ptr(const MR_Word *ptr)
-{
-    const MR_Context    *ctxt;
-
-    ctxt = MR_find_ctxt_for_non_ptr(ptr);
-    if (ctxt != NULL) {
-        return ctxt->MR_ctxt_nondetstack_zone;
-    }
-
-    MR_fatal_error("MR_find_zone_for_non_ptr: not in any context");
-}
-
-MR_Generator *
-MR_find_gen_for_det_ptr(const MR_Word *ptr)
-{
-    const MR_Context    *ctxt;
-
-    ctxt = MR_find_ctxt_for_det_ptr(ptr);
-    if (ctxt != NULL) {
-        return ctxt->MR_ctxt_owner_generator;
-    }
-
-    MR_fatal_error("MR_find_gen_for_det_ptr: not in any context");
-}
-
-MR_Generator *
-MR_find_gen_for_non_ptr(const MR_Word *ptr)
-{
-    const MR_Context    *ctxt;
-
-    ctxt = MR_find_ctxt_for_non_ptr(ptr);
-    if (ctxt != NULL) {
-        return ctxt->MR_ctxt_owner_generator;
-    }
-
-    MR_fatal_error("MR_find_gen_for_non_ptr: not in any context");
-}
-
-#endif  /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
-
 /* debugging messages */
 
 #ifdef MR_DEBUG_HEAP_ALLOC
 
 void
-MR_unravel_univ_msg(MR_Word univ, MR_TypeInfo type_info, MR_Word value)
+MR_unravel_univ_msg(FILE *fp, MR_Word univ, MR_TypeInfo type_info,
+    MR_Word value)
 {
     if (MR_lld_print_enabled && MR_heapdebug) {
-        printf("unravel univ %p: typeinfo %p, value %p\n",
+        fprintf(fp, "unravel univ %p: typeinfo %p, value %p\n",
             (void *) univ, (void *) type_info, (void *) value);
-        fflush(stdout);
+        fflush(fp);
     }
 }
 
 void
-MR_new_univ_on_hp_msg(MR_Word univ, MR_TypeInfo type_info, MR_Word value)
+MR_new_univ_on_hp_msg(FILE *fp, MR_Word univ, MR_TypeInfo type_info,
+    MR_Word value)
 {
     if (MR_lld_print_enabled && MR_heapdebug) {
-        printf("new univ on hp: typeinfo %p, value %p => %p\n",
+        fprintf(fp"new univ on hp: typeinfo %p, value %p => %p\n",
             (void *) type_info, (void *) value, (void *) univ);
-        fflush(stdout);
+        fflush(fp);
     }
 }
 
 void
-MR_debug_tag_offset_incr_hp_base_msg(MR_Word ptr, int tag, int offset,
-    int count, int is_atomic)
+MR_debug_tag_offset_incr_hp_base_msg(FILE *fp, MR_Word ptr,
+    int tag, int offset, int count, int is_atomic)
 {
     if (MR_lld_print_enabled && MR_heapdebug) {
-        printf("tag_offset_incr_hp: "
+        fprintf(fp, "tag_offset_incr_hp: "
             "tag %d, offset %d, count %d%s => %p\n",
             tag, offset, count, (is_atomic ? ", atomic" : ""), (void *) ptr);
-        fflush(stdout);
+        fflush(fp);
     }
 }
 
@@ -206,7 +96,7 @@
 #ifdef MR_LOWLEVEL_DEBUG
 
 void
-MR_mkframe_msg(const char *predname)
+MR_mkframe_msg(FILE *fp, const char *predname)
 {
     MR_restore_transient_registers();
 
@@ -214,24 +104,31 @@
         return;
     }
 
-    printf("\nnew choice point for procedure %s\n", predname);
-    printf("new  fr: "); MR_printnondstack(MR_curfr);
-    printf("prev fr: "); MR_printnondstack(MR_prevfr_slot(MR_curfr));
-    printf("succ fr: "); MR_printnondstack(MR_succfr_slot(MR_curfr));
-    printf("succ ip: "); MR_printlabel(stdout, MR_succip_slot(MR_curfr));
-    printf("redo fr: "); MR_printnondstack(MR_redofr_slot(MR_curfr));
-    printf("redo ip: "); MR_printlabel(stdout, MR_redoip_slot(MR_curfr));
+    fprintf(fp, "\nnew choice point for procedure %s\n", predname);
+    fprintf(fp, "new  fr: ");
+    MR_printnondetstack(fp, MR_curfr);
+    fprintf(fp, "prev fr: ");
+    MR_printnondetstack(fp, MR_prevfr_slot(MR_curfr));
+    fprintf(fp, "succ fr: ");
+    MR_printnondetstack(fp, MR_succfr_slot(MR_curfr));
+    fprintf(fp, "succ ip: ");
+    MR_printlabel(fp, MR_succip_slot(MR_curfr));
+    fprintf(fp, "redo fr: ");
+    MR_printnondetstack(fp, MR_redofr_slot(MR_curfr));
+    fprintf(fp, "redo ip: ");
+    MR_printlabel(fp, MR_redoip_slot(MR_curfr));
 #ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
-    printf("det fr:  "); MR_printdetstack(MR_table_detfr_slot(MR_curfr));
+    fprintf(fp, "det fr:  ");
+    MR_printdetstack(fp, MR_table_detfr_slot(MR_curfr));
 #endif
 
     if (MR_detaildebug) {
-        MR_dumpnondstack();
+        MR_dumpnondetstack(fp);
     }
 }
 
 void
-MR_mktempframe_msg(void)
+MR_mktempframe_msg(FILE *fp)
 {
     MR_restore_transient_registers();
 
@@ -239,19 +136,23 @@
         return;
     }
 
-    printf("\nnew temp nondet frame\n");
-    printf("new  fr: "); MR_printnondstack(MR_maxfr);
-    printf("prev fr: "); MR_printnondstack(MR_prevfr_slot(MR_maxfr));
-    printf("redo fr: "); MR_printnondstack(MR_redofr_slot(MR_maxfr));
-    printf("redo ip: "); MR_printlabel(stdout, MR_redoip_slot(MR_maxfr));
+    fprintf(fp, "\nnew temp nondet frame\n");
+    fprintf(fp, "new  fr: ");
+    MR_printnondetstack(fp, MR_maxfr);
+    fprintf(fp, "prev fr: ");
+    MR_printnondetstack(fp, MR_prevfr_slot(MR_maxfr));
+    fprintf(fp, "redo fr: ");
+    MR_printnondetstack(fp, MR_redofr_slot(MR_maxfr));
+    fprintf(fp, "redo ip: ");
+    MR_printlabel(fp, MR_redoip_slot(MR_maxfr));
 
     if (MR_detaildebug) {
-        MR_dumpnondstack();
+        MR_dumpnondetstack(fp);
     }
 }
 
 void
-MR_mkdettempframe_msg(void)
+MR_mkdettempframe_msg(FILE *fp)
 {
     MR_restore_transient_registers();
 
@@ -259,269 +160,285 @@
         return;
     }
 
-    printf("\nnew det temp nondet frame\n");
-    printf("new  fr: "); MR_printnondstack(MR_maxfr);
-    printf("prev fr: "); MR_printnondstack(MR_prevfr_slot(MR_maxfr));
-    printf("redo fr: "); MR_printnondstack(MR_redofr_slot(MR_maxfr));
-    printf("redo ip: "); MR_printlabel(stdout, MR_redoip_slot(MR_maxfr));
-    printf("det fr:  "); MR_printdetstack(MR_tmp_detfr_slot(MR_maxfr));
+    fprintf(fp, "\nnew det temp nondet frame\n");
+    fprintf(fp, "new  fr: ");
+    MR_printnondetstack(fp, MR_maxfr);
+    fprintf(fp, "prev fr: ");
+    MR_printnondetstack(fp, MR_prevfr_slot(MR_maxfr));
+    fprintf(fp, "redo fr: ");
+    MR_printnondetstack(fp, MR_redofr_slot(MR_maxfr));
+    fprintf(fp, "redo ip: ");
+    MR_printlabel(fp, MR_redoip_slot(MR_maxfr));
+    fprintf(fp, "det fr:  ");
+    MR_printdetstack(fp, MR_tmp_detfr_slot(MR_maxfr));
 
     if (MR_detaildebug) {
-        MR_dumpnondstack();
+        MR_dumpnondetstack(fp);
     }
 }
 
 void
-MR_succeed_msg(void)
+MR_succeed_msg(FILE *fp)
 {
     MR_restore_transient_registers();
 
-    MR_do_watches();
+    MR_do_watches(fp);
 
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("\nsucceeding from procedure\n");
-    printf("curr fr: "); MR_printnondstack(MR_curfr);
-    printf("succ fr: "); MR_printnondstack(MR_succfr_slot(MR_curfr));
-    printf("succ ip: "); MR_printlabel(stdout, MR_succip_slot(MR_curfr));
+    fprintf(fp, "\nsucceeding from procedure\n");
+    fprintf(fp, "curr fr: ");
+    MR_printnondetstack(fp, MR_curfr);
+    fprintf(fp, "succ fr: ");
+    MR_printnondetstack(fp, MR_succfr_slot(MR_curfr));
+    fprintf(fp, "succ ip: ");
+    MR_printlabel(fp, MR_succip_slot(MR_curfr));
 
     if (MR_detaildebug) {
-        MR_printregs("registers at success");
+        MR_printregs(fp, "registers at success");
     }
 }
 
 void
-MR_succeeddiscard_msg(void)
+MR_succeeddiscard_msg(FILE *fp)
 {
     MR_restore_transient_registers();
 
-    MR_do_watches();
+    MR_do_watches(fp);
 
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("\nsucceeding from procedure\n");
-    printf("curr fr: "); MR_printnondstack(MR_curfr);
-    printf("succ fr: "); MR_printnondstack(MR_succfr_slot(MR_curfr));
-    printf("succ ip: "); MR_printlabel(stdout, MR_succip_slot(MR_curfr));
+    fprintf(fp, "\nsucceeding from procedure\n");
+    fprintf(fp, "curr fr: ");
+    MR_printnondetstack(fp, MR_curfr);
+    fprintf(fp, "succ fr: ");
+    MR_printnondetstack(fp, MR_succfr_slot(MR_curfr));
+    fprintf(fp, "succ ip: ");
+    MR_printlabel(fp, MR_succip_slot(MR_curfr));
 
     if (MR_detaildebug) {
-        MR_printregs("registers at success");
+        MR_printregs(fp, "registers at success");
     }
 }
 
 void
-MR_fail_msg(void)
+MR_fail_msg(FILE *fp)
 {
     MR_restore_transient_registers();
 
-    MR_do_watches();
+    MR_do_watches(fp);
 
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("\nfailing from procedure\n");
-    printf("curr fr: "); MR_printnondstack(MR_curfr);
-    printf("fail fr: "); MR_printnondstack(MR_prevfr_slot(MR_curfr));
-    printf("fail ip: "); MR_printlabel(stdout,
-        MR_redoip_slot(MR_prevfr_slot(MR_curfr)));
+    fprintf(fp, "\nfailing from procedure\n");
+    fprintf(fp, "curr fr: ");
+    MR_printnondetstack(fp, MR_curfr);
+    fprintf(fp, "fail fr: ");
+    MR_printnondetstack(fp, MR_prevfr_slot(MR_curfr));
+    fprintf(fp, "fail ip: ");
+    MR_printlabel(fp, MR_redoip_slot(MR_prevfr_slot(MR_curfr)));
 }
 
 void
-MR_redo_msg(void)
+MR_redo_msg(FILE *fp)
 {
     MR_restore_transient_registers();
 
-    MR_do_watches();
+    MR_do_watches(fp);
 
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("\nredo from procedure\n");
-    printf("curr fr: "); MR_printnondstack(MR_curfr);
-    printf("redo fr: "); MR_printnondstack(MR_maxfr);
-    printf("redo ip: "); MR_printlabel(stdout, MR_redoip_slot(MR_maxfr));
+    fprintf(fp, "\nredo from procedure\n");
+    fprintf(fp, "curr fr: ");
+    MR_printnondetstack(fp, MR_curfr);
+    fprintf(fp, "redo fr: ");
+    MR_printnondetstack(fp, MR_maxfr);
+    fprintf(fp, "redo ip: ");
+    MR_printlabel(fp, MR_redoip_slot(MR_maxfr));
 }
 
 void
-MR_call_msg(/* const */ MR_Code *proc, /* const */ MR_Code *succ_cont)
+MR_call_msg(FILE *fp, const MR_Code *proc, const MR_Code *succ_cont)
 {
-    MR_count_call(proc);
+    MR_count_call(fp, proc);
 
 #ifdef  MR_DEEP_PROFILING
     MR_check_watch_csd_start(proc);
 #endif  /* MR_DEEP_PROFILING */
 
-    MR_do_watches();
+    MR_do_watches(fp);
 
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("\ncall %lu: ", MR_lld_cur_call);
-    MR_printlabel(stdout, proc);
-    printf("cont ");
-    MR_printlabel(stdout, succ_cont);
+    fprintf(fp, "\ncall %lu: ", MR_lld_cur_call);
+    MR_printlabel(fp, proc);
+    fprintf(fp, "cont ");
+    MR_printlabel(fp, succ_cont);
 
     if (MR_anyregdebug) {
-        MR_printregs("at call:");
+        MR_printregs(fp, "at call:");
     }
 
 #ifdef  MR_DEEP_PROFILING
-    MR_print_deep_prof_vars(stdout, "MR_call_msg");
+    MR_print_deep_prof_vars(fp, "MR_call_msg");
 #endif
 }
 
 void
-MR_tailcall_msg(/* const */ MR_Code *proc)
+MR_tailcall_msg(FILE *fp, const MR_Code *proc)
 {
     MR_restore_transient_registers();
 
-    MR_count_call(proc);
+    MR_count_call(fp, proc);
 
 #ifdef  MR_DEEP_PROFILING
     MR_check_watch_csd_start(proc);
 #endif  /* MR_DEEP_PROFILING */
 
-    MR_do_watches();
+    MR_do_watches(fp);
 
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("\ntail call %lu: ", MR_lld_cur_call);
-    MR_printlabel(stdout, proc);
-    printf("cont ");
-    MR_printlabel(stdout, MR_succip);
+    fprintf(fp, "\ntail call %lu: ", MR_lld_cur_call);
+    MR_printlabel(fp, proc);
+    fprintf(fp, "cont ");
+    MR_printlabel(fp, MR_succip);
 
     if (MR_anyregdebug) {
-        MR_printregs("at tailcall:");
+        MR_printregs(fp, "at tailcall:");
     }
 
 #ifdef  MR_DEEP_PROFILING
-    MR_print_deep_prof_vars(stdout, "MR_tailcall_msg");
+    MR_print_deep_prof_vars(fp, "MR_tailcall_msg");
 #endif
 }
 
 void
-MR_proceed_msg(void)
+MR_proceed_msg(FILE *fp)
 {
-    MR_do_watches();
+    MR_do_watches(fp);
 
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("\nreturning from determinate procedure\n");
+    fprintf(fp, "\nreturning from determinate procedure\n");
     if (MR_anyregdebug) {
-        MR_printregs("at proceed:");
+        MR_printregs(fp, "at proceed:");
     }
 
 #ifdef  MR_DEEP_PROFILING
-    MR_print_deep_prof_vars(stdout, "MR_proceed_msg");
+    MR_print_deep_prof_vars(fp, "MR_proceed_msg");
 #endif
 }
 
 void
-MR_cr1_msg(const MR_Word *addr)
+MR_cr1_msg(FILE *fp, const MR_Word *addr)
 {
     if (!MR_lld_print_enabled) {
         return;
     }
 
 #ifdef  MR_RECORD_TERM_SIZES
-    printf("create1: put size %ld, value %9lx at ",
+    fprintf(fp, "create1: put size %ld, value %9lx at ",
         (long) (MR_Integer) addr[-2],
         (long) (MR_Integer) addr[-1]);
 #else
-    printf("create1: put value %9lx at ",
+    fprintf(fp, "create1: put value %9lx at ",
         (long) (MR_Integer) addr[-1]);
 #endif
-    MR_printheap(addr);
+    MR_printheap(fp, addr);
 }
 
 void
-MR_cr2_msg(const MR_Word *addr)
+MR_cr2_msg(FILE *fp, const MR_Word *addr)
 {
     if (!MR_lld_print_enabled) {
         return;
     }
 
 #ifdef  MR_RECORD_TERM_SIZES
-    printf("create2: put size %ld, values %9lx,%9lx at ",
+    fprintf(fp, "create2: put size %ld, values %9lx,%9lx at ",
         (long) (MR_Integer) addr[-3],
         (long) (MR_Integer) addr[-2],
         (long) (MR_Integer) addr[-1]);
 #else
-    printf("create2: put values %9lx,%9lx at ",
+    fprintf(fp, "create2: put values %9lx,%9lx at ",
         (long) (MR_Integer) addr[-2],
         (long) (MR_Integer) addr[-1]);
 #endif
-    MR_printheap(addr);
+    MR_printheap(fp, addr);
 }
 
 void
-MR_cr3_msg(const MR_Word *addr)
+MR_cr3_msg(FILE *fp, const MR_Word *addr)
 {
     if (!MR_lld_print_enabled) {
         return;
     }
 
 #ifdef  MR_RECORD_TERM_SIZES
-    printf("create3: put size %ld, values %9lx,%9lx,%9lx at ",
+    fprintf(fp, "create3: put size %ld, values %9lx,%9lx,%9lx at ",
         (long) (MR_Integer) addr[-4],
         (long) (MR_Integer) addr[-3],
         (long) (MR_Integer) addr[-2],
         (long) (MR_Integer) addr[-1]);
 #else
-    printf("create3: put values %9lx,%9lx,%9lx at ",
+    fprintf(fp, "create3: put values %9lx,%9lx,%9lx at ",
         (long) (MR_Integer) addr[-3],
         (long) (MR_Integer) addr[-2],
         (long) (MR_Integer) addr[-1]);
 #endif
-    MR_printheap(addr);
+    MR_printheap(fp, addr);
 }
 
 void
-MR_incr_hp_debug_msg(MR_Word val, const MR_Word *addr)
+MR_incr_hp_debug_msg(FILE *fp, MR_Word val, const MR_Word *addr)
 {
     if (!MR_lld_print_enabled) {
         return;
     }
 
 #ifdef MR_CONSERVATIVE_GC
-    printf("allocated %ld words at %p\n", (long) val, addr);
+    fprintf(fp, "allocated %ld words at %p\n", (long) val, addr);
 #else
-    printf("increment hp by %ld from ", (long) (MR_Integer) val);
-    MR_printheap(addr);
+    fprintf(fp, "increment hp by %ld from ", (long) (MR_Integer) val);
+    MR_printheap(fp, addr);
 #endif
 }
 
 void
-MR_incr_sp_msg(MR_Word val, const MR_Word *addr)
+MR_incr_sp_msg(FILE *fp, MR_Word val, const MR_Word *addr)
 {
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("increment sp by %ld from ", (long) (MR_Integer) val);
-    MR_printdetstack(addr);
+    fprintf(fp, "increment sp by %ld from ", (long) (MR_Integer) val);
+    MR_printdetstack(fp, addr);
 }
 
 void
-MR_decr_sp_msg(MR_Word val, const MR_Word *addr)
+MR_decr_sp_msg(FILE *fp, MR_Word val, const MR_Word *addr)
 {
     if (!MR_lld_print_enabled) {
         return;
     }
 
-    printf("decrement sp by %ld from ", (long) (MR_Integer) val);
-    MR_printdetstack(addr);
+    fprintf(fp, "decrement sp by %ld from ", (long) (MR_Integer) val);
+    MR_printdetstack(fp, addr);
 }
 
 #endif /* defined(MR_LOWLEVEL_DEBUG) */
@@ -529,23 +446,23 @@
 #ifdef MR_DEBUG_GOTOS
 
 void
-MR_goto_msg(/* const */ MR_Code *addr)
+MR_goto_msg(FILE *fp, const MR_Code *addr)
 {
     if (!MR_lld_print_enabled) {
         return;
     }
 
     if (addr == NULL) {
-        printf("\ngoto NULL\n");
+        fprintf(fp, "\ngoto NULL\n");
         MR_fatal_error("MR_goto_msg: NULL");
     }
 
-    printf("\ngoto ");
-    MR_printlabel(stdout, addr);
+    fprintf(fp, "\ngoto ");
+    MR_printlabel(fp, addr);
 }
 
 void
-MR_reg_msg(void)
+MR_reg_msg(FILE *fp)
 {
     int         i;
     MR_Integer  x;
@@ -563,9 +480,9 @@
             x -= (MR_Integer) MR_ENGINE(MR_eng_heap_zone)->MR_zone_min;
         }
 #endif
-        printf("%8lx ", (long) x);
+        fprintf(fp, "%8lx ", (long) x);
     }
-    printf("\n");
+    fprintf(fp, "\n");
 }
 
 #endif /* defined(MR_DEBUG_GOTOS) */
@@ -577,14 +494,14 @@
 /* debugging printing tools */
 
 static void
-MR_count_call(MR_Code *proc)
+MR_count_call(FILE *fp, const MR_Code *proc)
 {
     MR_lld_cur_call++;
     if (!MR_lld_print_region_enabled) {
         if (MR_lld_cur_call == MR_lld_print_min) {
             MR_lld_print_region_enabled = MR_TRUE;
-            printf("entering printed region\n");
-            printf("min %lu, max %lu, more <%s>\n",
+            fprintf(fp, "entering printed region\n");
+            fprintf(fp, "min %lu, max %lu, more <%s>\n",
                 MR_lld_print_min, MR_lld_print_max,
                 MR_lld_print_more_min_max);
         }
@@ -593,8 +510,8 @@
             MR_lld_print_region_enabled = MR_FALSE;
             MR_setup_call_intervals(&MR_lld_print_more_min_max,
                 &MR_lld_print_min, &MR_lld_print_max);
-            printf("leaving printed region\n");
-            printf("min %lu, max %lu, more <%s>\n",
+            fprintf(fp, "leaving printed region\n");
+            fprintf(fp, "min %lu, max %lu, more <%s>\n",
                 MR_lld_print_min, MR_lld_print_max,
                 MR_lld_print_more_min_max);
         }
@@ -603,10 +520,10 @@
     if (MR_proc_matches_name(proc, MR_lld_start_name)) {
         MR_lld_print_name_enabled = MR_TRUE;
         MR_lld_start_until = MR_lld_cur_call + MR_lld_start_block;
-        printf("entering printed name block %s\n", MR_lld_start_name);
+        fprintf(fp, "entering printed name block %s\n", MR_lld_start_name);
     } else if (MR_lld_cur_call == MR_lld_start_until) {
         MR_lld_print_name_enabled = MR_FALSE;
-        printf("leaving printed name block\n");
+        fprintf(fp, "leaving printed name block\n");
     }
 
 #ifdef  MR_DEEP_PROFILING
@@ -616,10 +533,10 @@
         MR_lld_print_csd_enabled = MR_TRUE;
         MR_lld_csd_until = MR_lld_cur_call + MR_lld_start_block;
         MR_watch_csd_started = MR_TRUE;
-        printf("entering printed csd block %p\n", MR_watch_csd_addr);
+        fprintf(fp, "entering printed csd block %p\n", MR_watch_csd_addr);
     } else if (MR_lld_cur_call == MR_lld_csd_until) {
         MR_lld_print_csd_enabled = MR_FALSE;
-        printf("leaving printed csd block\n");
+        fprintf(fp, "leaving printed csd block\n");
     }
 #endif
 
@@ -630,121 +547,126 @@
 }
 
 void
-MR_printint(MR_Word n)
+MR_printint(FILE *fp, MR_Word n)
 {
-    printf("int %ld\n", (long) (MR_Integer) n);
+    fprintf(fp, "int %ld\n", (long) (MR_Integer) n);
 }
 
 void
-MR_printstring(const char *s)
+MR_printstring(FILE *fp, const char *s)
 {
     if (MR_print_raw_addrs) {
-        printf("string %p %s\n", (const void *) s, s);
+        fprintf(fp, "string %p %s\n", (const void *) s, s);
     } else {
-        printf("string %s\n", s);
+        fprintf(fp, "string %s\n", s);
     }
 }
 
 void
-MR_printheap(const MR_Word *h)
+MR_printheap(FILE *fp, const MR_Word *h)
 {
 #ifndef MR_CONSERVATIVE_GC
     if (MR_print_raw_addrs) {
-        printf("ptr %p, ", (const void *) h);
+        fprintf(fp, "ptr %p, ", (const void *) h);
     }
 
-    printf("offset %3ld words\n",
+    fprintf(fp, "offset %3ld words\n",
         (long) (MR_Integer) (h - MR_ENGINE(MR_eng_heap_zone)->min));
 #else
-    printf("ptr %p\n", (const void *) h);
+    fprintf(fp, "ptr %p\n", (const void *) h);
 #endif
 }
 
 void
-MR_dumpframe(/* const */ MR_Word *fr)
+MR_dumpframe(FILE *fp, const MR_Word *fr)
 {
     int i;
 
-    printf("frame at ");
-    if (MR_print_raw_addrs) {
-        printf("ptr %p, ", (const void *) fr);
-    }
-
-    printf("offset %3ld words\n",
-        (long) (MR_Integer) MR_non_stack_offset(fr));
-    printf("\t succip    "); MR_printlabel(stdout, MR_succip_slot(fr));
-    printf("\t redoip    "); MR_printlabel(stdout, MR_redoip_slot(fr));
-    printf("\t succfr    "); MR_printnondstack(MR_succfr_slot(fr));
-    printf("\t prevfr    "); MR_printnondstack(MR_prevfr_slot(fr));
+    fprintf(fp, "frame at ");
+    MR_printnondetstack(fp, fr),
+    fprintf(fp, "\n");
+    fprintf(fp, "\t succip    ");
+    MR_printlabel(fp, MR_succip_slot(fr));
+    fprintf(fp, "\t redoip    ");
+    MR_printlabel(fp, MR_redoip_slot(fr));
+    fprintf(fp, "\t succfr    ");
+    MR_printnondetstack(fp, MR_succfr_slot(fr));
+    fprintf(fp, "\t prevfr    ");
+    MR_printnondetstack(fp, MR_prevfr_slot(fr));
 
     for (i = 1; &MR_based_framevar(fr,i) > MR_prevfr_slot(fr); i++) {
-        printf("\t framevar(%d)  %ld 0x%lx\n",
+        fprintf(fp, "\t framevar(%d)  %ld 0x%lx\n",
             i, (long) (MR_Integer) MR_based_framevar(fr,i),
             (unsigned long) MR_based_framevar(fr,i));
     }
 }
 
 void
-MR_dumpnondstack(void)
+MR_dumpnondetstack(FILE *fp)
 {
     MR_Word *fr;
 
-    printf("\nnondstack dump\n");
+    fprintf(fp, "\nnondetstack dump\n");
     for (fr = MR_maxfr; fr > MR_nondet_stack_trace_bottom;
         fr = MR_prevfr_slot(fr))
     {
-        MR_dumpframe(fr);
+        MR_dumpframe(fp, fr);
     }
 }
 
 void
-MR_printframe(const char *msg)
+MR_printframe(FILE *fp, const char *msg)
 {
-    printf("\n%s\n", msg);
-    MR_dumpframe(MR_curfr);
+    fprintf(fp, "\n%s\n", msg);
+    MR_dumpframe(fp, MR_curfr);
 
-    MR_print_ordinary_regs();
+    MR_print_ordinary_regs(fp);
 }
 
 void
-MR_printregs(const char *msg)
+MR_printregs(FILE *fp, const char *msg)
 {
     MR_restore_transient_registers();
 
-    printf("\n%s\n", msg);
+    fprintf(fp, "\n%s\n", msg);
 
     if (MR_sregdebug) {
-        printf("%-9s", "succip:");  MR_printlabel(stdout, MR_succip);
-        printf("%-9s", "curfr:");   MR_printnondstack(MR_curfr);
-        printf("%-9s", "maxfr:");   MR_printnondstack(MR_maxfr);
-        printf("%-9s", "hp:");      MR_printheap(MR_hp);
-        printf("%-9s", "sp:");      MR_printdetstack(MR_sp);
+        fprintf(fp, "%-9s", "succip:");
+        MR_printlabel(fp, MR_succip);
+        fprintf(fp, "%-9s", "curfr:");
+        MR_printnondetstack(fp, MR_curfr);
+        fprintf(fp, "%-9s", "maxfr:");
+        MR_printnondetstack(fp, MR_maxfr);
+        fprintf(fp, "%-9s", "hp:");
+        MR_printheap(fp, MR_hp);
+        fprintf(fp, "%-9s", "sp:");
+        MR_printdetstack(fp, MR_sp);
     }
 
     if (MR_ordregdebug) {
-        MR_print_ordinary_regs();
+        MR_print_ordinary_regs(fp);
     }
 }
 
 static void
-MR_print_ordinary_regs(void)
+MR_print_ordinary_regs(FILE *fp)
 {
     int     i;
     MR_Integer  value;
 
     for (i = 0; i < 8; i++) {
-        printf("r%d:      ", i + 1);
+        fprintf(fp, "r%d:      ", i + 1);
         value = (MR_Integer) MR_get_reg(i+1);
 
 #ifndef MR_CONSERVATIVE_GC
         if ((MR_Integer) MR_ENGINE(MR_eng_heap_zone)->min <= value
             && value < (MR_Integer) MR_ENGINE(MR_eng_heap_zone)->top)
         {
-            printf("(heap) ");
+            fprintf(fp, "(heap) ");
         }
 #endif
 
-        printf("%ld %lx\n", (long) value, (long) value);
+        fprintf(fp, "%ld %lx\n", (long) value, (long) value);
     }
 }
 
@@ -884,10 +806,10 @@
 #endif  /* MR_DEEP_PROFILING */
 
 static void
-MR_do_watches(void)
+MR_do_watches(FILE *fp)
 {
     if (MR_watch_addr != NULL) {
-        printf("watch addr %p: 0x%lx %ld\n", MR_watch_addr,
+        fprintf(fp, "watch addr %p: 0x%lx %ld\n", MR_watch_addr,
             (long) *MR_watch_addr, (long) *MR_watch_addr);
     }
 
@@ -898,8 +820,8 @@
                 MR_watch_csd_addr))
             {
                 MR_assign_csd(&MR_watched_csd_last_value, MR_watch_csd_addr);
-                printf("current call: %lu\n", MR_lld_cur_call);
-                MR_print_deep_prof_var(stdout, "watch_csd", MR_watch_csd_addr);
+                fprintf(fp, "current call: %lu\n", MR_lld_cur_call);
+                MR_print_deep_prof_var(fp, "watch_csd", MR_watch_csd_addr);
             }
         }
     }
@@ -907,7 +829,7 @@
 }
 
 static MR_bool
-MR_proc_matches_name(MR_Code *proc, const char *name)
+MR_proc_matches_name(const MR_Code *proc, const char *name)
 {
 #ifdef  MR_NEED_ENTRY_LABEL_ARRAY
     MR_Entry    *entry;
@@ -928,56 +850,95 @@
 #ifndef MR_HIGHLEVEL_CODE
 
 void
-MR_printdetstackptr(const MR_Word *s)
-{
-    MR_print_detstackptr(stdout, s);
-}
-
-void
 MR_print_detstackptr(FILE *fp, const MR_Word *s)
 {
+    MR_MemoryZone   *zone;
+    int             zone_num;
+
+    if (MR_find_zone_for_det_ptr(s, NULL, &zone, &zone_num)) {
+        if (zone_num == 0) {
     fprintf(fp, "det %3ld",
-        (long) (MR_Integer) MR_det_stack_offset(s));
+                (long) (MR_Integer) (s - zone->MR_zone_min));
+        } else {
+            fprintf(fp, "det %3ld, segment %d",
+                (long) (MR_Integer) (s - zone->MR_zone_min), zone_num);
+        }
 
     if (MR_print_raw_addrs) {
         fprintf(fp, " (%p)", (const void *) s);
     }
+    } else {
+        fprintf(fp, "det raw %p", (const void *) s);
+    }
 }
 
 void
-MR_printdetstack(const MR_Word *s)
+MR_printdetstack(FILE *fp, const MR_Word *s)
 {
+    MR_MemoryZone   *zone;
+    int             zone_num;
+
+    if (MR_find_zone_for_det_ptr(s, NULL, &zone, &zone_num)) {
     if (MR_print_raw_addrs) {
-        printf("ptr %p, ", (const void *) s);
+            fprintf(fp, "ptr %p, ", (const void *) s);
     }
 
-    printf("offset %3ld words\n", (long) (MR_Integer) MR_det_stack_offset(s));
+        if (zone_num == 0) {
+            fprintf(fp, "offset %3ld words",
+                (long) (MR_Integer) (s - zone->MR_zone_min));
+        } else {
+            fprintf(fp, "offset %3ld words in segment %d",
+                (long) (MR_Integer) (s - zone->MR_zone_min), zone_num);
+        }
+    } else {
+        fprintf(fp, "raw ptr %p", (const void *) s);
+    }
 }
 
 void
-MR_printnondstackptr(const MR_Word *s)
+MR_print_nondetstackptr(FILE *fp, const MR_Word *s)
 {
-    MR_print_nondstackptr(stdout, s);
-}
+    MR_MemoryZone   *zone;
+    int             zone_num;
 
-void
-MR_print_nondstackptr(FILE *fp, const MR_Word *s)
-{
-    fprintf(fp, "non %3ld", (long) (MR_Integer) MR_non_stack_offset(s));
+    if (MR_find_zone_for_nondet_ptr(s, NULL, &zone, &zone_num)) {
+        if (zone_num == 0) {
+            fprintf(fp, "non %3ld",
+                (long) (MR_Integer) (s - zone->MR_zone_min));
+        } else {
+            fprintf(fp, "non %3ld, segment %d",
+                (long) (MR_Integer) (s - zone->MR_zone_min), zone_num);
+        }
 
     if (MR_print_raw_addrs) {
         fprintf(fp, " (%p)", (const void *) s);
     }
+    } else {
+        fprintf(fp, "non raw %p", (const void *) s);
+    }
 }
 
 void
-MR_printnondstack(const MR_Word *s)
+MR_printnondetstack(FILE *fp, const MR_Word *s)
 {
+    MR_MemoryZone   *zone;
+    int             zone_num;
+
+    if (MR_find_zone_for_nondet_ptr(s, NULL, &zone, &zone_num)) {
     if (MR_print_raw_addrs) {
-        printf("ptr %p, ", (const void *) s);
+            fprintf(fp, "ptr %p, ", (const void *) s);
     }
 
-    printf("offset %3ld words\n", (long) (MR_Integer) MR_non_stack_offset(s));
+        if (zone_num == 0) {
+            fprintf(fp, "offset %3ld words",
+                (long) (MR_Integer) (s - zone->MR_zone_min));
+        } else {
+            fprintf(fp, "offset %3ld words in segment %d",
+                (long) (MR_Integer) (s - zone->MR_zone_min), zone_num);
+        }
+    } else {
+        fprintf(fp, "raw ptr %p", (const void *) s);
+    }
 }
 
 #endif /* !MR_HIGHLEVEL_CODE */
@@ -993,12 +954,12 @@
 #endif
 
     if (MR_print_raw_addrs) {
-        printf(" (%p)", (const void *) s);
+        fprintf(fp, " (%p)", (const void *) s);
     }
 }
 
 void
-MR_print_label(FILE *fp, /* const */ MR_Code *w)
+MR_print_label(FILE *fp, const MR_Code *w)
 {
     MR_Internal *internal;
 
@@ -1039,7 +1000,7 @@
 }
 
 void
-MR_printlabel(FILE *fp, /* const */ MR_Code *w)
+MR_printlabel(FILE *fp, const MR_Code *w)
 {
     MR_print_label(fp, w);
     fprintf(fp, "\n");
@@ -1105,3 +1066,200 @@
     }
 #endif
 }
+
+/* auxiliary routines for the code that prints debugging messages */
+
+static MR_bool
+MR_find_zone_for_det_ptr_in_context(const MR_Word *ptr, MR_Context *ctxt,
+    MR_MemoryZone **zone_ptr, int *zone_num_ptr)
+{
+#ifdef  MR_HIGHLEVEL_CODE
+    return MR_FALSE;
+#else   /* !MR_HIGHLEVEL_CODE */
+    int             segment_number;
+    MR_MemoryZones  *remaining_zones;
+    MR_MemoryZone   *cur_zone;
+
+    remaining_zones = ctxt->MR_ctxt_prev_detstack_zones;
+    if (MR_in_zone(ptr, ctxt->MR_ctxt_detstack_zone)) {
+        if (zone_ptr != NULL) {
+            *zone_ptr = ctxt->MR_ctxt_detstack_zone;
+        }
+    } else {
+        while (remaining_zones != NULL) {
+            cur_zone = remaining_zones->MR_zones_head;
+            if (MR_in_zone(ptr, cur_zone)) {
+                if (zone_ptr != NULL) {
+                    *zone_ptr = cur_zone;
+                }
+
+                remaining_zones = remaining_zones->MR_zones_tail;
+                break;
+            }
+
+            remaining_zones = remaining_zones->MR_zones_tail;
+        }
+
+        return MR_FALSE;
+    }
+
+    if (zone_num_ptr != NULL) {
+        segment_number = 0;
+        while (remaining_zones != NULL) {
+            segment_number++;
+            remaining_zones = remaining_zones->MR_zones_tail;
+        }
+
+        *zone_num_ptr = segment_number;
+    }
+
+    return MR_TRUE;
+#endif  /* !MR_HIGHLEVEL_CODE */
+}
+
+static MR_bool
+MR_find_zone_for_nondet_ptr_in_context(const MR_Word *ptr, MR_Context *ctxt,
+    MR_MemoryZone **zone_ptr, int *zone_num_ptr)
+{
+#ifdef  MR_HIGHLEVEL_CODE
+    return MR_FALSE;
+#else   /* !MR_HIGHLEVEL_CODE */
+    int             segment_number;
+    MR_MemoryZones  *remaining_zones;
+    MR_MemoryZone   *cur_zone;
+
+    remaining_zones = ctxt->MR_ctxt_prev_nondetstack_zones;
+    if (MR_in_zone(ptr, ctxt->MR_ctxt_nondetstack_zone)) {
+        if (zone_ptr != NULL) {
+            *zone_ptr = ctxt->MR_ctxt_nondetstack_zone;
+        }
+    } else {
+        while (remaining_zones != NULL) {
+            cur_zone = remaining_zones->MR_zones_head;
+            if (MR_in_zone(ptr, cur_zone)) {
+                if (zone_ptr != NULL) {
+                    *zone_ptr = cur_zone;
+                }
+
+                remaining_zones = remaining_zones->MR_zones_tail;
+                break;
+            }
+
+            remaining_zones = remaining_zones->MR_zones_tail;
+        }
+
+        return MR_FALSE;
+    }
+
+    if (zone_num_ptr != NULL) {
+        segment_number = 0;
+        while (remaining_zones != NULL) {
+            segment_number++;
+            remaining_zones = remaining_zones->MR_zones_tail;
+        }
+
+        *zone_num_ptr = segment_number;
+    }
+
+    return MR_TRUE;
+#endif  /* !MR_HIGHLEVEL_CODE */
+}
+
+static MR_bool
+MR_find_zone_for_det_ptr(const MR_Word *ptr, MR_Context **ctxt_ptr,
+    MR_MemoryZone **zone_ptr, int *zone_num_ptr)
+{
+#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
+
+    const MR_Dlist      *item;
+    const MR_Context    *ctxt;
+
+    if (MR_find_zone_for_det_ptr_in_context(ptr,
+        MR_ENGINE(MR_eng_main_context), zone_ptr, zone_num_ptr))
+    {
+        if (ctxt_ptr != NULL) {
+            *ctxt_ptr = MR_ENGINE(MR_eng_main_context);
+        }
+
+        return MR_TRUE;
+    }
+
+    MR_for_dlist(item, MR_ENGINE(MR_eng_gen_contexts)) {
+        ctxt = (MR_Context *) MR_dlist_data(item);
+        if (MR_find_zone_for_det_ptr_in_context(ptr, ctxt,
+            zone_ptr, zone_num_ptr))
+        {
+            if (ctxt_ptr != NULL) {
+                *ctxt_ptr = ctxt;
+            }
+
+            return MR_TRUE;
+        }
+    }
+
+#else   /* !MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
+    if (MR_find_zone_for_det_ptr_in_context(ptr, &MR_ENGINE(MR_eng_context),
+        zone_ptr, zone_num_ptr))
+    {
+        if (ctxt_ptr != NULL) {
+            *ctxt_ptr = &MR_ENGINE(MR_eng_context);
+        }
+
+        return MR_TRUE;
+    }
+
+#endif  /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
+    return MR_FALSE;
+}
+
+static MR_bool
+MR_find_zone_for_nondet_ptr(const MR_Word *ptr, MR_Context **ctxt_ptr,
+    MR_MemoryZone **zone_ptr, int *zone_num_ptr)
+{
+#ifdef  MR_USE_MINIMAL_MODEL_OWN_STACKS
+
+    const MR_Dlist      *item;
+    const MR_Context    *ctxt;
+
+    if (MR_find_zone_for_nondet_ptr_in_context(ptr,
+        MR_ENGINE(MR_eng_main_context), zone_ptr, zone_num_ptr))
+    {
+        if (ctxt_ptr != NULL) {
+            *ctxt_ptr = MR_ENGINE(MR_eng_main_context);
+        }
+
+        return MR_TRUE;
+    }
+
+    MR_for_dlist(item, MR_ENGINE(MR_eng_gen_contexts)) {
+        ctxt = (MR_Context *) MR_dlist_data(item);
+        if (MR_find_zone_for_nondet_ptr_in_context(ptr, ctxt,
+            zone_ptr, zone_num_ptr))
+        {
+            if (ctxt_ptr != NULL) {
+                *ctxt_ptr = ctxt;
+            }
+
+            return MR_TRUE;
+        }
+    }
+
+#else   /* !MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
+    if (MR_find_zone_for_nondet_ptr_in_context(ptr, &MR_ENGINE(MR_eng_context),
+        zone_ptr, zone_num_ptr))
+    {
+        if (ctxt_ptr != NULL) {
+            *ctxt_ptr = &MR_ENGINE(MR_eng_context);
+        }
+
+        return MR_TRUE;
+    }
+
+#endif  /* MR_USE_MINIMAL_MODEL_OWN_STACKS */
+
+    return MR_FALSE;
+}
+
Index: runtime/mercury_debug.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_debug.h,v
retrieving revision 1.18
diff -u -b -r1.18 mercury_debug.h
--- runtime/mercury_debug.h	15 Sep 2006 04:08:54 -0000	1.18
+++ runtime/mercury_debug.h	30 Oct 2006 05:49:57 -0000
@@ -30,20 +30,20 @@
 
 #define	MR_debuggoto(label) \
 	MR_IF (MR_gotodebug, \
-		(MR_save_transient_registers(), MR_goto_msg(label)))
+		(MR_save_transient_registers(), MR_goto_msg(stdout, label)))
 
 #define	MR_debugsreg() \
 	MR_IF (MR_sregdebug, \
-		(MR_save_transient_registers(), MR_reg_msg()))
+		(MR_save_transient_registers(), MR_reg_msg(stdout)))
 
 #endif
 
 #ifndef MR_DEBUG_HEAP_ALLOC
 
-#define	MR_debug_unravel_univ(univ, typeinfo, value)		((void)0)
-#define	MR_debug_new_univ_on_hp(univ, typeinfo, value)		((void)0)
+#define	MR_debug_unravel_univ(univ, typeinfo, value)		((void) 0)
+#define	MR_debug_new_univ_on_hp(univ, typeinfo, value)		((void) 0)
 #define	MR_debug_tag_offset_incr_hp_base(ptr, tag, offset, count, is_atomic) \
-								((void)0)
+								((void) 0)
 
 #else
 
@@ -61,114 +61,132 @@
 
 #ifndef MR_LOWLEVEL_DEBUG
 
-#define	MR_debugcr1(hp)						((void)0)
-#define	MR_debugcr2(hp)						((void)0)
-#define	MR_debugcr3(hp)						((void)0)
-#define	MR_debugincrhp(val, hp)					((void)0)
-#define	MR_debugincrsp(val, sp)					((void)0)
-#define	MR_debugdecrsp(val, sp)					((void)0)
-#define	MR_debugregs(msg)					((void)0)
-#define	MR_debugframe(msg)					((void)0)
-#define	MR_debugmkframe(predname)				((void)0)
-#define	MR_debugmktempframe()					((void)0)
-#define	MR_debugmkdettempframe()				((void)0)
-#define	MR_debugsucceed()					((void)0)
-#define	MR_debugsucceeddiscard()				((void)0)
-#define	MR_debugfail()						((void)0)
-#define	MR_debugredo()						((void)0)
-#define	MR_debugcall(proc, succ_cont)				((void)0)
-#define	MR_debugtailcall(proc)					((void)0)
-#define	MR_debugproceed()					((void)0)
-#define	MR_debugmsg0(msg)					((void)0)
-#define	MR_debugmsg1(msg, arg1)					((void)0)
-#define	MR_debugmsg2(msg, arg1, arg2)				((void)0)
-#define	MR_debugmsg3(msg, arg1, arg2, arg3)			((void)0)
+#define	MR_debugcr1(hp)						((void) 0)
+#define	MR_debugcr2(hp)						((void) 0)
+#define	MR_debugcr3(hp)						((void) 0)
+#define	MR_debugincrhp(val, hp)					((void) 0)
+#define	MR_debugincrsp(val, sp)					((void) 0)
+#define	MR_debugdecrsp(val, sp)					((void) 0)
+#define	MR_debugregs(msg)					((void) 0)
+#define	MR_debugframe(msg)					((void) 0)
+#define	MR_debugmkframe(predname)				((void) 0)
+#define	MR_debugmktempframe()					((void) 0)
+#define	MR_debugmkdettempframe()				((void) 0)
+#define	MR_debugsucceed()					((void) 0)
+#define	MR_debugsucceeddiscard()				((void) 0)
+#define	MR_debugfail()						((void) 0)
+#define	MR_debugredo()						((void) 0)
+#define	MR_debugcall(proc, succ_cont)				((void) 0)
+#define	MR_debugtailcall(proc)					((void) 0)
+#define	MR_debugproceed()					((void) 0)
+#define	MR_debugmsg0(msg)					((void) 0)
+#define	MR_debugmsg1(msg, arg1)					((void) 0)
+#define	MR_debugmsg2(msg, arg1, arg2)				((void) 0)
+#define	MR_debugmsg3(msg, arg1, arg2, arg3)			((void) 0)
 
 #else
 
 #define	MR_debugcr1(hp) \
 	MR_IF (MR_heapdebug, \
-		(MR_save_transient_registers(), MR_cr1_msg(hp)))
+		(MR_save_transient_registers(), \
+		 MR_cr1_msg(stdout, hp)))
 
 #define	MR_debugcr2(hp) \
 	MR_IF (MR_heapdebug, \
-		(MR_save_transient_registers(), MR_cr2_msg(hp)))
+		(MR_save_transient_registers(), \
+		 MR_cr2_msg(stdout, hp)))
 
 #define	MR_debugcr3(hp) \
 	MR_IF (MR_heapdebug, \
-		(MR_save_transient_registers(), MR_cr3_msg(hp)))
+		(MR_save_transient_registers(), \
+		 MR_cr3_msg(stdout, hp)))
 
 #define	MR_debugincrhp(val, hp) \
 	MR_IF (MR_heapdebug, \
 		(MR_save_transient_registers(), \
-		 MR_incr_hp_debug_msg((val), (hp))))
+		 MR_incr_hp_debug_msg(stdout, (val), (hp))))
 
 #define	MR_debugincrsp(val, sp) \
 	MR_IF (MR_detstackdebug, \
-		(MR_save_transient_registers(), MR_incr_sp_msg((val), (sp))))
+		(MR_save_transient_registers(), \
+		 MR_incr_sp_msg(stdout, (val), (sp))))
 
 #define	MR_debugdecrsp(val, sp) \
 	MR_IF (MR_detstackdebug, \
-		(MR_save_transient_registers(), MR_decr_sp_msg((val), (sp))))
+		(MR_save_transient_registers(), \
+		 MR_decr_sp_msg(stdout, (val), (sp))))
 
 #define	MR_debugregs(msg) \
 	MR_IF (MR_progdebug, \
-		(MR_save_transient_registers(), MR_printregs(msg)))
+		(MR_save_transient_registers(), \
+		 MR_printregs(stdout, msg)))
 
 #define	MR_debugframe(msg)	 \
 	MR_IF (MR_progdebug, \
-		(MR_save_transient_registers(), MR_printframe(msg)))
+		(MR_save_transient_registers(), \
+		 MR_printframe(stdout, msg)))
 
 #define	MR_debugmkframe(predname) \
-	MR_IF (MR_nondstackdebug, \
-		(MR_save_transient_registers(), MR_mkframe_msg(predname)))
+	MR_IF (MR_nondetstackdebug, \
+		(MR_save_transient_registers(), \
+		 MR_mkframe_msg(stdout, predname)))
 
 #define	MR_debugmktempframe() \
-	MR_IF (MR_nondstackdebug, \
-		(MR_save_transient_registers(), MR_mktempframe_msg()))
+	MR_IF (MR_nondetstackdebug, \
+		(MR_save_transient_registers(), \
+		 MR_mktempframe_msg(stdout)))
 
 #define	MR_debugmkdettempframe() \
-	MR_IF (MR_nondstackdebug, \
-		(MR_save_transient_registers(), MR_mkdettempframe_msg()))
+	MR_IF (MR_nondetstackdebug, \
+		(MR_save_transient_registers(), \
+		 MR_mkdettempframe_msg(stdout)))
 
 #define	MR_debugsucceed() \
 	MR_IF (MR_calldebug, \
-		(MR_save_transient_registers(), MR_succeed_msg()))
+		(MR_save_transient_registers(), \
+		 MR_succeed_msg(stdout)))
 
 #define	MR_debugsucceeddiscard() \
 	MR_IF (MR_calldebug, \
-		(MR_save_transient_registers(), MR_succeeddiscard_msg()))
+		(MR_save_transient_registers(), \
+		 MR_succeeddiscard_msg(stdout)))
 
 #define	MR_debugfail() \
 	MR_IF (MR_calldebug, \
-		(MR_save_transient_registers(), MR_fail_msg()))
+		(MR_save_transient_registers(), \
+		 MR_fail_msg(stdout)))
 
 #define	MR_debugredo() \
 	MR_IF (MR_calldebug, \
-		(MR_save_transient_registers(), MR_redo_msg()))
+		(MR_save_transient_registers(), \
+		 MR_redo_msg(stdout)))
 
 #define	MR_debugcall(proc, succ_cont) \
 	MR_IF (MR_calldebug, \
-		(MR_save_transient_registers(), MR_call_msg(proc, succ_cont)))
+		(MR_save_transient_registers(), \
+		 MR_call_msg(stdout, proc, succ_cont)))
 
 #define	MR_debugtailcall(proc) \
 	MR_IF (MR_calldebug, \
-		(MR_save_transient_registers(), MR_tailcall_msg(proc)))
+		(MR_save_transient_registers(), \
+		 MR_tailcall_msg(stdout, proc)))
 
 #define	MR_debugproceed() \
-	MR_IF (MR_calldebug, (MR_save_transient_registers(), MR_proceed_msg()))
+	MR_IF (MR_calldebug, \
+		(MR_save_transient_registers(), \
+		 MR_proceed_msg(stdout)))
 
 #define	MR_debugmsg0(msg) \
-	MR_IF (MR_progdebug, (printf(msg)))
+	MR_IF (MR_progdebug, (fprintf(stdout, msg)))
 
 #define	MR_debugmsg1(msg, arg1) \
-	MR_IF (MR_progdebug, (printf(msg, arg1)))
+	MR_IF (MR_progdebug, (fprintf(stdout, msg, arg1)))
 
 #define	MR_debugmsg2(msg, arg1, arg2) \
-	MR_IF (MR_progdebug, (printf(msg, arg1, arg2)))
+	MR_IF (MR_progdebug, (fprintf(stdout, msg, arg1, arg2)))
 
 #define	MR_debugmsg3(msg, arg1, arg2, arg3) \
-	MR_IF (MR_progdebug, (printf(msg, arg1, arg2, arg3)))
+	MR_IF (MR_progdebug, (fprintf(stdout, msg, arg1, arg2, arg3)))
 
 #endif /* MR_LOWLEVEL_DEBUG */
 
@@ -184,59 +202,58 @@
 /*---------------------------------------------------------------------------*/
 
 #ifdef MR_DEBUG_HEAP_ALLOC
-extern	void	MR_unravel_univ_msg(MR_Word univ, MR_TypeInfo type_info,
-			MR_Word value);
-extern	void	MR_new_univ_on_hp_msg(MR_Word univ, MR_TypeInfo type_info,
-			MR_Word value);
-extern	void	MR_debug_tag_offset_incr_hp_base_msg(MR_Word ptr, int tag,
-			int offset, int count, int is_atomic);
+extern	void	MR_unravel_univ_msg(FILE *fp, MR_Word univ,
+			MR_TypeInfo type_info, MR_Word value);
+extern	void	MR_new_univ_on_hp_msg(FILE *fp, MR_Word univ,
+			MR_TypeInfo type_info, MR_Word value);
+extern	void	MR_debug_tag_offset_incr_hp_base_msg(FILE *fp, MR_Word ptr,
+			int tag, int offset, int count, int is_atomic);
 #endif
 
 #ifdef MR_LOWLEVEL_DEBUG
-extern	void	MR_mkframe_msg(const char *);
-extern	void	MR_mktempframe_msg(void);
-extern	void	MR_mkdettempframe_msg(void);
-extern	void	MR_succeed_msg(void);
-extern	void	MR_succeeddiscard_msg(void);
-extern	void	MR_fail_msg(void);
-extern	void	MR_redo_msg(void);
-extern	void	MR_call_msg(/* const */ MR_Code *proc,
-			/* const */ MR_Code *succcont);
-extern	void	MR_tailcall_msg(/* const */ MR_Code *proc);
-extern	void	MR_proceed_msg(void);
-extern	void	MR_cr1_msg(const MR_Word *addr);
-extern	void	MR_cr2_msg(const MR_Word *addr);
-extern	void	MR_cr3_msg(const MR_Word *addr);
-extern	void	MR_incr_hp_debug_msg(MR_Word val, const MR_Word *addr);
-extern	void	MR_incr_sp_msg(MR_Word val, const MR_Word *addr);
-extern	void	MR_decr_sp_msg(MR_Word val, const MR_Word *addr);
+extern	void	MR_mkframe_msg(FILE *fp, const char *);
+extern	void	MR_mktempframe_msg(FILE *fp);
+extern	void	MR_mkdettempframe_msg(FILE *fp);
+extern	void	MR_succeed_msg(FILE *fp);
+extern	void	MR_succeeddiscard_msg(FILE *fp);
+extern	void	MR_fail_msg(FILE *fp);
+extern	void	MR_redo_msg(FILE *fp);
+extern	void	MR_call_msg(FILE *fp, const MR_Code *proc,
+			const MR_Code *succ_cont);
+extern	void	MR_tailcall_msg(FILE *fp, const MR_Code *proc);
+extern	void	MR_proceed_msg(FILE *fp);
+extern	void	MR_cr1_msg(FILE *fp, const MR_Word *addr);
+extern	void	MR_cr2_msg(FILE *fp, const MR_Word *addr);
+extern	void	MR_cr3_msg(FILE *fp, const MR_Word *addr);
+extern	void	MR_incr_hp_debug_msg(FILE *fp, MR_Word val,
+			const MR_Word *addr);
+extern	void	MR_incr_sp_msg(FILE *fp, MR_Word val, const MR_Word *addr);
+extern	void	MR_decr_sp_msg(FILE *fp, MR_Word val, const MR_Word *addr);
 #endif
 
 #ifdef MR_DEBUG_GOTOS
-extern	void	MR_goto_msg(/* const */ MR_Code *addr);
-extern	void	MR_reg_msg(void);
+extern	void	MR_goto_msg(FILE *fp, const MR_Code *addr);
+extern	void	MR_reg_msg(FILE *fp);
 #endif
 
 #ifdef MR_LOWLEVEL_DEBUG
-extern	void	MR_printint(MR_Word n);
-extern	void	MR_printstring(const char *s);
-extern	void	MR_printheap(const MR_Word *h);
-extern	void	MR_dumpframe(/* const */ MR_Word *);
-extern	void	MR_dumpnondstack(void);
-extern	void	MR_printlist(MR_Word p);
-extern	void	MR_printframe(const char *);
-extern	void	MR_printregs(const char *msg);
+extern	void	MR_printint(FILE *fp, MR_Word n);
+extern	void	MR_printstring(FILE *fp, const char *s);
+extern	void	MR_printheap(FILE *fp, const MR_Word *h);
+extern	void	MR_dumpframe(FILE *fp, const MR_Word *);
+extern	void	MR_dumpnondetstack(FILE *fp);
+extern	void	MR_printlist(FILE *fp, MR_Word p);
+extern	void	MR_printframe(FILE *fp, const char *);
+extern	void	MR_printregs(FILE *fp, const char *msg);
 #endif
 
-extern	void	MR_printdetstack(const MR_Word *s);
-extern	void	MR_printdetstackptr(const MR_Word *s);
+extern	void	MR_printdetstack(FILE *fp, const MR_Word *s);
 extern	void	MR_print_detstackptr(FILE *fp, const MR_Word *s);
-extern	void	MR_printnondstack(const MR_Word *s);
-extern	void	MR_printnondstackptr(const MR_Word *s);
-extern	void	MR_print_nondstackptr(FILE *fp, const MR_Word *s);
+extern	void	MR_printnondetstack(FILE *fp, const MR_Word *s);
+extern	void	MR_print_nondetstackptr(FILE *fp, const MR_Word *s);
 extern	void	MR_print_heapptr(FILE *fp, const MR_Word *s);
-extern	void	MR_print_label(FILE *fp, /* const */ MR_Code *w);
-extern	void	MR_printlabel(FILE *fp, /* const */ MR_Code *w);
+extern	void	MR_print_label(FILE *fp, const MR_Code *w);
+extern	void	MR_printlabel(FILE *fp, const MR_Code *w);
 extern	void	MR_print_deep_prof_var(FILE *fp, const char *name,
 			MR_CallSiteDynamic *csd);
 
Index: runtime/mercury_engine.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_engine.c,v
retrieving revision 1.52
diff -u -b -r1.52 mercury_engine.c
--- runtime/mercury_engine.c	26 Sep 2006 03:53:22 -0000	1.52
+++ runtime/mercury_engine.c	29 Oct 2006 02:01:38 -0000
@@ -1,4 +1,7 @@
 /*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
 INIT mercury_sys_init_engine
 ENDINIT
 */
@@ -24,7 +27,7 @@
 
   #ifdef MR_USE_GCC_NONLOCAL_GOTOS
 
-    #define LOCALS_SIZE  10024	/* amount of space to reserve for local vars */
+    #define LOCALS_SIZE     10024   /* space to reserve for local vars */
     #define MAGIC_MARKER	187	/* a random character */
     #define MAGIC_MARKER_2	142	/* another random character */
 
@@ -47,7 +50,7 @@
 	{ "call",	MR_CALLFLAG },
 	{ "heap",	MR_HEAPFLAG },
 	{ "detstack",	MR_DETSTACKFLAG },
-	{ "nondstack",	MR_NONDSTACKFLAG },
+    { "nondetstack",    MR_NONDETSTACKFLAG },
 	{ "final",	MR_FINALFLAG },
 	{ "mem",	MR_MEMFLAG },
 	{ "sreg",	MR_SREGFLAG },
@@ -92,8 +95,7 @@
 	{
 		static MR_bool made_engine_done_label = MR_FALSE;
 		if (!made_engine_done_label) {
-			MR_make_label("engine_done", MR_LABEL(engine_done),
-				engine_done);
+            MR_make_label("engine_done", MR_LABEL(engine_done), engine_done);
 			made_engine_done_label = MR_TRUE;
 		}
 	}
@@ -106,14 +108,12 @@
 
 #ifndef	MR_CONSERVATIVE_GC
 	eng->MR_eng_heap_zone = MR_create_zone("heap", 1,
-		MR_heap_size, MR_next_offset(),
-		MR_heap_zone_size, MR_default_handler);
+        MR_heap_size, MR_next_offset(), MR_heap_zone_size, MR_default_handler);
 	eng->MR_eng_hp = eng->MR_eng_heap_zone->MR_zone_min;
 
   #ifdef MR_NATIVE_GC
 	eng->MR_eng_heap_zone2 = MR_create_zone("heap2", 1,
-		MR_heap_size, MR_next_offset(),
-		MR_heap_zone_size, MR_default_handler);
+        MR_heap_size, MR_next_offset(), MR_heap_zone_size, MR_default_handler);
 
     #ifdef MR_DEBUG_AGC_PRINT_VARS
 	eng->MR_eng_debug_heap_zone = MR_create_zone("debug_heap", 1,
@@ -142,8 +142,7 @@
 #endif
 
 	/*
-	** Don't allocate a context for this engine until it is actually
-	** needed.
+    ** Don't allocate a context for this engine until it is actually needed.
 	*/
 	eng->MR_eng_this_context = NULL;
 }
@@ -153,7 +152,7 @@
 void MR_finalize_engine(MercuryEngine *eng)
 {
 	/*
-	** XXX there are lots of other resources in MercuryEngine that
+    ** XXX There are lots of other resources in MercuryEngine that
 	** might need to be finalized.  
 	*/
 	if (eng->MR_eng_this_context) {
@@ -169,10 +168,9 @@
 	MercuryEngine *eng;
 
 	/*
-	** We need to use MR_GC_NEW_UNCOLLECTABLE() here,
-	** rather than MR_GC_NEW(), since the engine pointer
-	** will normally be stored in thread-local storage, which is
-	** not traced by the conservative garbage collector.
+    ** We need to use MR_GC_NEW_UNCOLLECTABLE() here, rather than MR_GC_NEW(),
+    ** since the engine pointer will normally be stored in thread-local
+    ** storage, which is not traced by the conservative garbage collector.
 	*/
 	eng = MR_GC_NEW_UNCOLLECTABLE(MercuryEngine);
 	MR_init_engine(eng);
@@ -194,6 +192,7 @@
 ** This debugging hook is empty in the high-level code case:
 ** we don't save the previous locations.
 */
+
 void 
 MR_dump_prev_locations(void) {}
 
@@ -273,12 +272,12 @@
 	MR_ENGINE(MR_eng_jmp_buf) = &curr_jmp_buf;
 
 	/*
-	** Create an exception handler frame on the nondet stack
-	** so that we can catch and return Mercury exceptions.
+    ** Create an exception handler frame on the nondet stack so that
+    ** we can catch and return Mercury exceptions.
 	*/
 	if (catch_exceptions) {
-		MR_create_exception_handler("call_engine",
-			MR_C_LONGJMP_HANDLER, 0, MR_ENTRY(MR_do_fail));
+        MR_create_exception_handler("call_engine", MR_C_LONGJMP_HANDLER, 0,
+            MR_ENTRY(MR_do_fail));
 	}
 
 	/*
@@ -300,32 +299,29 @@
 
 		MR_debugmsg0("...caught longjmp\n");
 		/*
-		** On return,
-		** set MR_prof_current_proc to be the caller proc again
-		** (if time profiling is enabled),
-		** restore the registers (since longjmp may clobber them),
-		** and restore the saved value of MR_ENGINE(MR_eng_jmp_buf).
+        ** On return, set MR_prof_current_proc to be the caller proc again
+        ** (if time profiling is enabled), restore the registers (since
+        ** longjmp may clobber them), and restore the saved value of
+        ** MR_ENGINE(MR_eng_jmp_buf).
 		*/
 		MR_update_prof_current_proc(prev_proc);
 		MR_restore_registers();
 		MR_ENGINE(MR_eng_jmp_buf) = prev_jmp_buf;
 		if (catch_exceptions) {
 			/*
-			** Figure out whether or not we got an exception.
-			** If we got an exception, then all of the necessary
-			** cleanup such as stack unwinding has already been
-			** done, so all we have to do here is to return the
-			** exception.
+            ** Figure out whether or not we got an exception. If we got an
+            ** exception, then all of the necessary cleanup such as stack
+            ** unwinding has already been done, so all we have to do here
+            ** is to return the exception.
 			*/
 			exception = MR_ENGINE(MR_eng_exception);
 			if (exception != NULL) {
 				return exception;
 			}
 			/*
-			** If we added an exception hander, but we didn't
-			** get an exception, then we need to remove the
-			** exception handler frames from the nondet stack
-			** and prune the trail ticket allocated by
+            ** If we added an exception hander, but we didn't get an exception,
+            ** then we need to remove the exception handler frames from the
+            ** nondet stack and prune the trail ticket allocated by
 			** MR_create_exception_handler().
 			*/
 			this_frame = MR_curfr;
@@ -342,10 +338,9 @@
   	MR_ENGINE(MR_eng_jmp_buf) = &curr_jmp_buf;
   
 	/*
-	** If call profiling is enabled, and this is a case of
-	** Mercury calling C code which then calls Mercury,
-	** then we record the Mercury caller / Mercury callee pair
-	** in the table of call counts, if possible.
+    ** If call profiling is enabled, and this is a case of Mercury calling C
+    ** code which then calls Mercury, then we record the Mercury caller
+    ** / Mercury callee pair in the table of call counts, if possible.
 	*/
 #ifdef MR_MPROF_PROFILE_CALLS
   #ifdef MR_MPROF_PROFILE_TIME
@@ -354,29 +349,25 @@
 	}
   #else
 	/*
-	** XXX There's not much we can do in this case
-	** to keep the call counts accurate, since
-	** we don't know who the caller is.
+    ** XXX There's not much we can do in this case to keep the call counts
+    ** accurate, since we don't know who the caller is.
 	*/ 
   #endif
 #endif /* MR_MPROF_PROFILE_CALLS */
 
 	/*
-	** If time profiling is enabled, then we need to
-	** save MR_prof_current_proc so that we can restore it
-	** when we return.  We must then set MR_prof_current_proc
-	** to the procedure that we are about to call.
+    ** If time profiling is enabled, then we need to save MR_prof_current_proc
+    ** so that we can restore it when we return.  We must then set
+    ** MR_prof_current_proc to the procedure that we are about to call.
 	**
-	** We do this last thing before calling call_engine_inner(),
-	** since we want to credit as much as possible of the time
-	** in C code to the caller, not to the callee.
-	** Note that setting and restoring MR_prof_current_proc
+    ** We do this last thing before calling call_engine_inner(), since we want
+    ** to credit as much as possible of the time in C code to the caller,
+    ** not to the callee. Note that setting and restoring MR_prof_current_proc
 	** here in call_engine() means that time in call_engine_inner()
-	** unfortunately gets credited to the callee.
-	** That is not ideal, but we can't move this code into
-	** call_engine_inner() since call_engine_inner() can't
-	** have any local variables and this code needs the
-	** `prev_proc' local variable.
+    ** unfortunately gets credited to the callee. That is not ideal, but we
+    ** can't move this code into call_engine_inner() since call_engine_inner()
+    ** can't have any local variables and this code needs the `prev_proc'
+    ** local variable.
 	*/
 #ifdef MR_MPROF_PROFILE_TIME
 	prev_proc = MR_prof_current_proc;
@@ -394,21 +385,19 @@
 call_engine_inner(MR_Code *entry_point)
 {
 	/*
-	** Allocate some space for local variables in other
-	** procedures. This is done because we may jump into the middle
-	** of a C function, which may assume that space on the stack
-	** has already been allocated for its variables. Such space
-	** would generally be used for expression temporary variables.
-	** How did we arrive at the correct value of LOCALS_SIZE?
+    ** Allocate some space for local variables in other procedures. This is
+    ** done because we may jump into the middle of a C function, which may
+    ** assume that space on the stack has already been allocated for its
+    ** variables. Such space would generally be used for expression temporary
+    ** variables. How did we arrive at the correct value of LOCALS_SIZE?
 	** Good question. I think it's more voodoo than science.
 	**
-	** This used to be done by just calling
-	** alloca(LOCALS_SIZE), but on the mips that just decrements the
-	** stack pointer, whereas local variables are referenced
-	** via the frame pointer, so it didn't work.
-	** This technique should work and should be vaguely portable,
-	** just so long as local variables and temporaries are allocated in
-	** the same way in every function.
+    ** This used to be done by just calling alloca(LOCALS_SIZE), but on MIPS
+    ** that just decrements the stack pointer, whereas local variables are
+    ** referenced via the frame pointer, so it didn't work. This technique
+    ** should work and should be vaguely portable, just so long as local
+    ** variables and temporaries are allocated in the same way in every
+    ** function.
 	**
 	** WARNING!
 	** Do not add local variables to call_engine_inner that you expect
@@ -421,28 +410,26 @@
 
 #ifdef MR_LOWLEVEL_DEBUG
 {
-	/* ensure that we only make the label once */
+    /* Ensure that we only make the label once. */
 	static	MR_bool	initialized = MR_FALSE;
 
-	if (!initialized)
-	{
-		MR_make_label("engine_done", MR_LABEL(engine_done),
-			engine_done);
+    if (!initialized) {
+        MR_make_label("engine_done", MR_LABEL(engine_done), engine_done);
 		initialized = MR_TRUE;
 	}
 }
 #endif
 
 	/*
-	** restore any registers that get clobbered by the C function
-	** call mechanism
+    ** Restore any registers that get clobbered by the C function call
+    ** mechanism.
 	*/
 
 	MR_restore_transient_registers();
 
 	/*
-	** We save the address of the locals in a global pointer to make
-	** sure that gcc can't optimize them away.
+    ** We save the address of the locals in a global pointer to make sure
+    ** that gcc can't optimize them away.
 	*/
 
 	MR_global_pointer = locals;
@@ -453,27 +440,25 @@
 	MR_debugmsg1("in `call_engine_inner', locals at %p\n", (void *)locals);
 
 	/*
-	** We need to ensure that there is at least one
-	** real function call in call_engine_inner(), because
-	** otherwise gcc thinks that it doesn't need to
-	** restore the caller-save registers (such as
-	** the return address!) because it thinks call_engine_inner() is
-	** a leaf routine which doesn't call anything else,
-	** and so it thinks that they won't have been clobbered.
+    ** We need to ensure that there is at least one real function call
+    ** in call_engine_inner(), because otherwise gcc thinks that it doesn't
+    ** need to restore the caller-save registers (such as the return address!)
+    ** because it thinks call_engine_inner() is a leaf routine which doesn't
+    ** call anything else, and so it thinks that they won't have been
+    ** clobbered.
 	**
 	** This probably isn't necessary now that we exit from this function
 	** using longjmp(), but it doesn't do much harm, so I'm leaving it in.
 	**
-	** Also for gcc versions >= egcs1.1, we need to ensure that
-	** there is at least one jump to an unknown label.
+    ** Also for gcc versions >= egcs1.1, we need to ensure that there is
+    ** at least one jump to an unknown label.
 	*/
 	goto *MR_dummy_identify_function(&&dummy_label);
 dummy_label:
 
 	/*
-	** Increment the number of times we've entered this
-	** engine from C, and mark the current context as being
-	** owned by this thread.
+    ** Increment the number of times we've entered this engine from C,
+    ** and mark the current context as being owned by this thread.
 	*/
 #ifdef	MR_THREAD_SAFE
 	MR_ENGINE(MR_eng_c_depth)++;
@@ -492,7 +477,7 @@
 #endif
 
 	/*
-	** Now just call the entry point
+    ** Now just call the entry point.
 	*/
 
 	MR_noprof_call(entry_point, MR_LABEL(engine_done));
@@ -500,9 +485,8 @@
 MR_define_label(engine_done);
 
 	/*
-	** Decrement the number of times we've entered this
-	** engine from C and restore the owning thread in
-	** the current context.
+    ** Decrement the number of times we've entered this engine from C
+    ** and restore the owning thread in the current context.
 	*/
 #ifdef	MR_THREAD_SAFE
 	if (MR_ENGINE(MR_eng_this_context)) {
@@ -514,8 +498,7 @@
 		MR_ENGINE(MR_eng_c_depth)--;
 
 		tmp = MR_ENGINE(MR_eng_saved_owners);
-		if (tmp != NULL)
-		{
+        if (tmp != NULL) {
 			val = tmp->thread;
 			MR_ENGINE(MR_eng_saved_owners) = tmp->next;
 			MR_GC_free(tmp);
@@ -553,14 +536,12 @@
 #endif /* MR_LOWLEVEL_DEBUG */
 
 	/*
-	** Despite the above precautions with allocating a large chunk
-	** of unused stack space, the return address may still have been
-	** stored on the top of the stack, past our dummy locals,
-	** where it may have been clobbered.
-	** Hence the only safe way to exit is with longjmp().
+    ** Despite the above precautions with allocating a large chunk of unused
+    ** stack space, the return address may still have been stored on the
+    ** top of the stack, past our dummy locals, where it may have been
+    ** clobbered. Hence the only safe way to exit is with longjmp().
 	**
-	** Since longjmp() may clobber the registers, we need to
-	** save them first.
+    ** Since longjmp() may clobber the registers, we need to save them first.
 	*/
 	MR_ENGINE(MR_eng_exception) = NULL;
 	MR_save_registers();
@@ -575,23 +556,25 @@
 
 /* with nonlocal gotos, we don't save the previous locations */
 void 
-MR_dump_prev_locations(void) {}
+MR_dump_prev_locations(void)
+{
+}
 
 #else /* not MR_USE_GCC_NONLOCAL_GOTOS */
 
 /*
-** The portable version
+** The portable version.
 **
-** To keep the main dispatch loop tight, instead of returning a null
-** pointer to indicate when we've finished executing, we just longjmp()
-** out.  We need to save the registers before calling longjmp(),
-** since doing a longjmp() might clobber them.
-**
-** With register windows, we need to restore the registers to
-** their initialized values from their saved copies.
-** This must be done in a function engine_init_registers() rather
-** than directly from call_engine_inner() because otherwise their value
-** would get mucked up because of the function call from call_engine_inner().
+** To keep the main dispatch loop tight, instead of returning a null pointer
+** to indicate when we've finished executing, we just longjmp() out.
+** We need to save the registers before calling longjmp(), since doing
+** a longjmp() might clobber them.
+**
+** With register windows, we need to restore the registers to their initialized
+** values from their saved copies. This must be done in a function
+** engine_init_registers() rather than directly from call_engine_inner()
+** because otherwise their value would get mucked up because of the function
+** call from call_engine_inner().
 */
 
 static MR_Code *
@@ -612,10 +595,9 @@
 }
 
 /*
-** For debugging purposes, we keep a circular buffer of
-** the last 40 locations that we jumped to.  This is
-** very useful for determining the cause of a crash,
-** since it runs a lot faster than -dg.
+** For debugging purposes, we keep a circular buffer of the last 40 locations
+** that we jumped to.  This is very useful for determining the cause of a
+** crash, since it runs a lot faster than -dg.
 */
 
 #define NUM_PREV_FPS	40
@@ -628,7 +610,8 @@
 void 
 MR_dump_prev_locations(void)
 {
-	int i, pos;
+    int i;
+    int pos;
 
 #if !defined(MR_DEBUG_GOTOS)
 	if (MR_tracedebug) 
@@ -658,8 +641,7 @@
 
 #if !defined(MR_DEBUG_GOTOS)
 if (!MR_tracedebug) {
-	for (;;)
-	{
+    for (;;) {
 		fp = (Func *) (*fp)();
 		fp = (Func *) (*fp)();
 		fp = (Func *) (*fp)();
@@ -671,12 +653,12 @@
 	}
 } else
 #endif
-	for (;;)
-	{
+    for (;;) {
 		prev_fps[prev_fp_index] = (MR_Code *) fp;
 
-		if (++prev_fp_index >= NUM_PREV_FPS)
+        if (++prev_fp_index >= NUM_PREV_FPS) {
 			prev_fp_index = 0;
+        }
 
 		MR_debuggoto(fp);
 		MR_debugsreg();
@@ -693,7 +675,7 @@
 MR_terminate_engine(void)
 {
 	/*
-	** we don't bother to deallocate memory...
+    ** We don't bother to deallocate memory...
 	** that will happen automatically on process exit anyway.
 	*/
 }
@@ -736,13 +718,13 @@
 MR_define_entry(MR_exception_handler_do_fail);
 	/*
 	** `MR_exception_handler_do_fail' is the same as `MR_do_fail':
-	** it just invokes MR_fail().  The reason we don't just use
-	** `MR_do_fail' for this is that when unwinding the stack we
-	** check for a redoip of `MR_exception_handler_do_fail' and
-	** handle it specially.
+    ** it just invokes MR_fail().  The reason we don't just use `MR_do_fail'
+    ** for this is that when unwinding the stack we check for a redoip
+    ** of `MR_exception_handler_do_fail' and handle it specially.
 	*/
 	MR_fail();
 
+
 MR_END_MODULE
 
 #endif /* !MR_HIGHLEVEL_CODE */
Index: runtime/mercury_engine.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_engine.h,v
retrieving revision 1.42
diff -u -b -r1.42 mercury_engine.h
--- runtime/mercury_engine.h	26 Sep 2006 03:53:21 -0000	1.42
+++ runtime/mercury_engine.h	30 Oct 2006 06:20:07 -0000
@@ -50,7 +50,7 @@
 #define MR_CALLFLAG                      2
 #define MR_HEAPFLAG                      3
 #define MR_DETSTACKFLAG                  4
-#define MR_NONDSTACKFLAG                 5
+#define MR_NONDETSTACKFLAG               5
 #define MR_FINALFLAG                     6
 #define MR_MEMFLAG                       7
 #define MR_SREGFLAG                      8
@@ -93,7 +93,7 @@
 ** MR_calldebug controls whether we should generate diagnostics when control
 ** crosses procedure boundaries, i.e. calls, exits, redos and fails.
 **
-** MR_detstackdebug and MR_nondstackdebug control whether we should generate
+** MR_detstackdebug and MR_nondetstackdebug control whether we should generate
 ** diagnostics when incrementing and decrementing the pointers to the
 ** respective stacks.
 **
@@ -148,7 +148,7 @@
 #define MR_calldebug                MR_debugflag[MR_CALLFLAG]
 #define MR_heapdebug                MR_debugflag[MR_HEAPFLAG]
 #define MR_detstackdebug            MR_debugflag[MR_DETSTACKFLAG]
-#define MR_nondstackdebug           MR_debugflag[MR_NONDSTACKFLAG]
+#define MR_nondetstackdebug         MR_debugflag[MR_NONDETSTACKFLAG]
 #define MR_finaldebug               MR_debugflag[MR_FINALFLAG]
 #define MR_memdebug                 MR_debugflag[MR_MEMFLAG]
 #define MR_sregdebug                MR_debugflag[MR_SREGFLAG]
@@ -198,7 +198,7 @@
 #if MR_NUM_REAL_REGS > 0
         MR_Word     regs[MR_NUM_REAL_REGS];
 #endif /* MR_NUM_REAL_REGS > 0 */
-    } MR_jmp_buf;
+} MR_jmp_buf;
 
 /*---------------------------------------------------------------------------*/
 
@@ -465,21 +465,16 @@
 
 #define MR_load_engine_regs(eng)                                              \
     do {                                                                      \
-        MR_IF_NOT_CONSERVATIVE_GC(MR_hp_word = (MR_Word)                      \
-            (eng)->MR_eng_hp;)                                                \
-        MR_IF_NOT_CONSERVATIVE_GC(MR_sol_hp =                                 \
-            (eng)->MR_eng_sol_hp;)                                            \
-        MR_IF_NOT_CONSERVATIVE_GC(MR_global_hp =                              \
-            (eng)->MR_eng_global_hp;)                                         \
+        MR_IF_NOT_CONSERVATIVE_GC(MR_hp_word = (MR_Word) (eng)->MR_eng_hp;)   \
+        MR_IF_NOT_CONSERVATIVE_GC(MR_sol_hp = (eng)->MR_eng_sol_hp;)          \
+        MR_IF_NOT_CONSERVATIVE_GC(MR_global_hp = (eng)->MR_eng_global_hp;)    \
     } while (0)
 
 #define MR_save_engine_regs(eng)                                              \
     do {                                                                      \
         MR_IF_NOT_CONSERVATIVE_GC((eng)->MR_eng_hp = MR_hp;)                  \
-        MR_IF_NOT_CONSERVATIVE_GC((eng)->MR_eng_sol_hp =                      \
-            MR_sol_hp;)                                                       \
-        MR_IF_NOT_CONSERVATIVE_GC((eng)->MR_eng_global_hp =                   \
-            MR_global_hp;)                                                    \
+        MR_IF_NOT_CONSERVATIVE_GC((eng)->MR_eng_sol_hp = MR_sol_hp;)          \
+        MR_IF_NOT_CONSERVATIVE_GC((eng)->MR_eng_global_hp = MR_global_hp;)    \
     } while (0)
 
 /*
@@ -511,7 +506,7 @@
 /*---------------------------------------------------------------------------*/
 
 /*
-** Builtin labels that point to commonly used code fragments.
+** Builtin labels that point to some standard code fragments.
 */
 
 MR_declare_entry(MR_do_redo);
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.66
diff -u -b -r1.66 mercury_grade.h
--- runtime/mercury_grade.h	4 Oct 2006 06:59:23 -0000	1.66
+++ runtime/mercury_grade.h	20 Oct 2006 03:40:09 -0000
@@ -394,6 +394,12 @@
   #if defined(MR_HIGHLEVEL_CODE)
     #error "--extend-stacks-when-needed and --high-level-code are not compatible"
   #endif
+#elif defined(MR_STACK_SEGMENTS)
+  #define MR_GRADE_PART_16	MR_PASTE2(MR_GRADE_PART_15, _stseg)
+  #define MR_GRADE_OPT_PART_16	MR_GRADE_OPT_PART_15 ".stseg"
+  #if defined(MR_HIGHLEVEL_CODE)
+    #error "--stack-segments and --high-level-code are not compatible"
+  #endif
 #else
   #define MR_GRADE_PART_16	MR_GRADE_PART_15
   #define MR_GRADE_OPT_PART_16	MR_GRADE_OPT_PART_15
Index: runtime/mercury_memory.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_memory.c,v
retrieving revision 1.38
diff -u -b -r1.38 mercury_memory.c
--- runtime/mercury_memory.c	2 Oct 2006 10:14:40 -0000	1.38
+++ runtime/mercury_memory.c	29 Oct 2006 02:04:24 -0000
@@ -17,7 +17,7 @@
 **	the register array 
 **	the bottom of the heap 
 **	the bottom of the detstack 
-**	the bottom of the nondstack 
+**	the bottom of the nondetstack 
 **
 ** all start at different offsets from multiples of the primary cache size.
 ** This should reduce cache conflicts (especially for small programs).
@@ -166,11 +166,11 @@
 					MR_unit);
 	MR_detstack_zone_size	 = MR_round_up(MR_detstack_zone_size * 1024,
 					MR_unit);
-	MR_nondstack_size	 = MR_round_up(MR_nondstack_size * 1024,
+	MR_nondetstack_size	 = MR_round_up(MR_nondetstack_size * 1024,
 					MR_unit);
-	MR_small_nondstack_size	 = MR_round_up(MR_small_nondstack_size * 1024,
+	MR_small_nondetstack_size= MR_round_up(MR_small_nondetstack_size * 1024,
 					MR_unit);
-	MR_nondstack_zone_size	 = MR_round_up(MR_nondstack_zone_size * 1024,
+	MR_nondetstack_zone_size = MR_round_up(MR_nondetstack_zone_size * 1024,
 					MR_unit);
 #ifdef	MR_USE_MINIMAL_MODEL_STACK_COPY
 	MR_genstack_size	 = MR_round_up(MR_genstack_size * 1024,
@@ -247,8 +247,8 @@
 		MR_detstack_zone_size = MR_unit;
 	}
 
-	if (MR_nondstack_zone_size >= MR_nondstack_size) {
-		MR_nondstack_zone_size = MR_unit;
+	if (MR_nondetstack_zone_size >= MR_nondetstack_size) {
+		MR_nondetstack_zone_size = MR_unit;
 	}
 
 #ifdef MR_USE_TRAIL
Index: runtime/mercury_memory_zones.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_memory_zones.c,v
retrieving revision 1.28
diff -u -b -r1.28 mercury_memory_zones.c
--- runtime/mercury_memory_zones.c	2 Mar 2006 07:40:48 -0000	1.28
+++ runtime/mercury_memory_zones.c	29 Oct 2006 01:48:15 -0000
@@ -310,7 +310,6 @@
 
 static void             MR_init_offsets(void);
 static MR_MemoryZone    *MR_get_zone(void);
-static void             MR_unget_zone(MR_MemoryZone *zone);
 
     /*
     ** We manage the handing out of offsets through the cache by
@@ -361,8 +360,8 @@
     MR_MemoryZone   *zone;
 
     /*
-    ** unlink the first zone on the free-list,
-    ** link it onto the used-list and return it.
+    ** Unlink the first zone on the free-list, link it onto the used-list
+    ** and return it.
     */
     MR_LOCK(&free_memory_zones_lock, "get_zone");
     if (free_memory_zones == NULL) {
@@ -379,19 +378,17 @@
     return zone;
 }
 
-#if 0
-/* this function is not currently used */
-
-static void
+void
 MR_unget_zone(MR_MemoryZone *zone)
 {
     MR_MemoryZone   *prev;
     MR_MemoryZone   *tmp;
 
     /*
-    ** Find the zone on the used list, and unlink it from
-    ** the list, then link it onto the start of the free-list.
+    ** Find the zone on the used list, and unlink it from the list,
+    ** then link it onto the start of the free-list.
     */
+
     MR_LOCK(&free_memory_zones_lock, "unget_zone");
     for(prev = NULL, tmp = used_memory_zones; tmp != NULL && tmp != zone;
         prev = tmp, tmp = tmp->MR_zone_next)
@@ -414,17 +411,15 @@
     MR_UNLOCK(&free_memory_zones_lock, "unget_zone");
 }
 
-#endif
-
 /*
-** successive calls to next_offset return offsets modulo the primary
+** Successive calls to next_offset return offsets modulo the primary
 ** cache size (carefully avoiding ever giving an offset that clashes
 ** with fake_reg_array). This is used to give different memory zones
-** different starting points across the caches so that it is better
-** utilized.
+** different starting points across the caches so that it is better utilized.
+**
 ** An alternative implementation would be to increment the offset by
-** a fixed amount (eg 2Kb) so that as primary caches get bigger, we
-** allocate more offsets across them.
+** a fixed amount (eg 2Kb) so that as primary caches get bigger, we allocate
+** more offsets across them.
 */
 
 size_t
@@ -627,6 +622,11 @@
     zone->MR_zone_gc_threshold = (char *) zone->MR_zone_end
         - MR_heap_margin_size;
 #endif
+
+#if defined(MR_STACK_SEGMENTS) && !defined(MR_HIGHLEVEL_CODE)
+    zone->MR_zone_extend_threshold = (char *) zone->MR_zone_end
+        - MR_stack_margin_size;
+#endif
 }
 
 void
Index: runtime/mercury_memory_zones.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_memory_zones.h,v
retrieving revision 1.17
diff -u -b -r1.17 mercury_memory_zones.h
--- runtime/mercury_memory_zones.h	13 Sep 2005 08:25:39 -0000	1.17
+++ runtime/mercury_memory_zones.h	29 Oct 2006 21:11:45 -0000
@@ -89,8 +89,12 @@
 ** gc_threshold	This field, which is only used for heap zones, points to
 ** 		MR_heap_margin_size bytes before MR_zone_end (which is defined
 ** 		as one the fields above by the macros below). It is used to
-** 		decide when to do garbage collection without incurrent the
+** 		decide when to do garbage collection without incurring the
 ** 		expense of a subtraction on every allocation.
+**
+** extend_threshold
+** 		This field, which is only used for stack zones, points to
+** 		MR_stack_margin_size bytes before MR_zone_end.
 */
 
 struct MR_MemoryZone_Struct {
@@ -117,6 +121,10 @@
 	char			*MR_zone_gc_threshold;
 				/* == MR_zone_end - MR_heap_margin_size */
 #endif
+#if defined(MR_STACK_SEGMENTS) && !defined(MR_HIGHLEVEL_CODE)
+	char			*MR_zone_extend_threshold;
+				/* == MR_zone_end - MR_stack_margin_size */
+#endif
 };
 
 	/*
@@ -194,7 +202,7 @@
 ** has the same behaviour as MR_create_zone, except instead of allocating
 ** the memory, it takes a pointer to a region of memory that must be at
 ** least Size + MR_unit[*] bytes, or if MR_PROTECTPAGE is defined, then it
-** must be at least Size + 2 * unit[*] bytes.
+** must be at least Size + 2 * MR_unit[*] bytes.
 ** If it fails to protect the redzone then it exits.
 ** If MR_CHECK_OVERFLOW_VIA_MPROTECT is unavailable, then the last two
 ** arguments are ignored.
@@ -252,6 +260,12 @@
 extern	void		MR_debug_memory_zone(FILE *fp, MR_MemoryZone *zone);
 
 /*
+** Return the given zone to tyhe list of free zones.
+*/
+
+extern	void		MR_unget_zone(MR_MemoryZone *zone);
+
+/*
 ** MR_next_offset() returns sucessive offsets across the primary cache. Useful
 ** when calling {create,construct}_zone().
 */
Index: runtime/mercury_minimal_model.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_minimal_model.c,v
retrieving revision 1.19
diff -u -b -r1.19 mercury_minimal_model.c
--- runtime/mercury_minimal_model.c	18 Sep 2005 14:20:19 -0000	1.19
+++ runtime/mercury_minimal_model.c	29 Oct 2006 01:58:40 -0000
@@ -412,7 +412,7 @@
     fprintf(fp, "subgoal %s: status %s, generator frame ",
         MR_subgoal_addr_name(subgoal),
         MR_subgoal_status(subgoal->MR_sg_status));
-    MR_print_nondstackptr(fp, subgoal->MR_sg_generator_fr);
+    MR_print_nondetstackptr(fp, subgoal->MR_sg_generator_fr);
     if (subgoal->MR_sg_back_ptr == NULL) {
         fprintf(fp, ", DELETED");
     }
@@ -841,9 +841,9 @@
   #ifdef MR_TABLE_DEBUG
         if (MR_tabledebug) {
             printf("common ancestor search: ");
-            MR_printnondstackptr(fr1);
+            MR_printnondetstackptr(fr1);
             printf(" vs ");
-            MR_printnondstackptr(fr2);
+            MR_printnondetstackptr(fr2);
             printf("\n");
         }
   #endif
@@ -858,7 +858,7 @@
   #ifdef MR_TABLE_DEBUG
     if (MR_tabledebug) {
         printf("the common ancestor is ");
-        MR_printnondstackptr(fr1);
+        MR_printnondetstackptr(fr1);
         printf("\n");
     }
   #endif
@@ -1150,9 +1150,9 @@
         printf("extending saved state of consumer %s for %s\n",
             MR_consumer_addr_name(consumer), MR_subgoal_addr_name(leader));
         printf("common ancestors: old ");
-        MR_printnondstackptr(old_common_ancestor_fr);
+        MR_printnondetstackptr(old_common_ancestor_fr);
         printf(", new ");
-        MR_printnondstackptr(new_common_ancestor_fr);
+        MR_printnondetstackptr(new_common_ancestor_fr);
         printf("\nold saved state:\n");
         print_saved_state(stdout, cons_saved_state);
     }
@@ -1226,9 +1226,9 @@
 #ifdef  MR_TABLE_DEBUG
         if (MR_tabledebug) {
             printf("assert: non arena_start ");
-            MR_printnondstackptr(arena_start);
+            MR_printnondetstackptr(arena_start);
             printf(" + %d = ", arena_size);
-            MR_printnondstackptr(cons_saved_state->MR_ss_max_fr);
+            MR_printnondetstackptr(cons_saved_state->MR_ss_max_fr);
             printf(" + 1: diff %d\n",
                 (arena_start + arena_size)
                 - (cons_saved_state->MR_ss_max_fr + 1));
@@ -1347,10 +1347,10 @@
         if (MR_tablestackdebug) {
             printf("considering %s frame ",
                 (ordinary? "ordinary" : "temp"));
-            MR_print_nondstackptr(stdout,
+            MR_print_nondetstackptr(stdout,
                 saved_to_real_nondet_stack(saved_state, saved_fr));
             printf(" with redoip slot at ");
-            MR_print_nondstackptr(stdout,
+            MR_print_nondetstackptr(stdout,
                 saved_to_real_nondet_stack(saved_state,
                     MR_redoip_addr(saved_fr)));
             printf("\n");
@@ -1371,7 +1371,7 @@
 #ifdef  MR_TABLE_DEBUG
                 if (MR_tabledebug) {
                     printf("next main sequence frame ");
-                    MR_printnondstackptr(MR_succfr_slot(saved_fr));
+                    MR_printnondetstackptr(MR_succfr_slot(saved_fr));
                 }
 #endif  /* MR_TABLE_DEBUG */
 
@@ -1401,7 +1401,7 @@
 #ifdef  MR_TABLE_DEBUG
             if (MR_tabledebug) {
                 printf("setting redoip to schedule completion in bottom frame ");
-                MR_print_nondstackptr(stdout,
+                MR_print_nondetstackptr(stdout,
                     saved_to_real_nondet_stack(saved_state, saved_fr));
                 printf(" (in saved copy)\n");
             }
@@ -1425,7 +1425,7 @@
 #ifdef  MR_TABLE_DEBUG
                 if (MR_tabledebug) {
                     printf("setting redoip to schedule completion in frame ");
-                    MR_print_nondstackptr(stdout,
+                    MR_print_nondetstackptr(stdout,
                         saved_to_real_nondet_stack(saved_state, saved_fr));
                     printf(" (in saved copy)\n");
                 }
@@ -1445,7 +1445,7 @@
   #ifdef  MR_TABLE_DEBUG
                 if (MR_tablestackdebug) {
                     printf("clobbering redoip of follower frame at ");
-                    MR_printnondstackptr(real_fr);
+                    MR_printnondetstackptr(real_fr);
                     printf(" (in saved copy)\n");
                 }
   #endif    /* MR_TABLE_DEBUG */
@@ -1467,7 +1467,7 @@
   #ifdef  MR_TABLE_DEBUG
             if (MR_tablestackdebug) {
                 printf("committing redoip of frame at ");
-                MR_printnondstackptr(real_fr);
+                MR_printnondetstackptr(real_fr);
                 printf(" (in saved copy)\n");
             }
   #endif    /* MR_TABLE_DEBUG */
@@ -1479,7 +1479,7 @@
 #ifdef  MR_TABLE_DEBUG
             if (MR_tabledebug) {
                 printf("clobbering redoip of frame at ");
-                MR_printnondstackptr(real_fr);
+                MR_printnondetstackptr(real_fr);
                 printf(" (in saved copy)\n");
             }
 
@@ -1556,9 +1556,9 @@
     fprintf(fp, "sp:\t");
     MR_print_detstackptr(fp, saved_state->MR_ss_s_p);
     fprintf(fp, "\ncurfr:\t");
-    MR_print_nondstackptr(fp, saved_state->MR_ss_cur_fr);
+    MR_print_nondetstackptr(fp, saved_state->MR_ss_cur_fr);
     fprintf(fp, "\nmaxfr:\t");
-    MR_print_nondstackptr(fp, saved_state->MR_ss_max_fr);
+    MR_print_nondetstackptr(fp, saved_state->MR_ss_max_fr);
     fprintf(fp, "\n");
     
     fprintf(fp, "slots saved: %" MR_INTEGER_LENGTH_MODIFIER "d non,",
@@ -1574,9 +1574,9 @@
 
     if (saved_state->MR_ss_non_stack_block_size > 0) {
         fprintf(fp, "non region from ");
-        MR_print_nondstackptr(fp, saved_state->MR_ss_non_stack_real_start);
+        MR_print_nondetstackptr(fp, saved_state->MR_ss_non_stack_real_start);
         fprintf(fp, " to ");
-        MR_print_nondstackptr(fp, saved_state->MR_ss_non_stack_real_start +
+        MR_print_nondetstackptr(fp, saved_state->MR_ss_non_stack_real_start +
             saved_state->MR_ss_non_stack_block_size - 1);
         fprintf(fp, " (both inclusive)\n");
     }
@@ -1895,9 +1895,9 @@
         if (MR_tabledebug) {
             printf("resetting deepest nca for subgoal %s from ",
                 MR_subgoal_addr_name(subgoal));
-            MR_print_nondstackptr(stdout, subgoal->MR_sg_deepest_nca_fr);
+            MR_print_nondetstackptr(stdout, subgoal->MR_sg_deepest_nca_fr);
             printf(" to ");
-            MR_print_nondstackptr(stdout, common_ancestor);
+            MR_print_nondetstackptr(stdout, common_ancestor);
             printf("\n");
         }
 #endif
Index: runtime/mercury_overflow.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_overflow.h,v
retrieving revision 1.9
diff -u -b -r1.9 mercury_overflow.h
--- runtime/mercury_overflow.h	20 Mar 2006 23:43:17 -0000	1.9
+++ runtime/mercury_overflow.h	29 Oct 2006 02:01:09 -0000
@@ -1,4 +1,7 @@
 /*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
 ** Copyright (C) 1995-1998,2000-2001, 2005-2006 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.
@@ -11,11 +14,11 @@
 
 #ifndef MR_CHECK_FOR_OVERFLOW
 
-#define	MR_heap_overflow_check()	((void)0)
-#define	MR_detstack_overflow_check()	((void)0)
-#define	MR_detstack_underflow_check()	((void)0)
-#define	MR_nondstack_overflow_check()	((void)0)
-#define	MR_nondstack_underflow_check()	((void)0)
+#define MR_heap_overflow_check()            ((void) 0)
+#define MR_detstack_overflow_check()        ((void) 0)
+#define MR_detstack_underflow_check()       ((void) 0)
+#define MR_nondetstack_overflow_check()     ((void) 0)
+#define MR_nondetstack_underflow_check()    ((void) 0)
 
 #else /* MR_CHECK_FOR_OVERFLOW */
 
@@ -35,7 +38,7 @@
 
 #define	MR_detstack_overflow_check()					\
 	(								\
-		MR_IF (MR_sp >= MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_top,(\
+        MR_IF (MR_sp >= MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_top,(     \
 			MR_fatal_error("stack overflow")		\
 		)),							\
 		MR_IF (MR_sp > MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_max,(	\
@@ -52,18 +55,18 @@
 		(void)0							\
 	)
 
-#define	MR_nondstack_overflow_check()					\
+#define MR_nondetstack_overflow_check()                                      \
 	(								\
 		MR_IF (MR_maxfr >= MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_top,( \
 			MR_fatal_error("nondetstack overflow")		\
 		)),							\
 		MR_IF (MR_maxfr > MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_max,( \
-			MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_max = MR_maxfr\
+            MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_max = MR_maxfr     \
 		)),							\
 		(void)0							\
 	)
 
-#define	MR_nondstack_underflow_check()					\
+#define MR_nondetstack_underflow_check()                                     \
 	(								\
 		MR_IF (MR_maxfr < MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_min,( \
 			MR_fatal_error("nondetstack underflow")		\
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.74
diff -u -b -r1.74 mercury_stack_trace.c
--- runtime/mercury_stack_trace.c	29 Sep 2006 06:34:55 -0000	1.74
+++ runtime/mercury_stack_trace.c	30 Oct 2006 05:27:26 -0000
@@ -29,6 +29,7 @@
 static  MR_Stack_Walk_Step_Result
                     MR_stack_walk_succip_layout(MR_Code *success,
                         const MR_Label_Layout **return_label_layout,
+                        MR_Word **base_sp_ptr, MR_Word **base_curfr_ptr,
                         const char **problem_ptr);
 
 #ifndef MR_HIGHLEVEL_CODE
@@ -302,12 +303,14 @@
     }
 
     return MR_stack_walk_succip_layout(success, return_label_layout,
-        problem_ptr);
+        stack_trace_sp_ptr, stack_trace_curfr_ptr, problem_ptr);
 }
 
 static MR_Stack_Walk_Step_Result
 MR_stack_walk_succip_layout(MR_Code *success,
-    const MR_Label_Layout **return_label_layout, const char **problem_ptr)
+    const MR_Label_Layout **return_label_layout,
+    MR_Word **stack_trace_sp_ptr, MR_Word **stack_trace_curfr_ptr,
+    const char **problem_ptr)
 {
     MR_Internal             *label;
 
@@ -315,6 +318,18 @@
         return MR_STEP_OK;
     }
 
+#ifndef MR_HIGHLEVEL_CODE
+    if (success == MR_ENTRY(MR_pop_detstack_segment)) {
+        success = (MR_Code *) MR_based_stackvar(*stack_trace_sp_ptr, 2);
+        *stack_trace_sp_ptr = (MR_Word *)
+            MR_based_stackvar(*stack_trace_sp_ptr, 1);
+    } else if (success == MR_ENTRY(MR_pop_nondetstack_segment)) {
+        success = MR_succip_slot(*stack_trace_curfr_ptr);
+        *stack_trace_curfr_ptr = (MR_Word *)
+            MR_based_framevar(*stack_trace_curfr_ptr, 1);
+    }
+#endif /* MR_HIGHLEVEL_CODE */
+
     label = MR_lookup_internal_by_addr(success);
     if (label == NULL) {
         *problem_ptr = "reached unknown label";
@@ -483,12 +498,12 @@
 
         frame_size = base_maxfr - MR_prevfr_slot(base_maxfr);
         if (frame_size == MR_NONDET_TEMP_SIZE) {
-            MR_print_nondstackptr(fp, base_maxfr);
+            MR_print_nondetstackptr(fp, base_maxfr);
             fprintf(fp, ": temp\n");
             fprintf(fp, " redoip: ");
             MR_printlabel(fp, MR_redoip_slot(base_maxfr));
             fprintf(fp, " redofr: ");
-            MR_print_nondstackptr(fp, MR_redofr_slot(base_maxfr));
+            MR_print_nondetstackptr(fp, MR_redofr_slot(base_maxfr));
             fprintf(fp, "\n");
 
             if (print_vars) {
@@ -497,12 +512,12 @@
 
             lines_dumped_so_far += 3;
         } else if (frame_size == MR_DET_TEMP_SIZE) {
-            MR_print_nondstackptr(fp, base_maxfr);
+            MR_print_nondetstackptr(fp, base_maxfr);
             fprintf(fp, ": temp\n");
             fprintf(fp, " redoip: ");
             MR_printlabel(fp, MR_redoip_slot(base_maxfr));
             fprintf(fp, " redofr: ");
-            MR_print_nondstackptr(fp, MR_redofr_slot(base_maxfr));
+            MR_print_nondetstackptr(fp, MR_redofr_slot(base_maxfr));
             fprintf(fp, "\n");
             fprintf(fp, " detfr:  ");
             MR_print_detstackptr(fp, MR_tmp_detfr_slot(base_maxfr));
@@ -510,7 +525,7 @@
 
             lines_dumped_so_far += 4;
         } else {
-            MR_print_nondstackptr(fp, base_maxfr);
+            MR_print_nondetstackptr(fp, base_maxfr);
             fprintf(fp, ": ordinary, %d words", frame_size);
             if (print_vars && MR_find_matching_branch(base_maxfr, &branch)) {
                 fprintf(fp, ", ");
@@ -522,12 +537,12 @@
             fprintf(fp, " redoip: ");
             MR_printlabel(fp, MR_redoip_slot(base_maxfr));
             fprintf(fp, " redofr: ");
-            MR_print_nondstackptr(fp, MR_redofr_slot(base_maxfr));
+            MR_print_nondetstackptr(fp, MR_redofr_slot(base_maxfr));
             fprintf(fp, "\n");
             fprintf(fp, " succip: ");
             MR_printlabel(fp, MR_succip_slot(base_maxfr));
             fprintf(fp, " succfr: ");
-            MR_print_nondstackptr(fp, MR_succfr_slot(base_maxfr));
+            MR_print_nondetstackptr(fp, MR_succfr_slot(base_maxfr));
             fprintf(fp, "\n");
             lines_dumped_so_far += 5;
 #ifdef  MR_USE_MINIMAL_MODEL_STACK_COPY
@@ -544,17 +559,17 @@
                 {
                     fprintf(fp, " debug:  ");
                     fprintf(fp, "call event ");
-                    MR_print_nondstackptr(fp,
+                    MR_print_nondetstackptr(fp,
                         &MR_event_num_framevar(base_maxfr));
                     fprintf(fp, " => %" MR_INTEGER_LENGTH_MODIFIER "d, ",
                         MR_event_num_framevar(base_maxfr) + 1);
                     fprintf(fp, "call seq ");
-                    MR_print_nondstackptr(fp,
+                    MR_print_nondetstackptr(fp,
                         &MR_call_num_framevar(base_maxfr));
                     fprintf(fp, " => %" MR_INTEGER_LENGTH_MODIFIER "d, ",
                         MR_call_num_framevar(base_maxfr)),
                     fprintf(fp, "depth ");
-                    MR_print_nondstackptr(fp,
+                    MR_print_nondetstackptr(fp,
                         &MR_call_depth_framevar(base_maxfr));
                     fprintf(fp, " => %" MR_INTEGER_LENGTH_MODIFIER "d\n",
                         MR_call_depth_framevar(base_maxfr));
@@ -589,22 +604,22 @@
     switch (category) {
         case MR_INTERNAL_FRAME_ON_SIDE_BRANCH:
             fprintf(dump_fp, " internal frame on nondet side branch ");
-            MR_printnondstackptr(top_fr);
+            MR_print_nondetstackptr(dump_fp, top_fr);
             fprintf(dump_fp, "\n");
             break;
         case MR_FRAME_ON_MAIN_BRANCH:
             fprintf(dump_fp, " on main nondet branch ");
-            MR_printnondstackptr(top_fr);
+            MR_print_nondetstackptr(dump_fp, top_fr);
             fprintf(dump_fp, "\n");
             break;
         case MR_TERMINAL_TOP_FRAME_ON_SIDE_BRANCH:
             fprintf(dump_fp, " terminal top frame of a nondet side branch ");
-            MR_printnondstackptr(base_curfr);
+            MR_print_nondetstackptr(dump_fp, base_curfr);
             fprintf(dump_fp, "\n");
             break;
         case MR_TOP_FRAME_ON_SIDE_BRANCH:
             fprintf(dump_fp, " top frame of a nondet side branch ");
-            MR_printnondstackptr(base_curfr);
+            MR_print_nondetstackptr(dump_fp, base_curfr);
             fprintf(dump_fp, "\n");
             break;
         default:
@@ -822,7 +837,7 @@
             base_curfr = MR_succfr_slot(fr);
             topfr = fr;
             result = MR_stack_walk_succip_layout(success, &label_layout,
-                &problem);
+                &base_sp, &base_curfr, &problem);
         } else {
             internal = MR_lookup_internal_by_addr(redoip);
             if (internal == NULL || internal->i_layout == NULL) {
@@ -1258,7 +1273,7 @@
     if (MR_DETISM_DET_STACK(entry->MR_sle_detism)) {
         MR_print_detstackptr(fp, base_sp);
     } else {
-        MR_print_nondstackptr(fp, base_curfr);
+        MR_print_nondetstackptr(fp, base_curfr);
     }
 
     fprintf(fp, " ");
Index: runtime/mercury_stacks.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stacks.c,v
retrieving revision 1.17
diff -u -b -r1.17 mercury_stacks.c
--- runtime/mercury_stacks.c	25 Nov 2005 05:40:47 -0000	1.17
+++ runtime/mercury_stacks.c	30 Oct 2006 06:02:27 -0000
@@ -2,6 +2,11 @@
 ** vim: ts=4 sw=4 expandtab
 */
 /*
+INIT mercury_sys_init_stacks
+ENDINIT
+*/
+
+/*
 ** Copyright (C) 1998-2001, 2003-2005 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.
@@ -34,6 +39,7 @@
 
 #include "mercury_imp.h"
 #include "mercury_runtime_util.h"
+#include "mercury_memory_handlers.h"    /* for MR_default_handler */
 #include <stdio.h>
 
 /***************************************************************************/
@@ -191,6 +197,255 @@
 
 /***************************************************************************/
 
+#ifndef  MR_HIGHLEVEL_CODE
+
+#ifdef  MR_STACK_SEGMENTS
+
+/*
+** These three global variables are used in the MR_detstack_extend_and_check
+** and MR_nondetstack_extend_and_check macros and nowhere else.
+*/
+
+MR_Code *MR_post_extend_succip;
+MR_Word *MR_pre_extend_maxfr;
+MR_Word *MR_pre_extend_curfr;
+
+MR_declare_entry(MR_pop_detstack_segment);
+MR_declare_entry(MR_pop_nondetstack_segment);
+
+MR_Word *MR_new_detstack_segment(MR_Word *sp, int n)
+{
+    MR_Word         *old_sp;
+    MR_MemoryZones  *list;
+    MR_MemoryZone   *new_zone;
+
+    old_sp = sp;
+
+    new_zone = MR_create_zone("detstack_segment", 0, MR_detstack_size, 0,
+        MR_detstack_zone_size, MR_default_handler);
+
+    list = GC_MALLOC_UNCOLLECTABLE(sizeof(MR_MemoryZones));
+    if (list == NULL) {
+        MR_fatal_error("cannot allocate new det stack segment");
+    }
+
+#ifdef  MR_DEBUG_STACK_SEGMENTS
+    printf("create new det segment: old zone: %p, old sp %p\n",
+        MR_CONTEXT(MR_ctxt_detstack_zone), old_sp);
+    printf("old sp: ");
+    MR_printdetstack(old_sp);
+    printf("old succip: ");
+    MR_printlabel(stdout, MR_succip);
+#endif
+
+    list->MR_zones_head = MR_CONTEXT(MR_ctxt_detstack_zone);
+    list->MR_zones_tail = MR_CONTEXT(MR_ctxt_prev_detstack_zones);
+    MR_CONTEXT(MR_ctxt_prev_detstack_zones) = list;
+    MR_CONTEXT(MR_ctxt_detstack_zone) = new_zone;
+    MR_CONTEXT(MR_ctxt_sp) = MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_min;
+
+    MR_sp_word = (MR_Word) MR_CONTEXT(MR_ctxt_sp);
+
+    MR_incr_sp_leaf(2);
+    MR_stackvar(1) = (MR_Word) old_sp;
+    MR_stackvar(2) = (MR_Word) MR_succip;
+    MR_post_extend_succip = MR_ENTRY(MR_pop_detstack_segment);
+
+    MR_incr_sp_leaf(n);
+
+#ifdef  MR_DEBUG_STACK_SEGMENTS
+    printf("create new det segment: new zone: %p, new sp %p\n",
+        MR_CONTEXT(MR_ctxt_detstack_zone), MR_sp);
+    printf("new sp: ");
+    MR_printdetstack(MR_sp);
+    printf("new succip: ");
+    MR_printlabel(stdout, MR_post_extend_succip);
+#endif
+
+    return MR_sp;
+}
+
+MR_Word *
+MR_new_nondetstack_segment(MR_Word *maxfr, int n)
+{
+    MR_Word         *old_maxfr;
+    MR_MemoryZones  *list;
+    MR_MemoryZone   *new_zone;
+
+    old_maxfr = maxfr;
+
+    new_zone = MR_create_zone("nondetstack_segment", 0, MR_nondetstack_size, 0,
+        MR_nondetstack_zone_size, MR_default_handler);
+
+    list = GC_MALLOC_UNCOLLECTABLE(sizeof(MR_MemoryZones));
+    if (list == NULL) {
+        MR_fatal_error("cannot allocate new nondet stack segment");
+    }
+
+#ifdef  MR_DEBUG_STACK_SEGMENTS
+    printf("create new nondet segment: old zone: %p, old maxfr %p\n",
+        MR_CONTEXT(MR_ctxt_nondetstack_zone), old_maxfr);
+    printf("old maxfr: ");
+    MR_printnondetstack(old_maxfr);
+    printf("old succip: ");
+    MR_printlabel(stdout, MR_succip);
+#endif
+
+    list->MR_zones_head = MR_CONTEXT(MR_ctxt_nondetstack_zone);
+    list->MR_zones_tail = MR_CONTEXT(MR_ctxt_prev_nondetstack_zones);
+    MR_CONTEXT(MR_ctxt_prev_nondetstack_zones) = list;
+    MR_CONTEXT(MR_ctxt_nondetstack_zone) = new_zone;
+    MR_CONTEXT(MR_ctxt_maxfr) =
+        MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_min;
+
+    MR_maxfr_word = (MR_Word) MR_CONTEXT(MR_ctxt_maxfr);
+
+    MR_mkframe("new_nondetstack_segment", 1, MR_ENTRY(MR_do_fail));
+    MR_framevar(1) = (MR_Word) old_maxfr;
+    MR_post_extend_succip = MR_ENTRY(MR_pop_nondetstack_segment);
+
+    MR_maxfr_word = (MR_Word) (MR_maxfr + (MR_NONDET_FIXED_SIZE + (n)));
+
+#ifdef  MR_DEBUG_STACK_SEGMENTS
+    printf("create new nondet segment: new zone: %p, new maxfr %p\n",
+        MR_CONTEXT(MR_ctxt_nondetstack_zone), MR_maxfr);
+    printf("new maxfr: ");
+    MR_printnondetstack(MR_maxfr);
+    printf("new succip: ");
+    MR_printlabel(stdout, MR_post_extend_succip);
+#endif
+
+    return MR_maxfr;
+}
+
+#endif  /* MR_STACK_SEGMENTS */
+
+MR_define_extern_entry(MR_pop_detstack_segment);
+MR_define_extern_entry(MR_pop_nondetstack_segment);
+
+MR_BEGIN_MODULE(stack_segment_module)
+    MR_init_entry_an(MR_pop_detstack_segment);
+    MR_init_entry_an(MR_pop_nondetstack_segment);
+MR_BEGIN_CODE
+
+MR_define_entry(MR_pop_detstack_segment);
+#ifdef MR_STACK_SEGMENTS
+{
+    MR_MemoryZones  *list;
+    MR_Word         *orig_sp;
+    MR_Code         *orig_succip;
+
+    orig_sp = (MR_Word *) MR_stackvar(1);
+    orig_succip = (MR_Code *) MR_stackvar(2);
+
+#ifdef  MR_DEBUG_STACK_SEGMENTS
+    printf("restore old det segment: old zone %p, old sp %p\n",
+        MR_CONTEXT(MR_ctxt_detstack_zone), MR_sp);
+    printf("old sp: ");
+    MR_printdetstack(MR_sp);
+    printf("old succip: ");
+    MR_printlabel(stdout, MR_succip);
+#endif
+
+    MR_unget_zone(MR_CONTEXT(MR_ctxt_detstack_zone));
+
+    list = MR_CONTEXT(MR_ctxt_prev_detstack_zones);
+    MR_CONTEXT(MR_ctxt_detstack_zone) = list->MR_zones_head;
+    MR_CONTEXT(MR_ctxt_prev_detstack_zones) = list->MR_zones_tail;
+    MR_CONTEXT(MR_ctxt_sp) = orig_sp;
+    GC_FREE(list);
+
+#ifdef  MR_DEBUG_STACK_SEGMENTS
+    printf("restore old det segment: new zone %p, new sp %p\n",
+        MR_CONTEXT(MR_ctxt_detstack_zone), orig_sp);
+    printf("new sp: ");
+    MR_printdetstack(orig_sp);
+    printf("new succip: ");
+    MR_printlabel(stdout, orig_succip);
+#endif
+
+    MR_sp_word = (MR_Word) orig_sp;
+    MR_GOTO(orig_succip);
+}
+#else   /* ! MR_STACK_SEGMENTS */
+    MR_fatal_error("MR_pop_detstack_segment reached\n");
+#endif  /* MR_STACK_SEGMENTS */
+
+MR_define_entry(MR_pop_nondetstack_segment);
+#ifdef MR_STACK_SEGMENTS
+{
+    MR_MemoryZones  *list;
+    MR_Word         *orig_maxfr;
+    MR_Code         *orig_succip;
+
+    orig_maxfr = (MR_Word *) MR_stackvar(1);
+    orig_succip = (MR_Code *) MR_stackvar(2);
+
+#ifdef  MR_DEBUG_STACK_SEGMENTS
+    printf("restore old nondet segment: old zone %p, old maxfr %p\n",
+        MR_CONTEXT(MR_ctxt_nondetstack_zone), MR_maxfr);
+    printf("old maxfr: ");
+    MR_printnondetstack(MR_maxfr);
+    printf("old succip: ");
+    MR_printlabel(stdout, MR_succip);
+#endif
+
+    MR_unget_zone(MR_CONTEXT(MR_ctxt_nondetstack_zone));
+
+    list = MR_CONTEXT(MR_ctxt_prev_nondetstack_zones);
+    MR_CONTEXT(MR_ctxt_nondetstack_zone) = list->MR_zones_head;
+    MR_CONTEXT(MR_ctxt_prev_nondetstack_zones) = list->MR_zones_tail;
+    MR_CONTEXT(MR_ctxt_maxfr) = orig_maxfr;
+    GC_FREE(list);
+
+#ifdef  MR_DEBUG_STACK_SEGMENTS
+    printf("restore old nondet segment: new zone %p, new maxfr %p\n",
+        MR_CONTEXT(MR_ctxt_nondetstack_zone), orig_maxfr);
+    printf("new maxfr: ");
+    MR_printnondetstack(orig_maxfr);
+    printf("new succip: ");
+    MR_printlabel(stdout, orig_succip);
+#endif
+
+    MR_maxfr_word = (MR_Word) orig_maxfr;
+    MR_GOTO(orig_succip);
+}
+#else   /* ! MR_STACK_SEGMENTS */
+    MR_fatal_error("MR_pop_nondetstack_segment reached\n");
+#endif  /* MR_STACK_SEGMENTS */
+
+MR_END_MODULE
+
+#endif /* !MR_HIGHLEVEL_CODE */
+
+/* forward decls to suppress gcc warnings */
+void mercury_sys_init_stacks_init(void);
+void mercury_sys_init_stacks_init_type_tables(void);
+#ifdef  MR_DEEP_PROFILING
+void mercury_sys_init_stacks_write_out_proc_statics(FILE *fp);
+#endif
+
+void mercury_sys_init_stacks_init(void)
+{
+#ifndef MR_HIGHLEVEL_CODE
+    stack_segment_module();
+#endif
+}
+
+void mercury_sys_init_stacks_init_type_tables(void)
+{
+    /* no types to register */
+}
+
+#ifdef  MR_DEEP_PROFILING
+void mercury_sys_init_stacks_write_out_proc_statics(FILE *fp)
+{
+    /* no proc_statics to write out */
+}
+#endif
+
+/***************************************************************************/
+
 #undef MR_TABLE_DEBUG
 
 #ifdef  MR_USE_MINIMAL_MODEL_STACK_COPY
@@ -302,7 +557,7 @@
     MR_SubgoalDebug *subgoal_debug;
 
     fprintf(fp, "gen %ld = <", (long) i);
-    MR_print_nondstackptr(fp, p->MR_gen_frame);
+    MR_print_nondetstackptr(fp, p->MR_gen_frame);
     subgoal_debug = MR_lookup_subgoal_debug_addr(p->MR_gen_subgoal);
     fprintf(fp, ", %s>\n", MR_subgoal_debug_name(subgoal_debug));
 }
@@ -479,7 +734,7 @@
     MR_CutGeneratorList gen_list;
 
     fprintf(fp, "cut %ld = <", (long) i);
-    MR_print_nondstackptr(fp, p->MR_cut_frame);
+    MR_print_nondetstackptr(fp, p->MR_cut_frame);
     fprintf(fp, ">");
     fprintf(fp, ", cut_gen_next %d", (int) p->MR_cut_gen_next);
 #ifdef  MR_MINIMAL_MODEL_DEBUG
@@ -667,7 +922,7 @@
     MR_PNegConsumerList l;
 
     fprintf(fp, "pneg %d = <", (int) i);
-    MR_print_nondstackptr(fp, p->MR_pneg_frame);
+    MR_print_nondetstackptr(fp, p->MR_pneg_frame);
     fprintf(fp, ">");
 #ifdef  MR_MINIMAL_MODEL_DEBUG
     fprintf(fp, ", pneg_gen_next %d", (int) p->MR_pneg_gen_next);
Index: runtime/mercury_stacks.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stacks.h,v
retrieving revision 1.54
diff -u -b -r1.54 mercury_stacks.h
--- runtime/mercury_stacks.h	26 Sep 2006 03:53:21 -0000	1.54
+++ runtime/mercury_stacks.h	29 Oct 2006 02:20:29 -0000
@@ -72,13 +72,95 @@
 
 /*---------------------------------------------------------------------------*/
 
+#ifdef MR_STACK_SEGMENTS
+
+  #define MR_detstack_extend_and_check(n)                                     \
+        do {                                                                  \
+            MR_Word *new_sp;                                                  \
+            MR_Word *threshold;                                               \
+                                                                              \
+            threshold = (MR_Word *) MR_CONTEXT(MR_ctxt_detstack_zone)->       \
+                MR_zone_extend_threshold;                                     \
+            new_sp = MR_sp + (n);                                             \
+            if (new_sp > threshold) {                                         \
+                MR_save_registers();                                          \
+                new_sp = MR_new_detstack_segment(MR_sp, n);                   \
+                MR_restore_registers();                                       \
+                MR_succip_word = (MR_Word) MR_post_extend_succip;             \
+            }                                                                 \
+            MR_sp_word = (MR_Word) new_sp;                                    \
+        } while (0)
+
+  #define MR_detstack_extend_and_no_check(n)                                  \
+        do {                                                                  \
+            MR_sp_word = (MR_Word) (MR_sp + (n));                             \
+        } while (0)
+
+  #define MR_nondetstack_extend_and_check(n, prevfr, succfr)                  \
+        do {                                                                  \
+            MR_Word *new_maxfr;                                               \
+            MR_Word *threshold;                                               \
+            int     incr;                                                     \
+                                                                              \
+            threshold = (MR_Word *) MR_CONTEXT(MR_ctxt_nondetstack_zone)->    \
+                MR_zone_extend_threshold;                                     \
+            incr = MR_NONDET_FIXED_SIZE + (n);                                \
+            new_maxfr = MR_maxfr + incr;                                      \
+            if (new_maxfr > threshold) {                                      \
+                MR_pre_extend_maxfr = MR_maxfr;                               \
+                MR_pre_extend_curfr = MR_curfr;                               \
+                MR_save_registers();                                          \
+                new_maxfr = MR_new_nondetstack_segment(MR_maxfr, incr);       \
+                MR_restore_registers();                                       \
+                MR_succip_word = (MR_Word) MR_post_extend_succip;             \
+                prevfr = MR_pre_extend_maxfr;                                 \
+                succfr = MR_pre_extend_curfr;                                 \
+            } else {                                                          \
+                prevfr = MR_maxfr;                                            \
+                succfr = MR_curfr;                                            \
+            }                                                                 \
+            MR_maxfr_word = (MR_Word) new_maxfr;                              \
+        } while (0)
+
+  extern    MR_Code         *MR_post_extend_succip;
+  extern    MR_Word         *MR_pre_extend_maxfr;
+  extern    MR_Word         *MR_pre_extend_curfr;
+
+  extern    MR_Word         *MR_new_detstack_segment(MR_Word *sp, int n);
+  extern    MR_Word         *MR_new_nondetstack_segment(MR_Word *maxfr, int n);
+
+#else   /* !MR_STACK_SEGMENTS */
+
+  #define MR_detstack_extend_and_check(n)                                     \
+        do {                                                                  \
+            MR_sp_word = (MR_Word) (MR_sp + (n));                             \
+        } while (0)
+
+  #define MR_detstack_extend_and_no_check(n)                                  \
+        do {                                                                  \
+            MR_sp_word = (MR_Word) (MR_sp + (n));                             \
+        } while (0)
+
+  #define MR_nondetstack_extend_and_check(n, prevfr, succfr)                  \
+        do {                                                                  \
+            prevfr = MR_maxfr;                                                \
+            succfr = MR_curfr;                                                \
+            MR_maxfr_word = (MR_Word)                                         \
+                (MR_maxfr + (MR_NONDET_FIXED_SIZE + (n)));                    \
+        } while (0)
+
+#endif  /* MR_STACK_SEGMENTS */
+
+MR_declare_entry(MR_pop_detstack_segment);
+MR_declare_entry(MR_pop_nondetstack_segment);
+
 #ifdef  MR_EXTEND_STACKS_WHEN_NEEDED
 
-  #define MR_detstack_extend_check()                                          \
+  #define MR_detstack_post_extend_check()                                     \
     MR_IF (MR_sp >= MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_end, (         \
         MR_extend_detstack()                                                  \
     ))
-  #define MR_nondetstack_extend_check()                                       \
+  #define MR_nondetstack_post_extend_check()                                  \
     MR_IF (MR_maxfr >= MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_end, (   \
         MR_extend_nondetstack()                                               \
     ))
@@ -86,10 +168,10 @@
   extern    void            MR_extend_detstack(void);
   extern    void            MR_extend_nondetstack(void);
 
-#else   /* MR_EXTEND_STACKS_WHEN_NEEDED */
+#else   /* !MR_EXTEND_STACKS_WHEN_NEEDED */
 
-  #define MR_detstack_extend_check()            ((void) 0)
-  #define MR_nondetstack_extend_check()         ((void) 0)
+  #define MR_detstack_post_extend_check()       ((void) 0)
+  #define MR_nondetstack_post_extend_check()    ((void) 0)
 
 #endif  /* MR_EXTEND_STACKS_WHEN_NEEDED */
 
@@ -116,8 +198,17 @@
 #define MR_incr_sp(n)                                                         \
     do {                                                                      \
         MR_debugincrsp(n, MR_sp);                                             \
-        MR_sp_word = (MR_Word) (MR_sp + (n));                                 \
-        MR_detstack_extend_check();                                           \
+        MR_detstack_extend_and_check(n);                                      \
+        MR_detstack_post_extend_check();                                      \
+        MR_detstack_overflow_check();                                         \
+        MR_collect_det_frame_stats(n);                                        \
+    } while (0)
+
+#define MR_incr_sp_leaf(n)                                                    \
+    do {                                                                      \
+        MR_debugincrsp(n, MR_sp);                                             \
+        MR_detstack_extend_and_no_check(n);                                   \
+        MR_detstack_post_extend_check();                                      \
         MR_detstack_overflow_check();                                         \
         MR_collect_det_frame_stats(n);                                        \
     } while (0)
@@ -271,11 +362,8 @@
         MR_Word *prevfr;                                                      \
         MR_Word *succfr;                                                      \
                                                                               \
-        prevfr = MR_maxfr;                                                    \
-        succfr = MR_curfr;                                                    \
-        MR_maxfr_word = (MR_Word)                                             \
-            (MR_maxfr + (MR_NONDET_FIXED_SIZE + (numslots)));                 \
-        MR_nondetstack_extend_check(),                                        \
+        MR_nondetstack_extend_and_check(numslots, prevfr, succfr);            \
+        MR_nondetstack_post_extend_check();                                   \
         MR_curfr_word = MR_maxfr_word;                                        \
         MR_prevfr_slot_word(MR_curfr) = (MR_Word) prevfr;                     \
         MR_succip_slot_word(MR_curfr) = (MR_Word) MR_succip;                  \
@@ -283,7 +371,7 @@
         MR_redofr_slot_word(MR_curfr) = MR_curfr_word;                        \
         MR_maybe_fill_table_detfr_slot();                                     \
         MR_debugmkframe(predname);                                            \
-        MR_nondstack_overflow_check();                                        \
+        MR_nondetstack_overflow_check();                                      \
         MR_collect_non_frame_stats(numslots);                                 \
     } while (0)
 
@@ -324,7 +412,7 @@
         MR_redoip_slot_word(MR_maxfr) = (MR_Word) redoip;                     \
         MR_redofr_slot_word(MR_maxfr) = MR_curfr_word;                        \
         MR_debugmktempframe();                                                \
-        MR_nondstack_overflow_check();                                        \
+        MR_nondetstack_overflow_check();                                      \
     } while (0)
 
 #define MR_mkdettempframe(redoip)                                             \
@@ -339,7 +427,7 @@
         MR_redofr_slot_word(MR_maxfr) = MR_curfr_word;                        \
         MR_tmp_detfr_slot_word(MR_maxfr) = MR_sp_word;                        \
         MR_debugmkdettempframe();                                             \
-        MR_nondstack_overflow_check();                                        \
+        MR_nondetstack_overflow_check();                                      \
     } while (0)
 
 #define MR_succeed()                                                          \
@@ -367,7 +455,7 @@
     do {                                                                      \
         MR_debugfail();                                                       \
         MR_maxfr_word = MR_prevfr_slot_word(MR_maxfr);                        \
-        MR_nondstack_underflow_check();                                       \
+        MR_nondetstack_underflow_check();                                     \
         MR_curfr_word = MR_redofr_slot_word(MR_maxfr);                        \
         MR_GOTO(MR_redoip_slot(MR_maxfr));                                    \
     } while (0)
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.170
diff -u -b -r1.170 mercury_wrapper.c
--- runtime/mercury_wrapper.c	9 Oct 2006 06:40:25 -0000	1.170
+++ runtime/mercury_wrapper.c	30 Oct 2006 05:49:57 -0000
@@ -65,23 +65,21 @@
 /* command-line options */
 
 /*
-** size of data areas (including redzones), in kilobytes
-** (but we later multiply by 1024 to convert to bytes)
+** Sizes of data areas (including redzones), in kilobytes
+** (but we later multiply by 1024 to convert to bytes).
 **
-** Note that it is OK to allocate a large heap, since
-** we will only touch the part of it that we use;
-** we're really only allocating address space,
-** not physical memory.
-** But the other areas should be kept small, at least
-** in the case when conservative GC is enabled, since
-** the conservative GC will scan them.
+** Note that it is OK to allocate a large heap, since we will only touch
+** the part of it that we use; we're really only allocating address space,
+** not physical memory. But the other areas should be kept small, at least
+** in the case when conservative GC is enabled, since the conservative GC
+** will scan them.
 **
-** Note that for the accurate collector, the total heap size
-** that we use will be twice the heap size specified here,
-** since it is a two-space collector.
+** Note that for the accurate collector, the total heap size that we use
+** will be twice the heap size specified here, since it is a two-space
+** collector.
 **
-** Changes to MR_heap_size, MR_detstack_size or MR_nondstack_size should
-** be reflected in the user guide.  Changes to MR_heap_size may also require
+** Changes to MR_heap_size, MR_detstack_size or MR_nondetstack_size should be
+** reflected in the user guide.  Changes to MR_heap_size may also require
 ** changing MR_heap_zone_size and/or the MR_heap_margin_size, which are
 ** defined below.
 */
@@ -91,10 +89,17 @@
 #else
   size_t    MR_heap_size =              8192 * sizeof(MR_Word);
 #endif
-size_t      MR_detstack_size =          1024 * sizeof(MR_Word);
-size_t      MR_nondstack_size =           64 * sizeof(MR_Word);
+#ifdef MR_STACK_SEGMENTS
+size_t      MR_detstack_size =            64 * sizeof(MR_Word);
+size_t      MR_nondetstack_size =         16 * sizeof(MR_Word);
+size_t      MR_small_detstack_size =       8 * sizeof(MR_Word);
+size_t      MR_small_nondetstack_size =    8 * sizeof(MR_Word);
+#else
+size_t      MR_detstack_size =          4096 * sizeof(MR_Word);
+size_t      MR_nondetstack_size =         64 * sizeof(MR_Word);
 size_t      MR_small_detstack_size =     512 * sizeof(MR_Word);
-size_t      MR_small_nondstack_size =      8 * sizeof(MR_Word);
+size_t      MR_small_nondetstack_size =    8 * sizeof(MR_Word);
+#endif
 size_t      MR_solutions_heap_size =     256 * sizeof(MR_Word);
 size_t      MR_global_heap_size =        256 * sizeof(MR_Word);
 size_t      MR_trail_size =               32 * sizeof(MR_Word);
@@ -129,7 +134,7 @@
   size_t        MR_heap_zone_size =        4 * sizeof(MR_Word);
 #endif
 size_t      MR_detstack_zone_size =        4 * sizeof(MR_Word);
-size_t      MR_nondstack_zone_size =       4 * sizeof(MR_Word);
+size_t      MR_nondetstack_zone_size =     4 * sizeof(MR_Word);
 size_t      MR_solutions_heap_zone_size =  4 * sizeof(MR_Word);
 size_t      MR_global_heap_zone_size =     4 * sizeof(MR_Word);
 size_t      MR_trail_zone_size =           4 * sizeof(MR_Word);
@@ -165,6 +170,18 @@
 
 double MR_heap_expansion_factor = 2.0;
 
+/*
+** When we use stack segments, we reserve the last MR_stack_margin_size bytes
+** of each stack segment for leaf procedures. This way, leaf procedures that
+** do not need this much stack space can allocate their stack space *without*
+** incurring the cost of a test.
+**
+** MR_stack_margin_size is never consulted directly; instead, its value is used
+** to set the MR_zone_extend_threshold field in a stack's memory zone.
+*/
+
+size_t      MR_stack_margin_size = 128;
+
 /* primary cache size to optimize for, in bytes */
 size_t      MR_pcache_size =            8192;
 
@@ -1206,7 +1223,7 @@
                     MR_usage();
                 }
 
-                MR_nondstack_size = size;
+                MR_nondetstack_size = size;
                 break;
 
             case MR_NONDETSTACK_SIZE_KWORDS:
@@ -1214,7 +1231,7 @@
                     MR_usage();
                 }
 
-                MR_nondstack_size = size * sizeof(MR_Word);
+                MR_nondetstack_size = size * sizeof(MR_Word);
                 break;
 
             case MR_SMALL_DETSTACK_SIZE:
@@ -1238,7 +1255,7 @@
                     MR_usage();
                 }
 
-                MR_small_nondstack_size = size;
+                MR_small_nondetstack_size = size;
                 break;
 
             case MR_SMALL_NONDETSTACK_SIZE_KWORDS:
@@ -1246,7 +1263,7 @@
                     MR_usage();
                 }
 
-                MR_small_nondstack_size = size * sizeof(MR_Word);
+                MR_small_nondetstack_size = size * sizeof(MR_Word);
                 break;
 
             case MR_SOLUTIONS_HEAP_SIZE:
@@ -1318,7 +1335,7 @@
                     MR_usage();
                 }
 
-                MR_nondstack_zone_size = size;
+                MR_nondetstack_zone_size = size;
                 break;
 
             case MR_NONDETSTACK_REDZONE_SIZE_KWORDS:
@@ -1326,7 +1343,7 @@
                     MR_usage();
                 }
 
-                MR_nondstack_zone_size = size * sizeof(MR_Word);
+                MR_nondetstack_zone_size = size * sizeof(MR_Word);
                 break;
 
             case MR_SOLUTIONS_HEAP_REDZONE_SIZE:
@@ -1653,7 +1670,7 @@
             case 'd':   
                 if (MR_streq(MR_optarg, "a")) {
                     MR_calldebug      = MR_TRUE;
-                    MR_nondstackdebug = MR_TRUE;
+                    MR_nondetstackdebug = MR_TRUE;
                     MR_detstackdebug  = MR_TRUE;
                     MR_heapdebug      = MR_TRUE;
                     MR_gotodebug      = MR_TRUE;
@@ -1667,7 +1684,7 @@
                     MR_agc_debug      = MR_TRUE;
 #endif
                 } else if (MR_streq(MR_optarg, "b")) {
-                    MR_nondstackdebug = MR_TRUE;
+                    MR_nondetstackdebug = MR_TRUE;
                 } else if (MR_streq(MR_optarg, "B")) {
                     if (sscanf(MR_optarg+1, "%u", &MR_lld_start_block) != 1) {
                         MR_usage();
@@ -1810,7 +1827,7 @@
                 use_own_timer = MR_TRUE;
 
                 MR_calldebug      = MR_FALSE;
-                MR_nondstackdebug = MR_FALSE;
+                MR_nondetstackdebug = MR_FALSE;
                 MR_detstackdebug  = MR_FALSE;
                 MR_heapdebug      = MR_FALSE;
                 MR_gotodebug      = MR_FALSE;
@@ -1873,7 +1890,7 @@
         exit(1);
     }
 
-    if (MR_small_nondstack_size > MR_nondstack_size) {
+    if (MR_small_nondetstack_size > MR_nondetstack_size) {
         printf("The small nondetstack size must be smaller than the "
             "regular nondetstack size.\n");
         fflush(stdout);
@@ -2081,7 +2098,7 @@
         printf("max detstack used:  %6ld words\n",
             (long)(MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_max
                    - MR_CONTEXT(MR_ctxt_detstack_zone)->MR_zone_min));
-        printf("max nondstack used: %6ld words\n",
+        printf("max nondetstack used: %6ld words\n",
             (long) (MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_max
                 - MR_CONTEXT(MR_ctxt_nondetstack_zone)->MR_zone_min));
     }
@@ -2327,9 +2344,9 @@
 #ifdef  MR_LOWLEVEL_DEBUG
     if (MR_finaldebug) {
         MR_save_transient_registers();
-        MR_printregs("do_interpreter started");
+        MR_printregs(stdout, "do_interpreter started");
         if (MR_detaildebug) {
-            MR_dumpnondstack();
+            MR_dumpnondetstack(stdout);
         }
     }
 #endif
@@ -2351,9 +2368,9 @@
 #ifdef  MR_LOWLEVEL_DEBUG
     if (MR_finaldebug) {
         MR_save_transient_registers();
-        MR_printregs("global succeeded");
+        MR_printregs(stdout, "global succeeded");
         if (MR_detaildebug) {
-            MR_dumpnondstack();
+            MR_dumpnondetstack(stdout);
         }
     }
 #endif
@@ -2368,10 +2385,10 @@
 #ifdef  MR_LOWLEVEL_DEBUG
     if (MR_finaldebug) {
         MR_save_transient_registers();
-        MR_printregs("global failed");
+        MR_printregs(stdout, "global failed");
 
         if (MR_detaildebug) {
-            MR_dumpnondstack();
+            MR_dumpnondetstack(stdout);
         }
     }
 #endif
@@ -2393,7 +2410,7 @@
 #ifdef MR_LOWLEVEL_DEBUG
     if (MR_finaldebug && MR_detaildebug) {
         MR_save_transient_registers();
-        MR_printregs("after popping...");
+        MR_printregs(stdout, "after popping...");
     }
 #endif
 
@@ -2406,7 +2423,7 @@
     MR_fatal_error("reached wrapper_not_reached");
 MR_END_MODULE
 
-#endif
+#endif  /* MR_HIGHLEVEL_CODE */
 
 /*---------------------------------------------------------------------------*/
 
Index: runtime/mercury_wrapper.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.h,v
retrieving revision 1.76
diff -u -b -r1.76 mercury_wrapper.h
--- runtime/mercury_wrapper.h	2 Oct 2006 10:14:40 -0000	1.76
+++ runtime/mercury_wrapper.h	29 Oct 2006 01:56:21 -0000
@@ -194,9 +194,9 @@
 /* sizes of the data areas, *including* the red zone size */
 extern	size_t		MR_heap_size;
 extern	size_t		MR_detstack_size;
-extern	size_t		MR_nondstack_size;
+extern	size_t		MR_nondetstack_size;
 extern	size_t		MR_small_detstack_size;
-extern	size_t		MR_small_nondstack_size;
+extern	size_t		MR_small_nondetstack_size;
 extern	size_t		MR_solutions_heap_size;
 extern	size_t		MR_trail_size;
 extern	size_t		MR_global_heap_size;
@@ -210,7 +210,7 @@
 /* sizes of the red zones */
 extern	size_t		MR_heap_zone_size;
 extern	size_t		MR_detstack_zone_size;
-extern	size_t		MR_nondstack_zone_size;
+extern	size_t		MR_nondetstack_zone_size;
 extern	size_t		MR_solutions_heap_zone_size;
 extern	size_t		MR_trail_zone_size;
 extern	size_t		MR_global_heap_zone_size;
@@ -227,6 +227,9 @@
 /* heap expansion factor for accurate GC (see mercury_accurate_gc.c) */
 extern  double		MR_heap_expansion_factor;
 
+/* margin for the stack segment test (documented in mercury_wrapper.c) */
+extern	size_t		MR_stack_margin_size;
+
 /* number of outstanding contexts we can create per thread (soft limit) */
 extern	MR_Unsigned	MR_contexts_per_thread;
 
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
Index: scripts/canonical_grade.sh-subr
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/canonical_grade.sh-subr,v
retrieving revision 1.15
diff -u -b -r1.15 canonical_grade.sh-subr
--- scripts/canonical_grade.sh-subr	2 Oct 2006 09:06:50 -0000	1.15
+++ scripts/canonical_grade.sh-subr	27 Oct 2006 16:22:26 -0000
@@ -156,7 +156,12 @@
 	*)		;;
 esac;
 
-case $extend_stacks in
-	true)		GRADE="$GRADE.exts" ;;
-	*)		;;
+case $extend_stacks,$stack_segments in
+	true,false)	GRADE="$GRADE.exts" ;;
+	false,true)	GRADE="$GRADE.stseg" ;;
+	false,false)	;;
+	*)		progname=`basename $0`
+			echo "$progname: error: invalid combination of stack extension options." 1>&2
+			exit 1
+			;;
 esac
Index: scripts/final_grade_options.sh-subr
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/final_grade_options.sh-subr,v
retrieving revision 1.14
diff -u -b -r1.14 final_grade_options.sh-subr
--- scripts/final_grade_options.sh-subr	18 May 2005 05:45:00 -0000	1.14
+++ scripts/final_grade_options.sh-subr	27 Oct 2006 16:07:28 -0000
@@ -41,6 +41,15 @@
 esac
 
 #
+# .exts grade is not compatible with .stseg
+#	(they are alternative ways of doing the same thing)
+#
+case $extend_stacks,$stack_segments in true,true)
+	echo "--extend-stacks and --stack-segments are not compatible" 1>&2
+	exit 1 ;;
+esac
+
+#
 # .debug grade (but not .decldebug) implies --use-trail in the absence of .*mm*
 #	(see comment in compiler/handle_options.m for rationale)
 #
Index: scripts/init_grade_options.sh-subr
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/init_grade_options.sh-subr,v
retrieving revision 1.26
diff -u -b -r1.26 init_grade_options.sh-subr
--- scripts/init_grade_options.sh-subr	2 Oct 2006 09:06:50 -0000	1.26
+++ scripts/init_grade_options.sh-subr	27 Oct 2006 16:02:02 -0000
@@ -49,6 +49,7 @@
 	--decl-debug
 	--low-level-debug
 	--extend-stacks-when-needed
+	--stack-segments
 		See the documentation in the \"Invocation\" section
 		of the Mercury User's Guide."
 
@@ -82,6 +83,7 @@
 decl_debug=false
 ll_debug=false
 extend_stacks=false
+stack_segments=false
 
 case $# in
 	0) set - --grade "$DEFAULT_GRADE" ;;
Index: scripts/mgnuc.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/mgnuc.in,v
retrieving revision 1.117
diff -u -b -r1.117 mgnuc.in
--- scripts/mgnuc.in	2 Oct 2006 09:06:50 -0000	1.117
+++ scripts/mgnuc.in	27 Oct 2006 16:09:05 -0000
@@ -399,6 +399,11 @@
     false)          EXTEND_STACKS_OPTS="" ;;
 esac
 
+case $stack_segments in
+    true)           STACK_SEGMENTS_OPTS="-DMR_STACK_SEGMENTS" ;;
+    false)          STACK_SEGMENTS_OPTS="" ;;
+esac
+
 GCC_OPTS="$NEST_OPTS $ASM_OPTS $GOTO_OPTS $REG_OPTS"
 
 # check that special grades are only used with gcc
@@ -584,6 +589,7 @@
     $DECL_DEBUG_OPTS\
     $LL_DEBUG_OPTS\
     $EXTEND_STACKS_OPTS\
+    $STACK_SEGMENTS_OPTS\
     $LLDEBUG_OPTS\
     $C_DEBUG_OPTS\
     $PROF_TIME_OPTS\
Index: scripts/parse_grade_options.sh-subr
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/scripts/parse_grade_options.sh-subr,v
retrieving revision 1.32
diff -u -b -r1.32 parse_grade_options.sh-subr
--- scripts/parse_grade_options.sh-subr	2 Oct 2006 09:06:51 -0000	1.32
+++ scripts/parse_grade_options.sh-subr	27 Oct 2006 16:57:36 -0000
@@ -1,4 +1,6 @@
 #---------------------------------------------------------------------------#
+# vim: ts=4 sw=4 expandtab
+#---------------------------------------------------------------------------#
 # Copyright (C) 1997-2006 The University of Melbourne.
 # This file may only be copied under the terms of the GNU General
 # Public License - see the file COPYING in the Mercury distribution.
@@ -188,6 +190,11 @@
 	--no-extend-stacks-when-needed)
 		extend_stacks=false ;;
 
+    --stack-segments)
+        stack_segments=true ;;
+    --no-stack-segments)
+        stack_segments=false ;;
+
 	-s|--grade)
 		shift
 		grade="$1";
@@ -223,6 +230,7 @@
 		decl_debug=false
 		ll_debug=false
 		extend_stacks=false
+        stack_segments=false
 
 		grade_pieces=`echo $grade | tr '.' ' '`
 		for grade_piece in $grade_pieces
@@ -467,9 +475,12 @@
 					extend_stacks=true
 					;;
 
+                stseg)
+                    stack_segments=true
+                    ;;
+
 				*)
-					echo "$0: unknown grade component" \
-						"\`$grade_piece'" 1>&2
+                    echo "$0: unknown grade component \`$grade_piece'" 1>&2
 					exit 1
 					;;
 			esac
cvs diff: Diffing slice
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/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
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/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.96
diff -u -b -r1.96 mercury_trace.c
--- trace/mercury_trace.c	29 Sep 2006 06:34:57 -0000	1.96
+++ trace/mercury_trace.c	29 Oct 2006 02:23:01 -0000
@@ -1164,9 +1164,9 @@
 #ifdef  MR_DEBUG_RETRY_STACKS
     MR_print_detstackptr(MR_mdb_out, *sp_ptr);
     fprintf(MR_mdb_out, "\n");
-    MR_print_nondstackptr(MR_mdb_out, *curfr_ptr);
+    MR_print_nondetstackptr(MR_mdb_out, *curfr_ptr);
     fprintf(MR_mdb_out, "\n");
-    MR_print_nondstackptr(MR_mdb_out, *maxfr_ptr);
+    MR_print_nondetstackptr(MR_mdb_out, *maxfr_ptr);
     fprintf(MR_mdb_out, "\n");
 #endif
 
@@ -1184,9 +1184,9 @@
 #ifdef  MR_DEBUG_RETRY_STACKS
     MR_print_detstackptr(MR_mdb_out, *sp_ptr);
     fprintf(MR_mdb_out, "\n");
-    MR_print_nondstackptr(MR_mdb_out, *curfr_ptr);
+    MR_print_nondetstackptr(MR_mdb_out, *curfr_ptr);
     fprintf(MR_mdb_out, "\n");
-    MR_print_nondstackptr(MR_mdb_out, *maxfr_ptr);
+    MR_print_nondetstackptr(MR_mdb_out, *maxfr_ptr);
     fprintf(MR_mdb_out, "\n");
 #endif
 
@@ -1206,9 +1206,9 @@
 #ifdef  MR_DEBUG_RETRY_STACKS
         MR_print_detstackptr(MR_mdb_out, *sp_ptr);
         fprintf(MR_mdb_out, "\n");
-        MR_print_nondstackptr(MR_mdb_out, *curfr_ptr);
+        MR_print_nondetstackptr(MR_mdb_out, *curfr_ptr);
         fprintf(MR_mdb_out, "\n");
-        MR_print_nondstackptr(MR_mdb_out, *maxfr_ptr);
+        MR_print_nondetstackptr(MR_mdb_out, *maxfr_ptr);
         fprintf(MR_mdb_out, "\n");
 #endif
 
@@ -1238,9 +1238,9 @@
 #ifdef  MR_DEBUG_RETRY_STACKS
     MR_print_detstackptr(MR_mdb_out, *sp_ptr);
     fprintf(MR_mdb_out, "\n");
-    MR_print_nondstackptr(MR_mdb_out, *curfr_ptr);
+    MR_print_nondetstackptr(MR_mdb_out, *curfr_ptr);
     fprintf(MR_mdb_out, "\n");
-    MR_print_nondstackptr(MR_mdb_out, *maxfr_ptr);
+    MR_print_nondetstackptr(MR_mdb_out, *maxfr_ptr);
     fprintf(MR_mdb_out, "\n");
 #endif
 
@@ -1267,7 +1267,7 @@
                 level_layout->MR_sle_maybe_maxfr);
 #if MR_DEBUG_RETRY
             fprintf(stdout, "resetting maxfr to ");
-            MR_print_nondstackptr(stdout, *maxfr_ptr);
+            MR_print_nondetstackptr(stdout, *maxfr_ptr);
             fprintf(stdout, "\n");
 #endif
         } /* else we need do nothing */
Index: trace/mercury_trace_util.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_util.c,v
retrieving revision 1.20
diff -u -b -r1.20 mercury_trace_util.c
--- trace/mercury_trace_util.c	30 Jun 2006 13:36:33 -0000	1.20
+++ trace/mercury_trace_util.c	29 Oct 2006 02:23:08 -0000
@@ -108,9 +108,9 @@
     fprintf(fp, "sp = ");
     MR_print_detstackptr(fp, MR_saved_sp(saved_regs));
     fprintf(fp, "\ncurfr = ");
-    MR_print_nondstackptr(fp, MR_saved_curfr(saved_regs));
+    MR_print_nondetstackptr(fp, MR_saved_curfr(saved_regs));
     fprintf(fp, "\nmaxfr = ");
-    MR_print_nondstackptr(fp, MR_saved_maxfr(saved_regs));
+    MR_print_nondetstackptr(fp, MR_saved_maxfr(saved_regs));
     fprintf(fp, "\n");
 #endif
 }
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list