ruby-changes:42590
From: naruse <ko1@a...>
Date: Fri, 22 Apr 2016 05:09:30 +0900 (JST)
Subject: [ruby-changes:42590] naruse:r54664 (trunk): * gc.c (rb_alloc_tmp_buffer_with_count): added like xmalloc2 to
naruse 2016-04-22 05:59:40 +0900 (Fri, 22 Apr 2016) New Revision: 54664 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54664 Log: * gc.c (rb_alloc_tmp_buffer_with_count): added like xmalloc2 to avoid duplicated check of size. * gc.c (ruby_xmalloc2): added to keep separate layers. * include/ruby/ruby.h (rb_alloc_tmp_buffer2): added to check the size more statically. Modified files: trunk/ChangeLog trunk/gc.c trunk/include/ruby/ruby.h Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 54663) +++ include/ruby/ruby.h (revision 54664) @@ -1615,6 +1615,7 @@ rb_num2char_inline(VALUE x) https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1615 #define ALLOCA_N(type,n) ((type*)alloca(sizeof(type)*(n))) void *rb_alloc_tmp_buffer(volatile VALUE *store, long len) RUBY_ATTR_ALLOC_SIZE((2)); +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 @@ -1625,21 +1626,38 @@ ruby_xmalloc2_size(const size_t count, c https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1626 } return count * elsize; } +static inline void * +rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize) +{ + size_t cnt = (size_t)count; + if (elsize % sizeof(VALUE) == 0) { + if (UNLIKELY(cnt > LONG_MAX / sizeof(VALUE))) { + ruby_malloc_size_overflow(cnt, elsize); + } + } + else { + if (UNLIKELY(cnt > (LONG_MAX - sizeof(VALUE)) / elsize)) { + ruby_malloc_size_overflow(count, elsize); + } + cnt = (cnt * elsize + sizeof(VALUE) - 1) / sizeof(VALUE); + } + return rb_alloc_tmp_buffer_with_count(store, cnt * sizeof(VALUE), cnt); +} /* allocates _n_ bytes temporary buffer and stores VALUE including it * in _v_. _n_ may be evaluated twice. */ #ifdef C_ALLOCA # define RB_ALLOCV(v, n) rb_alloc_tmp_buffer(&(v), (n)) # define RB_ALLOCV_N(type, v, n) \ - ((type*)RB_ALLOCV((v), ruby_xmalloc2_size((n), sizeof(type)))) + rb_alloc_tmp_buffer2(&(v), (n), sizeof(type)))) #else # define RUBY_ALLOCV_LIMIT 1024 # define RB_ALLOCV(v, n) ((n) < RUBY_ALLOCV_LIMIT ? \ (RB_GC_GUARD(v) = 0, alloca(n)) : \ rb_alloc_tmp_buffer(&(v), (n))) # define RB_ALLOCV_N(type, v, n) \ - ((type*)(ruby_xmalloc2_size((n), sizeof(type)) < RUBY_ALLOCV_LIMIT ? \ + ((type*)(((size_t)(n) < RUBY_ALLOCV_LIMIT / sizeof(type)) ? \ (RB_GC_GUARD(v) = 0, alloca((n) * sizeof(type))) : \ - rb_alloc_tmp_buffer(&(v), (n) * sizeof(type)))) + rb_alloc_tmp_buffer2(&(v), (n), sizeof(type)))) #endif #define RB_ALLOCV_END(v) rb_free_tmp_buffer(&(v)) Index: ChangeLog =================================================================== --- ChangeLog (revision 54663) +++ ChangeLog (revision 54664) @@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Fri Apr 22 04:57:01 2016 NARUSE, Yui <naruse@r...> + + * gc.c (rb_alloc_tmp_buffer_with_count): added like xmalloc2 to + avoid duplicated check of size. + + * gc.c (ruby_xmalloc2): added to keep separate layers. + + * include/ruby/ruby.h (rb_alloc_tmp_buffer2): added to check + the size more statically. + Fri Apr 22 04:54:40 2016 NARUSE, Yui <naruse@r...> * include/ruby/ruby.h (LIKELY): moved from internal.h. Index: gc.c =================================================================== --- gc.c (revision 54663) +++ gc.c (revision 54664) @@ -7850,6 +7850,12 @@ objspace_xfree(rb_objspace_t *objspace, https://github.com/ruby/ruby/blob/trunk/gc.c#L7850 objspace_malloc_increase(objspace, ptr, 0, old_size, MEMOP_TYPE_FREE); } +static void * +ruby_xmalloc0(size_t size) +{ + return objspace_xmalloc0(&rb_objspace, size); +} + void * ruby_xmalloc(size_t size) { @@ -7972,24 +7978,31 @@ ruby_mimfree(void *ptr) https://github.com/ruby/ruby/blob/trunk/gc.c#L7978 } void * -rb_alloc_tmp_buffer(volatile VALUE *store, long len) +rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t size, size_t cnt) { NODE *s; - long cnt; void *ptr; - if (len < 0 || (cnt = (long)roomof(len, sizeof(VALUE))) < 0) { - rb_raise(rb_eArgError, "negative buffer size (or size too big)"); - } - s = rb_node_newnode(NODE_ALLOCA, 0, 0, 0); - ptr = ruby_xmalloc(cnt * sizeof(VALUE)); + ptr = ruby_xmalloc0(size); s->u1.value = (VALUE)ptr; s->u3.cnt = cnt; *store = (VALUE)s; return ptr; } +void * +rb_alloc_tmp_buffer(volatile VALUE *store, long len) +{ + long cnt; + + if (len < 0 || (cnt = (long)roomof(len, sizeof(VALUE))) < 0) { + rb_raise(rb_eArgError, "negative buffer size (or size too big)"); + } + + return rb_alloc_tmp_buffer_with_count(store, len, cnt); +} + void rb_free_tmp_buffer(volatile VALUE *store) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/