[前][次][番号順一覧][スレッド一覧]

ruby-changes:43501

From: naruse <ko1@a...>
Date: Tue, 5 Jul 2016 11:09:04 +0900 (JST)
Subject: [ruby-changes:43501] naruse:r55573 (trunk): * pack.c (pack_pack): use union instead of bare variable to ease

naruse	2016-07-05 11:08:55 +0900 (Tue, 05 Jul 2016)

  New Revision: 55573

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55573

  Log:
    * pack.c (pack_pack): use union instead of bare variable to ease
      optimizations and avoid assigning x87 floating point number.
      [ruby-core:74496] [Bug #12209]
    
    * pack.c (pack_unpack): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/pack.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55572)
+++ ChangeLog	(revision 55573)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Jul  5 11:07:14 2016  NARUSE, Yui  <naruse@r...>
+
+	* pack.c (pack_pack): use union instead of bare variable to ease
+	  optimizations and avoid assigning x87 floating point number.
+	  [ruby-core:74496] [Bug #12209]
+
+	* pack.c (pack_unpack): ditto.
+
 Mon Jul  4 13:56:34 2016  NARUSE, Yui  <naruse@r...>
 
 	* process.c: define sig_t if not exist.
Index: pack.c
===================================================================
--- pack.c	(revision 55572)
+++ pack.c	(revision 55573)
@@ -68,59 +68,18 @@ static const char endstr[] = "sSiIlLqQjJ https://github.com/ruby/ruby/blob/trunk/pack.c#L68
 # define NATINT_LEN(type,len) ((int)sizeof(type))
 #endif
 
-#define define_swapx(x, xtype)		\
-static xtype				\
-TOKEN_PASTE(swap,x)(xtype z)		\
-{					\
-    xtype r;				\
-    xtype *zp;				\
-    unsigned char *s, *t;		\
-    int i;				\
-					\
-    zp = xmalloc(sizeof(xtype));	\
-    *zp = z;				\
-    s = (unsigned char*)zp;		\
-    t = xmalloc(sizeof(xtype));		\
-    for (i=0; i<sizeof(xtype); i++) {	\
-	t[sizeof(xtype)-i-1] = s[i];	\
-    }					\
-    r = *(xtype *)t;			\
-    xfree(t);				\
-    xfree(zp);				\
-    return r;				\
-}
-
-#if SIZEOF_FLOAT == 4 && defined(HAVE_INT32_T)
-#   define swapf(x)	swap32(x)
-#   define FLOAT_SWAPPER	uint32_t
-#else
-    define_swapx(f,float)
-#endif
-
-#if SIZEOF_DOUBLE == 8 && defined(HAVE_INT64_T)
-#   define swapd(x)	swap64(x)
-#   define DOUBLE_SWAPPER	uint64_t
-#elif SIZEOF_DOUBLE == 8 && defined(HAVE_INT32_T)
-    static double
-    swapd(const double d)
-    {
-	double dtmp = d;
-	uint32_t utmp[2];
-	uint32_t utmp0;
-
-	utmp[0] = 0; utmp[1] = 0;
-	memcpy(utmp,&dtmp,sizeof(double));
-	utmp0 = utmp[0];
-	utmp[0] = swap32(utmp[1]);
-	utmp[1] = swap32(utmp0);
-	memcpy(&dtmp,utmp,sizeof(double));
-	return dtmp;
-    }
-#else
-    define_swapx(d, double)
-#endif
-
-#undef define_swapx
+typedef union {
+    float f;
+    uint32_t u;
+    char buf[4];
+} FLOAT_SWAPPER;
+typedef union {
+    double d;
+    uint64_t u;
+    char buf[8];
+} DOUBLE_SWAPPER;
+#define swapf(x) swap32(x)
+#define swapd(x) swap64(x)
 
 #define rb_ntohf(x) (BIGENDIAN_P()?(x):swapf(x))
 #define rb_ntohd(x) (BIGENDIAN_P()?(x):swapd(x))
@@ -131,57 +90,17 @@ TOKEN_PASTE(swap,x)(xtype z)		\ https://github.com/ruby/ruby/blob/trunk/pack.c#L90
 #define rb_vtohf(x) (BIGENDIAN_P()?swapf(x):(x))
 #define rb_vtohd(x) (BIGENDIAN_P()?swapd(x):(x))
 
-#ifdef FLOAT_SWAPPER
-# define FLOAT_CONVWITH(y)	FLOAT_SWAPPER y;
-# define HTONF(x,y)	(memcpy(&(y),&(x),sizeof(float)),	\
-			 (y) = rb_htonf((FLOAT_SWAPPER)(y)),	\
-			 memcpy(&(x),&(y),sizeof(float)),	\
-			 (x))
-# define HTOVF(x,y)	(memcpy(&(y),&(x),sizeof(float)),	\
-			 (y) = rb_htovf((FLOAT_SWAPPER)(y)),	\
-			 memcpy(&(x),&(y),sizeof(float)),	\
-			 (x))
-# define NTOHF(x,y)	(memcpy(&(y),&(x),sizeof(float)),	\
-			 (y) = rb_ntohf((FLOAT_SWAPPER)(y)),	\
-			 memcpy(&(x),&(y),sizeof(float)),	\
-			 (x))
-# define VTOHF(x,y)	(memcpy(&(y),&(x),sizeof(float)),	\
-			 (y) = rb_vtohf((FLOAT_SWAPPER)(y)),	\
-			 memcpy(&(x),&(y),sizeof(float)),	\
-			 (x))
-#else
-# define FLOAT_CONVWITH(y)
-# define HTONF(x,y)	rb_htonf(x)
-# define HTOVF(x,y)	rb_htovf(x)
-# define NTOHF(x,y)	rb_ntohf(x)
-# define VTOHF(x,y)	rb_vtohf(x)
-#endif
-
-#ifdef DOUBLE_SWAPPER
-# define DOUBLE_CONVWITH(y)	DOUBLE_SWAPPER y;
-# define HTOND(x,y)	(memcpy(&(y),&(x),sizeof(double)),	\
-			 (y) = rb_htond((DOUBLE_SWAPPER)(y)),	\
-			 memcpy(&(x),&(y),sizeof(double)),	\
-			 (x))
-# define HTOVD(x,y)	(memcpy(&(y),&(x),sizeof(double)),	\
-			 (y) = rb_htovd((DOUBLE_SWAPPER)(y)),	\
-			 memcpy(&(x),&(y),sizeof(double)),	\
-			 (x))
-# define NTOHD(x,y)	(memcpy(&(y),&(x),sizeof(double)),	\
-			 (y) = rb_ntohd((DOUBLE_SWAPPER)(y)),	\
-			 memcpy(&(x),&(y),sizeof(double)),	\
-			 (x))
-# define VTOHD(x,y)	(memcpy(&(y),&(x),sizeof(double)),	\
-			 (y) = rb_vtohd((DOUBLE_SWAPPER)(y)),	\
-			 memcpy(&(x),&(y),sizeof(double)),	\
-			 (x))
-#else
-# define DOUBLE_CONVWITH(y)
-# define HTOND(x,y)	rb_htond(x)
-# define HTOVD(x,y)	rb_htovd(x)
-# define NTOHD(x,y)	rb_ntohd(x)
-# define VTOHD(x,y)	rb_vtohd(x)
-#endif
+#define FLOAT_CONVWITH(x)	FLOAT_SWAPPER x;
+#define HTONF(x)	((x).u = rb_htonf((x).u))
+#define HTOVF(x)	((x).u = rb_htovf((x).u))
+#define NTOHF(x)	((x).u = rb_ntohf((x).u))
+#define VTOHF(x)	((x).u = rb_vtohf((x).u))
+
+#define DOUBLE_CONVWITH(x)	DOUBLE_SWAPPER x;
+#define HTOND(x)	((x).u = rb_htond((x).u))
+#define HTOVD(x)	((x).u = rb_htovd((x).u))
+#define NTOHD(x)	((x).u = rb_ntohd((x).u))
+#define VTOHD(x)	((x).u = rb_vtohd((x).u))
 
 #define MAX_INTEGER_PACK_SIZE 8
 
