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/