[PATCH] S/390: Improve dynamic stack checking

Andreas Krebbel Andreas.Krebbel@de.ibm.com
Tue Mar 6 16:34:00 GMT 2007


Hi,

the attached patch modifies the S/390 dynamic stack checking.
Formerly we always needed a stack guard value provided via command
line option when enabling stack checking.

The stack guard value describes the size of the area which is held free
below the stack limit.  A function allocating more than that value at once
may circumvent our dynamic stack check.  With the attached patch the stack
guard value is chosen per function as the smallest power of 2 which is larger
than the current frame size.  This makes our stack checking much more
flexible and easy to use.

Bootstrapped on s390.

OK given no testsuite regression occurs?

Bye,

-Andreas-


2007-03-06  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.c (override_options): Don't emit an error when
	-mstack-size is used without providing -mstack-guard.
	(s390_emit_prologue): Choose stack_guard value automatically if not
	provided via command line.
	* doc/invoke.texi: Adjust description of -mstack-guard and -mstack-size.



Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig	2007-03-05 10:45:28.000000000 +0100
--- gcc/config/s390/s390.c	2007-03-06 17:05:28.000000000 +0100
*************** override_options (void)
*** 1437,1445 ****
  
    if (s390_stack_size)
      {
!       if (!s390_stack_guard)
! 	error ("-mstack-size implies use of -mstack-guard");
!       else if (s390_stack_guard >= s390_stack_size)
  	error ("stack size must be greater than the stack guard value");
        else if (s390_stack_size > 1 << 16)
  	error ("stack size must not be greater than 64k");
--- 1437,1443 ----
  
    if (s390_stack_size)
      {
!       if (s390_stack_guard >= s390_stack_size)
  	error ("stack size must be greater than the stack guard value");
        else if (s390_stack_size > 1 << 16)
  	error ("stack size must not be greater than 64k");
*************** s390_emit_prologue (void)
*** 7245,7265 ****
  
        if (s390_stack_size)
    	{
! 	  HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
! 					    & ~(s390_stack_guard - 1));
! 	  rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
! 			       GEN_INT (stack_check_mask));
  
! 	  if (TARGET_64BIT)
! 	    gen_cmpdi (t, const0_rtx);
  	  else
! 	    gen_cmpsi (t, const0_rtx);
  
! 	  emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode, 
! 						       gen_rtx_REG (CCmode, 
! 								    CC_REGNUM),
! 						       const0_rtx),
! 					   const0_rtx));
    	}
  
        if (s390_warn_framesize > 0 
--- 7243,7289 ----
  
        if (s390_stack_size)
    	{
! 	  HOST_WIDE_INT stack_guard;
  
! 	  if (s390_stack_guard)
! 	    stack_guard = s390_stack_guard;
  	  else
! 	    {
! 	      /* If no value for stack guard is provided the smallest power of 2
! 		 larger than the current frame size is chosen.  */
! 	      stack_guard = 1;
! 	      while (stack_guard < cfun_frame_layout.frame_size)
! 		stack_guard <<= 1;
! 	    }
  
! 	  if (cfun_frame_layout.frame_size >= s390_stack_size)
! 	    {
! 	      warning (0, "frame size of function %qs is "
! 		       HOST_WIDE_INT_PRINT_DEC
! 		       " bytes exceeding user provided stack limit of "
! 		       HOST_WIDE_INT_PRINT_DEC " bytes.  "
! 		       "An unconditional trap is added.",
! 		       current_function_name(), cfun_frame_layout.frame_size,
! 		       s390_stack_size);
! 	      emit_insn (gen_trap ());
! 	    }
! 	  else
! 	    {
! 	      HOST_WIDE_INT stack_check_mask = ((s390_stack_size - 1)
! 						& ~(stack_guard - 1));
! 	      rtx t = gen_rtx_AND (Pmode, stack_pointer_rtx,
! 				   GEN_INT (stack_check_mask));
! 	      if (TARGET_64BIT)
! 		gen_cmpdi (t, const0_rtx);
! 	      else
! 		gen_cmpsi (t, const0_rtx);
! 
! 	      emit_insn (gen_conditional_trap (gen_rtx_EQ (CCmode,
! 							   gen_rtx_REG (CCmode,
! 								     CC_REGNUM),
! 							   const0_rtx),
! 					       const0_rtx));
! 	    }
    	}
  
        if (s390_warn_framesize > 0 
Index: gcc/doc/invoke.texi
===================================================================
*** gcc/doc/invoke.texi.orig	2007-03-05 10:45:08.000000000 +0100
--- gcc/doc/invoke.texi	2007-03-06 16:33:39.000000000 +0100
*************** sized arrays.  This is generally a bad i
*** 12752,12768 ****
  @item -mstack-size=@var{stack-size}
  @opindex mstack-guard
  @opindex mstack-size
! These arguments always have to be used in conjunction.  If they are present the s390
! back end emits additional instructions in the function prologue which trigger a trap
! if the stack size is @var{stack-guard} bytes above the @var{stack-size}
! (remember that the stack on s390 grows downward).  These options are intended to
! be used to help debugging stack overflow problems.  The additionally emitted code
! causes only little overhead and hence can also be used in production like systems
! without greater performance degradation.  The given values have to be exact
! powers of 2 and @var{stack-size} has to be greater than @var{stack-guard} without
! exceeding 64k.
  In order to be efficient the extra code makes the assumption that the stack starts
  at an address aligned to the value given by @var{stack-size}.
  @end table
  
  @node Score Options
--- 12752,12770 ----
  @item -mstack-size=@var{stack-size}
  @opindex mstack-guard
  @opindex mstack-size
! If these options are provided the s390 back end emits additional instructions in
! the function prologue which trigger a trap if the stack size is @var{stack-guard}
! bytes above the @var{stack-size} (remember that the stack on s390 grows downward).
! If the @var{stack-guard} option is omitted the smallest power of 2 larger than
! the frame size of the compiled function is chosen.
! These options are intended to be used to help debugging stack overflow problems.
! The additionally emitted code causes only little overhead and hence can also be
! used in production like systems without greater performance degradation.  The given
! values have to be exact powers of 2 and @var{stack-size} has to be greater than
! @var{stack-guard} without exceeding 64k.
  In order to be efficient the extra code makes the assumption that the stack starts
  at an address aligned to the value given by @var{stack-size}.
+ The @var{stack-guard} option can only be used in conjunction with @var{stack-size}.
  @end table
  
  @node Score Options



More information about the Gcc-patches mailing list