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

ruby-changes:29117

From: akr <ko1@a...>
Date: Sat, 8 Jun 2013 16:40:13 +0900 (JST)
Subject: [ruby-changes:29117] akr:r41169 (trunk): * bignum.c (rb_integer_unpack): Don't use rb_funcall if possible.

akr	2013-06-08 16:40:03 +0900 (Sat, 08 Jun 2013)

  New Revision: 41169

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41169

  Log:
    * bignum.c (rb_integer_unpack): Don't use rb_funcall if possible.
    
    * random.c: Use uint32_t for elements of seed.
      (make_seed_value): Use rb_integer_unpack.

  Modified files:
    trunk/ChangeLog
    trunk/bignum.c
    trunk/random.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 41168)
+++ ChangeLog	(revision 41169)
@@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Jun  8 16:38:02 2013  Tanaka Akira  <akr@f...>
+
+	* bignum.c (rb_integer_unpack): Don't use rb_funcall if possible.
+
+	* random.c: Use uint32_t for elements of seed.
+	  (make_seed_value): Use rb_integer_unpack.
+
 Sat Jun  8 15:58:18 2013  Tanaka Akira  <akr@f...>
 
 	* random.c (rand_init): Add a cast to fix clang compile error:
Index: bignum.c
===================================================================
--- bignum.c	(revision 41168)
+++ bignum.c	(revision 41169)
@@ -852,7 +852,6 @@ integer_unpack_push_bits(int data, int n https://github.com/ruby/ruby/blob/trunk/bignum.c#L852
 VALUE
 rb_integer_unpack(int sign, const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
 {
-    VALUE num_bits, num_bdigits;
     VALUE result;
     const unsigned char *buf = words;
 
@@ -877,20 +876,34 @@ rb_integer_unpack(int sign, const void * https://github.com/ruby/ruby/blob/trunk/bignum.c#L876
     if (sign != 1 && sign != 0 && sign != -1)
         rb_raise(rb_eArgError, "unexpected sign: %d", sign);
 
-    /* num_bits = (wordsize * CHAR_BIT - nails) * count */
-    num_bits = SIZET2NUM(wordsize);
-    num_bits = rb_funcall(num_bits, '*', 1, LONG2FIX(CHAR_BIT));
-    num_bits = rb_funcall(num_bits, '-', 1, SIZET2NUM(nails));
-    num_bits = rb_funcall(num_bits, '*', 1, SIZET2NUM(numwords));
-
-    if (num_bits == LONG2FIX(0))
-        return LONG2FIX(0);
-
-    /* num_bdigits = (num_bits + SIZEOF_BDIGITS*CHAR_BIT - 1) / (SIZEOF_BDIGITS*CHAR_BIT) */
-    num_bdigits = rb_funcall(num_bits, '+', 1, LONG2FIX(SIZEOF_BDIGITS*CHAR_BIT-1));
-    num_bdigits = rb_funcall(num_bdigits, '/', 1, LONG2FIX(SIZEOF_BDIGITS*CHAR_BIT));
+    if (numwords <= (SIZE_MAX - (SIZEOF_BDIGITS*CHAR_BIT-1)) / CHAR_BIT / wordsize) {
+        size_t num_bits, num_bdigits;
+        num_bits = (wordsize * CHAR_BIT - nails) * numwords;
+        if (num_bits == 0)
+            return LONG2FIX(0);
+        num_bdigits = (num_bits + SIZEOF_BDIGITS*CHAR_BIT - 1) / (SIZEOF_BDIGITS*CHAR_BIT);
+        if (LONG_MAX < num_bdigits)
+            rb_raise(rb_eArgError, "too big to unpack as an integer");
+        result = bignew((long)num_bdigits, 0 <= sign);
+    }
+    else {
+        VALUE num_bits, num_bdigits;
+
+        /* num_bits = (wordsize * CHAR_BIT - nails) * numwords */
+        num_bits = SIZET2NUM(wordsize);
+        num_bits = rb_funcall(num_bits, '*', 1, LONG2FIX(CHAR_BIT));
+        num_bits = rb_funcall(num_bits, '-', 1, SIZET2NUM(nails));
+        num_bits = rb_funcall(num_bits, '*', 1, SIZET2NUM(numwords));
+
+        if (num_bits == LONG2FIX(0))
+            return LONG2FIX(0);
+
+        /* num_bdigits = (num_bits + SIZEOF_BDIGITS*CHAR_BIT - 1) / (SIZEOF_BDIGITS*CHAR_BIT) */
+        num_bdigits = rb_funcall(num_bits, '+', 1, LONG2FIX(SIZEOF_BDIGITS*CHAR_BIT-1));
+        num_bdigits = rb_funcall(num_bdigits, '/', 1, LONG2FIX(SIZEOF_BDIGITS*CHAR_BIT));
 
-    result = bignew(NUM2LONG(num_bdigits), 0 <= sign);
+        result = bignew(NUM2LONG(num_bdigits), 0 <= sign);
+    }
 
     dp = BDIGITS(result);
     de = dp + RBIGNUM_LEN(result);
Index: random.c
===================================================================
--- random.c	(revision 41168)
+++ random.c	(revision 41169)
@@ -440,7 +440,7 @@ random_init(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/random.c#L440
     return obj;
 }
 
-#define DEFAULT_SEED_LEN (DEFAULT_SEED_CNT * (int)sizeof(int))
+#define DEFAULT_SEED_LEN (DEFAULT_SEED_CNT * (int)sizeof(int32_t))
 
 #if defined(S_ISCHR) && !defined(DOSISH)
 # define USE_DEV_URANDOM 1
@@ -449,7 +449,7 @@ random_init(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/random.c#L449
 #endif
 
 static void
-fill_random_seed(unsigned int seed[DEFAULT_SEED_CNT])
+fill_random_seed(uint32_t seed[DEFAULT_SEED_CNT])
 {
     static int n = 0;
     struct timeval tv;
@@ -500,28 +500,27 @@ fill_random_seed(unsigned int seed[DEFAU https://github.com/ruby/ruby/blob/trunk/random.c#L500
 }
 
 static VALUE
-make_seed_value(const void *ptr)
+make_seed_value(const uint32_t *ptr)
 {
-    const long len = DEFAULT_SEED_LEN/SIZEOF_BDIGITS;
-    BDIGIT *digits;
-    NEWOBJ_OF(big, struct RBignum, rb_cBignum, T_BIGNUM | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0));
-
-    RBIGNUM_SET_SIGN(big, 1);
-    rb_big_resize((VALUE)big, len + 1);
-    digits = RBIGNUM_DIGITS(big);
-
-    MEMCPY(digits, ptr, char, DEFAULT_SEED_LEN);
-
-    /* set leading-zero-guard if need. */
-    digits[len] =
-#if SIZEOF_INT32 / SIZEOF_BDIGITS > 1
-	digits[len-2] <= 1 && digits[len-1] == 0
-#else
-	digits[len-1] <= 1
-#endif
-	? 1 : 0;
+    VALUE seed;
+    size_t len;
+
+    if (ptr[DEFAULT_SEED_CNT-1] <= 1) {
+        /* set leading-zero-guard */
+        uint32_t buf[DEFAULT_SEED_CNT+1];
+        MEMCPY(buf, ptr, uint32_t, DEFAULT_SEED_CNT);
+        buf[DEFAULT_SEED_CNT] = 1;
+        ptr = buf;
+        len = DEFAULT_SEED_CNT+1;
+    }
+    else {
+        len = DEFAULT_SEED_CNT;
+    }
 
-    return rb_big_norm((VALUE)big);
+    seed = rb_integer_unpack(+1, ptr, DEFAULT_SEED_CNT, sizeof(uint32_t), 0,
+        INTEGER_PACK_LSWORD_FIRST|INTEGER_PACK_NATIVE_BYTE_ORDER);
+
+    return seed;
 }
 
 /*
@@ -535,7 +534,7 @@ make_seed_value(const void *ptr) https://github.com/ruby/ruby/blob/trunk/random.c#L534
 static VALUE
 random_seed(void)
 {
-    unsigned int buf[DEFAULT_SEED_CNT];
+    uint32_t buf[DEFAULT_SEED_CNT];
     fill_random_seed(buf);
     return make_seed_value(buf);
 }
@@ -1271,7 +1270,7 @@ static union { https://github.com/ruby/ruby/blob/trunk/random.c#L1270
 } sipseed;
 
 static VALUE
-init_randomseed(struct MT *mt, unsigned int initial[DEFAULT_SEED_CNT])
+init_randomseed(struct MT *mt, uint32_t initial[DEFAULT_SEED_CNT])
 {
     VALUE seed;
     fill_random_seed(initial);
@@ -1285,7 +1284,7 @@ void https://github.com/ruby/ruby/blob/trunk/random.c#L1284
 Init_RandomSeed(void)
 {
     rb_random_t *r = &default_rand;
-    unsigned int initial[DEFAULT_SEED_CNT];
+    uint32_t initial[DEFAULT_SEED_CNT];
     struct MT *mt = &r->mt;
     VALUE seed = init_randomseed(mt, initial);
     int i;

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

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