diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index bd2b0a4b05..5ffe89eae3 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py @@ -31,6 +31,7 @@ except ImportError: import logging import atexit import traceback +import ast import bb.utils import bb.compat import bb.exceptions @@ -189,13 +190,15 @@ def register(name, handler, mask=None, filename=None, lineno=None): if isinstance(handler, basestring): tmp = "def %s(e):\n%s" % (name, handler) try: - import ast - if filename is None: - filename = "%s(e)" % name - code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST) - if lineno is not None: - ast.increment_lineno(code, lineno-1) - code = compile(code, filename, "exec") + code = bb.methodpool.compile_cache(tmp) + if not code: + if filename is None: + filename = "%s(e)" % name + code = compile(tmp, filename, "exec", ast.PyCF_ONLY_AST) + if lineno is not None: + ast.increment_lineno(code, lineno-1) + code = compile(code, filename, "exec") + bb.methodpool.compile_cache_add(tmp, code) except SyntaxError: logger.error("Unable to register event handler '%s':\n%s", name, ''.join(traceback.format_exc(limit=0))) diff --git a/bitbake/lib/bb/methodpool.py b/bitbake/lib/bb/methodpool.py index b2ea1a1887..49aed3338b 100644 --- a/bitbake/lib/bb/methodpool.py +++ b/bitbake/lib/bb/methodpool.py @@ -27,3 +27,14 @@ def insert_method(modulename, code, fn, lineno): comp = better_compile(code, modulename, fn, lineno=lineno) better_exec(comp, None, code, fn) +compilecache = {} + +def compile_cache(code): + h = hash(code) + if h in compilecache: + return compilecache[h] + return None + +def compile_cache_add(code, compileobj): + h = hash(code) + compilecache[h] = compileobj diff --git a/bitbake/lib/bb/utils.py b/bitbake/lib/bb/utils.py index e564bb6ff4..cd5fcede3c 100644 --- a/bitbake/lib/bb/utils.py +++ b/bitbake/lib/bb/utils.py @@ -298,10 +298,15 @@ def better_compile(text, file, realfile, mode = "exec", lineno = None): will print the offending lines. """ try: + cache = bb.methodpool.compile_cache(text) + if cache: + return cache code = compile(text, realfile, mode, ast.PyCF_ONLY_AST) if lineno is not None: ast.increment_lineno(code, lineno) - return compile(code, realfile, mode) + code = compile(code, realfile, mode) + bb.methodpool.compile_cache_add(text, code) + return code except Exception as e: error = [] # split the text into lines again