summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bitbake/lib/bb/codeparser.py66
-rw-r--r--bitbake/lib/bb/cooker.py2
2 files changed, 58 insertions, 10 deletions
diff --git a/bitbake/lib/bb/codeparser.py b/bitbake/lib/bb/codeparser.py
index 88a26c82a..faffe390d 100644
--- a/bitbake/lib/bb/codeparser.py
+++ b/bitbake/lib/bb/codeparser.py
@@ -4,6 +4,14 @@ from bb import msg, utils
import ast
import codegen
+PARSERCACHE_VERSION = 1
+
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+ bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.")
+
def check_indent(codestr):
"""If the code is indented, add a top level piece of code to 'remove' the indentation"""
@@ -13,6 +21,43 @@ def check_indent(codestr):
return codestr
pythonparsecache = {}
+shellparsecache = {}
+
+def parser_cachefile(d):
+ cachedir = bb.data.getVar("PERSISTENT_DIR", d, True) or bb.data.getVar("CACHE", d, True)
+ if cachedir in [None, '']:
+ return None
+ bb.utils.mkdirhier(cachedir)
+ cachefile = os.path.join(cachedir, "bb_codeparser.dat")
+ bb.msg.debug(1, bb.msg.domain.Cache, "Using cache in '%s' for codeparser cache" % cachefile)
+ return cachefile
+
+def parser_cache_init(d):
+
+ cachefile = parser_cachefile(d)
+ if not cachefile:
+ return
+
+ try:
+ p = pickle.Unpickler(file(cachefile, "rb"))
+ data, version = p.load()
+ except:
+ return
+
+ if version != PARSERCACHE_VERSION:
+ return
+
+ bb.codeparser.pythonparsecache = data[0]
+ bb.codeparser.shellparsecache = data[1]
+
+def parser_cache_save(d):
+
+ cachefile = parser_cachefile(d)
+ if not cachefile:
+ return
+
+ p = pickle.Pickler(file(cachefile, "wb"), -1)
+ p.dump([[bb.codeparser.pythonparsecache, bb.codeparser.shellparsecache], PARSERCACHE_VERSION])
class PythonParser():
class ValueVisitor():
@@ -125,9 +170,11 @@ class PythonParser():
def parse_python(self, node):
- if node in pythonparsecache:
- self.references = pythonparsecache[node].references
- self.execs = pythonparsecache[node].execs
+ h = hash(node)
+
+ if h in pythonparsecache:
+ self.references = pythonparsecache[h].references
+ self.execs = pythonparsecache[h].execs
return
code = compile(check_indent(str(node)), "<string>", "exec",
@@ -142,10 +189,7 @@ class PythonParser():
self.references.update(visitor.var_execs)
self.execs = visitor.direct_func_calls
- pythonparsecache[node] = self
-
-
-shellparsecache = {}
+ pythonparsecache[h] = self
class ShellParser():
def __init__(self):
@@ -158,8 +202,10 @@ class ShellParser():
commands it executes.
"""
- if value in pythonparsecache:
- self.execs = shellparsecache[value].execs
+ h = hash(value)
+
+ if h in shellparsecache:
+ self.execs = shellparsecache[h].execs
return
try:
@@ -171,7 +217,7 @@ class ShellParser():
self.process_tokens(token)
self.execs = set(cmd for cmd in self.allexecs if cmd not in self.funcdefs)
- shellparsecache[value] = self
+ shellparsecache[h] = self
return self.execs
diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py
index dcdcb7d44..ea33693dd 100644
--- a/bitbake/lib/bb/cooker.py
+++ b/bitbake/lib/bb/cooker.py
@@ -546,6 +546,7 @@ class BBCooker:
if bb.data.getVar("BB_WORKERCONTEXT", self.configuration.data) is None:
bb.fetch.fetcher_init(self.configuration.data)
+ bb.codeparser.parser_cache_init(self.configuration.data)
bb.event.fire(bb.event.ConfigParsed(), self.configuration.data)
@@ -1011,6 +1012,7 @@ class CookerParser:
if self.pointer >= self.total:
cooker.bb_cache.sync()
+ bb.codeparser.parser_cache_save(cooker.configuration.data)
if self.error > 0:
raise ParsingErrorsFound
return False