[m-rev.] for review: use bytecode for procedure body representations

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Mar 30 11:39:07 AEST 2005


For review by Ian.

Zoltan.

Change the mechanism we use to transmit a representation of procedure bodies
from the compiler to the declarative debugger from Mercury terms to a bytecode.
This achieves two objectives.

First, the code for Mercury terms worked only as long as the compiler used
the same data representation as the program being compiled; it generated
incorrect term representations when e.g. the compiler generating code in
reserve tag grades.

Second, the new representation is significantly smaller. The total size of the
.c files in the compiler directory in grade asm_fast.gc.decldebug.tr is now
only 213 Mb compared with 313 Mb previously (a reduction of almost one third).
The executable file size of a compiler compiled in asm_fast.gc.decldebug.tr is
now only 59 Mb, compare with 64 Mb previously (a reduction of almost 8%, and
there is room for further reductions). The overhead of the decldebug grade
when compared with a plain debug grade now only about 25%, compared to
about 36% before.

The downside is that the procedure body representation must now be constructed
by the declarative debugger from the bytecode instead of being available
directly. We minimize this effect by using a cache to ensure that each
procedure's body representation is constructed at most once.

browser/declarative_execution.m:
	Do not include the procedure representation in call nodes. This should
	make the annotated trace somewhat smaller and quicker to construct.
	Since this code will be executed many more times than the number of
	procedures whose bodies are needed by subterm dependency tracking,
	the overall effect of this change on speed should be positive.

	Instead, add code to construct procedure body representations on demand
	from bytecode, which is reachable indirectly through the call's node
	label label structure.

compiler/prog_rep.m:
	Replace the code that generated the term representation of procedure
	bodies with code that generates a bytecode representation of procedure
	bodies.

compiler/static_term.m:
	Delete this file, since it is no longer needed.

mdbcomp/program_representation.m:
	Add the definitions related to the structure of the bytecode that are
	shared by the compiler and the declarative debugger. This includes
	the representations of determinisms.

compiler/code_model.m:
	To prevent requiring double maintenance, use the facilities now in
	mdbcomp/program_representation.m to encode determinisms.

runtime/mercury_stack_layout.h:
compiler/layout.m:
compiler/layout_out.m:
compiler/opt_debug.m:
compiler/stack_layout.m:
	Replace the proc layout field holding the procedure representation term
	with the field holding the procedure representation bytecode.

runtime/mercury_grade.h:
	Record the breaking of backward compatibility in debug grades.

compiler/options.m:
	Add an option for use by compiler implementors while implementing
	changes like this.

runtime/mercury_trace_base.[ch]:
	Add the hash table that caches the results of bytecode translations.

trace/mercury_trace_declarative.c:
	Do not include procedure representations when constructing call nodes,
	since it is no longer necessary.

trace/mercury_trace_internal.c:
	Update the code that deals with procedure bodies to use the bytecode 
	representation.

cvs diff: Diffing .
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/tests
cvs diff: Diffing browser
Index: browser/declarative_execution.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/declarative_execution.m,v
retrieving revision 1.39
diff -u -b -r1.39 declarative_execution.m
--- browser/declarative_execution.m	12 Mar 2005 04:46:29 -0000	1.39
+++ browser/declarative_execution.m	29 Mar 2005 03:20:23 -0000
@@ -23,7 +23,10 @@
 :- import_module mdbcomp.prim_data.
 :- import_module mdbcomp.program_representation.
 
-:- import_module list, std_util, io, bool.
+:- import_module bool.
+:- import_module io.
+:- import_module list.
+:- import_module std_util.
 
 	% This type represents a port in the annotated trace.
 	% The type R is the type of references to other nodes
@@ -48,8 +51,6 @@
 						% Trace event number.
 			call_at_max_depth	:: bool,
 						% At the maximum depth?
-			call_proc_rep		:: maybe(proc_rep),
-						% Body of the called procedure.
 			call_return_label	:: maybe(label_layout),
 						% The return label, if there
 						% is one.
@@ -233,6 +234,9 @@
 :- pred get_context_from_label_layout(label_layout::in, string::out, int::out)
 	is semidet.
 
+:- pred call_node_maybe_proc_rep(trace_node(R)::in(trace_node_call),
+	maybe(proc_rep)::out) is det.
+
 %-----------------------------------------------------------------------------%
 
 	% If the following type is modified, some of the macros in
@@ -299,7 +303,7 @@
 	<= annotated_trace(S, R).
 
 :- inst trace_node_call ---> call(ground, ground, ground, ground, ground,
-	ground, ground, ground, ground, ground).
+	ground, ground, ground, ground).
 
 :- pred call_node_from_id(S::in, R::in, trace_node(R)::out(trace_node_call)) 
 	is det <= annotated_trace(S, R).
@@ -397,9 +401,13 @@
 :- implementation.
 
 :- import_module mdb.declarative_debugger.
-:- import_module int, map, exception, store.
-:- import_module require.
 :- import_module mdb.declarative_edt.
+
+:- import_module exception.
+:- import_module int.
+:- import_module map.
+:- import_module require.
+:- import_module store.
 :- import_module string.
 
 %-----------------------------------------------------------------------------%
