void ObjectMemory::collect_mature_finish(STATE, GCData* data) {

    immix_->collect_finish(data);
    code_manager_.sweep();

    data->global_cache()->prune_unmarked(mark());

    prune_handles(data->handles(), data->cached_handles(), NULL);

    // Have to do this after all things that check for mark bits is
    // done, as it free()s objects, invalidating mark bits.
    mark_sweep_->after_marked();

    inflated_headers_->deallocate_headers(mark());

#ifdef RBX_GC_DEBUG
    immix_->verify(data);
#endif
    immix_->sweep();

    rotate_mark();

    gc_stats.full_collection_count++;
    if(FinalizerHandler* hdl = state->shared().finalizer_handler()) {
      hdl->finish_collection(state);
    }

    RUBINIUS_GC_END(1);
    young_autotune();
    young_gc_while_marking_ = 0;
  }
Beispiel #2
0
  void ObjectMemory::collect_mature_finish(STATE, GCData* data) {

    immix_->collect_finish(data);
    code_manager_.sweep();

    data->global_cache()->prune_unmarked(mark());

    prune_handles(data->handles(), data->cached_handles(), NULL);

    // Have to do this after all things that check for mark bits is
    // done, as it free()s objects, invalidating mark bits.
    mark_sweep_->after_marked();

    inflated_headers_->deallocate_headers(mark());

#ifdef RBX_GC_DEBUG
    immix_->verify(data);
#endif
    immix_->sweep();

    rotate_mark();

    metrics::MetricsData& metrics = state->vm()->metrics();
    metrics.m.ruby_metrics.gc_immix_count++;
    metrics.m.ruby_metrics.gc_large_count++;
    metrics.m.ruby_metrics.memory_immix_bytes = immix_->bytes_allocated();
    metrics.m.ruby_metrics.memory_large_bytes = mark_sweep_->allocated_bytes;
    metrics.m.ruby_metrics.memory_symbols_bytes = shared_.symbols.bytes_used();
    metrics.m.ruby_metrics.memory_code_bytes = code_manager_.size();
    metrics.m.ruby_metrics.memory_jit_bytes = data->jit_bytes_allocated();

    if(FinalizerThread* hdl = state->shared().finalizer_handler()) {
      hdl->finish_collection(state);
    }

    RUBINIUS_GC_END(1);
    young_autotune();
    young_gc_while_marking_ = 0;
  }
  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;
  }
Beispiel #4
0
  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;

      RUBINIUS_GC_BEGIN(0);
#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

      RUBINIUS_GC_END(0);

      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;
      }

      RUBINIUS_GC_BEGIN(1);
#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

      RUBINIUS_GC_END(1);

      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;
  }