Skip to content

Commit 9755952

Browse files
committed
merge revision(s) r46501,r47372,r47460: [Backport ruby#10191]
* object.c (rb_obj_copy_ivar): extract function to copy instance variables only for T_OBJECT from init_copy. * object.c (rb_obj_copy_ivar): allocate no memory for empty instance variables. [ruby-core:64700] [Bug ruby#10191] * test/ruby/test_object.rb: extend timeout. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@47520 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 052b926 commit 9755952

File tree

5 files changed

+54
-20
lines changed

5 files changed

+54
-20
lines changed

ChangeLog

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
Wed Sep 10 23:36:38 2014 Koichi Sasada <[email protected]>
2+
3+
* test/ruby/test_object.rb: extend timeout.
4+
5+
Wed Sep 10 23:36:38 2014 Nobuyoshi Nakada <[email protected]>
6+
7+
* object.c (rb_obj_copy_ivar): allocate no memory for empty
8+
instance variables. [ruby-core:64700] [Bug #10191]
9+
10+
Wed Sep 10 23:36:38 2014 Nobuyoshi Nakada <[email protected]>
11+
12+
* object.c (rb_obj_copy_ivar): extract function to copy instance
13+
variables only for T_OBJECT from init_copy.
14+
115
Wed Sep 10 23:14:42 2014 NARUSE, Yui <[email protected]>
216

317
merge r46831 partially. extracted commits are as follows. [Bug #9344]

internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ rb_float_new_inline(double d)
595595
#define rb_float_new(d) rb_float_new_inline(d)
596596

597597
/* object.c */
598+
void rb_obj_copy_ivar(VALUE dest, VALUE obj);
598599
VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
599600
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
600601

object.c

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,33 @@ rb_obj_singleton_class(VALUE obj)
252252
return rb_singleton_class(obj);
253253
}
254254

255+
void
256+
rb_obj_copy_ivar(VALUE dest, VALUE obj)
257+
{
258+
if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
259+
xfree(ROBJECT_IVPTR(dest));
260+
ROBJECT(dest)->as.heap.ivptr = 0;
261+
ROBJECT(dest)->as.heap.numiv = 0;
262+
ROBJECT(dest)->as.heap.iv_index_tbl = 0;
263+
}
264+
if (RBASIC(obj)->flags & ROBJECT_EMBED) {
265+
MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
266+
RBASIC(dest)->flags |= ROBJECT_EMBED;
267+
}
268+
else {
269+
long len = ROBJECT(obj)->as.heap.numiv;
270+
VALUE *ptr = 0;
271+
if (len > 0) {
272+
ptr = ALLOC_N(VALUE, len);
273+
MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len);
274+
}
275+
ROBJECT(dest)->as.heap.ivptr = ptr;
276+
ROBJECT(dest)->as.heap.numiv = len;
277+
ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
278+
RBASIC(dest)->flags &= ~ROBJECT_EMBED;
279+
}
280+
}
281+
255282
static void
256283
init_copy(VALUE dest, VALUE obj)
257284
{
@@ -264,25 +291,7 @@ init_copy(VALUE dest, VALUE obj)
264291
rb_gc_copy_finalizer(dest, obj);
265292
switch (TYPE(obj)) {
266293
case T_OBJECT:
267-
if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
268-
xfree(ROBJECT_IVPTR(dest));
269-
ROBJECT(dest)->as.heap.ivptr = 0;
270-
ROBJECT(dest)->as.heap.numiv = 0;
271-
ROBJECT(dest)->as.heap.iv_index_tbl = 0;
272-
}
273-
if (RBASIC(obj)->flags & ROBJECT_EMBED) {
274-
MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
275-
RBASIC(dest)->flags |= ROBJECT_EMBED;
276-
}
277-
else {
278-
long len = ROBJECT(obj)->as.heap.numiv;
279-
VALUE *ptr = ALLOC_N(VALUE, len);
280-
MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len);
281-
ROBJECT(dest)->as.heap.ivptr = ptr;
282-
ROBJECT(dest)->as.heap.numiv = len;
283-
ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
284-
RBASIC(dest)->flags &= ~ROBJECT_EMBED;
285-
}
294+
rb_obj_copy_ivar(dest, obj);
286295
break;
287296
case T_CLASS:
288297
case T_MODULE:

test/ruby/test_object.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,4 +805,14 @@ def test_type_error_message
805805
assert_raise_with_message(TypeError, "can't convert Array into Integer") {Integer([42])}
806806
assert_raise_with_message(TypeError, 'no implicit conversion of Array into Integer') {[].first([42])}
807807
end
808+
809+
def test_copied_ivar_memory_leak
810+
bug10191 = '[ruby-core:64700] [Bug #10191]'
811+
assert_no_memory_leak([], <<-"end;", <<-"end;", bug10191, rss: true, timeout: 60, limit: 2.5)
812+
def (a = Object.new).set; @v = nil; end
813+
num = 500_000
814+
end;
815+
num.times {a.clone.set}
816+
end;
817+
end
808818
end

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#define RUBY_VERSION "2.1.2"
22
#define RUBY_RELEASE_DATE "2014-09-10"
3-
#define RUBY_PATCHLEVEL 234
3+
#define RUBY_PATCHLEVEL 235
44

55
#define RUBY_RELEASE_YEAR 2014
66
#define RUBY_RELEASE_MONTH 9

0 commit comments

Comments
 (0)