develooper Front page | perl.perl5.porters | Postings from March 2003

Re: [PATCH] glibc _moddi3

Thread Previous | Thread Next
From:
A. Bergman
Date:
March 3, 2003 04:47
Subject:
Re: [PATCH] glibc _moddi3
Message ID:
20030301233702.GA19002@borderline.itt.org
On Sat, Mar 01, 2003 at 10:57:51PM +0200, Jarkko Hietaniemi wrote:
> Here's an attempt to squash the glibc _moddi3 negative quad bug that's
> been around for aeons.  An aeon.  Almost a year.  (The bug is also
> known as [perl #9402] or "Abigail's faithfully failing int.t".)
> I didn't feel like writing a Configure test for such a precise bug
> but instead went for runtime.  Now pp_i_modulo is basically a switchboard
> that rewires the opcode dispatch table as required (thus effectively
> rewiring itself out of the way).  The patch works for me-- I've got
> the same buggy glibc in the Debian box I run my smokes in.
> 

Nice hack, however don't you also want to replace 

PL_op->op_ppaddr so that the next time this OP executes it will use the 
direct version, since the PL_peepaddr is only used for new ops since 
runops does  while ((PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX))) {


> --- pp.c.orig	2003-03-01 22:51:50.000000000 +0200
> +++ pp.c	2003-03-01 22:51:55.000000000 +0200
> @@ -2457,6 +2457,40 @@
>      }
>  }
>  
> +STATIC
> +PP(pp_i_modulo_0)
> +{
> +    /* This is the vanilla old i_modulo. */
> +    dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
> +    {
> +      dPOPTOPiirl;
> +      if (!right)
> +	DIE(aTHX_ "Illegal modulus zero");
> +      SETi( left % right );
> +      RETURN;
> +    }
> +}
> +
> +STATIC
> +PP(pp_i_modulo_1)
> +{
> +#ifdef __GLIBC__
> +    /* This is the i_modulo with the workaround for the _moddi3
> +     * bug in (at least) glibc 2.2.5 (the "right = -right" part
> +     * is the workaround).  See below for pp_i_modulo. */
> +    dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
> +    {
> +      dPOPTOPiirl;
> +      if (!right)
> +	DIE(aTHX_ "Illegal modulus zero");
> +      if (right < 0)
> +	right = -right;
> +      SETi( left % right );
> +      RETURN;
> +    }
> +#endif
> +}
> +
>  PP(pp_i_modulo)
>  {
>      dSP; dATARGET; tryAMAGICbin(modulo,opASSIGN);
> @@ -2464,6 +2498,28 @@
>        dPOPTOPiirl;
>        if (!right)
>  	DIE(aTHX_ "Illegal modulus zero");
> +      /* The assumption is to use hereafter the old vanilla version... */
> +      PL_ppaddr[OP_I_MODULO] = &Perl_pp_i_modulo_0;


+ PL_op->op_ppaddr = &Perl_pp_i_modulo_0;

> +      /* .. but if we have glibc, we might have a buggy _moddi3
> +       * (at least glicb 2.2.5 is known to have this bug), in other
> +       * words our integer modulus with negative quad as the second
> +       * argument might be broken.  Test for this and re-patch the
> +       * opcode dispatch table if that is the case, remembering to
> +       * also apply the workaround so that this first round works
> +       * right, too.
> +       *
> +       * See [perl #9402] for more information. */
> +#if defined(__GLIBC__) && IVSIZE == 8
> +      {
> +	IV l =   3;
> +	IV r = -10;
> +	if (l % r == -3) {
> +	  PL_ppaddr[OP_I_MODULO] = &Perl_pp_i_modulo_1;

PL_op->op_ppaddr = &Perl_pp_i_modulo_1;

> +	  if (right < 0)
> +	    right = -right;
> +	}
> +      }
> +#endif
>        SETi( left % right );
>        RETURN;
>      }
> 
> -- 
> Jarkko Hietaniemi <jhi@iki.fi> http://www.iki.fi/jhi/ "There is this special
> biologist word we use for 'stable'.  It is 'dead'." -- Jack Cohen


Yes this is threadsafe.

Arthur

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About