[m-rev.] for review: stack segments

Peter Wang wangp at students.csse.unimelb.edu.au
Tue Oct 31 12:51:09 AEDT 2006


On 2006-10-31, Zoltan Somogyi <zs at csse.unimelb.edu.au> wrote:
> For review by anyone.
> 
> Zoltan.
> 
> Add a mechanism for growing the stacks on demand by adding new segments
> to them. You can ask for the new mechanism via a new grade component, stseg
> (short for "stack segments").

That was quick :-)

> Index: compiler/options.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
> retrieving revision 1.532
> diff -u -b -r1.532 options.m
> --- compiler/options.m	5 Oct 2006 04:59:21 -0000	1.532
> +++ compiler/options.m	27 Oct 2006 15:58:23 -0000
> @@ -1774,6 +1776,7 @@
>  long_option("type-layout",          type_layout).
>  long_option("maybe-thread-safe",    maybe_thread_safe_opt).
>  long_option("extend-stacks-when-needed",    extend_stacks_when_needed).
> +long_option("stack-segments",       stack_segments).
>  % Data representation options
>  long_option("reserve-tag",          reserve_tag).
>  long_option("use-minimal-model-stack_copy", use_minimal_model_stack_copy).
> @@ -3575,7 +3578,10 @@
>          "\tattribute.  The default is no.",
>          "--extend-stacks-when-needed",
>          "\tSpecify that code that increments a stack pointer must",
> -        "\textend the stack when this is needed."
> +        "\textend the stack when this is needed.",
> +        "--stack-segments-needed",

--stack-segments

> Index: runtime/mercury_memory_zones.h
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_memory_zones.h,v
> retrieving revision 1.17
> diff -u -b -r1.17 mercury_memory_zones.h
> --- runtime/mercury_memory_zones.h	13 Sep 2005 08:25:39 -0000	1.17
> +++ runtime/mercury_memory_zones.h	29 Oct 2006 21:11:45 -0000
> @@ -194,7 +202,7 @@
>  ** has the same behaviour as MR_create_zone, except instead of allocating
>  ** the memory, it takes a pointer to a region of memory that must be at
>  ** least Size + MR_unit[*] bytes, or if MR_PROTECTPAGE is defined, then it
> -** must be at least Size + 2 * unit[*] bytes.
> +** must be at least Size + 2 * MR_unit[*] bytes.
>  ** If it fails to protect the redzone then it exits.
>  ** If MR_CHECK_OVERFLOW_VIA_MPROTECT is unavailable, then the last two
>  ** arguments are ignored.
> @@ -252,6 +260,12 @@
>  extern	void		MR_debug_memory_zone(FILE *fp, MR_MemoryZone *zone);
>  
>  /*
> +** Return the given zone to tyhe list of free zones.

the

> +*/
> +
> +extern	void		MR_unget_zone(MR_MemoryZone *zone);


> Index: runtime/mercury_stack_trace.c
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
> retrieving revision 1.74
> diff -u -b -r1.74 mercury_stack_trace.c
> --- runtime/mercury_stack_trace.c	29 Sep 2006 06:34:55 -0000	1.74
> +++ runtime/mercury_stack_trace.c	30 Oct 2006 05:27:26 -0000
> @@ -315,6 +318,18 @@
>          return MR_STEP_OK;
>      }
>  
> +#ifndef MR_HIGHLEVEL_CODE
> +    if (success == MR_ENTRY(MR_pop_detstack_segment)) {
> +        success = (MR_Code *) MR_based_stackvar(*stack_trace_sp_ptr, 2);
> +        *stack_trace_sp_ptr = (MR_Word *)
> +            MR_based_stackvar(*stack_trace_sp_ptr, 1);
> +    } else if (success == MR_ENTRY(MR_pop_nondetstack_segment)) {
> +        success = MR_succip_slot(*stack_trace_curfr_ptr);
> +        *stack_trace_curfr_ptr = (MR_Word *)
> +            MR_based_framevar(*stack_trace_curfr_ptr, 1);
> +    }
> +#endif /* MR_HIGHLEVEL_CODE */
> +

