summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/bb/event.py17
-rw-r--r--lib/bb/methodpool.py11
-rw-r--r--lib/bb/utils.py7
3 files changed, 27 insertions, 8 deletions
diff --git a/lib/bb/event.py b/lib/bb/event.py
index bd2b0a4b05..5ffe89eae3 100644
--- a/lib/bb/event.py
+++ b/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/lib/bb/methodpool.py b/lib/bb/methodpool.py
index b2ea1a1887..49aed3338b 100644
--- a/lib/bb/methodpool.py
+++ b/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/lib/bb/utils.py b/lib/bb/utils.py
index e564bb6ff4..cd5fcede3c 100644
--- a/lib/bb/utils.py
+++ b/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