From: wanabe Date: 2009-10-16T21:05:24+09:00 Subject: [ruby-dev:39493] Re: [BUG: trunk] GC mark bug ワナベです。 2009年10月15日6:34 wanabe : > ワナベと申します。 > eval された ISeq が破棄されるとき、現在の iseq_free では > 子 ISeq のマーク状態に関わらず先頭の iseq->iseq からすべて > 破棄しているからではないでしょうか。 すみません、よく調べずに的外れなことを言っていました。 もしかして、モジュールのメソッドエントリのテーブルが unpack_entries で再構築されるときに、その中の st_insert が vm_xmalloc を呼び出して GC が始まってしまう、ということはないでしょうか。 だとすると、もしかして例えば以下のようにすると落ちなくなったりしないでしょうか。 Index: st.c =================================================================== --- st.c (revision 25371) +++ st.c (working copy) @@ -418,15 +418,17 @@ { int i; struct st_table_entry *packed_bins[MAX_PACKED_NUMHASH*2]; - int num_entries = table->num_entries; + st_table tmp_table = *table; - memcpy(packed_bins, table->bins, sizeof(struct st_table_entry *) * num_entries*2); - table->entries_packed = 0; - table->num_entries = 0; - memset(table->bins, 0, sizeof(struct st_table_entry *) * table->num_bins); - for (i = 0; i < num_entries; i++) { - st_insert(table, (st_data_t)packed_bins[i*2], (st_data_t)packed_bins[i*2+1]); + memcpy(packed_bins, table->bins, sizeof(struct st_table_entry *) * table->num_entries*2); + table->bins = packed_bins; + tmp_table.entries_packed = 0; + tmp_table.num_entries = 0; + memset(tmp_table.bins, 0, sizeof(struct st_table_entry *) * tmp_table.num_bins); + for (i = 0; i < table->num_entries; i++) { + st_insert(&tmp_table, (st_data_t)packed_bins[i*2], (st_data_t)packed_bins[i*2+1]); } + *table = tmp_table; } int -- ワナベ