void ObjectMemory::collect_maybe(STATE, GCToken gct, CallFrame* call_frame) { // Don't go any further unless we're allowed to GC. if(!can_gc()) return; while(!state->stop_the_world()) { state->checkpoint(gct, call_frame); // Someone else got to the GC before we did! No problem, all done! if(!collect_young_now && !collect_mature_now) return; } // Ok, everyone in stopped! LET'S GC! SYNC(state); state->shared().finalizer_handler()->start_collection(state); if(cDebugThreading) { std::cerr << std::endl << "[" << state << " WORLD beginning GC.]" << std::endl; } if(collect_young_now) { GCData gc_data(state->vm()); YoungCollectStats stats; RUBINIUS_GC_BEGIN(0); #ifdef RBX_PROFILER if(unlikely(state->vm()->tooling())) { tooling::GCEntry method(state, tooling::GCYoung); collect_young(state, &gc_data, &stats); } else { collect_young(state, &gc_data, &stats); } #else collect_young(state, &gc_data, &stats); #endif RUBINIUS_GC_END(0); print_young_stats(state, &gc_data, &stats); } if(collect_mature_now) { GCData* gc_data = new GCData(state->vm()); RUBINIUS_GC_BEGIN(1); #ifdef RBX_PROFILER if(unlikely(state->vm()->tooling())) { tooling::GCEntry method(state, tooling::GCMature); collect_mature(state, gc_data); } else { collect_mature(state, gc_data); } #else collect_mature(state, gc_data); #endif if(!mature_mark_concurrent_) { collect_mature_finish(state, gc_data); print_mature_stats(state, gc_data); } } state->restart_world(); UNSYNC; }
void ObjectMemory::collect_maybe(STATE, GCToken gct, CallFrame* call_frame) { // Don't go any further unless we're allowed to GC. if(!can_gc()) return; while(!state->stop_the_world()) { state->checkpoint(gct, call_frame); // Someone else got to the GC before we did! No problem, all done! if(!collect_young_now && !collect_mature_now) return; } // Ok, everyone in stopped! LET'S GC! SYNC(state); state->shared().finalizer_handler()->start_collection(state); if(cDebugThreading) { std::cerr << std::endl << "[" << state << " WORLD beginning GC.]" << std::endl; } GCData gc_data(state->vm(), gct); uint64_t start_time = 0; if(collect_young_now) { if(state->shared().config.gc_show) { start_time = get_current_time(); } YoungCollectStats stats; #ifdef RBX_PROFILER if(unlikely(state->vm()->tooling())) { tooling::GCEntry method(state, tooling::GCYoung); collect_young(gc_data, &stats); } else { collect_young(gc_data, &stats); } #else collect_young(gc_data, &stats); #endif if(state->shared().config.gc_show) { uint64_t fin_time = get_current_time(); int diff = (fin_time - start_time) / 1000000; std::cerr << "[GC " << std::fixed << std::setprecision(1) << stats.percentage_used << "% " << stats.promoted_objects << "/" << stats.excess_objects << " " << stats.lifetime << " " << diff << "ms]" << std::endl; if(state->shared().config.gc_noisy) { std::cerr << "\a" << std::flush; } } } if(collect_mature_now) { size_t before_kb = 0; if(state->shared().config.gc_show) { start_time = get_current_time(); before_kb = mature_bytes_allocated() / 1024; } #ifdef RBX_PROFILER if(unlikely(state->vm()->tooling())) { tooling::GCEntry method(state, tooling::GCMature); collect_mature(gc_data); } else { collect_mature(gc_data); } #else collect_mature(gc_data); #endif if(state->shared().config.gc_show) { uint64_t fin_time = get_current_time(); int diff = (fin_time - start_time) / 1000000; size_t kb = mature_bytes_allocated() / 1024; std::cerr << "[Full GC " << before_kb << "kB => " << kb << "kB " << diff << "ms]" << std::endl; if(state->shared().config.gc_noisy) { std::cerr << "\a\a" << std::flush; } } } state->shared().finalizer_handler()->finish_collection(state); state->restart_world(); UNSYNC; }