ruby-changes:21098
From: nahi <ko1@a...>
Date: Wed, 31 Aug 2011 17:35:35 +0900 (JST)
Subject: [ruby-changes:21098] nahi:r33147 (trunk): * variable.c (rb_autoload): There was a chance to run GC (from
nahi 2011-08-31 17:35:27 +0900 (Wed, 31 Aug 2011) New Revision: 33147 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=33147 Log: * variable.c (rb_autoload): There was a chance to run GC (from rb_str_new2()) before finishing autoload_data_i construction. It caused SEGV at rb_gc_mark() at autoload_i_mark. * variable.c (rb_autoload_load): Move RB_GC_GUARD() to proper position based on suggestion by CHIKANAGA Tomoyuki at http://d.hatena.ne.jp/nagachika/20110826/ruby_trunk_changes_33070_33078 * variable.c (autoload_defined_p): Fix incompatible autoload behavior that causes Rails crash. Class deifnition instruction defined in 'defineclass' in insns.def always invokes rb_autoload_load for a constant. It's invoked for every class definition regardless of existence of autoload definition. rb_autoload_load checkes if a constant is defined as autoloaded, but new thread-safe autoload returned different value if the constant is under autoloading. Modified files: trunk/ChangeLog trunk/variable.c Index: ChangeLog =================================================================== --- ChangeLog (revision 33146) +++ ChangeLog (revision 33147) @@ -1,3 +1,21 @@ +Wed Aug 31 17:28:23 2011 Hiroshi Nakamura <nahi@r...> + + * variable.c (rb_autoload): There was a chance to run GC (from + rb_str_new2()) before finishing autoload_data_i construction. It + caused SEGV at rb_gc_mark() at autoload_i_mark. + + * variable.c (rb_autoload_load): Move RB_GC_GUARD() to proper + position based on suggestion by CHIKANAGA Tomoyuki at + http://d.hatena.ne.jp/nagachika/20110826/ruby_trunk_changes_33070_33078 + + * variable.c (autoload_defined_p): Fix incompatible autoload behavior + that causes Rails crash. Class deifnition instruction defined in + 'defineclass' in insns.def always invokes rb_autoload_load for a + constant. It's invoked for every class definition regardless of + existence of autoload definition. rb_autoload_load checkes if a + constant is defined as autoloaded, but new thread-safe autoload + returned different value if the constant is under autoloading. + Wed Aug 31 17:20:56 2011 Hiroshi Nakamura <nahi@r...> * Re-apply r33078, thread-safe autoload which is reverted at r33093. Index: variable.c =================================================================== --- variable.c (revision 33146) +++ variable.c (revision 33147) @@ -1524,17 +1524,17 @@ st_add_direct(tbl, (st_data_t)autoload, av); DATA_PTR(av) = tbl = st_init_numtable(); } - ad = TypedData_Wrap_Struct(0, &autoload_data_i_type, 0); - st_insert(tbl, (st_data_t)id, (st_data_t)ad); - DATA_PTR(ad) = ele = ALLOC(struct autoload_data_i); - fn = rb_str_new2(file); FL_UNSET(fn, FL_TAINT); OBJ_FREEZE(fn); + + ele = ALLOC(struct autoload_data_i); ele->feature = fn; ele->safe_level = rb_safe_level(); ele->thread = Qnil; ele->value = Qundef; + ad = TypedData_Wrap_Struct(0, &autoload_data_i_type, ele); + st_insert(tbl, (st_data_t)id, (st_data_t)ad); } static void @@ -1610,7 +1610,7 @@ if (!tbl || !st_lookup(tbl, (st_data_t)id, &val) || ((rb_const_entry_t*)val)->value != Qundef) { return 0; } - return 1; + return !rb_autoloading_value(mod, id, NULL); } int @@ -1674,7 +1674,6 @@ ele->thread = rb_thread_current(); } /* autoload_data_i can be deleted by another thread while require */ - RB_GC_GUARD(load); result = rb_protect((VALUE(*)(VALUE))autoload_require, (VALUE)ele, &state); if (ele->thread == rb_thread_current()) { ele->thread = Qnil; @@ -1694,6 +1693,7 @@ rb_ensure((VALUE(*)(VALUE))autoload_const_set, (VALUE)&args, reset_safe, (VALUE)safe_backup); } } + RB_GC_GUARD(load); return result; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/