Subject: Re: bug#79346: igc: PolicyShouldCollectWorld

From: Gerd Möllmann <[email-masked]>
Date: Thu, 04 Sep 2025 09:46:02 +0200

Helmut Eller <[email-masked]> writes:

> On Thu, Sep 04 2025, Gerd Möllmann wrote:
>> Good find, Helmut. There used to be a comment in arena_step wondering
>> what's going on, but it got removed, apparently. Does this look right?
>
> LGTM.

I've also made an issue for that

  https://github.com/Ravenbrook/mps/issues/308

> BTW, in igc_on_idle, arena_step is called repeatedly as long as
> work_done is true.  Note that buffer_step sets work_done to true until
> the buffer iterator is exhausted.  So arena_step is called for each
> buffer.  That seems a bit excessive.
>
> What would you think of making mps_arena_step and perhaps buffer_step
> available from Lisp so that those things can be called from Lisp-level
> idle timers?

Sounds like a good idea.

I think there quite some areas one could and probably should play more
with (ignoring the fact that Andrea made it a feature branch; maybe we
should rename it back to a scratch branch? :-)).

Anyway, the number and size of generations is such a thing. I've been
playing with that on and off and I think I found a setting that works
noticeably smoother than the default. I've made me something that makes
it easier to play with:

static bool
read_gens (mps_gen_param_s **gens, int *ngens)
{
  const char *env = getenv ("EMACS_IGC_GENS");
  if (env == NULL)
    return false;
  const char *verbose = getenv ("EMACS_IGC_VERBOSE");
  const char *end = env + strlen (env);
  static struct mps_gen_param_s parms[10];
  *ngens = 0;
  *gens = parms;
  for (int i = 0; i < ARRAYELTS (parms) && env < end; ++i)
    {
      int nchars;
      if (sscanf (env, "%zu %lf%n", &parms[i].mps_capacity,
		  &parms[i].mps_mortality, &nchars) == 2)
	{
	  if (verbose)
	    fprintf (stderr, "gen %d: %zu %lf\n", i, parms[i].mps_capacity,
		     parms[i].mps_mortality);
	  env += nchars;
	  ++*ngens;
	}
    }

  return true;
}

static void
make_arena (struct igc *gc)
{
  mps_res_t res;
  MPS_ARGS_BEGIN (args)
  {
    res = mps_arena_create_k (&gc->arena, mps_arena_class_vm (), args);
  }
  MPS_ARGS_END (args);
  IGC_CHECK_RES (res);

  mps_gen_param_s *gens;
  int ngens;
  if (!read_gens (&gens, &ngens))
    {
      static mps_gen_param_s default_gens[] = {
	{ 256000, 0.8 }, { 256000, 0.6 }, { 256000, 0.4 }, { 2 * 256000, 0.2 }
      };
      gens = default_gens;
      ngens = ARRAYELTS (default_gens);
    }

  res = mps_chain_create (&gc->chain, gc->arena, ngens, gens);
  IGC_CHECK_RES (res);
}