function childContext(path, context) {
  const { settings, parserOptions, parserPath, languageOptions } = context;

  if (JSON.stringify(settings) !== prevSettings) {
    settingsHash = hashObject({ settings }).digest('hex');
    prevSettings = JSON.stringify(settings);
  }

  // We'll use either a combination of `parserOptions` and `parserPath` or `languageOptions`
  // to construct the cache key, depending on whether this is using a flat config or not.
  let optionsToken;
  if (!parserPath && languageOptions) {
    if (JSON.stringify(languageOptions, stringifyReplacerFn) !== prevOptions) {
      optionsHash = hashObject({ languageOptions }).digest('hex');
      prevOptions = JSON.stringify(languageOptions, stringifyReplacerFn);
    }
    // For languageOptions, we're just using the hashed options as the options token
    optionsToken = optionsHash;
  } else {
    if (JSON.stringify(parserOptions) !== prevOptions) {
      optionsHash = hashObject({ parserOptions }).digest('hex');
      prevOptions = JSON.stringify(parserOptions);
    }
    // When not using flat config, we use a combination of the hashed parserOptions
    // and parserPath as the token
    optionsToken = String(parserPath) + optionsHash;
  }

  return {
    cacheKey: optionsToken + settingsHash + String(path),
    settings,
    parserOptions,
    parserPath,
    path,
    languageOptions,
  };
}
don't hold full context object in memory, just grab what we need.
also calculate a cacheKey, where parts of the cacheKey hash are memoized