Add Compiler.cached_run()

Caching Compiler.run() seems likely to cause problems, but some users, like
.sizeof(), we know enough about the program run to make it safe.

This commit just adds the Compiler.cached_run(), a subsequent commit makes use
of it.
pull/11478/head
Andres Freund 2 years ago committed by Eli Schwartz
parent ba72fc7f40
commit 9a41ce58d6
  1. 30
      mesonbuild/compilers/compilers.py
  2. 5
      mesonbuild/coredata.py

@ -456,11 +456,13 @@ class CrossNoRunException(MesonException):
class RunResult(HoldableObject):
def __init__(self, compiled: bool, returncode: int = 999,
stdout: str = 'UNDEFINED', stderr: str = 'UNDEFINED'):
stdout: str = 'UNDEFINED', stderr: str = 'UNDEFINED',
cached: bool = False):
self.compiled = compiled
self.returncode = returncode
self.stdout = stdout
self.stderr = stderr
self.cached = cached
class CompileResult(HoldableObject):
@ -689,6 +691,32 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
dependencies: T.Optional[T.List['Dependency']] = None) -> RunResult:
raise EnvironmentException('Language %s does not support run checks.' % self.get_display_language())
# Caching run() in general seems too risky (no way to know what the program
# depends on), but some callers know more about the programs they intend to
# run.
# For now we just accept code as a string, as that's what internal callers
# need anyway. If we wanted to accept files, the cache key would need to
# include mtime.
def cached_run(self, code: str, env: 'Environment', *,
extra_args: T.Union[T.List[str], T.Callable[[CompileCheckMode], T.List[str]], None] = None,
dependencies: T.Optional[T.List['Dependency']] = None) -> RunResult:
run_check_cache = env.coredata.run_check_cache
args = self.build_wrapper_args(env, extra_args, dependencies, CompileCheckMode('link'))
key = (code, tuple(args))
if key in run_check_cache:
p = run_check_cache[key]
p.cached = True
mlog.debug('Using cached run result:')
mlog.debug('Code:\n', code)
mlog.debug('Args:\n', extra_args)
mlog.debug('Cached run returncode:\n', p.returncode)
mlog.debug('Cached run stdout:\n', p.stdout)
mlog.debug('Cached run stderr:\n', p.stderr)
else:
p = self.run(code, env, extra_args=extra_args, dependencies=dependencies)
run_check_cache[key] = p
return p
def sizeof(self, typename: str, prefix: str, env: 'Environment', *,
extra_args: T.Union[None, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]] = None,
dependencies: T.Optional[T.List['Dependency']] = None) -> int:

@ -39,7 +39,7 @@ import typing as T
if T.TYPE_CHECKING:
from . import dependencies
from .compilers.compilers import Compiler, CompileResult
from .compilers.compilers import Compiler, CompileResult, RunResult
from .dependencies.detect import TV_DepID
from .environment import Environment
from .mesonlib import OptionOverrideProxy, FileOrString
@ -49,6 +49,8 @@ if T.TYPE_CHECKING:
MutableKeyedOptionDictType = T.Dict['OptionKey', 'UserOption[T.Any]']
KeyedOptionDictType = T.Union[MutableKeyedOptionDictType, OptionOverrideProxy]
CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], str]
# code, args
RunCheckCacheKey = T.Tuple[str, T.Tuple[str, ...]]
# typeshed
StrOrBytesPath = T.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]
@ -474,6 +476,7 @@ class CoreData:
DependencyCache(self.options, MachineChoice.HOST))
self.compiler_check_cache: T.Dict['CompilerCheckCacheKey', 'CompileResult'] = OrderedDict()
self.run_check_cache: T.Dict['RunCheckCacheKey', 'RunResult'] = OrderedDict()
# CMake cache
self.cmake_cache: PerMachine[CMakeStateCache] = PerMachine(CMakeStateCache(), CMakeStateCache())

Loading…
Cancel
Save