[m-dev.] for review: --stack-trace-higher-order

Zoltan Somogyi zs at cs.mu.OZ.AU
Mon Nov 2 18:32:06 AEDT 1998


> runtime/mercury_ho_call.c:
> > -	int	type_arity;
> > -
> > -	type_arity = pop();
> > -	MR_succip = (Code *) pop();
> > +	MR_succip = (Code *) MR_stackvar(2);
> >  	save_registers();
> > -	r2 = virtual_reg(type_arity + 1);
> > +	r2 = virtual_reg(MR_stackvar(1) + 1);
> > +	decr_sp_pop_msg(2);
> 
> The use of the named variable `type_arity' is good
> documentation, so I think it should stay.

In the original source, although not the diff, the assignment of type_arity
to the stack slot is just a few lines up.

> > Index: runtime/mercury_stack_layout.h
> 
> There was no log message for the changes to this file.

There was, it was just the filename accidentally had a .c instead of a .h
ending.

> > +++ mercury_stack_trace.c	1998/11/01 04:25:09
> > @@ -194,7 +194,7 @@
> >  
> >  	label = MR_lookup_internal_by_addr(success);
> >  	if (label == NULL) {
> > -		*problem_ptr = "reached label with no stack trace info";
> > +		*problem_ptr = "reached unregistered label";
> >  		return STEP_ERROR_AFTER;
> >  	}
> >  
> 
> I think the original message will be easier for users to understand.
> What should users know about label registration?
> 
> You could perhaps make it "reached label for which stack trace information
> is not available".

Both the original and your suggested replacements are wrong. If the test
succeeds, then the label is not just missing stack trace info; the label
is not in the label table *at all*.

I replaced the message with "reached unknown label"

> Apart from that, it looks OK, but I haven't finished reviewing the
> changes to llds_out.m yet.

To make this easier, I append the rewritten portion, since it is much
easier to read than the diff.

Apart from that, I made all the other changes you asked for.

Zoltan.

-----------------------------------------------------------------------

:- pred output_c_module_init_list(module_name, list(c_module),
	set_bbbtree(label), io__state, io__state).
:- mode output_c_module_init_list(in, in, in, di, uo) is det.

output_c_module_init_list(ModuleName, Modules, StackLayoutLabels) -->
	{ divide_modules_on_init_status(Modules, StackLayoutLabels,
		AlwaysInitModules, MaybeInitModules) },
	{ list__chunk(AlwaysInitModules, 40, AlwaysInitModuleBunches) },
	{ list__chunk(MaybeInitModules, 40, MaybeInitModuleBunches) },
	globals__io_lookup_bool_option(split_c_files, SplitFiles),

	output_init_bunch_defs(AlwaysInitModuleBunches, ModuleName,
		"always", 0, SplitFiles),

	( { MaybeInitModuleBunches = [] } ->
		[]
	;
		io__write_string("#ifdef MR_MAY_NEED_INITIALIZATION\n\n"),
		output_init_bunch_defs(MaybeInitModuleBunches, ModuleName,
			"maybe", 0, SplitFiles),
		io__write_string("#endif\n\n")
	),

	io__write_string("void "),
	output_init_name(ModuleName),
	io__write_string("(void);"),
	io__write_string("/* suppress gcc -Wmissing-decls warning */\n"),
	io__write_string("void "),
	output_init_name(ModuleName),
	io__write_string("(void)\n"),
	io__write_string("{\n"),
	io__write_string("\tstatic bool done = FALSE;\n"),
	io__write_string("\tif (!done) {\n"),
	io__write_string("\t\tdone = TRUE;\n"),

	output_init_bunch_calls(AlwaysInitModuleBunches, ModuleName,
		"always", 0),

	( { MaybeInitModuleBunches = [] } ->
		[]
	;
		io__write_string("\n#ifdef MR_MAY_NEED_INITIALIZATION\n"),
		output_init_bunch_calls(MaybeInitModuleBunches, ModuleName,
			"maybe", 0),
		io__write_string("#endif\n\n")
	),

	output_c_data_init_list(Modules),
	io__write_string("\t}\n"),
	io__write_string("}\n\n"),
	io__write_string(
		"/* ensure everything is compiled with the same grade */\n"),
	io__write_string(
		"static const void *const MR_grade = &MR_GRADE_VAR;\n").

	% Divide_modules_on_init_status checks every module in its input list.
	% If the module does not have compiler-generated code in it, it
	% ignores the module. If it does, it will include the module in
	% one of its output lists. If the module defines a label that has
	% a stack layout structure, it will go into the always-init list,
	% otherwise it will go into the maybe-init list.

:- pred divide_modules_on_init_status(list(c_module), set_bbbtree(label),
	list(c_module), list(c_module)).
:- mode divide_modules_on_init_status(in, in, out, out) is det.

divide_modules_on_init_status([], _, [], []).
divide_modules_on_init_status([Module | Modules], StackLayoutLabels,
		AlwaysInit, MaybeInit) :-
	(
		Module = c_data(_, _, _, _, _),
		divide_modules_on_init_status(Modules, StackLayoutLabels,
			AlwaysInit, MaybeInit)
	;
		Module = c_export(_),
		divide_modules_on_init_status(Modules, StackLayoutLabels,
			AlwaysInit, MaybeInit)
	;
		Module = c_code(_, _),
		divide_modules_on_init_status(Modules, StackLayoutLabels,
			AlwaysInit, MaybeInit)
	;
		Module = c_module(_, Procedures),
		divide_modules_on_init_status(Modules, StackLayoutLabels,
			AlwaysInit1, MaybeInit1),
		( set_bbbtree__empty(StackLayoutLabels) ->
			% Checking whether the set is empty or not
			% allows us to avoid calling gather_c_module_labels.
			AlwaysInit = AlwaysInit1,
			MaybeInit = [Module | MaybeInit1]
		;
			gather_c_module_labels(Procedures, Labels),
			(
				list__member(Label, Labels),
				set_bbbtree__member(Label, StackLayoutLabels)
			->
				AlwaysInit = [Module | AlwaysInit1],
				MaybeInit = MaybeInit1
			;
				AlwaysInit = AlwaysInit1,
				MaybeInit = [Module | MaybeInit1]
			)
		)
	).

:- pred output_init_bunch_defs(list(list(c_module)), module_name, string, int,
	bool, io__state, io__state).
:- mode output_init_bunch_defs(in, in, in, in, in, di, uo) is det.

output_init_bunch_defs([], _, _, _, _) --> [].
output_init_bunch_defs([Bunch | Bunches], ModuleName, InitStatus, Seq,
		SplitFiles) -->
	io__write_string("static void "),
	output_bunch_name(ModuleName, InitStatus, Seq),
	io__write_string("(void)\n"),
	io__write_string("{\n"),
	output_init_bunch_def(Bunch, ModuleName, SplitFiles),
	io__write_string("}\n\n"),
	{ NextSeq is Seq + 1 },
	output_init_bunch_defs(Bunches, ModuleName, InitStatus, NextSeq,
		SplitFiles).

:- pred output_init_bunch_def(list(c_module), module_name, bool,
	io__state, io__state).
:- mode output_init_bunch_def(in, in, in, di, uo) is det.

output_init_bunch_def([], _, _) --> [].
output_init_bunch_def([Module | Modules], ModuleName, SplitFiles) -->
	( { Module = c_module(C_ModuleName, _) } ->
		( { SplitFiles = yes } ->
			io__write_string("\t{ extern ModuleFunc "),
			io__write_string(C_ModuleName),
			io__write_string(";\n"),
			io__write_string("\t  "),
			io__write_string(C_ModuleName),
			io__write_string("(); }\n")
		;
			io__write_string("\t"),
			io__write_string(C_ModuleName),
			io__write_string("();\n")
		),
		output_init_bunch_def(Modules, ModuleName, SplitFiles)
	;
		% divide_modules_on_init_status should have filtered out
		% whatever kind of module we just got.
		{ error("unexpected type of c_module in output_init_bunch") }
	).

:- pred output_init_bunch_calls(list(list(c_module)), module_name, string, int,
	io__state, io__state).
:- mode output_init_bunch_calls(in, in, in, in, di, uo) is det.

output_init_bunch_calls([], _, _, _) --> [].
output_init_bunch_calls([_ | Bunches], ModuleName, InitStatus, Seq) -->
	io__write_string("\t\t"),
	output_bunch_name(ModuleName, InitStatus, Seq),
	io__write_string("();\n"),
	{ NextSeq is Seq + 1 },
	output_init_bunch_calls(Bunches, ModuleName, InitStatus, NextSeq).



More information about the developers mailing list