diff options
author | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-04-21 20:59:40 +0000 |
---|---|---|
committer | naruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-04-21 20:59:40 +0000 |
commit | feaa82a42ba238d9192d219f72229f4c3948957f (patch) | |
tree | 0e4259a2b8c8ba9a3466526ad7931ea95c22b054 /include | |
parent | f056071cdc1541e60c80d9034c75e374b1790ea1 (diff) | |
download | ruby-feaa82a42ba238d9192d219f72229f4c3948957f.tar.gz |
* 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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54664 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'include')
-rw-r--r-- | include/ruby/ruby.h | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 71a91b558f..b4bb7267de 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -1615,6 +1615,7 @@ rb_num2char_inline(VALUE x) #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, const size_t elsize) } 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)) |