@@ -728,25 +647,22 @@ pack_pack(VALUE ary, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L647
 
 	  case 'e':		/* single precision float in VAX byte-order */
 	    while (len-- > 0) {
-		float f;
-		FLOAT_CONVWITH(ftmp);
+		FLOAT_CONVWITH(tmp);
 
 		from = NEXTFROM;
-		f = (float)RFLOAT_VALUE(rb_to_float(from));
-		f = HTOVF(f,ftmp);
-		rb_str_buf_cat(res, (char*)&f, sizeof(float));
+		tmp.f = (float)RFLOAT_VALUE(rb_to_float(from));
+		HTOVF(tmp);
+		rb_str_buf_cat(res, tmp.buf, sizeof(float));
 	    }
 	    break;
 
 	  case 'E':		/* double precision float in VAX byte-order */
 	    while (len-- > 0) {
-		double d;
-		DOUBLE_CONVWITH(dtmp);
-
+		DOUBLE_CONVWITH(tmp);
 		from = NEXTFROM;
-		d = RFLOAT_VALUE(rb_to_float(from));
-		d = HTOVD(d,dtmp);
-		rb_str_buf_cat(res, (char*)&d, sizeof(double));
+		tmp.d = RFLOAT_VALUE(rb_to_float(from));
+		HTOVD(tmp);
+		rb_str_buf_cat(res, tmp.buf, sizeof(double));
 	    }
 	    break;
 
@@ -763,25 +679,22 @@ pack_pack(VALUE ary, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L679
 
 	  case 'g':		/* single precision float in network byte-order */
 	    while (len-- > 0) {
-		float f;
-		FLOAT_CONVWITH(ftmp);
-
+		FLOAT_CONVWITH(tmp);
 		from = NEXTFROM;
-		f = (float)RFLOAT_VALUE(rb_to_float(from));
-		f = HTONF(f,ftmp);
-		rb_str_buf_cat(res, (char*)&f, sizeof(float));
+		tmp.f = (float)RFLOAT_VALUE(rb_to_float(from));
+		HTONF(tmp);
+		rb_str_buf_cat(res, tmp.buf, sizeof(float));
 	    }
 	    break;
 
 	  case 'G':		/* double precision float in network byte-order */
 	    while (len-- > 0) {
-		double d;
-		DOUBLE_CONVWITH(dtmp);
+		DOUBLE_CONVWITH(tmp);
 
 		from = NEXTFROM;
-		d = RFLOAT_VALUE(rb_to_float(from));
-		d = HTOND(d,dtmp);
-		rb_str_buf_cat(res, (char*)&d, sizeof(double));
+		tmp.d = RFLOAT_VALUE(rb_to_float(from));
+		HTOND(tmp);
+		rb_str_buf_cat(res, tmp.buf, sizeof(double));
 	    }
 	    break;
 
@@ -1578,13 +1491,11 @@ pack_unpack(VALUE str, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L1491
 	  case 'e':
 	    PACK_LENGTH_ADJUST_SIZE(sizeof(float));
 	    while (len-- > 0) {
-	        float tmp;
-		FLOAT_CONVWITH(ftmp);
-
-		memcpy(&tmp, s, sizeof(float));
+		FLOAT_CONVWITH(tmp);
+		memcpy(tmp.buf, s, sizeof(float));
 		s += sizeof(float);
-		tmp = VTOHF(tmp,ftmp);
-		UNPACK_PUSH(DBL2NUM((double)tmp));
+		VTOHF(tmp);
+		UNPACK_PUSH(DBL2NUM(tmp.f));
 	    }
 	    PACK_ITEM_ADJUST();
 	    break;
@@ -1592,13 +1503,11 @@ pack_unpack(VALUE str, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L1503
 	  case 'E':
 	    PACK_LENGTH_ADJUST_SIZE(sizeof(double));
 	    while (len-- > 0) {
-		double tmp;
-		DOUBLE_CONVWITH(dtmp);
-
-		memcpy(&tmp, s, sizeof(double));
+		DOUBLE_CONVWITH(tmp);
+		memcpy(tmp.buf, s, sizeof(double));
 		s += sizeof(double);
-		tmp = VTOHD(tmp,dtmp);
-		UNPACK_PUSH(DBL2NUM(tmp));
+		VTOHD(tmp);
+		UNPACK_PUSH(DBL2NUM(tmp.d));
 	    }
 	    PACK_ITEM_ADJUST();
 	    break;
@@ -1618,13 +1527,11 @@ pack_unpack(VALUE str, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L1527
 	  case 'g':
 	    PACK_LENGTH_ADJUST_SIZE(sizeof(float));
 	    while (len-- > 0) {
-	        float tmp;
-		FLOAT_CONVWITH(ftmp);
-
-		memcpy(&tmp, s, sizeof(float));
+		FLOAT_CONVWITH(tmp);
+		memcpy(tmp.buf, s, sizeof(float));
 		s += sizeof(float);
-		tmp = NTOHF(tmp,ftmp);
-		UNPACK_PUSH(DBL2NUM((double)tmp));
+		NTOHF(tmp);
+		UNPACK_PUSH(DBL2NUM(tmp.f));
 	    }
 	    PACK_ITEM_ADJUST();
 	    break;
@@ -1632,13 +1539,11 @@ pack_unpack(VALUE str, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L1539
 	  case 'G':
 	    PACK_LENGTH_ADJUST_SIZE(sizeof(double));
 	    while (len-- > 0) {
-		double tmp;
-		DOUBLE_CONVWITH(dtmp);
-
-		memcpy(&tmp, s, sizeof(double));
+		DOUBLE_CONVWITH(tmp);
+		memcpy(tmp.buf, s, sizeof(double));
 		s += sizeof(double);
-		tmp = NTOHD(tmp,dtmp);
-		UNPACK_PUSH(DBL2NUM(tmp));
+		NTOHD(tmp);
+		UNPACK_PUSH(DBL2NUM(tmp.d));
 	    }
 	    PACK_ITEM_ADJUST();
 	    break;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]