ruby-changes:42630
From: naruse <ko1@a...>
Date: Fri, 22 Apr 2016 19:45:54 +0900 (JST)
Subject: [ruby-changes:42630] naruse:r54704 (trunk): * include/ruby/ruby.h (rb_mul_size_overflow): added to handle
naruse 2016-04-22 20:42:31 +0900 (Fri, 22 Apr 2016) New Revision: 54704 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54704 Log: * include/ruby/ruby.h (rb_mul_size_overflow): added to handle mul overflow efficiently. * include/ruby/ruby.h (rb_alloc_tmp_buffer2): use rb_mul_size_overflow and avoid division where it can define DSIZE_T. * gc.c (xmalloc2_size): moved from ruby.h and use rb_mul_size_overflow. Modified files: trunk/ChangeLog trunk/gc.c trunk/include/ruby/ruby.h Index: gc.c =================================================================== --- gc.c (revision 54703) +++ gc.c (revision 54704) @@ -7792,7 +7792,16 @@ objspace_xmalloc(rb_objspace_t *objspace https://github.com/ruby/ruby/blob/trunk/gc.c#L7792 return objspace_xmalloc0(objspace, size); } -#define xmalloc2_size ruby_xmalloc2_size +static inline size_t +xmalloc2_size(const size_t count, const size_t elsize) +{ + size_t ret; + if (rb_mul_size_overflow(count, elsize, SSIZE_MAX, &ret)) { + ruby_malloc_size_overflow(count, elsize); + } + return ret; +} + static void * objspace_xmalloc2(rb_objspace_t *objspace, size_t n, size_t size) { Index: ChangeLog =================================================================== --- ChangeLog (revision 54703) +++ ChangeLog (revision 54704) @@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Apr 22 20:18:40 2016 NARUSE, Yui <naruse@r...> + + * include/ruby/ruby.h (rb_mul_size_overflow): added to handle + mul overflow efficiently. + + * include/ruby/ruby.h (rb_alloc_tmp_buffer2): use rb_mul_size_overflow + and avoid division where it can define DSIZE_T. + + * gc.c (xmalloc2_size): moved from ruby.h and use rb_mul_size_overflow. + Fri Apr 22 20:34:04 2016 Nobuyoshi Nakada <nobu@r...> * time.c (time_asctime): [DOC] add ctime example, not only Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 54703) +++ include/ruby/ruby.h (revision 54704) @@ -1618,13 +1618,23 @@ void *rb_alloc_tmp_buffer(volatile VALUE https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1618 void *rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t len,size_t count) RUBY_ATTR_ALLOC_SIZE((2,3)); void rb_free_tmp_buffer(volatile VALUE *store); NORETURN(void ruby_malloc_size_overflow(size_t, size_t)); -static inline size_t -ruby_xmalloc2_size(const size_t count, const size_t elsize) +#if HAVE_LONG_LONG && SIZEOF_SIZE_T * 2 <= SIZEOF_LONG_LONG +# define DSIZE_T unsigned LONG_LONG +#elif defined(HAVE_INT128_T) +# define DSIZE_T uint128_t +#endif +static inline int +rb_mul_size_overflow(size_t a, size_t b, size_t max, size_t *c) { - if (count > SSIZE_MAX / elsize) { - ruby_malloc_size_overflow(count, elsize); - } - return count * elsize; +#ifdef DSIZE_T + DSIZE_T c2 = (DSIZE_T)a * (DSIZE_T)b; + if (UNLIKELY(c2 > max)) return 1; + *c = (size_t)c2; +#else + if (b != 0 && UNLIKELY(a > max / b)) return 1; + *c = a * b; +#endif + return 0; } static inline void * rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize) @@ -1636,10 +1646,11 @@ rb_alloc_tmp_buffer2(volatile VALUE *sto https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1646 } } else { - if (UNLIKELY(cnt > (LONG_MAX - sizeof(VALUE)) / elsize)) { - ruby_malloc_size_overflow(count, elsize); + size_t size, max = LONG_MAX - sizeof(VALUE) + 1; + if (UNLIKELY(rb_mul_size_overflow(count, elsize, max, &size))) { + ruby_malloc_size_overflow(cnt, elsize); } - cnt = (cnt * elsize + sizeof(VALUE) - 1) / sizeof(VALUE); + cnt = (size + sizeof(VALUE) - 1) / sizeof(VALUE); } return rb_alloc_tmp_buffer_with_count(store, cnt * sizeof(VALUE), cnt); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/