summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-05-27 02:08:29 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-05-27 02:08:29 +0000
commit7615c70db7ff2ed874626e4afa60d2a29636315e (patch)
tree7ddddb83c60d496c350d8ea4e5009a43d3fb2b34
parent9fbf488746ae71923180289d9d832d8ad87fd579 (diff)
gc.c: stress_to_class
* gc.c (newobj_of): debug feature to fail allocation of particular classes. * gc.c (rb_gcdebug_add_stress_to_class): add classes to the list. * gc.c (rb_gcdebug_remove_stress_to_class): remove classes from the list. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50647 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--gc.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/gc.c b/gc.c
index 454034afdb..ace0b74baf 100644
--- a/gc.c
+++ b/gc.c
@@ -301,6 +301,10 @@ static ruby_gc_params_t gc_params = {
#define MALLOC_ALLOCATED_SIZE_CHECK 0
#endif
+#ifndef GC_DEBUG_STRESS_TO_CLASS
+#define GC_DEBUG_STRESS_TO_CLASS 0
+#endif
+
typedef enum {
GPR_FLAG_NONE = 0x000,
/* major reason */
@@ -612,6 +616,10 @@ typedef struct rb_objspace {
} rincgc;
#endif
#endif /* USE_RGENGC */
+
+#if GC_DEBUG_STRESS_TO_CLASS
+ VALUE stress_to_class;
+#endif
} rb_objspace_t;
@@ -715,6 +723,11 @@ VALUE *ruby_initial_gc_stress_ptr = &ruby_initial_gc_stress;
#define global_list objspace->global_list
#define ruby_gc_stressful objspace->flags.gc_stressful
#define ruby_gc_stress_mode objspace->gc_stress_mode
+#if GC_DEBUG_STRESS_TO_CLASS
+#define stress_to_class objspace->stress_to_class
+#else
+#define stress_to_class 0
+#endif
#define is_marking(objspace) ((objspace)->flags.stat == gc_stat_marking)
#define is_sweeping(objspace) ((objspace)->flags.stat == gc_stat_sweeping)
@@ -1674,6 +1687,16 @@ newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3)
rb_objspace_t *objspace = &rb_objspace;
VALUE obj;
+#if GC_DEBUG_STRESS_TO_CLASS
+ if (UNLIKELY(stress_to_class)) {
+ long i, cnt = RARRAY_LEN(stress_to_class);
+ const VALUE *ptr = RARRAY_CONST_PTR(stress_to_class);
+ for (i = 0; i < cnt; ++i) {
+ if (klass == ptr[i]) rb_memerror();
+ }
+ }
+#endif
+
if (UNLIKELY(during_gc || ruby_gc_stressful)) {
if (during_gc) {
dont_gc = 1;
@@ -8991,6 +9014,37 @@ rb_gcdebug_sentinel(VALUE obj, const char *name)
#endif /* GC_DEBUG */
+#if GC_DEBUG_STRESS_TO_CLASS
+static VALUE
+rb_gcdebug_add_stress_to_class(int argc, VALUE *argv, VALUE self)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+
+ if (!stress_to_class) {
+ stress_to_class = rb_ary_tmp_new(argc);
+ }
+ rb_ary_cat(stress_to_class, argv, argc);
+ return self;
+}
+
+static VALUE
+rb_gcdebug_remove_stress_to_class(int argc, VALUE *argv, VALUE self)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+ int i;
+
+ if (stress_to_class) {
+ for (i = 0; i < argc; ++i) {
+ rb_ary_delete_same(stress_to_class, argv[i]);
+ }
+ if (RARRAY_LEN(stress_to_class) == 0) {
+ stress_to_class = 0;
+ }
+ }
+ return Qnil;
+}
+#endif
+
/*
* Document-module: ObjectSpace
*
@@ -9136,6 +9190,11 @@ Init_GC(void)
rb_define_singleton_method(rb_mGC, "malloc_allocations", gc_malloc_allocations, 0);
#endif
+#if GC_DEBUG_STRESS_TO_CLASS
+ rb_define_singleton_method(rb_mGC, "add_stress_to_class", rb_gcdebug_add_stress_to_class, -1);
+ rb_define_singleton_method(rb_mGC, "remove_stress_to_class", rb_gcdebug_remove_stress_to_class, -1);
+#endif
+
/* ::GC::OPTS, which shows GC build options */
{
VALUE opts;