Ejemplo n.º 1
0
 void ObjectMemory::young_autotune() {
   if(young_autotune_size) {
     // We autotune the size if we do multiple young
     // collections during a mature mark phase. This indicates
     // that memory pressure is higher and we might want to grow
     // if we haven't met the young size factor yet.
     //
     // If we don't see any young GC's we check if we should shrink it
     if(young_gc_while_marking_ > 1) {
       if(young_->bytes_size() < young_max_bytes &&
          young_->bytes_size() < mature_bytes_allocated() / young_autotune_factor) {
         young_->grow(young_->bytes_size() * 2);
       }
     } else if(young_gc_while_marking_ == 0) {
       if(young_->bytes_size() > mature_bytes_allocated() / young_autotune_factor) {
         young_->grow(young_->bytes_size() / 2);
       }
     }
   }
 }
Ejemplo n.º 2
0
  void ObjectMemory::print_mature_stats(STATE, GCData* data) {
    if(state->shared().config.gc_show) {
      uint64_t stop = gc_stats.last_full_stop_collection_time.value;
      uint64_t concur = gc_stats.last_full_concurrent_collection_time.value;
      size_t before_mature_kb = data->mature_bytes_allocated() / 1024;
      size_t mature_kb = mature_bytes_allocated() / 1024;
      size_t before_code_kb = data->code_bytes_allocated() / 1024;
      size_t code_kb = code_bytes_allocated() / 1024;
      std::cerr << "[Full GC mature: " << before_mature_kb << "kB => " << mature_kb << "kB, ";
      std::cerr << "code: " << before_code_kb << "kB => " << code_kb << "kB, ";
      std::cerr << "symbols: " << data->symbol_bytes_allocated() / 1024 << "kB, ";
      std::cerr << "jit: " << data->jit_bytes_allocated() / 1024 << "kB, ";
      std::cerr << "time: " << stop << "ms (" << concur << "ms), ";
      std::cerr << capi_handles_->size() << " C-API handles, " << inflated_headers_->size() << " inflated headers]" << std::endl;

      if(state->shared().config.gc_noisy) {
        std::cerr << "\a\a" << std::flush;
      }
    }
  }
Ejemplo n.º 3
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;

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