@@ -497,7 +505,7 @@
 :- pragma foreign_proc("C",
 	get_all_modes_for_layout(Layout::in) = (Layouts::out),
 	[will_not_call_mercury, thread_safe, promise_pure],
-	"
+"
 	const MR_Module_Layout	*module;
 	const MR_Proc_Layout	*proc;
 	int			i;
@@ -609,15 +617,15 @@
 	% stub only
 :- pragma foreign_type("Java", label_layout, "java.lang.Object", []). 
 
-:- pragma foreign_proc("C", get_proc_layout_from_label_layout(Label::in)
-	= (ProcLayout::out),
+:- pragma foreign_proc("C",
+	get_proc_layout_from_label_layout(Label::in) = (ProcLayout::out),
 	[will_not_call_mercury, thread_safe, promise_pure],
 "
 	ProcLayout = Label->MR_sll_entry;
 ").
 
-:- pragma foreign_proc("C", get_goal_path_from_label_layout(Label::in)
-	= (GoalPath::out),
+:- pragma foreign_proc("C",
+	get_goal_path_from_label_layout(Label::in) = (GoalPath::out),
 	[will_not_call_mercury, thread_safe, promise_pure],
 "
 	GoalPath = (MR_String)MR_label_goal_path(Label);
@@ -627,8 +635,8 @@
 	= get_goal_path_from_label_layout(Label).
 get_goal_path_from_maybe_label(no) = "".
 
-:- pragma foreign_proc("C", get_context_from_label_layout(Label::in, 
-	FileName::out, LineNo::out), 
+:- pragma foreign_proc("C",
+	get_context_from_label_layout(Label::in, FileName::out, LineNo::out), 
 	[will_not_call_mercury, thread_safe, promise_pure],
 "
 	const char	*filename;
@@ -639,13 +647,113 @@
 	);
 ").
 
+:- pragma promise_pure(call_node_maybe_proc_rep/2).
+
+call_node_maybe_proc_rep(CallNode, MaybeProcRep) :-
+	( call_node_bytecode_layout(CallNode ^ call_label, ProcLayout) ->
+		( semipure have_cached_proc_rep(ProcLayout, ProcRep) ->
+			MaybeProcRep = yes(ProcRep)
+		;
+			lookup_proc_bytecode(ProcLayout, ByteCode),
+			read_proc_rep(ByteCode, ProcRep),
+			impure cache_proc_rep(ProcLayout, ProcRep),
+			MaybeProcRep = yes(ProcRep)
+		)
+	;
+		MaybeProcRep = no
+	).
+
+:- pred call_node_bytecode_layout(label_layout::in, proc_layout::out)
+	is semidet.
+
+	% Default version for non-C backends.
+call_node_bytecode_layout(_, _) :-
+	semidet_fail.
+
+:- pragma foreign_proc("C",
+	call_node_bytecode_layout(CallLabelLayout::in, ProcLayout::out),
+	[will_not_call_mercury, thread_safe, promise_pure],
+"
+	ProcLayout = CallLabelLayout->MR_sll_entry;
+	if (ProcLayout->MR_sle_body_bytes != NULL) {
+#ifdef MR_DEBUG_PROC_REP
+		printf(""call_node_bytecode_layout: %p success\\n"",
+			CallLabelLayout);
+#endif
+		SUCCESS_INDICATOR = MR_TRUE;
+	} else {
+#ifdef MR_DEBUG_PROC_REP
+		printf(""call_node_bytecode_layout: %p failure\\n"",
+			CallLabelLayout);
+#endif
+		SUCCESS_INDICATOR = MR_FALSE;
+	}
+").
+
+:- pred lookup_proc_bytecode(proc_layout::in, bytecode::out) is det.
+
+	% Default version for non-C backends.
+lookup_proc_bytecode(_, dummy_bytecode).
+
+:- pragma foreign_proc("C",
+	lookup_proc_bytecode(ProcLayout::in, ByteCode::out),
+	[will_not_call_mercury, thread_safe, promise_pure],
+"
+	ByteCode = ProcLayout->MR_sle_body_bytes;
+#ifdef MR_DEBUG_PROC_REP
+	printf(""lookup_proc_bytecode: %p %p\\n"", ProcLayout, ByteCode);
+#endif
+").
+
+:- semipure pred have_cached_proc_rep(proc_layout::in, proc_rep::out)
+	is semidet.
+
+	% Default version for non-C backends.
+have_cached_proc_rep(_, _) :-
+	semidet_fail.
+
+:- pragma foreign_proc("C",
+	have_cached_proc_rep(ProcLayout::in, ProcRep::out),
+	[will_not_call_mercury, thread_safe, promise_semipure],
+"
+	ProcRep = MR_lookup_proc_rep(ProcLayout);
+	if (ProcRep != 0) {
+#ifdef MR_DEBUG_PROC_REP
+		printf(""have_cached_proc_rep: %p success\\n"",
+			ProcLayout);
+#endif
+		SUCCESS_INDICATOR = MR_TRUE;
+	} else {
+#ifdef MR_DEBUG_PROC_REP
+		printf(""have_cached_proc_rep: %p failure\\n"",
+			ProcLayout);
+#endif
+		SUCCESS_INDICATOR = MR_FALSE;
+	}
+").
+
+:- impure pred cache_proc_rep(proc_layout::in, proc_rep::in) is det.
+
+	% Default version for non-C backends.
+cache_proc_rep(_, _).
+
+:- pragma foreign_proc("C",
+	cache_proc_rep(ProcLayout::in, ProcRep::in),
+	[will_not_call_mercury, thread_safe],
+"
+#ifdef MR_DEBUG_PROC_REP
+	printf(""cache_proc_rep: %p %x\\n"", ProcLayout, ProcRep);
+#endif
+	MR_insert_proc_rep(ProcLayout, ProcRep);
+").
+
 %-----------------------------------------------------------------------------%
 
 get_trace_exit_atom(exit(_, _, _, AtomArgs, _, Label, _)) = Atom :-
 	ProcLayout = get_proc_layout_from_label_layout(Label),
 	Atom = atom(ProcLayout, AtomArgs).
 
-get_trace_call_atom(call(_, _, AtomArgs, _, _, _, _, _, Label, _)) = Atom :-
+get_trace_call_atom(call(_, _, AtomArgs, _, _, _, _, Label, _)) = Atom :-
 	ProcLayout = get_proc_layout_from_label_layout(Label),
 	Atom = atom(ProcLayout, AtomArgs).
 
@@ -679,7 +787,7 @@
 	% The following cases are possibly at the left end of a contour,
 	% where we cannot step any further.
 	%
-step_left_in_contour(_, call(_, _, _, _, _, _, _, _, _, _)) = _ :-
+step_left_in_contour(_, call(_, _, _, _, _, _, _, _, _)) = _ :-
 	throw(internal_error("step_left_in_contour", "unexpected CALL node")).
 step_left_in_contour(_, neg(Prec, _, Status)) = Next :-
 	(
@@ -733,7 +841,7 @@
 	% The following cases are at the left end of a contour,
 	% so there are no previous contours in the same stratum.
 	%
-find_prev_contour(_, call(_, _, _, _, _, _, _, _, _, _), _) :-
+find_prev_contour(_, call(_, _, _, _, _, _, _, _, _), _) :-
 	throw(internal_error("find_prev_contour", "reached CALL node")).
 find_prev_contour(_, cond(_, _, _), _) :-
 	throw(internal_error("find_prev_contour", "reached COND node")).
@@ -771,7 +879,7 @@
 	% The following cases mark the boundary of the stratum,
 	% so we cannot step any further.
 	%
-step_in_stratum(_, call(_, _, _, _, _, _, _, _, _, _)) = _ :-
+step_in_stratum(_, call(_, _, _, _, _, _, _, _, _)) = _ :-
 	throw(internal_error("step_in_stratum", "unexpected CALL node")).
 step_in_stratum(_, neg(_, _, _)) = _ :-
 	throw(internal_error("step_in_stratum", "unexpected NEGE node")).
@@ -800,7 +908,7 @@
 call_node_from_id(Store, NodeId, Node) :-
 	(
 		trace_node_from_id(Store, NodeId, Node0),
-		Node0 = call(_, _, _, _, _, _, _, _, _, _)
+		Node0 = call(_, _, _, _, _, _, _, _, _)
 	->
 		Node = Node0
 	;
@@ -918,7 +1026,7 @@
 
 call_node_get_last_interface(Call) = Last :-
 	(
-		Call = call(_, Last0, _, _, _, _, _, _, _, _)
+		Call = call(_, Last0, _, _, _, _, _, _, _)
 	->
 		Last = Last0
 	;
@@ -934,7 +1042,7 @@
 
 call_node_set_last_interface(Call0, Last) = Call :-
 	(
-		Call0 = call(_, _, _, _, _, _, _, _, _, _)
+		Call0 = call(_, _, _, _, _, _, _, _, _)
 	->
 		Call1 = Call0
 	;
@@ -998,7 +1106,7 @@
 :- pragma export(trace_node_port(in) = out,
 		"MR_DD_trace_node_port").
 
-trace_node_port(call(_, _, _, _, _, _, _, _, _, _))	= call.
+trace_node_port(call(_, _, _, _, _, _, _, _, _))	= call.
 trace_node_port(exit(_, _, _, _, _, _, _))		= exit.
 trace_node_port(redo(_, _, _, _))			= redo.
 trace_node_port(fail(_, _, _, _, _))			= fail.
@@ -1022,7 +1130,7 @@
 
 :- func get_trace_node_label(trace_node(R)) = label_layout.
 
-get_trace_node_label(call(_, _, _, _, _, _, _, _, Label, _)) = Label.
+get_trace_node_label(call(_, _, _, _, _, _, _, Label, _)) = Label.
 get_trace_node_label(exit(_, _, _, _, _, Label, _)) = Label.
 get_trace_node_label(redo(_, _, _, Label)) = Label.
 get_trace_node_label(fail(_, _, _, _, Label)) = Label.
@@ -1135,19 +1243,7 @@
 construct_call_node(Preceding, AtomArgs, SeqNo, EventNo, MaxDepth, 
 		MaybeReturnLabel, Label, IoSeqNum) = Call :-
 	Call = call(Preceding, Answer, AtomArgs, SeqNo, EventNo, MaxDepth,
-		no, MaybeReturnLabel, Label, IoSeqNum),
-	null_trace_node_id(Answer).
-
-:- func construct_call_node_with_goal(trace_node_id, list(trace_atom_arg),
-	sequence_number, event_number, bool, proc_rep, maybe(label_layout), 
-	label_layout, int) = trace_node(trace_node_id).
-:- pragma export(construct_call_node_with_goal(in, in, in, in, in, in, in, in,
-	in) = out, "MR_DD_construct_call_node_with_goal").
-
-construct_call_node_with_goal(Preceding, AtomArgs, SeqNo, EventNo, MaxDepth,
-		ProcRep, MaybeReturnLabel, Label, IoSeqNum) = Call :-
-	Call = call(Preceding, Answer, AtomArgs, SeqNo, EventNo, MaxDepth,
-		yes(ProcRep), MaybeReturnLabel, Label, IoSeqNum),
+		MaybeReturnLabel, Label, IoSeqNum),
 	null_trace_node_id(Answer).
 
 :- func make_yes_maybe_label(label_layout) = maybe(label_layout).
@@ -1275,8 +1371,9 @@
 :- pragma foreign_proc("C",
 	null_trace_node_id(Id::out),
 	[will_not_call_mercury, promise_pure, thread_safe],
-"Id = (MR_Word) NULL;"
-).
+"
+	Id = (MR_Word) NULL;
+").
 
 null_trace_node_id(_) :-
 	private_builtin.sorry("null_trace_node_id").
@@ -1406,9 +1503,12 @@
 
 :- pred node_id_to_key(trace_node_id::in, trace_node_key::out) is det.
 
-:- pragma foreign_proc("C", node_id_to_key(Id::in, Key::out),
+:- pragma foreign_proc("C",
+	node_id_to_key(Id::in, Key::out),
 	[will_not_call_mercury, promise_pure, thread_safe],
-"Key = (MR_Integer) Id;").
+"
+	Key = (MR_Integer) Id;
+").
 
 node_id_to_key(_, _) :-
 	private_builtin.sorry("node_id_to_key").
@@ -1416,9 +1516,12 @@
 :- pred convert_node(trace_node(trace_node_id)::in, 
 	trace_node(trace_node_key)::out) is det.
 
-:- pragma foreign_proc("C", convert_node(N1::in, N2::out),
+:- pragma foreign_proc("C",
+	convert_node(N1::in, N2::out),
 	[will_not_call_mercury, promise_pure, thread_safe],
-"N2 = N1;").
+"
+	N2 = N1;
+").
 
 convert_node(_, _) :-
 	private_builtin.sorry("convert_node").
@@ -1429,7 +1532,7 @@
 	%
 :- func preceding_node(trace_node(T)) = T.
 
-preceding_node(call(P, _, _, _, _, _, _, _, _, _)) = P.
+preceding_node(call(P, _, _, _, _, _, _, _, _)) = P.
 preceding_node(exit(P, _, _, _, _, _, _))	= P.
 preceding_node(redo(P, _, _, _))		= P.
 preceding_node(fail(P, _, _, _, _))		= P.
@@ -1501,3 +1604,282 @@
 				CurArgNum + 1, ArgNum)
 		)
 	).
+
+%-----------------------------------------------------------------------------%
+
+:- type bytecode --->	dummy_bytecode.
+
+:- pragma foreign_type("C", bytecode, "const MR_uint_least8_t *",
+	[can_pass_as_mercury_type, stable]).
+:- pragma foreign_type("Java", bytecode, "java.lang.Object", []). %stub only
+
+:- pred read_proc_rep(bytecode::in, proc_rep::out) is det.
+:- pragma export(read_proc_rep(in, out), "MR_DD_trace_read_rep").
+
+read_proc_rep(Bytecode, ProcRep) :-
+	some [!Pos] (
+		!:Pos = 0,
+		read_int32(Bytecode, !Pos, Limit),
+		read_string(Bytecode, !Pos, FileName),
+		Info = read_proc_rep_info(Limit, FileName),
+		read_vars(Bytecode, !Pos, HeadVars),
+		read_goal(Bytecode, !Pos, Info, Goal),
+		ProcRep = proc_rep(HeadVars, Goal),
+		require(unify(!.Pos, Limit), "read_proc_rep: limit mismatch")
+	).
+
+:- type read_proc_rep_info
+	--->	read_proc_rep_info(
+			limit		:: int,
+			filename	:: string
+		).
+
+:- pred read_goal(bytecode::in, int::in, int::out, read_proc_rep_info::in,
+	goal_rep::out) is det.
+
+read_goal(Bytecode, !Pos, Info, Goal) :-
+	read_byte(Bytecode, !Pos, GoalTypeByte),
+	( byte_to_goal_type(GoalTypeByte) = GoalType ->
+		(
+			GoalType = goal_conj,
+			read_goals(Bytecode, !Pos, Info, Goals),
+			Goal = conj_rep(Goals)
+		;
+			GoalType = goal_disj,
+			read_goals(Bytecode, !Pos, Info, Goals),
+			Goal = disj_rep(Goals)
+		;
+			GoalType = goal_neg,
+			read_goal(Bytecode, !Pos, Info, SubGoal),
+			Goal = negation_rep(SubGoal)
+		;
+			GoalType = goal_ite,
+			read_goal(Bytecode, !Pos, Info, Cond),
+			read_goal(Bytecode, !Pos, Info, Then),
+			read_goal(Bytecode, !Pos, Info, Else),
+			Goal = ite_rep(Cond, Then, Else)
+		;
+			GoalType = goal_switch,
+			read_goals(Bytecode, !Pos, Info, Goals),
+			Goal = switch_rep(Goals)
+		;
+			GoalType = goal_assign,
+			read_var(Bytecode, !Pos, Target),
+			read_var(Bytecode, !Pos, Source),
+			AtomicGoal = unify_assign_rep(Target, Source),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_construct,
+			read_var(Bytecode, !Pos, Var),
+			read_cons_id(Bytecode, !Pos, ConsId),
+			read_vars(Bytecode, !Pos, ArgVars),
+			AtomicGoal = unify_construct_rep(Var, ConsId, ArgVars),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_deconstruct,
+			read_var(Bytecode, !Pos, Var),
+			read_cons_id(Bytecode, !Pos, ConsId),
+			read_vars(Bytecode, !Pos, ArgVars),
+			AtomicGoal = unify_deconstruct_rep(Var, ConsId,
+				ArgVars),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_simple_test,
+			read_var(Bytecode, !Pos, Var1),
+			read_var(Bytecode, !Pos, Var2),
+			AtomicGoal = unify_simple_test_rep(Var1, Var2),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_scope,
+			read_byte(Bytecode, !Pos, MaybeCutByte),
+			( MaybeCutByte = 0 ->
+				MaybeCut = no_cut
+			; MaybeCutByte = 1 ->
+				MaybeCut = cut
+			;
+				error("read_goal: bad maybe_cut")
+			),
+			read_goal(Bytecode, !Pos, Info, SubGoal),
+			Goal = scope_rep(SubGoal, MaybeCut)
+		;
+			GoalType = goal_ho_call,
+			read_var(Bytecode, !Pos, Var),
+			read_vars(Bytecode, !Pos, Args),
+			AtomicGoal = higher_order_call_rep(Var, Args),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_method_call,
+			read_var(Bytecode, !Pos, Var),
+			read_method_num(Bytecode, !Pos, MethodNum),
+			read_vars(Bytecode, !Pos, Args),
+			AtomicGoal = method_call_rep(Var, MethodNum, Args),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_unsafe_cast,
+			read_var(Bytecode, !Pos, OutputVar),
+			read_var(Bytecode, !Pos, InputVar),
+			AtomicGoal = unsafe_cast_rep(OutputVar, InputVar),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_plain_call,
+			read_string(Bytecode, !Pos, ModuleName),
+			read_string(Bytecode, !Pos, PredName),
+			read_vars(Bytecode, !Pos, Args),
+			AtomicGoal = plain_call_rep(ModuleName, PredName,
+				Args),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_builtin_call,
+			read_string(Bytecode, !Pos, ModuleName),
+			read_string(Bytecode, !Pos, PredName),
+			read_vars(Bytecode, !Pos, Args),
+			AtomicGoal = builtin_call_rep(ModuleName, PredName,
+				Args),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		;
+			GoalType = goal_foreign,
+			read_vars(Bytecode, !Pos, Args),
+			AtomicGoal = pragma_foreign_code_rep(Args),
+			read_atomic_info(Bytecode, !Pos, Info, AtomicGoal,
+				Goal)
+		)
+	;
+		error("read_goal: invalid goal type")
+	).
+
+:- pred read_atomic_info(bytecode::in, int::in, int::out,
+	read_proc_rep_info::in, atomic_goal_rep::in, goal_rep::out) is det.
+
+read_atomic_info(Bytecode, !Pos, Info, AtomicGoal, Goal) :-
+	read_byte(Bytecode, !Pos, DetismByte),
+	( determinism_representation(DetismPrime, DetismByte) ->
+		Detism = DetismPrime
+	;
+		error("read_atomic_info: bad detism")
+	),
+	read_string(Bytecode, !Pos, FileName0),
+	( FileName0 = "" ->
+		FileName = Info ^ filename
+	;
+		FileName = FileName0
+	),
+	read_lineno(Bytecode, !Pos, LineNo),
+	read_vars(Bytecode, !Pos, BoundVars),
+	Goal = atomic_goal_rep(Detism, FileName, LineNo, BoundVars,
+		AtomicGoal).
+
+:- pred read_goals(bytecode::in, int::in, int::out, read_proc_rep_info::in,
+	list(goal_rep)::out) is det.
+
+read_goals(Bytecode, !Pos, Info, Goals) :-
+	read_length(Bytecode, !Pos, Len),
+	read_goals_2(Bytecode, !Pos, Info, Len, Goals).
+
+:- pred read_goals_2(bytecode::in, int::in, int::out,
+	read_proc_rep_info::in, int::in, list(goal_rep)::out) is det.
+
+read_goals_2(Bytecode, !Pos, Info, N, Goals) :-
+	( N > 0 ->
+		read_goal(Bytecode, !Pos, Info, Head),
+		read_goals_2(Bytecode, !Pos, Info, N - 1, Tail),
+		Goals = [Head | Tail]
+	;
+		Goals = []
+	).
+
+:- pred read_vars(bytecode::in, int::in, int::out, list(var_rep)::out) is det.
+
+read_vars(Bytecode, !Pos, Vars) :-
+	read_length(Bytecode, !Pos, Len),
+	read_vars_2(Bytecode, Len, !Pos, Vars).
+
+:- pred read_vars_2(bytecode::in, int::in, int::in, int::out,
+	list(var_rep)::out) is det.
+
+read_vars_2(Bytecode, N, !Pos, Vars) :-
+	( N > 0 ->
+		read_var(Bytecode, !Pos, Head),
+		read_vars_2(Bytecode, N - 1, !Pos, Tail),
+		Vars = [Head | Tail]
+	;
+		Vars = []
+	).
+
+:- pred read_var(bytecode::in, int::in, int::out, var_rep::out) is det.
+
+read_var(Bytecode, !Pos, Var) :-
+	read_short(Bytecode, !Pos, Var).
+
+:- pred read_length(bytecode::in, int::in, int::out, var_rep::out) is det.
+
+read_length(Bytecode, !Pos, Len) :-
+	read_short(Bytecode, !Pos, Len).
+
+:- pred read_lineno(bytecode::in, int::in, int::out, var_rep::out) is det.
+
+read_lineno(Bytecode, !Pos, LineNo) :-
+	read_short(Bytecode, !Pos, LineNo).
+
+:- pred read_method_num(bytecode::in, int::in, int::out, var_rep::out) is det.
+
+read_method_num(Bytecode, !Pos, MethodNum) :-
+	read_short(Bytecode, !Pos, MethodNum).
+
+:- pred read_cons_id(bytecode::in, int::in, int::out, cons_id_rep::out) is det.
+
+read_cons_id(Bytecode, !Pos, ConsId) :-
+	read_string(Bytecode, !Pos, ConsId).
+
+%-----------------------------------------------------------------------------%
+
+:- pred read_byte(bytecode::in, int::in, int::out, int::out) is det.
+
+:- pragma foreign_proc("C",
+	read_byte(Bytecode::in, Pos0::in, Pos::out, Value::out),
+	[will_not_call_mercury, thread_safe, promise_pure],
+"
+	Value = Bytecode[Pos0];
+	Pos = Pos0 + 1;
+").
+
+:- pred read_short(bytecode::in, int::in, int::out, int::out) is det.
+
+:- pragma foreign_proc("C",
+	read_short(Bytecode::in, Pos0::in, Pos::out, Value::out),
+	[will_not_call_mercury, thread_safe, promise_pure],
+"
+	Value = (Bytecode[Pos0] << 8) + Bytecode[Pos0+1];
+	Pos = Pos0 + 2;
+").
+
+:- pred read_int32(bytecode::in, int::in, int::out, int::out) is det.
+
+:- pragma foreign_proc("C",
+	read_int32(Bytecode::in, Pos0::in, Pos::out, Value::out),
+	[will_not_call_mercury, thread_safe, promise_pure],
+"
+	Value = (Bytecode[Pos0] << 24) + (Bytecode[Pos0+1] << 16) +
+		(Bytecode[Pos0+2] << 8) + Bytecode[Pos0+3];
+	Pos = Pos0 + 4;
+").
+
+:- pred read_string(bytecode::in, int::in, int::out, string::out) is det.
+
+:- pragma foreign_proc("C",
+	read_string(Bytecode::in, Pos0::in, Pos::out, Value::out),
+	[will_not_call_mercury, thread_safe, promise_pure],
+"
+	MR_make_aligned_string(Value, (char *) &Bytecode[Pos0]);
+	Pos = Pos0 + strlen(Value) + 1;
+").
+
+%-----------------------------------------------------------------------------%
Index: browser/declarative_tree.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/browser/declarative_tree.m,v
retrieving revision 1.23
diff -u -b -r1.23 declarative_tree.m
--- browser/declarative_tree.m	24 Mar 2005 05:33:53 -0000	1.23
+++ browser/declarative_tree.m	28 Mar 2005 08:20:29 -0000
@@ -259,7 +259,7 @@
 		Node = excp(_, CallId, _, _, _, _)
 	),
 	% The node is topmost of the call sequence number is 1.
-	call_node_from_id(Store, CallId, call(_, _, _, 1, _, _, _, _, _, _)).
+	call_node_from_id(Store, CallId, call(_, _, _, 1, _, _, _, _, _)).
 
 :- pred trace_children(wrap(S)::in, edt_node(R)::in, list(edt_node(R))::out)
 	is semidet <= annotated_trace(S, R).
@@ -454,7 +454,7 @@
 	det_trace_node_from_id(Store, NodeId, Node),
 	(
 		( 
-			Node = call(_, _, _, _, _, _, _, _, _, _)
+			Node = call(_, _, _, _, _, _, _, _, _)
 		; 
 			%
 			% A non-failed NEGE could be encountered when gathering
@@ -587,7 +587,7 @@
 stratum_children_2(Store, NodeId, StartId, Ns0, Ns) :-
 	det_trace_node_from_id(Store, NodeId, Node),
 	(
-		( Node = call(_, _, _, _, _, _, _, _, _, _)
+		( Node = call(_, _, _, _, _, _, _, _, _)
 		; Node = neg(_, _, _)
 		; Node = cond(_, _, failed)
 		)
@@ -863,7 +863,7 @@
 	TotalArgs = length(ExitAtom ^ atom_args),
 	StartId = ExitNode ^ exit_preceding,
 	StartPath = no,
-	StartRep = CallNode ^ call_proc_rep,
+	call_node_maybe_proc_rep(CallNode, StartRep),
 	ChainStart = chain_start(StartLoc, ArgNum, TotalArgs, StartId,
 		StartPath, StartRep).
 
@@ -876,7 +876,7 @@
 	(
 		step_left_to_call(Store, CallPrecId, ParentCallNode)
 	->
-		ProcRep = ParentCallNode ^ call_proc_rep
+		call_node_maybe_proc_rep(ParentCallNode, ProcRep)
 	;
 		ProcRep = no
 	).
@@ -891,7 +891,7 @@
 
 step_left_to_call(Store, NodeId, ParentCallNode) :-
 	trace_node_from_id(Store, NodeId, Node),
-	( Node = call(_, _, _, _, _, _, _, _, _, _) ->
+	( Node = call(_, _, _, _, _, _, _, _, _) ->
 		ParentCallNode = Node
 	;
 		%
@@ -919,7 +919,7 @@
 	is det <= annotated_trace(S, R).
 
 materialize_contour(Store, NodeId, Node, Nodes0, Nodes) :-
-	( Node = call(_, _, _, _, _, _, _, _, _, _) ->
+	( Node = call(_, _, _, _, _, _, _, _, _) ->
 		
 		Nodes = Nodes0
 	;
@@ -1065,7 +1065,7 @@
 :- pred contour_at_end_path(assoc_list(R, trace_node(R))::in, 
 	maybe(goal_path)::in) is semidet.
 
-contour_at_end_path([_ - call(_, _, _, _, _, _, _, MaybeReturnLabel, _, _)], 
+contour_at_end_path([_ - call(_, _, _, _, _, _, MaybeReturnLabel, _, _)], 
 		yes(EndPath)) :-
 	CallPathStr = get_goal_path_from_maybe_label(MaybeReturnLabel),
 	path_from_string_det(CallPathStr, CallPath),
@@ -1280,7 +1280,7 @@
 		MaybeEnd = yes(EndPath)
 	->
 		(
-			ContourHeadNode = call(_, _, _, _, _, _, _, 
+			ContourHeadNode = call(_, _, _, _, _, _, 
 				MaybeReturnLabel, _, _),
 			Atom = get_trace_call_atom(ContourHeadNode),
 			CallPathStr = get_goal_path_from_maybe_label(
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/code_model.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_model.m,v
retrieving revision 1.6
diff -u -b -r1.6 code_model.m
--- compiler/code_model.m	20 Oct 2004 09:44:57 -0000	1.6
+++ compiler/code_model.m	28 Mar 2005 06:16:46 -0000
@@ -54,6 +54,7 @@
 
 :- implementation.
 
+:- import_module mdbcomp.program_representation.
 :- import_module int.
 
 determinism_to_code_model(det,         model_det).
@@ -73,27 +74,13 @@
 	goal_info_get_determinism(GoalInfo, Determinism),
 	determinism_to_code_model(Determinism, CodeModel).
 
-represent_determinism(det) = max_more_than_zero \/ min_more_than_zero.
-represent_determinism(semidet) = max_more_than_zero.
-represent_determinism(nondet) = max_more_than_one.
-represent_determinism(multidet) = max_more_than_one \/ min_more_than_zero.
-represent_determinism(erroneous) = min_more_than_zero.
-represent_determinism(failure) = 0.
-represent_determinism(cc_nondet) =
-		represent_determinism(nondet) \/ first_solution.
-represent_determinism(cc_multidet) =
-		represent_determinism(multidet) \/ first_solution.
-
-:- func first_solution = int.
-first_solution = 8.
-
-:- func min_more_than_zero = int.
-min_more_than_zero = 4.
-
-:- func max_more_than_zero = int.
-max_more_than_zero = 2.
-
-:- func max_more_than_one = int.
-max_more_than_one = 3.
+represent_determinism(det) = detism_rep(det_rep).
+represent_determinism(semidet) = detism_rep(semidet_rep).
+represent_determinism(nondet) = detism_rep(nondet_rep).
+represent_determinism(multidet) = detism_rep(multidet_rep).
+represent_determinism(erroneous) = detism_rep(erroneous_rep).
+represent_determinism(failure) = detism_rep(failure_rep).
+represent_determinism(cc_nondet) = detism_rep(cc_nondet_rep).
+represent_determinism(cc_multidet) = detism_rep(cc_multidet_rep).
 
 %-----------------------------------------------------------------------------%
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.18
diff -u -b -r1.18 layout.m
--- compiler/layout.m	22 Mar 2005 06:40:03 -0000	1.18
+++ compiler/layout.m	28 Mar 2005 12:06:58 -0000
@@ -150,7 +150,11 @@
 :- type proc_layout_exec_trace			% defines MR_Exec_Trace
 	--->	proc_layout_exec_trace(
 			call_label_layout	:: layout_name,
-			proc_body		:: maybe(rval),
+			proc_body_bytes		:: list(int),
+						% The procedure body
+						% represented as a list of
+						% bytecodes.
+
 			maybe_table_info	:: maybe(layout_name),
 			head_var_nums		:: list(int),
 						% The variable numbers of the
@@ -159,10 +163,12 @@
 						% in order. The length of the
 						% list must be the same as the
 						% procedure's arity.
+
 			var_names		:: list(int),
 						% Each variable name is an
 						% offset into the module's
 						% string table.
+
 			max_var_num		:: int,
 			max_r_num		:: int,
 			maybe_from_full_slot	:: maybe(int),
@@ -196,6 +202,7 @@
 	;	proc_layout_var_names(rtti_proc_label)
 		% A vector of variable names (represented as offsets into
 		% the string table) for a procedure layout structure.
+	;	proc_layout_body_bytecode(rtti_proc_label)
 	;	table_io_decl(rtti_proc_label)
 	;	table_gen_info(rtti_proc_label)
 	;	table_gen_enum_params(rtti_proc_label)
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.46
diff -u -b -r1.46 layout_out.m
--- compiler/layout_out.m	22 Mar 2005 06:40:03 -0000	1.46
+++ compiler/layout_out.m	28 Mar 2005 12:34:18 -0000
@@ -233,6 +233,10 @@
 	io__write_string(mercury_data_prefix, !IO),
 	io__write_string("_var_names__", !IO),
 	output_proc_label(make_proc_label_from_rtti(RttiProcLabel), no, !IO).
+output_layout_name(proc_layout_body_bytecode(RttiProcLabel), !IO) :-
+	io__write_string(mercury_data_prefix, !IO),
+	io__write_string("_body_bytecode__", !IO),
+	output_proc_label(make_proc_label_from_rtti(RttiProcLabel), no, !IO).
 output_layout_name(closure_proc_id(CallerProcLabel, SeqNo, _), !IO) :-
 	io__write_string(mercury_data_prefix, !IO),
 	io__write_string("_closure_layout__", !IO),
@@ -361,6 +365,12 @@
 	io__write_string("MR_uint_least32_t ", !IO),
 	output_layout_name(proc_layout_var_names(ProcLabel), !IO),
 	io__write_string("[]", !IO).
+output_layout_name_storage_type_name(proc_layout_body_bytecode(ProcLabel),
+		_BeingDefined, !IO) :-
+	io__write_string("static const ", !IO),
+	io__write_string("MR_uint_least8_t ", !IO),
+	output_layout_name(proc_layout_body_bytecode(ProcLabel), !IO),
+	io__write_string("[]", !IO).
 output_layout_name_storage_type_name(closure_proc_id(CallerProcLabel, SeqNo,
 		ClosureProcLabel), _BeingDefined, !IO) :-
 	io__write_string("static const ", !IO),
@@ -449,6 +459,7 @@
 layout_name_would_include_code_addr(proc_layout_exec_trace(_)) = yes.
 layout_name_would_include_code_addr(proc_layout_head_var_nums(_)) = no.
 layout_name_would_include_code_addr(proc_layout_var_names(_)) = no.
+layout_name_would_include_code_addr(proc_layout_body_bytecode(_)) = no.
 layout_name_would_include_code_addr(closure_proc_id(_, _, _)) = no.
 layout_name_would_include_code_addr(file_layout(_, _)) = no.
 layout_name_would_include_code_addr(file_layout_line_number_vector(_, _)) = no.
@@ -821,7 +832,7 @@
 	io::di, io::uo) is det.
 
 output_layout_exec_trace_decls(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
-	ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
+	ExecTrace = proc_layout_exec_trace(CallLabelLayout, _ProcBodyBytes,
 		MaybeTableInfo, _HeadVarNums, _VarNames, _MaxVarNum,
 		_MaxRegNum, _MaybeFromFullSlot, _MaybeIoSeqSlot,
 		_MaybeTrailSlot, _MaybeMaxfrSlot, _EvalMethod,
@@ -831,28 +842,72 @@
 	output_layout_decl(CallLabelLayout, !DeclSet, !IO),
 	output_layout_decl(module_layout(ModuleName), !DeclSet, !IO),
 	(
-		MaybeProcBody = yes(ProcBody),
-		output_rval_decls(ProcBody, !DeclSet, !IO)
-	;
-		MaybeProcBody = no
-	),
-	(
 		MaybeTableInfo = yes(TableInfo),
 		output_layout_decl(TableInfo, !DeclSet, !IO)
 	;
 		MaybeTableInfo = no
 	).
 
+	% The job of this predicate is to minimize stack space consumption in
+	% grades that do not allow output_bytecode to be tail recursive.
+	%
+:- pred output_bytecodes_driver(list(int)::in, io::di, io::uo)
+	is det.
+
+output_bytecodes_driver(Bytes, !IO) :-
+	(
+		Bytes = []
+	;
+		Bytes = [_ | _],
+		output_bytecodes(Bytes, BytesLeft, 0, 256, !IO),
+		output_bytecodes_driver(BytesLeft, !IO)
+	).
+
+:- pred output_bytecodes(list(int)::in, list(int)::out, int::in, int::in,
+	io::di, io::uo) is det.
+
+output_bytecodes(Bytes, BytesLeft, !.Seq, MaxSeq, !IO) :-
+	(
+		Bytes = [],
+		BytesLeft = []
+	;
+		Bytes = [Head | Tail],
+		( !.Seq < MaxSeq ->
+			io__write_int(Head, !IO),
+			io__write_char(',', !IO),
+			!:Seq = !.Seq + 1,
+			( unchecked_rem(!.Seq, 16) = 0 ->
+				io__write_char('\n', !IO)
+			;
+				true
+			),
+			output_bytecodes(Tail, BytesLeft, !.Seq, MaxSeq, !IO)
+		;
+			BytesLeft = Bytes
+		)
+	).
+
 :- pred output_layout_exec_trace(rtti_proc_label::in,
 	proc_layout_exec_trace::in, decl_set::in, decl_set::out,
 	io::di, io::uo) is det.
 
 output_layout_exec_trace(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
-	ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
+	ExecTrace = proc_layout_exec_trace(CallLabelLayout, ProcBodyBytes,
 		MaybeTableInfo, HeadVarNums, _VarNames, MaxVarNum,
 		MaxRegNum, MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
 		MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot, EffTraceLevel,
 		Flags),
+	(
+		ProcBodyBytes = []
+	;
+		ProcBodyBytes = [_ | _],
+		io__write_string("\n", !IO),
+		output_layout_name_storage_type_name(
+			proc_layout_body_bytecode(RttiProcLabel), yes, !IO),
+		io__write_string(" = {\n", !IO),
+		output_bytecodes_driver(ProcBodyBytes, !IO),
+		io__write_string("};\n", !IO)
+	),
 	io__write_string("\n", !IO),
 	output_layout_name_storage_type_name(
 		proc_layout_exec_trace(RttiProcLabel), yes, !IO),
@@ -868,11 +923,12 @@
 	output_layout_name(module_layout(ModuleName), !IO),
 	io__write_string(",\n", !IO),
 	(
-		MaybeProcBody = yes(ProcBody),
-		output_rval(ProcBody, !IO)
+		ProcBodyBytes = [],
+		io__write_string("NULL", !IO)
 	;
-		MaybeProcBody = no,
-		io__write_int(0, !IO)
+		ProcBodyBytes = [_ | _],
+		output_layout_name(proc_layout_body_bytecode(RttiProcLabel),
+			!IO)
 	),
 	io__write_string(",\n", !IO),
 	(
@@ -1280,11 +1336,11 @@
 	io__write_string("};\n", !IO),
 	decl_set_insert(data_addr(layout_addr(TableName)), !DeclSet).
 
-% The jobs of this predicate is to minimize stack space consumption in
-% grades that do not allow output_module_string_table_chars to be tail
-% recursive. The maximum observed size of the module string so far has
-% been just short of 64 kilobytes; writing that out in 256 batches of 256
-% characters minimizes maximum total stack requirements.
+	% The job of this predicate is to minimize stack space consumption in
+	% grades that do not allow output_module_string_table_chars to be tail
+	% recursive. The maximum observed size of the module string so far has
+	% been just short of 64 kilobytes; writing that out in 256 batches of
+	% 256 characters minimizes maximum total stack requirements.
 
 :- pred output_module_string_table_chars_driver(int::in, int::in,
 	string_with_0s::in, io::di, io::uo) is det.
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.149
diff -u -b -r1.149 opt_debug.m
--- compiler/opt_debug.m	22 Mar 2005 06:40:15 -0000	1.149
+++ compiler/opt_debug.m	26 Mar 2005 14:48:35 -0000
@@ -513,6 +513,10 @@
 	dump_rttiproclabel(RttiProcLabel, ProcLabelStr),
 	string__append_list(["proc_layout_var_names(", ProcLabelStr, ")"],
 		Str).
+dump_layout_name(proc_layout_body_bytecode(RttiProcLabel), Str) :-
+	dump_rttiproclabel(RttiProcLabel, ProcLabelStr),
+	string__append_list(["proc_layout_body_bytecode(", ProcLabelStr, ")"],
+		Str).
 dump_layout_name(closure_proc_id(ProcLabel, SeqNo, _), Str) :-
 	dump_proclabel(ProcLabel, ProcLabelStr),
 	string__int_to_string(SeqNo, SeqNoStr),
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.454
diff -u -b -r1.454 options.m
--- compiler/options.m	24 Mar 2005 05:34:10 -0000	1.454
+++ compiler/options.m	28 Mar 2005 08:03:08 -0000
@@ -713,7 +713,25 @@
 				% This option is used to test that the compiler
 				% is sufficiently recent when no other test
 				% can easily be constructed in configure.in.
-		.
+		;	experiment.
+				% This option is provided for use by
+				% implementors who want to compare a new way
+				% of doing something with the old way.
+				% The idea is that the code that switches
+				% between the two ways should consult this
+				% option and make its decision accordingly.
+				%
+				% The intention is that all use of this
+				% option is within developer workspaces;
+				% no code using this option should be
+				% committed.
+				%
+				% Of course, a developer could always create
+				% a purpose-specific option to control their
+				% code, but adding an option requires
+				% recompiling most of the modules in the
+				% compiler. Having this option permanently here
+				% should reduce the need for that.
 
 :- implementation.
 
@@ -1374,7 +1392,8 @@
 	version			-	bool(no),
 	fullarch		-	string(""),
 	compiler_sufficiently_recent
-				-	bool(no)
+				-	bool(no),
+	experiment 		-	string("")
 ]).
 
 	% please keep this in alphabetic order
@@ -2070,6 +2089,7 @@
 long_option("install-opt-files-2002-08-30", compiler_sufficiently_recent).
 long_option("read-config-file-2003-03-01", compiler_sufficiently_recent).
 long_option("no-noncompact-ho-call-2004-01-15", compiler_sufficiently_recent).
+long_option("experiment",		experiment).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.33
diff -u -b -r1.33 prog_rep.m
--- compiler/prog_rep.m	24 Mar 2005 05:34:13 -0000	1.33
+++ compiler/prog_rep.m	28 Mar 2005 12:21:17 -0000
@@ -24,9 +24,6 @@
 :- import_module hlds__instmap.
 :- import_module parse_tree__prog_data.
 
-:- import_module mdbcomp.
-:- import_module mdbcomp__program_representation.
-
 :- import_module list.
 :- import_module map.
 :- import_module std_util.
@@ -43,16 +40,22 @@
 
 :- type var_num_map	== map(prog_var, pair(int, string)).
 
-:- func prog_rep__represent_proc(list(prog_var), hlds_goal,
-	instmap, vartypes, var_num_map, module_info) = proc_rep.
+:- func prog_rep__represent_proc(list(prog_var), hlds_goal, instmap, vartypes,
+	var_num_map, module_info) = list(int).
 
 :- implementation.
 
+:- import_module backend_libs__bytecode_data.
+:- import_module hlds__code_model.
 :- import_module hlds__hlds_data.
 :- import_module mdbcomp__prim_data.
 :- import_module parse_tree__prog_out.
 :- import_module parse_tree__prog_util.
 
+:- import_module mdbcomp.
+:- import_module mdbcomp__program_representation.
+
+:- import_module int.
 :- import_module require.
 :- import_module set.
 :- import_module std_util.
@@ -61,253 +64,313 @@
 
 :- type prog_rep__info
 	--->	info(
+			filename	:: string,
 			vartypes	:: vartypes,
 			var_num_map	:: var_num_map,
 			module_info	:: module_info
 		).
 
 prog_rep__represent_proc(HeadVars, Goal, InstMap0, VarTypes, VarNumMap,
-		ModuleInfo) = proc_rep(HeadVarsRep, GoalRep) :-
-	list__map(term__var_to_int, HeadVars, HeadVarsRep),
-	prog_rep__represent_goal(Goal, InstMap0,
-		info(VarTypes, VarNumMap, ModuleInfo), GoalRep).
-
-:- pred prog_rep__represent_goal(hlds_goal::in, instmap::in,
-	prog_rep__info::in, goal_rep::out) is det.
-
-prog_rep__represent_goal(GoalExpr - GoalInfo, InstMap0, Info, Rep) :-
-	prog_rep__represent_goal_expr(GoalExpr, GoalInfo, InstMap0, Info, Rep).
-
-:- pred prog_rep__represent_atomic_goal(hlds_goal_info::in,
-	instmap::in, prog_rep__info::in, detism_rep::out,
-	string::out, int::out, list(var_rep)::out) is det.
-
-prog_rep__represent_atomic_goal(GoalInfo, InstMap0, Info,
-		DetismRep, FilenameRep, LinenoRep, ChangedVarsRep) :-
-	goal_info_get_determinism(GoalInfo, Detism),
-	prog_rep__represent_detism(Detism, DetismRep),
+		ModuleInfo) = ProcRepBytes :-
+	Goal = _ - GoalInfo,
 	goal_info_get_context(GoalInfo, Context),
-	term__context_file(Context, FilenameRep),
-	term__context_line(Context, LinenoRep),
-	goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
-	instmap__apply_instmap_delta(InstMap0, InstMapDelta, InstMap),
-	instmap_changed_vars(InstMap0, InstMap, Info ^ vartypes,
-		Info ^ module_info, ChangedVars),
-	set__to_sorted_list(ChangedVars, ChangedVarsList),
-	list__map(term__var_to_int, ChangedVarsList, ChangedVarsRep).
+	term__context_file(Context, FileName),
+	Info = info(FileName, VarTypes, VarNumMap, ModuleInfo),
 
-:- pred prog_rep__represent_detism(determinism::in,
-	detism_rep::out) is det.
+	ProcRepBytes0 = string_to_byte_list(FileName) ++
+		vars_to_byte_list(Info, HeadVars) ++
+		goal_to_byte_list(Goal, InstMap0, Info),
+	int32_to_byte_list(list__length(ProcRepBytes0) + 4, LimitBytes),
+	ProcRepBytes = LimitBytes ++ ProcRepBytes0.
 
-prog_rep__represent_detism(det, det_rep).
-prog_rep__represent_detism(semidet, semidet_rep).
-prog_rep__represent_detism(nondet, nondet_rep).
-prog_rep__represent_detism(multidet, multidet_rep).
-prog_rep__represent_detism(cc_nondet, cc_nondet_rep).
-prog_rep__represent_detism(cc_multidet, cc_multidet_rep).
-prog_rep__represent_detism(erroneous, erroneous_rep).
-prog_rep__represent_detism(failure, failure_rep).
-
-:- pred prog_rep__represent_cons_id(cons_id::in,
-	cons_id_rep::out) is det.
-
-prog_rep__represent_cons_id(cons(SymName, _), Rep) :-
-	prog_rep__represent_sym_name(SymName, Rep).
-prog_rep__represent_cons_id(int_const(Int), Rep) :-
-	string__int_to_string(Int, Rep).
-prog_rep__represent_cons_id(float_const(Float), Rep) :-
-	string__float_to_string(Float, Rep).
-prog_rep__represent_cons_id(string_const(String), Rep) :-
-	string__append_list(["""", String, """"], Rep).
-prog_rep__represent_cons_id(pred_const(_, _), Rep) :-
-	Rep = "$pred_const".
-prog_rep__represent_cons_id(type_ctor_info_const(_, _, _), Rep) :-
-	Rep = "$type_ctor_info_const".
-prog_rep__represent_cons_id(base_typeclass_info_const(_, _, _, _), Rep) :-
-	Rep = "$base_typeclass_info_const".
-prog_rep__represent_cons_id(type_info_cell_constructor(_), Rep) :-
-	Rep = "$type_info_cell_constructor".
-prog_rep__represent_cons_id(typeclass_info_cell_constructor, Rep) :-
-	Rep = "$typeclass_info_cell_constructor".
-prog_rep__represent_cons_id(tabling_pointer_const(_), Rep) :-
-	Rep = "$tabling_pointer_const".
-prog_rep__represent_cons_id(deep_profiling_proc_layout(_), Rep) :-
-	Rep = "$deep_profiling_procedure_data".
-prog_rep__represent_cons_id(table_io_decl(_), Rep) :-
-	Rep = "$table_io_decl".
-
-:- pred prog_rep__represent_sym_name(sym_name::in, string::out) is det.
+%---------------------------------------------------------------------------%
 
-prog_rep__represent_sym_name(unqualified(String), String).
-prog_rep__represent_sym_name(qualified(_, String), String).
+:- func goal_to_byte_list(hlds_goal, instmap, prog_rep__info) = list(int).
 
-%---------------------------------------------------------------------------%
+goal_to_byte_list(GoalExpr - GoalInfo, InstMap0, Info) =
+	goal_expr_to_byte_list(GoalExpr, GoalInfo, InstMap0, Info).
 
-:- pred prog_rep__represent_goal_expr(hlds_goal_expr::in, hlds_goal_info::in,
-	instmap::in, prog_rep__info::in, goal_rep::out) is det.
+:- func goal_expr_to_byte_list(hlds_goal_expr, hlds_goal_info, instmap,
+	prog_rep__info) = list(int).
 
-prog_rep__represent_goal_expr(unify(_, _, _, Uni, _), GoalInfo, InstMap0,
-		Info, Rep) :-
+goal_expr_to_byte_list(conj(Goals), _, InstMap0, Info) = Bytes :-
+	Bytes = [goal_type_to_byte(goal_conj)] ++
+		length_to_byte_list(Goals) ++
+		conj_to_byte_list(Goals, InstMap0, Info).
+goal_expr_to_byte_list(par_conj(_), _, _, _) = _ :-
+	error("Sorry, not yet implemented:\n\
+		parallel conjunctions and declarative debugging").
+goal_expr_to_byte_list(disj(Goals), _, InstMap0, Info) = Bytes :-
+	Bytes = [goal_type_to_byte(goal_disj)] ++
+		length_to_byte_list(Goals) ++
+		disj_to_byte_list(Goals, InstMap0, Info).
+goal_expr_to_byte_list(not(Goal), _GoalInfo, InstMap0, Info) = Bytes :-
+	Bytes = [goal_type_to_byte(goal_neg)] ++
+		goal_to_byte_list(Goal, InstMap0, Info).
+goal_expr_to_byte_list(if_then_else(_, Cond, Then, Else), _, InstMap0, Info)
+		= Bytes :-
+	Cond = _ - CondGoalInfo,
+	goal_info_get_instmap_delta(CondGoalInfo, InstMapDelta),
+	instmap__apply_instmap_delta(InstMap0, InstMapDelta, InstMap1),
+	Bytes = [goal_type_to_byte(goal_ite)] ++
+		goal_to_byte_list(Cond, InstMap0, Info) ++
+		goal_to_byte_list(Then, InstMap1, Info) ++
+		goal_to_byte_list(Else, InstMap0, Info).
+goal_expr_to_byte_list(unify(_, _, _, Uni, _), GoalInfo, InstMap0, Info)
+		= Bytes :-
+	AtomicBytes = atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info),
 	(
 		Uni = assign(Target, Source),
-		term__var_to_int(Target, TargetRep),
-		term__var_to_int(Source, SourceRep),
-		AtomicGoalRep = unify_assign_rep(TargetRep, SourceRep)
+		Bytes = [goal_type_to_byte(goal_assign)] ++
+			var_to_byte_list(Info, Target) ++
+			var_to_byte_list(Info, Source) ++
+			AtomicBytes
 	;
 		Uni = construct(Var, ConsId, Args, _, _, _, _),
-		term__var_to_int(Var, VarRep),
-		prog_rep__represent_cons_id(ConsId, ConsIdRep),
-		list__map(term__var_to_int, Args, ArgsRep),
-		AtomicGoalRep = unify_construct_rep(VarRep, ConsIdRep, ArgsRep)
+		Bytes = [goal_type_to_byte(goal_construct)] ++
+			var_to_byte_list(Info, Var) ++
+			cons_id_to_byte_list(ConsId) ++
+			vars_to_byte_list(Info, Args) ++
+			AtomicBytes
 	;
 		Uni = deconstruct(Var, ConsId, Args, _, _, _),
-		term__var_to_int(Var, VarRep),
-		prog_rep__represent_cons_id(ConsId, ConsIdRep),
-		list__map(term__var_to_int, Args, ArgsRep),
-		AtomicGoalRep = unify_deconstruct_rep(VarRep, ConsIdRep,
-			ArgsRep)
+		Bytes = [goal_type_to_byte(goal_deconstruct)] ++
+			var_to_byte_list(Info, Var) ++
+			cons_id_to_byte_list(ConsId) ++
+			vars_to_byte_list(Info, Args) ++
+			AtomicBytes
 	;
 		Uni = simple_test(Var1, Var2),
-		term__var_to_int(Var1, Var1Rep),
-		term__var_to_int(Var2, Var2Rep),
-		AtomicGoalRep = unify_simple_test_rep(Var1Rep, Var2Rep)
+		Bytes = [goal_type_to_byte(goal_simple_test)] ++
+			var_to_byte_list(Info, Var1) ++
+			var_to_byte_list(Info, Var2) ++
+			AtomicBytes
 	;
 		Uni = complicated_unify(_, _, _),
-		error("prog_rep__represent_goal_expr: complicated_unify")
-	),
-	prog_rep__represent_atomic_goal(GoalInfo, InstMap0, Info,
-		DetismRep, FilenameRep, LinenoRep, ChangedVarsRep),
-	Rep = atomic_goal_rep(DetismRep, FilenameRep, LinenoRep, ChangedVarsRep,
-		AtomicGoalRep).
-prog_rep__represent_goal_expr(conj(Goals), _, InstMap0, Info, Rep) :-
-	prog_rep__represent_conj(Goals, InstMap0, Info, Reps),
-	Rep = conj_rep(Reps).
-prog_rep__represent_goal_expr(par_conj(_), _, _, _, _) :-
-	error("Sorry, not yet implemented:\n\
-	parallel conjunctions and declarative debugging").
-prog_rep__represent_goal_expr(disj(Goals), _, InstMap0, Info, Rep) :-
-	prog_rep__represent_disj(Goals, InstMap0, Info, DisjReps),
-	Rep = disj_rep(DisjReps).
-prog_rep__represent_goal_expr(not(Goal), _GoalInfo, InstMap0, Info, Rep)
-		:-
-	prog_rep__represent_goal(Goal, InstMap0, Info, InnerRep),
-	Rep = negation_rep(InnerRep).
-prog_rep__represent_goal_expr(if_then_else(_, Cond, Then, Else),
-		_, InstMap0, Info, Rep) :-
-	prog_rep__represent_goal(Cond, InstMap0, Info, CondRep),
-	Cond = _ - CondGoalInfo,
-	goal_info_get_instmap_delta(CondGoalInfo, InstMapDelta),
-	instmap__apply_instmap_delta(InstMap0, InstMapDelta, InstMap1),
-	prog_rep__represent_goal(Then, InstMap1, Info, ThenRep),
-	prog_rep__represent_goal(Else, InstMap0, Info, ElseRep),
-	Rep = ite_rep(CondRep, ThenRep, ElseRep).
-prog_rep__represent_goal_expr(switch(_, _, Cases), _,
-		InstMap0, Info, Rep) :-
-	prog_rep__represent_cases(Cases, InstMap0, Info, CaseReps),
-	Rep = switch_rep(CaseReps).
-prog_rep__represent_goal_expr(scope(_, Goal), GoalInfo, InstMap0, Info, Rep) :-
-	prog_rep__represent_goal(Goal, InstMap0, Info, InnerRep),
+		error("goal_expr_to_byte_list: complicated_unify")
+	).
+goal_expr_to_byte_list(switch(_, _, Cases), _, InstMap0, Info) = Bytes :-
+	Bytes = [goal_type_to_byte(goal_switch)] ++
+		length_to_byte_list(Cases) ++
+		cases_to_byte_list(Cases, InstMap0, Info).
+goal_expr_to_byte_list(scope(_, Goal), GoalInfo, InstMap0, Info) = Bytes :-
 	Goal = _ - InnerGoalInfo,
 	goal_info_get_determinism(GoalInfo, OuterDetism),
 	goal_info_get_determinism(InnerGoalInfo, InnerDetism),
 	( InnerDetism = OuterDetism ->
-		MaybeCut = no_cut
+		MaybeCut = 0
 	;
-		MaybeCut = cut
+		MaybeCut = 1
 	),
-	Rep = scope_rep(InnerRep, MaybeCut).
-prog_rep__represent_goal_expr(generic_call(GenericCall, Args, _, _),
-		GoalInfo, InstMap0, Info, Rep) :-
-	list__map(term__var_to_int, Args, ArgsRep),
+	Bytes = [goal_type_to_byte(goal_scope)] ++
+		[MaybeCut] ++
+		goal_to_byte_list(Goal, InstMap0, Info).
+goal_expr_to_byte_list(generic_call(GenericCall, Args, _, _),
+		GoalInfo, InstMap0, Info) = Bytes :-
+	AtomicBytes = atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info),
 	(
 		GenericCall = higher_order(PredVar, _, _, _),
-		term__var_to_int(PredVar, PredVarRep),
-		AtomicGoalRep = higher_order_call_rep(PredVarRep, ArgsRep)
+		Bytes = [goal_type_to_byte(goal_ho_call)] ++
+			var_to_byte_list(Info, PredVar) ++
+			vars_to_byte_list(Info, Args) ++
+			AtomicBytes
 	;
 		GenericCall = class_method(Var, MethodNum, _, _),
-		term__var_to_int(Var, VarRep),
-		AtomicGoalRep = method_call_rep(VarRep, MethodNum, ArgsRep)
+		Bytes = [goal_type_to_byte(goal_method_call)] ++
+			var_to_byte_list(Info, Var) ++
+			method_num_to_byte_list(MethodNum) ++
+			vars_to_byte_list(Info, Args) ++
+			AtomicBytes
 	;
 		GenericCall = unsafe_cast,
-		( ArgsRep = [InputArgRep, OutputArgRep] ->
-			AtomicGoalRep = unsafe_cast_rep(OutputArgRep,
-				InputArgRep)
+		( Args = [InputArg, OutputArg] ->
+			Bytes = [goal_type_to_byte(goal_unsafe_cast)] ++
+				var_to_byte_list(Info, OutputArg) ++
+				var_to_byte_list(Info, InputArg) ++
+				AtomicBytes
 		;
-			error("represent_goal_expr: unsafe_cast arity != 2")
+			error("goal_expr_to_byte_list: unsafe_cast arity != 2")
 		)
 	;
 		GenericCall = aditi_builtin(_, _),
 		error("Sorry, not yet implemented\n\
 		Aditi and declarative debugging")
-	),
-	prog_rep__represent_atomic_goal(GoalInfo, InstMap0, Info,
-		DetismRep, FilenameRep, LinenoRep, ChangedVarsRep),
-	Rep = atomic_goal_rep(DetismRep, FilenameRep, LinenoRep,
-		ChangedVarsRep, AtomicGoalRep).
-prog_rep__represent_goal_expr(call(PredId, _, Args, Builtin, _, _),
-		GoalInfo, InstMap0, Info, Rep) :-
+	).
+goal_expr_to_byte_list(call(PredId, _, Args, Builtin, _, _),
+		GoalInfo, InstMap0, Info) = Bytes :-
+	AtomicBytes = atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info),
 	module_info_pred_info(Info ^ module_info, PredId, PredInfo),
 	ModuleSymName = pred_info_module(PredInfo),
 	mdbcomp__prim_data__sym_name_to_string(ModuleSymName, ModuleName),
 	PredName = pred_info_name(PredInfo),
-	list__map(term__var_to_int, Args, ArgsRep),
-	(
-		Builtin = not_builtin
-	->
-		AtomicGoalRep = plain_call_rep(ModuleName, PredName, ArgsRep)
+	( Builtin = not_builtin ->
+		Bytes = [goal_type_to_byte(goal_plain_call)] ++
+			string_to_byte_list(ModuleName) ++
+			string_to_byte_list(PredName) ++
+			vars_to_byte_list(Info, Args) ++
+			AtomicBytes
 	;
-		AtomicGoalRep = builtin_call_rep(ModuleName, PredName, 
-			ArgsRep)
-	),
-	prog_rep__represent_atomic_goal(GoalInfo, InstMap0, Info,
-		DetismRep, FilenameRep, LinenoRep, ChangedVarsRep),
-	Rep = atomic_goal_rep(DetismRep, FilenameRep, LinenoRep,
-		ChangedVarsRep, AtomicGoalRep).
-prog_rep__represent_goal_expr(foreign_proc(_, _PredId, _, Args, _, _),
-		GoalInfo, InstMap0, Info, Rep) :-
+		Bytes = [goal_type_to_byte(goal_builtin_call)] ++
+			string_to_byte_list(ModuleName) ++
+			string_to_byte_list(PredName) ++
+			vars_to_byte_list(Info, Args) ++
+			AtomicBytes
+	).
+goal_expr_to_byte_list(foreign_proc(_, _PredId, _, Args, _, _),
+		GoalInfo, InstMap0, Info) = Bytes :-
 	ArgVars = list__map(foreign_arg_var, Args),
-	list__map(term__var_to_int, ArgVars, ArgsRep),
-	AtomicGoalRep = pragma_foreign_code_rep(ArgsRep),
-	prog_rep__represent_atomic_goal(GoalInfo, InstMap0, Info,
-		DetismRep, FilenameRep, LinenoRep, ChangedVarsRep),
-	Rep = atomic_goal_rep(DetismRep, FilenameRep, LinenoRep,
-		ChangedVarsRep, AtomicGoalRep).
-prog_rep__represent_goal_expr(shorthand(_), _, _, _, _) :-
+	Bytes = [goal_type_to_byte(goal_foreign)] ++
+		vars_to_byte_list(Info, ArgVars) ++
+		atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info).
+goal_expr_to_byte_list(shorthand(_), _, _, _) = _ :-
 	% these should have been expanded out by now
-	error("prog_rep__represent_goal: unexpected shorthand").
+	error("goal_expr_to_byte_list: unexpected shorthand").
 
 %---------------------------------------------------------------------------%
 
-:- pred prog_rep__represent_conj(hlds_goals::in, instmap::in,
-	prog_rep__info::in, list(goal_rep)::out) is det.
+:- func atomic_goal_info_to_byte_list(hlds_goal_info, instmap, prog_rep__info)
+	= list(int).
 
-prog_rep__represent_conj([], _, _, []).
-prog_rep__represent_conj([Goal | Goals], InstMap0, Info, [Rep | Reps]) :-
-	prog_rep__represent_goal(Goal, InstMap0, Info, Rep),
+atomic_goal_info_to_byte_list(GoalInfo, InstMap0, Info) = Bytes :-
+	goal_info_get_determinism(GoalInfo, Detism),
+	goal_info_get_context(GoalInfo, Context),
+	term__context_file(Context, FileName0),
+	( FileName0 = Info ^ filename ->
+		FileName = ""
+	;
+		FileName = FileName0
+	),
+	term__context_line(Context, LineNo),
+	goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
+	instmap__apply_instmap_delta(InstMap0, InstMapDelta, InstMap),
+	instmap_changed_vars(InstMap0, InstMap, Info ^ vartypes,
+		Info ^ module_info, ChangedVars),
+	set__to_sorted_list(ChangedVars, ChangedVarList),
+	Bytes = [represent_determinism(Detism)] ++
+		string_to_byte_list(FileName) ++
+		lineno_to_byte_list(LineNo) ++
+		vars_to_byte_list(Info, ChangedVarList).
+
+:- func cons_id_to_byte_list(cons_id) = list(int).
+
+cons_id_to_byte_list(SymName) =
+	string_to_byte_list(cons_id_to_string(SymName)).
+
+:- func cons_id_to_string(cons_id) = string.
+
+cons_id_to_string(cons(SymName, _)) =
+	prog_rep__sym_name_to_string(SymName).
+cons_id_to_string(int_const(Int)) =
+	string__int_to_string(Int).
+cons_id_to_string(float_const(Float)) =
+	string__float_to_string(Float).
+cons_id_to_string(string_const(String)) =
+	string__append_list(["""", String, """"]).
+cons_id_to_string(pred_const(_, _)) = "$pred_const".
+cons_id_to_string(type_ctor_info_const(_, _, _)) =
+	"$type_ctor_info_const".
+cons_id_to_string(base_typeclass_info_const(_, _, _, _)) =
+	"$base_typeclass_info_const".
+cons_id_to_string(type_info_cell_constructor(_)) =
+	"$type_info_cell_constructor".
+cons_id_to_string(typeclass_info_cell_constructor) =
+	"$typeclass_info_cell_constructor".
+cons_id_to_string(tabling_pointer_const(_)) =
+	"$tabling_pointer_const".
+cons_id_to_string(deep_profiling_proc_layout(_)) =
+	"$deep_profiling_procedure_data".
+cons_id_to_string(table_io_decl(_)) =
+	"$table_io_decl".
+
+:- func sym_name_to_byte_list(sym_name) = list(int).
+
+sym_name_to_byte_list(SymName) =
+	string_to_byte_list(prog_rep__sym_name_to_string(SymName)).
+
+:- func sym_name_to_string(sym_name) = string.
+
+sym_name_to_string(unqualified(String)) = String.
+sym_name_to_string(qualified(_, String)) = String.
+
+%---------------------------------------------------------------------------%
+
+:- func conj_to_byte_list(hlds_goals, instmap, prog_rep__info) = list(int).
+
+conj_to_byte_list([], _, _) = [].
+conj_to_byte_list([Goal | Goals], InstMap0, Info) = Bytes :-
+	GoalBytes = goal_to_byte_list(Goal, InstMap0, Info),
 	Goal = _ - GoalInfo,
 	goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
 	instmap__apply_instmap_delta(InstMap0, InstMapDelta, InstMap1),
-	prog_rep__represent_conj(Goals, InstMap1, Info, Reps).
+	GoalsBytes = conj_to_byte_list(Goals, InstMap1, Info),
+	Bytes = GoalBytes ++ GoalsBytes.
+
+%---------------------------------------------------------------------------%
+
+:- func disj_to_byte_list(hlds_goals, instmap, prog_rep__info) = list(int).
+
+disj_to_byte_list([], _, _) = [].
+disj_to_byte_list([Goal | Goals], InstMap0, Info) = Bytes :-
+	GoalBytes = goal_to_byte_list(Goal, InstMap0, Info),
+	GoalsBytes = disj_to_byte_list(Goals, InstMap0, Info),
+	Bytes = GoalBytes ++ GoalsBytes.
 
 %---------------------------------------------------------------------------%
 
-:- pred prog_rep__represent_disj(hlds_goals::in, instmap::in,
-	prog_rep__info::in, list(goal_rep)::out) is det.
+:- func cases_to_byte_list(list(case), instmap, prog_rep__info) = list(int).
 
-prog_rep__represent_disj([], _, _, []).
-prog_rep__represent_disj([Goal | Goals], InstMap0, Info, [Rep | Reps]) :-
-	prog_rep__represent_goal(Goal, InstMap0, Info, Rep),
-	prog_rep__represent_disj(Goals, InstMap0, Info, Reps).
+cases_to_byte_list([], _, _) = [].
+cases_to_byte_list([case(_ConsId, Goal) | Cases], InstMap0, Info) = Bytes :-
+	GoalBytes = goal_to_byte_list(Goal, InstMap0, Info),
+	GoalsBytes = cases_to_byte_list(Cases, InstMap0, Info),
+	% XXX
+	% Bytes = cons_id_and_arity_to_byte_list(ConsId)
+	%	++ GoalBytes ++ GoalsBytes.
+	Bytes = GoalBytes ++ GoalsBytes.
 
 %---------------------------------------------------------------------------%
 
-:- pred prog_rep__represent_cases(list(case)::in, instmap::in,
-	prog_rep__info::in, list(goal_rep)::out) is det.
+% The operations to convert primitive constructs to bytecode.
+%
+% We use the operations defined in bytecode_data. Each of the functions below
+% stands for a given primitive construct. If we need to expand the number of
+% bytes we use to represent one of these, it should be sufficient to change
+% the number of bits here and in mdbcomp/program_representation.m.
+%
+% Warning: the predicates we use from bytecode_data deal with signed integers,
+% but we here use them to represent unsigned quantities. This effectively
+% halves their range.
+
+:- func string_to_byte_list(string) = list(int).
+
+string_to_byte_list(String) = Bytes :-
+	string_to_byte_list(String, Bytes).
+
+:- func vars_to_byte_list(prog_rep__info, list(prog_var)) = list(int).
+
+vars_to_byte_list(Info, Vars) =
+	length_to_byte_list(Vars) ++
+	list__condense(list__map(var_to_byte_list(Info), Vars)).
+
+:- func var_to_byte_list(prog_rep__info, prog_var) = list(int).
+
+var_to_byte_list(Info, Var) = Bytes :-
+	map__lookup(Info ^ var_num_map, Var, VarNum - _),
+	short_to_byte_list(VarNum, Bytes).
+
+:- func length_to_byte_list(list(T)) = list(int).
+
+length_to_byte_list(List) = Bytes :-
+	short_to_byte_list(list__length(List), Bytes).
+
+:- func lineno_to_byte_list(int) = list(int).
+
+lineno_to_byte_list(VarNum) = Bytes :-
+	short_to_byte_list(VarNum, Bytes).
+
+:- func method_num_to_byte_list(int) = list(int).
 
-prog_rep__represent_cases([], _, _, []).
-prog_rep__represent_cases([case(_, Goal) | Cases], InstMap0, Info,
-		[Rep | Reps]) :-
-	prog_rep__represent_goal(Goal, InstMap0, Info, Rep),
-	prog_rep__represent_cases(Cases, InstMap0, Info, Reps).
+method_num_to_byte_list(VarNum) = Bytes :-
+	short_to_byte_list(VarNum, Bytes).
 
 %---------------------------------------------------------------------------%
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.99
diff -u -b -r1.99 stack_layout.m
--- compiler/stack_layout.m	22 Mar 2005 06:40:25 -0000	1.99
+++ compiler/stack_layout.m	29 Mar 2005 03:34:35 -0000
@@ -76,7 +76,6 @@
 :- import_module ll_backend__ll_pseudo_type_info.
 :- import_module ll_backend__llds_out.
 :- import_module ll_backend__prog_rep.
-:- import_module ll_backend__static_term.
 :- import_module ll_backend__trace.
 :- import_module parse_tree__prog_out.
 :- import_module parse_tree__prog_util.
@@ -576,17 +575,11 @@
 	ModuleInfo = !.Info ^ module_info,
 	(
 		MaybeGoal = no,
-		MaybeProcRepRval = no
+		ProcBytes = []
 	;
 		MaybeGoal = yes(Goal),
-		ProcRep = prog_rep__represent_proc(HeadVars, Goal, InstMap,
-			VarTypes, VarNumMap, ModuleInfo),
-		type_to_univ(ProcRep, ProcRepUniv),
-		StaticCellInfo0 = !.Info ^ static_cell_info,
-		static_term__term_to_rval(ProcRepUniv, ProcRepRval,
-			StaticCellInfo0, StaticCellInfo),
-		MaybeProcRepRval = yes(ProcRepRval),
-		!:Info = !.Info ^ static_cell_info := StaticCellInfo
+		ProcBytes = prog_rep__represent_proc(HeadVars,
+			Goal, InstMap, VarTypes, VarNumMap, ModuleInfo)
 	),
 	(
 		MaybeCallLabel = yes(CallLabelPrime),
@@ -622,7 +615,7 @@
 	),
 	encode_exec_trace_flags(ModuleInfo, HeadVars, ArgModes, VarTypes,
 		0, Flags),
-	ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcRepRval,
+	ExecTrace = proc_layout_exec_trace(CallLabelLayout, ProcBytes,
 		MaybeTableName, HeadVarNumVector, VarNameVector,
 		MaxVarNum, MaxTraceReg, MaybeFromFullSlot, MaybeIoSeqSlot,
 		MaybeTrailSlots, MaybeMaxfrSlot, EvalMethod,
@@ -633,8 +626,8 @@
 
 encode_exec_trace_flags(ModuleInfo, HeadVars, ArgModes, VarTypes, !Flags) :-
 	(
-		proc_info_has_io_state_pair_from_details(ModuleInfo, HeadVars, ArgModes,
-			VarTypes, _, _)
+		proc_info_has_io_state_pair_from_details(ModuleInfo, HeadVars,
+			ArgModes, VarTypes, _, _)
 	->
 		!:Flags = !.Flags + 1
 	;
Index: compiler/static_term.m
===================================================================
RCS file: compiler/static_term.m
diff -N compiler/static_term.m
--- compiler/static_term.m	22 Mar 2005 06:40:25 -0000	1.8
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,89 +0,0 @@
-%---------------------------------------------------------------------------%
-% Copyright (C) 2000,2002-2003, 2005 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.
-%---------------------------------------------------------------------------%
-%
-% File: static_term.m.
-% Author: zs.
-%
-% This module handles the conversion of Mercury terms in the compiler
-% into rvals we can give to llds_out.m in order to make those terms available
-% at runtime in the program being compiled.
-%
-% XXX At the moment, the constructed term never has term_size slots.
-%
-%---------------------------------------------------------------------------%
-
-:- module ll_backend__static_term.
-
-:- interface.
-
-:- import_module ll_backend__global_data.
-:- import_module ll_backend__llds.
-
-:- import_module std_util.
-
-:- pred static_term__term_to_rval(univ::in, rval::out,
-	static_cell_info::in, static_cell_info::out) is det.
-
-%---------------------------------------------------------------------------%
-
-:- implementation.
-
-:- import_module backend_libs__builtin_ops.
-
-:- import_module deconstruct.
-:- import_module list.
-:- import_module require.
-
-static_term__term_to_rval(Univ, Rval, !StaticCellInfo) :-
-	( deconstruct__get_functor_info(Univ, FunctorInfo) ->
-		static_term__functor_info_to_rval(FunctorInfo, Rval,
-			!StaticCellInfo)
-	;
-		error("static_term__term_to_rval: unexpected kind of term")
-	).
-
-:- pred static_term__functor_info_to_rval(functor_tag_info::in,
-	rval::out, static_cell_info::in, static_cell_info::out) is det.
-
-static_term__functor_info_to_rval(FunctorInfo, Rval, !StaticCellInfo) :-
-	(
-		FunctorInfo = functor_integer(Int),
-		Rval = const(int_const(Int))
-	;
-		FunctorInfo = functor_float(Float),
-		Rval = const(float_const(Float))
-	;
-		FunctorInfo = functor_string(String),
-		Rval = const(string_const(String))
-	;
-		FunctorInfo = functor_enum(Enum),
-		Rval = const(int_const(Enum))
-	;
-		FunctorInfo = functor_local(Ptag, Sectag),
-		Rval = mkword(Ptag,
-			unop(mkbody, const(int_const(Sectag))))
-	;
-		FunctorInfo = functor_remote(Ptag, Sectag, Args),
-		SectagRval = const(int_const(Sectag)),
-		list__map_foldl(static_term__term_to_rval, Args, ArgRvals,
-			!StaticCellInfo),
-		add_static_cell_natural_types([SectagRval | ArgRvals],
-			DataAddr, !StaticCellInfo),
-		Rval = mkword(Ptag, const(data_addr_const(DataAddr, no)))
-	;
-		FunctorInfo = functor_unshared(Ptag, Args),
-		list__map_foldl(static_term__term_to_rval, Args, ArgRvals,
-			!StaticCellInfo),
-		add_static_cell_natural_types(ArgRvals, DataAddr,
-			!StaticCellInfo),
-		Rval = mkword(Ptag, const(data_addr_const(DataAddr, no)))
-	;
-		FunctorInfo = functor_notag(Univ),
-		static_term__term_to_rval(Univ, Rval, !StaticCellInfo)
-	;
-		FunctorInfo = functor_equiv(Univ),
-		static_term__term_to_rval(Univ, Rval, !StaticCellInfo)
-	).
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
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/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.3
diff -u -b -r1.3 program_representation.m
--- mdbcomp/program_representation.m	24 Mar 2005 05:34:30 -0000	1.3
+++ mdbcomp/program_representation.m	28 Mar 2005 07:23:17 -0000
@@ -233,6 +233,44 @@
 	% Returns type_of(_ `with_type` goal_rep), for use in C code.
 :- func goal_rep_type = type_desc.
 
+	% Construct a representation of the interface determinism of a
+	% procedure. The code we have chosen is not sequential; instead
+	% it encodes the various properties of each determinism.
+	% This must match the encoding of MR_Determinism in
+	% mercury_stack_layout.h.
+	%
+	% The 8 bit is set iff the context is first_solution.
+	% The 4 bit is set iff the min number of solutions is more than zero.
+	% The 2 bit is set iff the max number of solutions is more than zero.
+	% The 1 bit is set iff the max number of solutions is more than one.
+:- func detism_rep(detism_rep) = int.
+
+:- pred determinism_representation(detism_rep, int).
+:- mode determinism_representation(in, out) is det.
+:- mode determinism_representation(out, in) is semidet.
+
+:- type bytecode_goal_type
+	--->	goal_conj
+	;	goal_disj
+	;	goal_switch
+	;	goal_ite
+	;	goal_neg
+	;	goal_scope
+	;	goal_construct
+	;	goal_deconstruct
+	;	goal_assign
+	;	goal_unsafe_cast
+	;	goal_simple_test
+	;	goal_foreign
+	;	goal_ho_call
+	;	goal_method_call
+	;	goal_plain_call
+	;	goal_builtin_call.
+
+:- func goal_type_to_byte(bytecode_goal_type) = int.
+
+:- func byte_to_goal_type(int) = bytecode_goal_type is semidet.
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -364,4 +402,46 @@
 string_from_path_step(later, "l").
 
 %-----------------------------------------------------------------------------%
+
+detism_rep(Detism) = Rep :-
+	determinism_representation(Detism, Rep).
+
+determinism_representation(det_rep, 6).
+determinism_representation(semidet_rep, 2).
+determinism_representation(nondet_rep, 3).
+determinism_representation(multidet_rep, 7).
+determinism_representation(erroneous_rep, 4).
+determinism_representation(failure_rep, 0).
+determinism_representation(cc_nondet_rep, 10).
+determinism_representation(cc_multidet_rep, 14).
+
+%-----------------------------------------------------------------------------%
+
+goal_type_to_byte(Type) = TypeInt :-
+	goal_type_byte(TypeInt, Type).
+
+byte_to_goal_type(TypeInt) = Type :-
+	goal_type_byte(TypeInt, Type).
+
+:- pred goal_type_byte(int, bytecode_goal_type).
+:- mode goal_type_byte(in, out) is semidet.
+:- mode goal_type_byte(out, in) is det.
+
+goal_type_byte(1, goal_conj).
+goal_type_byte(2, goal_disj).
+goal_type_byte(3, goal_switch).
+goal_type_byte(4, goal_ite).
+goal_type_byte(5, goal_neg).
+goal_type_byte(6, goal_scope).
+goal_type_byte(7, goal_construct).
+goal_type_byte(8, goal_deconstruct).
+goal_type_byte(9, goal_assign).
+goal_type_byte(10, goal_unsafe_cast).
+goal_type_byte(11, goal_simple_test).
+goal_type_byte(12, goal_foreign).
+goal_type_byte(13, goal_ho_call).
+goal_type_byte(14, goal_method_call).
+goal_type_byte(15, goal_plain_call).
+goal_type_byte(16, goal_builtin_call).
+
 %-----------------------------------------------------------------------------%
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.58
diff -u -b -r1.58 mercury_grade.h
--- runtime/mercury_grade.h	15 Feb 2005 04:45:03 -0000	1.58
+++ runtime/mercury_grade.h	30 Mar 2005 00:19:09 -0000
@@ -60,7 +60,7 @@
 */
 
 #define MR_GRADE_PART_0	v13_
-#define MR_GRADE_EXEC_TRACE_VERSION_NO	3
+#define MR_GRADE_EXEC_TRACE_VERSION_NO	4
 #define MR_GRADE_DEEP_PROF_VERSION_NO	1
 
 #ifdef MR_HIGHLEVEL_CODE
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.87
diff -u -b -r1.87 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	19 Nov 2004 05:46:13 -0000	1.87
+++ runtime/mercury_stack_layout.h	28 Mar 2005 12:11:11 -0000
@@ -51,7 +51,7 @@
 ** that we do not set the 1 bit unless we also set the 2 bit.
 **
 ** NOTE: this must match the encoding specified by represent_determinism/1
-** in compiler/code_model.m.
+** in mdbcomp/program_representation.m.
 */
 
 typedef	MR_int_least16_t	MR_Determinism;
@@ -697,12 +697,10 @@
 ** containing the procedure. This allows the debugger access to the string table
 ** stored there, as well the table associating source-file contexts with labels.
 **
-** The proc_rep field contains a representation of the body of the procedure
-** as a Mercury term of type proc_rep, defined in program_representation.m.
-** Note that the type of this field is `MR_Word *', not `MR_Word',
-** for the same reasons that MR_mkword() has type `MR_Word *' rather
-** than `MR_Word' (see the comment in runtime/mercury_tags.h).
-** It will be a null pointer if no such representation is available.
+** The body_bytes field contains a pointer to a list of bytecodes that
+** represents the body of the procedure. It will be a null pointer if no
+** representation is available. If it is not null pointer, then it should
+** be interpreted by read_proc_rep in browser/declarative_execution.m.
 **
 ** The used_var_names field points to an array that contains offsets
 ** into the string table, with the offset at index i-1 giving the name of
@@ -796,7 +794,7 @@
 typedef	struct MR_Exec_Trace_Struct {
 	const MR_Label_Layout	*MR_exec_call_label;
 	const MR_Module_Layout	*MR_exec_module_layout;
-	MR_Word			*MR_exec_proc_rep;
+	const MR_uint_least8_t	*MR_exec_body_bytes;
 	MR_TrieNode		MR_exec_tabling_pointer;
 	MR_Table_Info		MR_exec_table_info;
 	const MR_uint_least16_t	*MR_exec_head_var_nums;
@@ -812,7 +810,6 @@
 	MR_int_least8_t		MR_exec_maybe_call_table;
 	MR_TraceLevelInt	MR_exec_trace_level_CAST_ME;
 	MR_uint_least8_t	MR_exec_flags;
-	const MR_Label_Layout	**MR_exec_label_layout;
 } MR_Exec_Trace;
 
 #define MR_compute_max_mr_num(max_mr_num, layout)			\
@@ -918,7 +915,7 @@
 
 #define	MR_sle_call_label	MR_sle_exec_trace->MR_exec_call_label
 #define	MR_sle_module_layout	MR_sle_exec_trace->MR_exec_module_layout
-#define	MR_sle_proc_rep		MR_sle_exec_trace->MR_exec_proc_rep
+#define	MR_sle_body_bytes       MR_sle_exec_trace->MR_exec_body_bytes
 #define	MR_sle_tabling_pointer	MR_sle_exec_trace->MR_exec_tabling_pointer
 #define	MR_sle_table_info	MR_sle_exec_trace->MR_exec_table_info
 #define	MR_sle_head_var_nums	MR_sle_exec_trace->MR_exec_head_var_nums
Index: runtime/mercury_trace_base.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_trace_base.c,v
retrieving revision 1.64
diff -u -b -r1.64 mercury_trace_base.c
--- runtime/mercury_trace_base.c	24 Mar 2005 01:58:05 -0000	1.64
+++ runtime/mercury_trace_base.c	28 Mar 2005 10:34:13 -0000
@@ -419,6 +419,7 @@
                 break;
         }
     }
+
     fputc('\'', fp);
 }
 
@@ -812,6 +813,119 @@
 }
 
 #endif  /* MR_TRACE_HISTOGRAM */
+
+/*
+** We record information about procedure representations in a hash table
+** that is indexed by the proc layout address.
+**
+** This table is used by the declarative debugger. Since the declarative
+** debugger can be required any grade, we always include this table, but
+** it is initialized (and the bulk of its memory allocated) only if the
+** declarative debugger is in fact invoked.
+*/
+
+#define PROC_REP_TABLE_SIZE (1 << 16)   /* 64k */
+
+typedef struct {
+    const MR_Proc_Layout    *plr_layout;
+    MR_Word                 plr_rep;
+} MR_Proc_Layout_Rep;
+
+static  void                MR_do_init_proc_rep_table(void);
+static  const void          *proc_layout_rep_key(const void *proc_layout);
+static  int                 hash_proc_layout_addr(const void *addr);
+static  MR_bool             equal_proc_layouts(const void *addr1,
+                                const void *addr2);
+
+static  MR_Hash_Table       proc_rep_table = {PROC_REP_TABLE_SIZE, NULL,
+                                proc_layout_rep_key, hash_proc_layout_addr,
+                                equal_proc_layouts};
+
+static void
+MR_do_init_proc_rep_table(void)
+{
+    static  MR_bool done = MR_FALSE;
+
+    if (!done) {
+        MR_init_hash_table(proc_rep_table);
+        done = MR_TRUE;
+    }
+}
+
+void
+MR_insert_proc_rep(const MR_Proc_Layout *proc_layout, MR_Word proc_rep)
+{
+    MR_Proc_Layout_Rep  *layout_rep;
+
+    MR_do_init_proc_rep_table();
+
+    layout_rep = MR_GC_NEW(MR_Proc_Layout_Rep);
+    layout_rep->plr_layout = proc_layout;
+    layout_rep->plr_rep = proc_rep;
+
+    (void) MR_insert_hash_table(proc_rep_table, layout_rep);
+
+#ifdef  MR_DEBUG_PROC_REP
+    if (MR_progdebug) {
+        printf("insert: layout %p, rep %x, pair %p\n",
+            proc_layout, proc_rep, layout_rep);
+    }
+#endif
+}
+
+MR_Word
+MR_lookup_proc_rep(const MR_Proc_Layout *proc_layout)
+{
+    const MR_Proc_Layout_Rep  *layout_rep;
+
+    MR_do_init_proc_rep_table();
+
+    layout_rep = MR_lookup_hash_table(proc_rep_table, proc_layout);
+    if (layout_rep == NULL) {
+#ifdef  MR_DEBUG_PROC_REP
+        if (MR_progdebug) {
+            printf("search for layout %p: not found\n", proc_layout);
+        }
+#endif
+
+        return 0;
+    }
+
+#ifdef  MR_DEBUG_PROC_REP
+    if (MR_progdebug) {
+        printf("search for layout %p: found pair %p, rep %x\n",
+            proc_layout, layout_rep, layout_rep->plr_rep);
+    }
+#endif
+
+    return layout_rep->plr_rep;
+}
+
+static const void *
+proc_layout_rep_key(const void *pair)
+{
+    MR_Proc_Layout_Rep  *proc_layout_rep;
+
+    proc_layout_rep = (MR_Proc_Layout_Rep *) pair;
+    if (proc_layout_rep == NULL) {
+        return NULL;
+    } else {
+        return (const void *) proc_layout_rep->plr_layout;
+    }
+}
+
+static int
+hash_proc_layout_addr(const void *addr)
+{
+    return (((MR_Unsigned) addr) >> 5) % PROC_REP_TABLE_SIZE;
+}
+
+static MR_bool
+equal_proc_layouts(const void *addr1, const void *addr2)
+{
+    return ((const MR_Proc_Layout *) addr1) ==
+        ((const MR_Proc_Layout *) addr2);
+}
 
 #ifndef MR_HIGHLEVEL_CODE
 
Index: runtime/mercury_trace_base.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_trace_base.h,v
retrieving revision 1.45
diff -u -b -r1.45 mercury_trace_base.h
--- runtime/mercury_trace_base.h	24 Mar 2005 01:58:05 -0000	1.45
+++ runtime/mercury_trace_base.h	28 Mar 2005 09:20:33 -0000
@@ -472,6 +472,25 @@
 
 #endif	/* MR_TRACE_HISTOGRAM */
 
+/*
+** These two functions work on a table that maps proc layout structures
+** to the Mercury terms representing the bodies of those procedures.
+** The Mercury term representation of the procedure body is constructed
+** on demand from the bytecode in the procedure layout structure, but since
+** this construction process allocates a significant amount of memory and
+** takes a nontrivial amount of time, we cache the results in this table.
+**
+** MR_insert_proc_rep adds the result of a conversion to the cache.
+**
+** MR_lookup_proc_rep checks whether a previous call to MR_lookup_proc_rep
+** has already cached the procedure body representation of a given procedure;
+** a zero return value means that the answer is "no".
+*/
+
+extern	void	MR_insert_proc_rep(const MR_Proc_Layout *proc_layout,
+		MR_Word proc_rep);
+extern	MR_Word MR_lookup_proc_rep(const MR_Proc_Layout *proc_layout);
+
 #ifndef	MR_HIGHLEVEL_CODE
 
 MR_declare_entry(MR_do_trace_redo_fail_shallow);
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/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/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace_declarative.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_declarative.c,v
retrieving revision 1.82
diff -u -b -r1.82 mercury_trace_declarative.c
--- trace/mercury_trace_declarative.c	12 Mar 2005 04:46:33 -0000	1.82
+++ trace/mercury_trace_declarative.c	28 Mar 2005 08:10:27 -0000
@@ -638,7 +638,6 @@
 	const MR_Label_Layout		*event_label_layout;
 	const MR_Proc_Layout		*event_proc_layout;
 	const MR_Label_Layout		*return_label_layout;
-	MR_Word				proc_rep;
 	MR_Stack_Walk_Step_Result	result;
 	MR_ConstString			problem;
 	MR_String			goal_path;
@@ -654,7 +653,6 @@
 
 	event_label_layout = event_info->MR_event_sll;
 	event_proc_layout = event_label_layout->MR_sll_entry;
-	proc_rep = (MR_Word) event_proc_layout->MR_sle_proc_rep;
 	atom_args = MR_decl_make_atom_args(event_label_layout, 
 		event_info->MR_saved_regs, MR_PORT_CALL);
 	base_sp = MR_saved_sp(event_info->MR_saved_regs);
@@ -679,25 +677,13 @@
 	}
 
 	MR_TRACE_CALL_MERCURY(
-		if (proc_rep) {
 			node = (MR_Trace_Node)
-				MR_DD_construct_call_node_with_goal(
-					(MR_Word) prev, atom_args,
-					(MR_Word) event_info->MR_call_seqno,
-					(MR_Word) event_info->MR_event_number,
-					(MR_Word) at_depth_limit, proc_rep,
-					maybe_return_label, event_label_layout, 
-					MR_io_tabling_counter);
-		} else {
-			node = (MR_Trace_Node)
-				MR_DD_construct_call_node((MR_Word) prev, 
-					atom_args,
+			MR_DD_construct_call_node((MR_Word) prev, atom_args,
 					(MR_Word) event_info->MR_call_seqno,
 					(MR_Word) event_info->MR_event_number,
 					(MR_Word) at_depth_limit, 
 					maybe_return_label, event_label_layout,
 					MR_io_tabling_counter);
-		}
 	);
 
 	return node;
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.197
diff -u -b -r1.197 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	2 Mar 2005 01:20:23 -0000	1.197
+++ trace/mercury_trace_internal.c	28 Mar 2005 12:18:33 -0000
@@ -36,6 +36,7 @@
 
 #include "mdb.browse.mh"
 #include "mdb.browser_info.mh"
+#include "mdb.declarative_execution.mh"
 #include "mdbcomp.program_representation.mh"
 #include "mdb.dice.mh"
 
@@ -1382,15 +1383,19 @@
     MR_Browse_Caller_Type caller, MR_Browse_Format format)
 {
     const MR_Proc_Layout    *entry;
+    MR_Word                 rep;
 
     entry = event_info->MR_event_sll->MR_sll_entry;
-    if (entry->MR_sle_proc_rep == NULL) {
-        return "current procedure has no body info";
+
+    if (entry->MR_sle_body_bytes == NULL) {
+        return "current procedure has no body bytecodes";
     }
 
-    (*browser)(ML_proc_rep_type(), (MR_Word) entry->MR_sle_proc_rep,
-        caller, format);
+    MR_TRACE_CALL_MERCURY(
+        MR_DD_trace_read_rep(entry->MR_sle_body_bytes, &rep);
+    );
 
+    (*browser)(ML_proc_rep_type(), rep, caller, format);
     return (const char *) NULL;
 }
 
@@ -2444,14 +2449,19 @@
             }
         } else if (MR_streq(words[1], "proc_body")) {
             const MR_Proc_Layout    *entry;
+            MR_Word                 rep;
 
             entry = event_info->MR_event_sll->MR_sll_entry;
-            if (entry->MR_sle_proc_rep == NULL) {
-                problem = "current procedure has no body info";
+
+            if (entry->MR_sle_body_bytes == NULL) {
+                problem = "current procedure has no body bytecodes";
             } else {
+                MR_TRACE_CALL_MERCURY(
+                    MR_DD_trace_read_rep(entry->MR_sle_body_bytes, &rep);
+                );
+
                 browser_term = MR_type_value_to_browser_term(
-                    (MR_TypeInfo) ML_proc_rep_type(),
-                    (MR_Word) entry->MR_sle_proc_rep);
+                    (MR_TypeInfo) ML_proc_rep_type(), rep);
             }
         } else {
             MR_Var_Spec var_spec;
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:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list