]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
bitbake: event/utils/methodpool: Add a cache of compiled code objects
authorRichard Purdie <richard.purdie@linuxfoundation.org>
Sun, 20 Dec 2015 13:22:19 +0000 (13:22 +0000)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Tue, 22 Dec 2015 00:02:05 +0000 (00:02 +0000)
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>
bitbake/lib/bb/event.py
bitbake/lib/bb/methodpool.py
bitbake/lib/bb/utils.py

index bd2b0a4b059eef9bd4174f97532f70ae0f845d6c..5ffe89eae3eeb563732ed558a3ee73f78506f051 100644 (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)))
index b2ea1a188704140dd13ee8366f8061dbdf4b5d70..49aed3338b9b2f300901e87fdf4c90c96f033858 100644 (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
index e564bb6ff460523ee4b5758eb030db7a0393f141..cd5fcede3c82b13773ceeab30fc2e8956dfee442 100644 (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