diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /js/src/devtools/rootAnalysis/explain.py | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/devtools/rootAnalysis/explain.py')
-rwxr-xr-x | js/src/devtools/rootAnalysis/explain.py | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/js/src/devtools/rootAnalysis/explain.py b/js/src/devtools/rootAnalysis/explain.py new file mode 100755 index 0000000000..993725273c --- /dev/null +++ b/js/src/devtools/rootAnalysis/explain.py @@ -0,0 +1,129 @@ +#!/usr/bin/python3 +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + + +from __future__ import print_function + +import argparse +import re + +from collections import defaultdict + +parser = argparse.ArgumentParser(description="Process some integers.") +parser.add_argument("rootingHazards", nargs="?", default="rootingHazards.txt") +parser.add_argument("gcFunctions", nargs="?", default="gcFunctions.txt") +parser.add_argument("hazards", nargs="?", default="hazards.txt") +parser.add_argument("extra", nargs="?", default="unnecessary.txt") +parser.add_argument("refs", nargs="?", default="refs.txt") +args = parser.parse_args() + +num_hazards = 0 +num_refs = 0 +num_missing = 0 + +try: + with open(args.rootingHazards) as rootingHazards, open( + args.hazards, "w" + ) as hazards, open(args.extra, "w") as extra, open(args.refs, "w") as refs: + current_gcFunction = None + + # Map from a GC function name to the list of hazards resulting from + # that GC function + hazardousGCFunctions = defaultdict(list) + + # List of tuples (gcFunction, index of hazard) used to maintain the + # ordering of the hazards + hazardOrder = [] + + # Map from a hazardous GC function to the filename containing it. + fileOfFunction = {} + + for line in rootingHazards: + m = re.match(r"^Time: (.*)", line) + mm = re.match(r"^Run on:", line) + if m or mm: + print(line, file=hazards) + print(line, file=extra) + print(line, file=refs) + continue + + m = re.match(r"^Function.*has unnecessary root", line) + if m: + print(line, file=extra) + continue + + m = re.match(r"^Function.*takes unsafe address of unrooted", line) + if m: + num_refs += 1 + print(line, file=refs) + continue + + m = re.match( + r"^Function.*has unrooted.*of type.*live across GC call '(.*?)' at (\S+):\d+$", + line, + ) # NOQA: E501 + if m: + current_gcFunction = m.group(1) + hazardousGCFunctions[current_gcFunction].append(line) + hazardOrder.append( + ( + current_gcFunction, + len(hazardousGCFunctions[current_gcFunction]) - 1, + ) + ) + num_hazards += 1 + fileOfFunction[current_gcFunction] = m.group(2) + continue + + m = re.match(r"Function.*expected hazard.*but none were found", line) + if m: + num_missing += 1 + print(line + "\n", file=hazards) + continue + + if current_gcFunction: + if not line.strip(): + # Blank line => end of this hazard + current_gcFunction = None + else: + hazardousGCFunctions[current_gcFunction][-1] += line + + with open(args.gcFunctions) as gcFunctions: + gcExplanations = {} # gcFunction => stack showing why it can GC + + current_func = None + explanation = None + for line in gcFunctions: + m = re.match(r"^GC Function: (.*)", line) + if m: + if current_func: + gcExplanations[current_func] = explanation + current_func = None + if m.group(1) in hazardousGCFunctions: + current_func = m.group(1) + explanation = line + elif current_func: + explanation += line + if current_func: + gcExplanations[current_func] = explanation + + for gcFunction, index in hazardOrder: + gcHazards = hazardousGCFunctions[gcFunction] + + if gcFunction in gcExplanations: + print(gcHazards[index] + gcExplanations[gcFunction], file=hazards) + else: + print(gcHazards[index], file=hazards) + +except IOError as e: + print("Failed: %s" % str(e)) + +print("Wrote %s" % args.hazards) +print("Wrote %s" % args.extra) +print("Wrote %s" % args.refs) +print( + "Found %d hazards %d unsafe references %d missing" + % (num_hazards, num_refs, num_missing) +) |