Revert "Fix finalize of WeakRef"
This causes segv on rubyspec.
http://u64.rubyci.org/~chkbuild/ruby-trunk/log/20121124T050101Z.log.html.gz

you can reproduce by
 make test-rubyspec MSPECOPT='-V library/weakref'

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37831 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2012-11-24 07:43:13 +00:00
Родитель 9d803dfd5f
Коммит 757413f6bb
3 изменённых файлов: 15 добавлений и 66 удалений

Просмотреть файл

@ -20,35 +20,6 @@ Sat Nov 24 12:28:04 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
(VALUE *), but 0 of variable argument seems not equal to null pointer
on x64 mingw.
Sat Nov 24 12:12:41 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
* gc.c (wmap_final_func): rename variables to clarify the meaning.
In wmap2obj the key is WeakRef and the value is referenced object.
In obj2wmap the key is referenced object and the value is an array
of WeakRef.
* gc.c (wmap_finalize): ditto.
[ruby-core:49044] [Bug #7304]
Sat Nov 24 12:10:26 2012 Hiroshi Shirosaki <h.shirosaki@gmail.com>
* gc.c (wmap_final_func): remove WeakRef object reference from the
array.
* gc.c (wmap_finalize): remove recycled object references from weak
map hash properly. How to get object reference from object id was
wrong. st_delete() doesn't work properly if key and value arguments
are same. The key of obj2wmap is referenced object and the value of
obj2wmap is WeakRef array.
* gc.c (wmap_aset): obj2wmap should contain WeakRef array in the
definition.
* test/test_weakref.rb
(TestWeakRef#test_not_reference_different_object): add a test for
above.
[ruby-core:49044] [Bug #7304]
Sat Nov 24 11:47:14 2012 KOSAKI Motohiro <kosaki.motohiro@gmail.com>
* process.c (proc_getsid): adds new method for getting session id.

33
gc.c
Просмотреть файл

@ -3749,40 +3749,37 @@ wmap_allocate(VALUE klass)
static int
wmap_final_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
{
VALUE wmap, ary;
VALUE obj, ary;
if (!existing) return ST_STOP;
wmap = (VALUE)arg, ary = (VALUE)*value;
rb_ary_delete(ary, wmap);
obj = (VALUE)*key, ary = (VALUE)*value;
rb_ary_delete(ary, obj);
if (!RARRAY_LEN(ary)) return ST_DELETE;
return ST_CONTINUE;
}
static VALUE
wmap_finalize(VALUE self, VALUE objid)
wmap_finalize(VALUE self, VALUE obj)
{
st_data_t orig, wmap, data;
VALUE obj, rids;
st_data_t data;
VALUE rids;
long i;
struct weakmap *w;
TypedData_Get_Struct(self, struct weakmap, &weakmap_type, w);
/* Get reference from object id. */
obj = objid ^ FIXNUM_FLAG; /* unset FIXNUM_FLAG */
obj = NUM2PTR(obj);
/* obj is original referenced object and/or weak reference. */
orig = (st_data_t)obj;
if (st_delete(w->obj2wmap, &orig, &data)) {
data = (st_data_t)obj;
if (st_delete(w->obj2wmap, &data, &data)) {
rids = (VALUE)data;
for (i = 0; i < RARRAY_LEN(rids); ++i) {
wmap = (st_data_t)RARRAY_PTR(rids)[i];
st_delete(w->wmap2obj, &wmap, NULL);
data = (st_data_t)RARRAY_PTR(rids)[i];
st_delete(w->wmap2obj, &data, NULL);
}
}
wmap = (st_data_t)obj;
if (st_delete(w->wmap2obj, &wmap, &orig)) {
wmap = (st_data_t)obj;
st_update(w->obj2wmap, orig, wmap_final_func, wmap);
data = (st_data_t)obj;
if (st_delete(w->wmap2obj, &data, &data)) {
st_update(w->obj2wmap, (st_data_t)obj, wmap_final_func, 0);
}
return self;
}
@ -3804,7 +3801,7 @@ wmap_aset(VALUE self, VALUE wmap, VALUE orig)
rids = rb_ary_tmp_new(1);
st_insert(w->obj2wmap, (st_data_t)orig, (st_data_t)rids);
}
rb_ary_push(rids, wmap);
rb_ary_push(rids, orig);
st_insert(w->wmap2obj, (st_data_t)wmap, (st_data_t)orig);
return nonspecial_obj_id(orig);
}

Просмотреть файл

@ -21,23 +21,4 @@ class TestWeakRef < Test::Unit::TestCase
ObjectSpace.garbage_collect
assert_raise(WeakRef::RefError) {weak.to_s}
end
def test_not_reference_different_object
bug7304 = '[ruby-core:49044]'
weakrefs = []
3.times do
obj = Object.new
def obj.foo; end
weakrefs << WeakRef.new(obj)
ObjectSpace.garbage_collect
end
assert_nothing_raised(NoMethodError, bug7304) {
weakrefs.each do |weak|
begin
weak.foo
rescue WeakRef::RefError
end
end
}
end
end