[m-rev.] fix LLDS accurate GC bug
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Nov 13 03:15:43 AEDT 2003
Estimated hours taken: 4
Branches: main
Fix a bug with accurate GC. The mapping from code addresses to stack
layouts was not working properly, because GCC was reordering code within
C functions (LLDS modules) so that a label at end of the module did not
necessarily have the highest address. The solution is to put the end label
in a different C function, i.e. a new LLDS module.
runtime/mercury_goto.h:
Back out previous attempt to solve this problem, since it didn't work.
compiler/transform_llds.m:
If accurate GC is enabled, append a module containing a dummy end label
at the end of the module list.
Workspace: /home/jupiter/fjh/ws-jupiter/mercury
Index: compiler/transform_llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/transform_llds.m,v
retrieving revision 1.10
diff -u -d -r1.10 transform_llds.m
--- compiler/transform_llds.m 14 Mar 2003 08:10:12 -0000 1.10
+++ compiler/transform_llds.m 12 Nov 2003 16:03:40 -0000
@@ -16,6 +16,9 @@
% down to smaller computed gotos. This avoids a limitation in the lcc
% compiler.
%
+% If accurate GC is enabled, we also append a module containing an end label
+% to the list of comp_gen_c_modules.
+%
%-----------------------------------------------------------------------------%
:- module ll_backend__transform_llds.
@@ -32,6 +35,7 @@
:- implementation.
+:- import_module hlds__hlds_pred.
:- import_module backend_libs__builtin_ops.
:- import_module backend_libs__proc_label.
:- import_module libs__globals.
@@ -39,17 +43,10 @@
:- import_module ll_backend__opt_util.
:- import_module parse_tree__prog_data.
-:- import_module bool, int, list, require, std_util, counter.
+:- import_module bool, int, string, list, require, std_util, counter.
transform_llds(LLDS0, LLDS) -->
- globals__io_lookup_int_option(max_jump_table_size, Size),
- (
- { Size = 0 }
- ->
- { LLDS = LLDS0 }
- ;
- transform_c_file(LLDS0, LLDS)
- ).
+ transform_c_file(LLDS0, LLDS).
%-----------------------------------------------------------------------------%
@@ -58,7 +55,60 @@
transform_c_file(c_file(ModuleName, HeaderInfo, A, B, C, D, Modules0),
c_file(ModuleName, HeaderInfo, A, B, C, D, Modules)) -->
- transform_c_module_list(Modules0, Modules).
+ % split up large computed gotos
+ globals__io_lookup_int_option(max_jump_table_size, MaxJumpTableSize),
+ ( { MaxJumpTableSize = 0 } ->
+ { Modules1 = Modules0 }
+ ;
+ transform_c_module_list(Modules0, Modules1)
+ ),
+ % append an end label for accurate GC
+ globals__io_get_gc_method(GC),
+ { GC = accurate, Modules1 \= [] ->
+ list__last_det(Modules1, LastModule),
+ LastModule = comp_gen_c_module(LastModuleName, _),
+ Modules = Modules1 ++
+ [gen_end_label_module(ModuleName, LastModuleName)]
+ ;
+ Modules = Modules1
+ }.
+
+%
+% For LLDS native GC, we need to add a dummy comp_gen_c_module at the end of
+% the list. This dummy module contains only a single dummy procedure which
+% in turn contains only a single label, for which there is no stack layout
+% structure. The point of this is to ensure that the address of this label
+% gets inserted into the entry table, so that we know where the preceding
+% procedure finishes when mapping from instruction pointer values to stack
+% layout entries.
+%
+% Without this, we might think that the following C function was
+% actually part of the last Mercury procedure in the preceding module,
+% and then incorrectly use the stack layout of the Mercury procedure
+% if we happened to get a heap overflow signal (SIGSEGV) while in that
+% C function.
+%
+% Note that it is not sufficient to generate a label at end of the module,
+% because GCC (e.g. GCC 3.2) sometimes reorders code within a single C
+% function, so that a label declared at the end of the module might not
+% be actually have highest address. So we generate a new module (which
+% corresponds to a new C function). XXX Hopefully GCC won't mess with the
+% order of the functions...
+%
+:- func gen_end_label_module(module_name, string) = comp_gen_c_module.
+gen_end_label_module(ModuleName, LastModule) = EndLabelModule :-
+ Arity = 0,
+ ProcId = hlds_pred__initial_proc_id,
+ PredId = hlds_pred__initial_pred_id,
+ PredName = "ACCURATE_GC_END_LABEL",
+ ProcLabel = proc(ModuleName, predicate, ModuleName, PredName,
+ Arity, ProcId),
+ Instrs = [label(local(ProcLabel)) -
+ "label to indicate end of previous procedure"],
+ DummyProc = c_procedure(PredName, Arity, proc(PredId, ProcId),
+ Instrs, ProcLabel,
+ counter__init(0), must_not_alter_rtti),
+ EndLabelModule = comp_gen_c_module(LastModule ++ "_END", [DummyProc]).
%-----------------------------------------------------------------------------%
@@ -132,6 +182,7 @@
transform_instruction(Instr0, ProcLabel, C0, Instrs, C) -->
globals__io_lookup_int_option(max_jump_table_size, Size),
(
+ { Size \= 0 },
{ Instr0 = computed_goto(_Rval, Labels) - _},
{ list__length(Labels, L) },
{ L > Size }
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.37
diff -u -d -r1.37 mercury_goto.h
--- runtime/mercury_goto.h 22 Oct 2003 05:56:07 -0000 1.37
+++ runtime/mercury_goto.h 12 Nov 2003 16:06:55 -0000
@@ -108,23 +108,6 @@
#define MR_MODULE_STATIC_OR_EXTERN static
#endif
-/*
-** For LLDS native GC, we need to record the addresses of the end of modules
-** in the entry table, so that we know where each procedure finishes when
-** mapping from instruction pointer values to stack layout entries.
-** Without this, we might think that the following C function was
-** actually part of the preceding Mercury procedure, and then incorrectly
-** use the stack layout of the Mercury procedure if we happened to
-** get a heap overflow signal (SIGSEGV) while in that C function.
-*/
-#ifdef MR_NATIVE_GC
- #define MR_MAYBE_DEFINE_MODULE_END_LABEL MR_define_local(module_end_label)
- #define MR_MAYBE_INIT_MODULE_END_LABEL() MR_init_local(module_end_label)
-#else
- #define MR_MAYBE_DEFINE_MODULE_END_LABEL /* nothing */
- #define MR_MAYBE_INIT_MODULE_END_LABEL() /* nothing */
-#endif
-
/*---------------------------------------------------------------------------*/
/* MACHINE SPECIFIC STUFF REQUIRED FOR NON-LOCAL GOTOS */
@@ -555,8 +538,7 @@
goto *MR_dummy_identify_function( \
&&MR_PASTE2(module_name,_dummy_label)); \
MR_PASTE2(module_name,_dummy_label): \
- { \
- MR_MAYBE_INIT_MODULE_END_LABEL();
+ {
#else /* gcc version <= egcs 1.1.2 */
#define MR_BEGIN_MODULE(module_name) \
MR_MODULE_STATIC_OR_EXTERN void module_name(void); \
@@ -565,14 +547,13 @@
MR_PRETEND_ADDRESS_IS_USED( \
&&MR_PASTE2(module_name,_dummy_label)); \
MR_PASTE2(module_name,_dummy_label): \
- { \
- MR_MAYBE_INIT_MODULE_END_LABEL();
+ {
#endif /* gcc version <= egcs 1.1.2 */
/* initialization code for module goes between MR_BEGIN_MODULE */
/* and MR_BEGIN_CODE */
#define MR_BEGIN_CODE } return; {
/* body of module goes between MR_BEGIN_CODE and MR_END_MODULE */
- #define MR_END_MODULE MR_MAYBE_DEFINE_MODULE_END_LABEL; } }
+ #define MR_END_MODULE } }
#if defined(MR_USE_ASM_LABELS)
@@ -704,10 +685,9 @@
#define MR_BEGIN_MODULE(module_name) \
MR_MODULE_STATIC_OR_EXTERN MR_Code* module_name(void); \
- MR_MODULE_STATIC_OR_EXTERN MR_Code* module_name(void) { \
- MR_MAYBE_INIT_MODULE_END_LABEL();
+ MR_MODULE_STATIC_OR_EXTERN MR_Code* module_name(void) {
#define MR_BEGIN_CODE return 0;
- #define MR_END_MODULE MR_MAYBE_DEFINE_MODULE_END_LABEL; }
+ #define MR_END_MODULE }
#define MR_declare_entry(label) extern MR_Code *label(void)
#define MR_declare_static(label) static MR_Code *label(void)
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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