class_docstr: This mixin provides ability to split the code into subroutines based on
  the size of the AST.
  
  Subclasses only need to implement `create_code_generator` method.
  
  Their code generators should implement 3 methods:
       - function_definition;
       - function_invocation;
       - add_return_statement.
  
  Interpreter should prepare at least one subroutine using method
  `enqueue_subroutine` and then call method `process_subroutine_queue` with
  instance of code generator, which will be populated with the result code.
code: def _pre_interpret_hook(
      self, expr, ast_size_check_counter=0, **kwargs
  ):
      if isinstance(expr, ast.BinExpr) and not expr.to_reuse:
          frequency = self._adjust_ast_check_frequency(expr)
          self.ast_size_check_frequency = min(
              frequency, self.ast_size_check_frequency
          )
  
          ast_size_check_counter += 1
          if ast_size_check_counter >= self.ast_size_check_frequency:
              ast_size_check_counter = 0
              ast_size = ast.count_exprs(expr)
              if ast_size > self.ast_size_per_subroutine_threshold:
                  function_name = self._get_subroutine_name()
                  self.enqueue_subroutine(function_name, expr)
                  return (
                      self._cg.function_invocation(
                          function_name, self._feature_array_name
                      ),
                      kwargs,
                  )
  
          kwargs["ast_size_check_counter"] = ast_size_check_counter
  
      return super()._pre_interpret_hook(expr, **kwargs)
  
imports: import math
  import sys
  from collections import namedtuple
  from m2cgen import ast
  from m2cgen.interpreters.interpreter import BaseToCodeInterpreter
label_desc: Use image node_id 4 for calling the SubroutinesMixin obj's underlying member method code with example usage: obj._pre_interpret_hook(expr, ast_size_check_counter) and returns: super, self,  kwargs