mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
merge revision(s) 46501,47372,47460: [Backport #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 #10191] * test/ruby/test_object.rb: extend timeout. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@47548 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
97acdd7143
commit
9f67424dc9
5 changed files with 54 additions and 20 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
Fri Sep 12 11:34:39 2014 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* test/ruby/test_object.rb: extend timeout.
|
||||||
|
|
||||||
|
Fri Sep 12 11:34:39 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* object.c (rb_obj_copy_ivar): allocate no memory for empty
|
||||||
|
instance variables. [ruby-core:64700] [Bug #10191]
|
||||||
|
|
||||||
|
Fri Sep 12 11:34:39 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* object.c (rb_obj_copy_ivar): extract function to copy instance
|
||||||
|
variables only for T_OBJECT from init_copy.
|
||||||
|
|
||||||
Fri Sep 12 11:30:50 2014 NAKAMURA Usaku <usa@ruby-lang.org>
|
Fri Sep 12 11:30:50 2014 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* regcomp.c: Merge Onigmo 988517a4f16f14acbd7cc9d5b51a096d5153992c.
|
* regcomp.c: Merge Onigmo 988517a4f16f14acbd7cc9d5b51a096d5153992c.
|
||||||
|
|
|
@ -182,6 +182,7 @@ VALUE rb_int_succ(VALUE num);
|
||||||
VALUE rb_int_pred(VALUE num);
|
VALUE rb_int_pred(VALUE num);
|
||||||
|
|
||||||
/* object.c */
|
/* object.c */
|
||||||
|
void rb_obj_copy_ivar(VALUE dest, VALUE obj);
|
||||||
VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
|
VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
|
||||||
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
|
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
|
||||||
|
|
||||||
|
|
47
object.c
47
object.c
|
@ -219,6 +219,33 @@ rb_obj_singleton_class(VALUE obj)
|
||||||
return rb_singleton_class(obj);
|
return rb_singleton_class(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_obj_copy_ivar(VALUE dest, VALUE obj)
|
||||||
|
{
|
||||||
|
if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
|
||||||
|
xfree(ROBJECT_IVPTR(dest));
|
||||||
|
ROBJECT(dest)->as.heap.ivptr = 0;
|
||||||
|
ROBJECT(dest)->as.heap.numiv = 0;
|
||||||
|
ROBJECT(dest)->as.heap.iv_index_tbl = 0;
|
||||||
|
}
|
||||||
|
if (RBASIC(obj)->flags & ROBJECT_EMBED) {
|
||||||
|
MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
|
||||||
|
RBASIC(dest)->flags |= ROBJECT_EMBED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
long len = ROBJECT(obj)->as.heap.numiv;
|
||||||
|
VALUE *ptr = 0;
|
||||||
|
if (len > 0) {
|
||||||
|
ptr = ALLOC_N(VALUE, len);
|
||||||
|
MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len);
|
||||||
|
}
|
||||||
|
ROBJECT(dest)->as.heap.ivptr = ptr;
|
||||||
|
ROBJECT(dest)->as.heap.numiv = len;
|
||||||
|
ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
|
||||||
|
RBASIC(dest)->flags &= ~ROBJECT_EMBED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_copy(VALUE dest, VALUE obj)
|
init_copy(VALUE dest, VALUE obj)
|
||||||
{
|
{
|
||||||
|
@ -231,25 +258,7 @@ init_copy(VALUE dest, VALUE obj)
|
||||||
rb_gc_copy_finalizer(dest, obj);
|
rb_gc_copy_finalizer(dest, obj);
|
||||||
switch (TYPE(obj)) {
|
switch (TYPE(obj)) {
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
|
rb_obj_copy_ivar(dest, obj);
|
||||||
xfree(ROBJECT_IVPTR(dest));
|
|
||||||
ROBJECT(dest)->as.heap.ivptr = 0;
|
|
||||||
ROBJECT(dest)->as.heap.numiv = 0;
|
|
||||||
ROBJECT(dest)->as.heap.iv_index_tbl = 0;
|
|
||||||
}
|
|
||||||
if (RBASIC(obj)->flags & ROBJECT_EMBED) {
|
|
||||||
MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
|
|
||||||
RBASIC(dest)->flags |= ROBJECT_EMBED;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
long len = ROBJECT(obj)->as.heap.numiv;
|
|
||||||
VALUE *ptr = ALLOC_N(VALUE, len);
|
|
||||||
MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len);
|
|
||||||
ROBJECT(dest)->as.heap.ivptr = ptr;
|
|
||||||
ROBJECT(dest)->as.heap.numiv = len;
|
|
||||||
ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
|
|
||||||
RBASIC(dest)->flags &= ~ROBJECT_EMBED;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
|
|
|
@ -898,4 +898,14 @@ class TestObject < Test::Unit::TestCase
|
||||||
err = assert_raise(TypeError){ [].first([42]) }
|
err = assert_raise(TypeError){ [].first([42]) }
|
||||||
assert_equal 'no implicit conversion of Array into Integer', err.message, issue
|
assert_equal 'no implicit conversion of Array into Integer', err.message, issue
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_copied_ivar_memory_leak
|
||||||
|
bug10191 = '[ruby-core:64700] [Bug #10191]'
|
||||||
|
assert_no_memory_leak([], <<-"end;", <<-"end;", bug10191, rss: true, timeout: 60)
|
||||||
|
def (a = Object.new).set; @v = nil; end
|
||||||
|
num = 500_000
|
||||||
|
end;
|
||||||
|
num.times {a.clone.set}
|
||||||
|
end;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#define RUBY_VERSION "2.0.0"
|
#define RUBY_VERSION "2.0.0"
|
||||||
#define RUBY_RELEASE_DATE "2014-09-12"
|
#define RUBY_RELEASE_DATE "2014-09-12"
|
||||||
#define RUBY_PATCHLEVEL 569
|
#define RUBY_PATCHLEVEL 570
|
||||||
|
|
||||||
#define RUBY_RELEASE_YEAR 2014
|
#define RUBY_RELEASE_YEAR 2014
|
||||||
#define RUBY_RELEASE_MONTH 9
|
#define RUBY_RELEASE_MONTH 9
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue