@@ -161,6 +161,18 @@ rb_darray_free(void *ary)
161161 xfree (ary );
162162}
163163
164+ void ruby_sized_xfree (void * x , size_t size );
165+
166+ static inline void
167+ rb_darray_free_sized0 (void * ary , size_t element_size )
168+ {
169+ const rb_darray_meta_t * meta = ary ;
170+ if (meta ) {
171+ ruby_sized_xfree (ary , sizeof (* meta ) + (element_size * meta -> capa ));
172+ }
173+ }
174+ #define rb_darray_free_sized (ary , T ) rb_darray_free_sized0((ary), sizeof(T))
175+
164176static inline void
165177rb_darray_free_without_gc (void * ary )
166178{
@@ -191,13 +203,16 @@ rb_darray_calloc_mul_add_without_gc(size_t x, size_t y, size_t z)
191203 return ptr ;
192204}
193205
206+ void * ruby_sized_xrealloc (void * ptr , size_t new_size , size_t old_size );
207+
194208/* Internal function. Like rb_xrealloc_mul_add. */
195209static inline void *
196- rb_darray_realloc_mul_add (void * orig_ptr , size_t x , size_t y , size_t z )
210+ rb_darray_realloc_mul_add (void * orig_ptr , size_t capa , size_t element_size , size_t header_size )
197211{
198- size_t size = rbimpl_size_add_or_raise (rbimpl_size_mul_or_raise (x , y ), z );
212+ size_t size = rbimpl_size_add_or_raise (rbimpl_size_mul_or_raise (capa , element_size ), header_size );
213+ size_t old_size = (rb_darray_capa (orig_ptr ) * element_size ) + header_size ; // We know it won't overflow
199214
200- void * ptr = xrealloc (orig_ptr , size );
215+ void * ptr = ruby_sized_xrealloc (orig_ptr , size , old_size );
201216 RUBY_ASSERT (ptr != NULL );
202217
203218 return ptr ;
0 commit comments