bitbake: event/utils/methodpool: Add a cache of compiled code objects

With the addition of function line number handling, the overhead of
the compile functions is no longer negligible. We tend to compile
the same pieces of code over and over again so wrapping a cache around
this is beneficial and removes the overhead of line numbered functions.

Life cycle of a cache using a global like this is in theory problematic
although in reality unlikely to be an issue. It can be dealt with
if/as/when we deal with the other global caches.

(Bitbake rev: 98d7002d1dca4b62042e1589fd5b9b3805d57f7a)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie 2015-12-20 13:22:19 +00:00
parent c61c1eb26a
commit 0381b78aa4
3 changed files with 27 additions and 8 deletions

View File

@ -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)))

View File

@ -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

View File

@ -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