Skip to content

Commit

Permalink
Add RBX_GC_STRESS compile time flag to enable GC stress testing
Browse files Browse the repository at this point in the history
This allows for defining stress testing of the young and / or mature GC.
This means that the given GC will run as often as possible on every
possible GC checkpoint. This makes it easier to flush out issues due
to for example the GC moving objects.
  • Loading branch information
dbussink committed May 27, 2013
1 parent 8e6e5fb commit c1955fa
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 9 deletions.
9 changes: 9 additions & 0 deletions vm/builtin/class.cpp
Expand Up @@ -133,6 +133,9 @@ namespace rubinius {
if(unlikely(state->vm()->allocation_tracking())) {
new_obj->setup_allocation_site(state, calling_environment);
}
#endif
#ifdef RBX_GC_STRESS
state->shared().gc_soon();
#endif
return new_obj;
} else if(!type_info_->allow_user_allocate || kind_of<SingletonClass>(this)) {
Expand All @@ -149,6 +152,9 @@ namespace rubinius {
if(unlikely(state->vm()->allocation_tracking())) {
new_obj->setup_allocation_site(state, calling_environment);
}
#endif
#ifdef RBX_GC_STRESS
state->shared().gc_soon();
#endif
return new_obj;
} else {
Expand All @@ -160,6 +166,9 @@ namespace rubinius {
if(unlikely(state->vm()->allocation_tracking())) {
new_obj->setup_allocation_site(state, calling_environment);
}
#endif
#ifdef RBX_GC_STRESS
state->shared().gc_soon();
#endif
return new_obj;
}
Expand Down
20 changes: 16 additions & 4 deletions vm/config.h
Expand Up @@ -6,8 +6,20 @@

#define RBX_STRERROR_BUFSIZE 256

/*
* Enable this define for some minimal GC debugging
* #define RBX_GC_DEBUG
*/
// Enable this define for some minimal GC debugging
// #define RBX_GC_DEBUG

// Enable for GC stress. This only ensures that the interrupts
// for a GC are set. Use RBX_GC_STRESS_YOUNG and / or RBX_GC_STRESS_MATURE
// to run either the young or mature gen on each possibility
// #define RBX_GC_STRESS

// When stress testing is enabled, forces a young collection every time it
// is possible. This can be useful to flush out bugs because of moving objects.
// #define RBX_GC_STRESS_YOUNG

// When stress testing is enabled, forces a mature collection every time it
// is possible. This can be useful to flush out bugs with reachability etc.
// #define RBX_GC_STRESS_MATURE

#endif
3 changes: 3 additions & 0 deletions vm/gc/heap.cpp
Expand Up @@ -61,7 +61,10 @@ namespace rubinius {
current_ = start_;
scan_ = start_;
#ifdef RBX_GC_DEBUG
// To heavy when doing GC stress and not necessary
#ifndef RBX_GC_STRESS
memset(start_, 0xff, size_);
#endif
#endif
}

Expand Down
5 changes: 4 additions & 1 deletion vm/objectmemory.cpp
Expand Up @@ -580,7 +580,9 @@ namespace rubinius {
}

void ObjectMemory::collect_young(GCData& data, YoungCollectStats* stats) {
#ifndef RBX_GC_STRESS_YOUNG
collect_young_now = false;
#endif

timer::Running<1000000> timer(gc_stats.total_young_collection_time,
gc_stats.last_young_collection_time);
Expand Down Expand Up @@ -620,8 +622,9 @@ namespace rubinius {

timer::Running<1000000> timer(gc_stats.total_full_collection_time,
gc_stats.last_full_collection_time);

#ifndef RBX_GC_STRESS_MATURE
collect_mature_now = false;
#endif

code_manager_.clear_marks();

Expand Down
14 changes: 10 additions & 4 deletions vm/vm.cpp
Expand Up @@ -197,7 +197,9 @@ namespace rubinius {
}

obj->init_header(cls, YoungObjectZone, type);

#ifdef RBX_GC_STRESS
state.shared().gc_soon();
#endif
return obj;
}

Expand All @@ -208,6 +210,7 @@ namespace rubinius {
}

Tuple* VM::new_young_tuple_dirty(size_t fields) {
State state(this);
size_t bytes = Tuple::fields_offset + (sizeof(Object*) * fields);

if(unlikely(bytes > om->large_object_threshold)) {
Expand All @@ -217,7 +220,6 @@ namespace rubinius {
Tuple* tup = local_slab().allocate(bytes).as<Tuple>();

if(unlikely(!tup)) {
State state(this);

if(shared.om->refill_slab(&state, local_slab())) {
tup = local_slab().allocate(bytes).as<Tuple>();
Expand All @@ -228,13 +230,17 @@ namespace rubinius {

tup->init_header(G(tuple), YoungObjectZone, Tuple::type);
tup->full_size_ = bytes;

#ifdef RBX_GC_STRESS
state.shared().gc_soon();
#endif
return tup;
}

Object* VM::new_object_typed_mature(Class* cls, size_t bytes, object_type type) {
State state(this);

#ifdef RBX_GC_STRESS
state.shared().gc_soon();
#endif
return om->new_object_typed_mature(&state, cls, bytes, type);
}

Expand Down

0 comments on commit c1955fa

Please sign in to comment.