summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--class.c4
-rw-r--r--eval.c4
-rw-r--r--vm_method.c19
4 files changed, 34 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 41d6683630..81c39cc3d3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Sun Jun 23 05:41:32 2013 Koichi Sasada <ko1@atdot.net>
+
+ * class.c (rb_include_class_new), eval.c (rb_using_refinement):
+ make classes/modules (who share method table) shady.
+ If module `a' and `b' shares method table m_tbl and new method
+ with iseq is added, then write barrier is applied only `a' or `b'.
+ To avoid this issue, shade such classes/modules.
+
+ * vm_method.c (rb_method_entry_make): add write barriers.
+
Sun Jun 23 01:27:54 2013 Tanaka Akira <akr@fsij.org>
* bignum.c (bytes_zero_p): Removed.
diff --git a/class.c b/class.c
index 21e39e2efe..b4614efadd 100644
--- a/class.c
+++ b/class.c
@@ -689,7 +689,9 @@ rb_include_class_new(VALUE module, VALUE super)
}
RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
- RCLASS_M_TBL(klass) = RCLASS_M_TBL(RCLASS_ORIGIN(module));
+
+ RCLASS_M_TBL(OBJ_WB_GIVEUP(klass)) = RCLASS_M_TBL(OBJ_WB_GIVEUP(RCLASS_ORIGIN(module)));
+
RCLASS_SET_SUPER(klass, super);
if (RB_TYPE_P(module, T_ICLASS)) {
RBASIC_SET_CLASS(klass, RBASIC(module)->klass);
diff --git a/eval.c b/eval.c
index c6b6aad8b4..6d6eb55426 100644
--- a/eval.c
+++ b/eval.c
@@ -1099,7 +1099,9 @@ rb_using_refinement(NODE *cref, VALUE klass, VALUE module)
FL_SET(module, RMODULE_IS_OVERLAID);
c = iclass = rb_include_class_new(module, superclass);
RCLASS_REFINED_CLASS(c) = klass;
- RCLASS_M_TBL(c) = RCLASS_M_TBL(module);
+
+ RCLASS_M_TBL(OBJ_WB_GIVEUP(c)) = RCLASS_M_TBL(OBJ_WB_GIVEUP(module));
+
module = RCLASS_SUPER(module);
while (module && module != klass) {
FL_SET(module, RMODULE_IS_OVERLAID);
diff --git a/vm_method.c b/vm_method.c
index 427ee9b06b..969facc3b1 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -317,7 +317,24 @@ rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type,
me->called_id = mid;
me->klass = klass;
me->def = def;
- if (def) def->alias_count++;
+
+ if (def) {
+ def->alias_count++;
+
+ switch(def->type) {
+ case VM_METHOD_TYPE_ISEQ:
+ OBJ_WRITTEN(klass, Qundef, def->body.iseq);
+ break;
+ case VM_METHOD_TYPE_IVAR:
+ OBJ_WRITTEN(klass, Qundef, def->body.attr.location);
+ break;
+ case VM_METHOD_TYPE_BMETHOD:
+ OBJ_WRITTEN(klass, Qundef, def->body.proc);
+ break;
+ default:;
+ /* ignore */
+ }
+ }
/* check mid */
if (klass == rb_cObject && mid == idInitialize) {