Missing #ifdef MR_STACK_SEGMENTS around this?

> Index: runtime/mercury_stacks.c
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stacks.c,v
> retrieving revision 1.17
> diff -u -b -r1.17 mercury_stacks.c
> --- runtime/mercury_stacks.c	25 Nov 2005 05:40:47 -0000	1.17
> +++ runtime/mercury_stacks.c	30 Oct 2006 06:02:27 -0000
> @@ -191,6 +197,255 @@
>  
>  /***************************************************************************/
>  
> +#ifndef  MR_HIGHLEVEL_CODE
> +
> +#ifdef  MR_STACK_SEGMENTS
> +
> +/*
> +** These three global variables are used in the MR_detstack_extend_and_check
> +** and MR_nondetstack_extend_and_check macros and nowhere else.
> +*/
> +
> +MR_Code *MR_post_extend_succip;
> +MR_Word *MR_pre_extend_maxfr;
> +MR_Word *MR_pre_extend_curfr;

These globals are going to be a problem for multithreaded code.

> +MR_declare_entry(MR_pop_detstack_segment);
> +MR_declare_entry(MR_pop_nondetstack_segment);
> +
> +MR_Word *MR_new_detstack_segment(MR_Word *sp, int n)
> +{
> +    MR_Word         *old_sp;
> +    MR_MemoryZones  *list;
> +    MR_MemoryZone   *new_zone;
> +
> +    old_sp = sp;
> +
> +    new_zone = MR_create_zone("detstack_segment", 0, MR_detstack_size, 0,
> +        MR_detstack_zone_size, MR_default_handler);
> +
> +    list = GC_MALLOC_UNCOLLECTABLE(sizeof(MR_MemoryZones));

MR_GC_NEW_UNCOLLECTABLE

> +MR_Word *
> +MR_new_nondetstack_segment(MR_Word *maxfr, int n)
> +{
> +    MR_Word         *old_maxfr;
> +    MR_MemoryZones  *list;
> +    MR_MemoryZone   *new_zone;
> +
> +    old_maxfr = maxfr;
> +
> +    new_zone = MR_create_zone("nondetstack_segment", 0, MR_nondetstack_size, 0,
> +        MR_nondetstack_zone_size, MR_default_handler);
> +
> +    list = GC_MALLOC_UNCOLLECTABLE(sizeof(MR_MemoryZones));

Ditto.

> +MR_define_extern_entry(MR_pop_detstack_segment);
> +MR_define_extern_entry(MR_pop_nondetstack_segment);
> +
> +MR_BEGIN_MODULE(stack_segment_module)
> +    MR_init_entry_an(MR_pop_detstack_segment);
> +    MR_init_entry_an(MR_pop_nondetstack_segment);
> +MR_BEGIN_CODE
> +
> +MR_define_entry(MR_pop_detstack_segment);
> +#ifdef MR_STACK_SEGMENTS
> +{
> +    MR_MemoryZones  *list;
> +    MR_Word         *orig_sp;
> +    MR_Code         *orig_succip;
> +
> +    orig_sp = (MR_Word *) MR_stackvar(1);
> +    orig_succip = (MR_Code *) MR_stackvar(2);
> +
> +#ifdef  MR_DEBUG_STACK_SEGMENTS
> +    printf("restore old det segment: old zone %p, old sp %p\n",
> +        MR_CONTEXT(MR_ctxt_detstack_zone), MR_sp);
> +    printf("old sp: ");
> +    MR_printdetstack(MR_sp);
> +    printf("old succip: ");
> +    MR_printlabel(stdout, MR_succip);
> +#endif
> +
> +    MR_unget_zone(MR_CONTEXT(MR_ctxt_detstack_zone));
> +
> +    list = MR_CONTEXT(MR_ctxt_prev_detstack_zones);
> +    MR_CONTEXT(MR_ctxt_detstack_zone) = list->MR_zones_head;
> +    MR_CONTEXT(MR_ctxt_prev_detstack_zones) = list->MR_zones_tail;
> +    MR_CONTEXT(MR_ctxt_sp) = orig_sp;
> +    GC_FREE(list);

MR_GC_FREE

> +MR_define_entry(MR_pop_nondetstack_segment);
> +#ifdef MR_STACK_SEGMENTS
> +{
> +    MR_MemoryZones  *list;
> +    MR_Word         *orig_maxfr;
> +    MR_Code         *orig_succip;
> +
> +    orig_maxfr = (MR_Word *) MR_stackvar(1);
> +    orig_succip = (MR_Code *) MR_stackvar(2);
> +
> +#ifdef  MR_DEBUG_STACK_SEGMENTS
> +    printf("restore old nondet segment: old zone %p, old maxfr %p\n",
> +        MR_CONTEXT(MR_ctxt_nondetstack_zone), MR_maxfr);
> +    printf("old maxfr: ");
> +    MR_printnondetstack(MR_maxfr);
> +    printf("old succip: ");
> +    MR_printlabel(stdout, MR_succip);
> +#endif
> +
> +    MR_unget_zone(MR_CONTEXT(MR_ctxt_nondetstack_zone));
> +
> +    list = MR_CONTEXT(MR_ctxt_prev_nondetstack_zones);
> +    MR_CONTEXT(MR_ctxt_nondetstack_zone) = list->MR_zones_head;
> +    MR_CONTEXT(MR_ctxt_prev_nondetstack_zones) = list->MR_zones_tail;
> +    MR_CONTEXT(MR_ctxt_maxfr) = orig_maxfr;
> +    GC_FREE(list);

Ditto.

> Index: runtime/mercury_wrapper.c
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
> retrieving revision 1.170
> diff -u -b -r1.170 mercury_wrapper.c
> --- runtime/mercury_wrapper.c	9 Oct 2006 06:40:25 -0000	1.170
> +++ runtime/mercury_wrapper.c	30 Oct 2006 05:49:57 -0000
> @@ -165,6 +170,18 @@
>  
>  double MR_heap_expansion_factor = 2.0;
>  
> +/*
> +** When we use stack segments, we reserve the last MR_stack_margin_size bytes
> +** of each stack segment for leaf procedures. This way, leaf procedures that
> +** do not need this much stack space can allocate their stack space *without*
> +** incurring the cost of a test.
> +**
> +** MR_stack_margin_size is never consulted directly; instead, its value is used
> +** to set the MR_zone_extend_threshold field in a stack's memory zone.
> +*/
> +
> +size_t      MR_stack_margin_size = 128;
> +

It might be worth checking that the user hasn't specified a detstack or
nondetstack size smaller than the margin size.

> Index: scripts/final_grade_options.sh-subr
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/scripts/final_grade_options.sh-subr,v
> retrieving revision 1.14
> diff -u -b -r1.14 final_grade_options.sh-subr
> --- scripts/final_grade_options.sh-subr	18 May 2005 05:45:00 -0000	1.14
> +++ scripts/final_grade_options.sh-subr	27 Oct 2006 16:07:28 -0000
> @@ -41,6 +41,15 @@
>  esac
>  
>  #
> +# .exts grade is not compatible with .stseg
> +#	(they are alternative ways of doing the same thing)
> +#
> +case $extend_stacks,$stack_segments in true,true)
> +	echo "--extend-stacks and --stack-segments are not compatible" 1>&2
> +	exit 1 ;;

--extend-stacks-when-needed

The rest looked fine, but some files had an inconsistent mix of tabs and
spaces so indentation was off when viewed with the default tab size.

Peter

--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list