From 295825e3f515f08e67a84e19c84c011311999d0f Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 27 May 2015 02:08:29 +0000 Subject: 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 --- gc.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) 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; -- cgit v1.2.3