def load_db_entry(self, dbname, pattern): """Look up an entry from an XDB database file, 'pattern' may be an exact
matching string, or an re pattern object matching a single entry."""
if hasattr(pattern, "match"):
output = subprocess.check_output(
[self.binpath("xdbkeys"), dbname + ".xdb"], universal_newlines=True
)
matches = list(filter(lambda _: re.search(pattern, _), output.splitlines())) if len(matches) == 0: raise Exception("entry not found") if len(matches) > 1: raise Exception("multiple entries found")
pattern = matches[0]
def process(line): if line.startswith("#"):
name = line.split(" ", 1)[1]
data.nameToId[name] = len(data.functionNames)
data.functionNames.append(name) return
if line.startswith("="):
m = re.match(r"^= (\d+) (.*)", line)
mangled = data.functionNames[int(m.group(1))]
unmangled = m.group(2)
data.nameToId[unmangled] = id
data.mangledToUnmangled[mangled] = unmangled
data.unmangledToMangled[unmangled] = mangled return
# Sample lines: # D 10 20 # D /3 10 20 # D 3:3 10 20 # All of these mean that there is a direct call from function #10 # to function #20. The latter two mean that the call is made in a # context where the 0x1 and 0x2 properties (3 == 0x1 | 0x2) are in # effect. The `/n` syntax was the original, which was then expanded # to `m:n` to allow multiple calls to be combined together when not # all calls have the same properties in effect. The `/n` syntax is # deprecated. # # The properties usually refer to "limits", eg "GC is suppressed # in the scope surrounding this call". For testing purposes, the # difference between `m` and `n` in `m:n` is currently ignored.
tokens = line.split(" ")
limit = 0 if tokens[1].startswith("/"):
attr_str = tokens.pop(1)
limit = int(attr_str[1:]) elif":"in tokens[1]:
attr_str = tokens.pop(1)
limit = int(attr_str[0 : attr_str.index(":")])
if tokens[0] in ("D", "R"):
_, caller, callee = tokens
add_call(lookup(caller), lookup(callee), limit) elif tokens[0] == "T":
data.tags[tokens[1]].add(line.split(" ", 2)[2]) elif tokens[0] in ("F", "V"): pass
self.load_text_file("callgraph.txt", extract=process) return data
def load_hazards(self): def grab_hazard(line):
m = re.match(
r"Function '(.*?)' has unrooted '(.*?)' of type '(.*?)' live across GC call '(.*?)' at (.*)", # NOQA: E501
line,
) if m:
info = list(m.groups())
info[0] = info[0].split("$")[-1]
info[3] = info[3].split("$")[-1] return HazardSummary(*info) returnNone
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.