summaryrefslogtreecommitdiffhomepage
path: root/src/gc.c
diff options
context:
space:
mode:
authorKOBAYASHI Shuji <[email protected]>2019-12-25 20:01:55 +0900
committerKOBAYASHI Shuji <[email protected]>2019-12-25 21:31:10 +0900
commit0b2d54f4f1d66a0b00625dcc634966d67c29b8b8 (patch)
treefb34f7702c2654160b4a34b639b147df2a116d91 /src/gc.c
parentd4cbe6271cc8343647fd0841bb549e1b7c804c34 (diff)
downloadmruby-0b2d54f4f1d66a0b00625dcc634966d67c29b8b8.tar.gz
mruby-0b2d54f4f1d66a0b00625dcc634966d67c29b8b8.zip
Fix potentially use of wrong method cache
#### Example (with `MRB_METHOD_CACHE`) ```ruby GC.start c = Class.new p c #=> #<Class:0x7fd6a180e790> c.new #=> cache `c.new` c = nil GC.start #=> `c` is GCed r = Range.dup p r #=> #<Class:0x7fd6a180e790> # [same pointer as `c`] r.new(2, 3) #=> ArgumentError: 'initialize': # wrong number of arguments (2 for 0) # [`c.new` is called instead of `r.new`] ``` #### Cause An entry of method cache is identified by class pointer and method id. However, reusing memory after GC may create a class with the same pointer as the cached class. #### Treatment Cleared method caches of the class when the class is GCed.
Diffstat (limited to 'src/gc.c')
-rw-r--r--src/gc.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/src/gc.c b/src/gc.c
index 40c85a373..8d9a1806c 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -807,10 +807,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end)
case MRB_TT_SCLASS:
mrb_gc_free_mt(mrb, (struct RClass*)obj);
mrb_gc_free_iv(mrb, (struct RObject*)obj);
+ mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
break;
case MRB_TT_ICLASS:
if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN))
mrb_gc_free_mt(mrb, (struct RClass*)obj);
+ mrb_mc_clear_by_class(mrb, (struct RClass*)obj);
break;
case MRB_TT_ENV:
{