/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/tools/regexp-sequences.py
126 строк
4 KB
Michaël Zasso
deps: update V8 to 14.6.202.33
24 апр 2026, 19:01
Не верифицирован
24 апр 2026, 19:01
f1e0b83
Код
Авторство
О чём код?
#!/usr/bin/env python3 # Copyright 2019 the V8 project authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """ python %prog trace-file Parses output generated by v8 with flag --trace-regexp-bytecodes and generates a list of the most common sequences. """ from __future__ import print_function import sys import re import collections def parse(file, seqlen): # example: # pc = 00, sp = 0, curpos = 0, curchar = 0000000a ..., PushBacktrack, label: e4 rx = re.compile( r'pc = (?P<pc>[0-9a-f]+), sp = (?P<sp>\d+), ' r'curpos = (?P<curpos>\d+), curchar = (?P<char_hex>[0-9a-f]+) ' r'(:?\.|\()(?P<char>\.|\w)(:?\.|\)), (?P<bc>\w+), .*') total = 0 # stats[len][seq_tuple] = {'count': 0, 'loops': 0} # Using tuple as key for easier rotation stats = [{} for _ in range(seqlen)] # last[len] = deque of (bc, pc_int) last = [collections.deque(maxlen=i + 1) for i in range(seqlen)] with open(file) as f: l = f.readline() while l: l = l.strip() if l.startswith("Start bytecode interpreter"): for i in range(seqlen): last[i].clear() match = rx.search(l) if match: total += 1 bc = match.group('bc') pc = int(match.group('pc'), 16) current_node = (bc, pc) for i in range(seqlen): deque = last[i] if len(deque) == i + 1: # Canonicalize based on PC: find the rotation that starts with the # lowest PC. This aligns loops to their header. min_pc = float('inf') rotation_start = 0 # Find the index with the minimum PC for idx, item in enumerate(deque): if item[1] < min_pc: min_pc = item[1] rotation_start = idx elif item[1] == min_pc: # Tie-break. If the same sequence appears twice (A->B->A->B), # we prefer the first. pass # Rotate to start at rotation_start canonical_seq = [] for k in range(i + 1): idx = (rotation_start + k) % (i + 1) canonical_seq.append(deque[idx][0]) seq_key = tuple(canonical_seq) if seq_key not in stats[i]: stats[i][seq_key] = {'count': 0, 'loops': 0} stats[i][seq_key]['count'] += 1 # Check for loops. Note that current_node is the node *after* the # sequence we are currently looking at. first_node = deque[0] if current_node[1] == first_node[1]: stats[i][seq_key]['loops'] += 1 deque.append(current_node) l = f.readline() return stats, total def print_most_common(d, seqlen, total): # Sort by count sorted_items = sorted(d.items(), key=lambda kv: kv[1]['count'], reverse=True) for (k, val) in sorted_items: count = val['count'] loops = val['loops'] pct = count * 100.0 / total if pct < 1.0: return loop_pct = loops * 100.0 / count seq_str = ' --> '.join(k) print("{}: {} ({:.2f} %) - Loops: {} ({:.2f} %)".format( seq_str, count, pct, loops, loop_pct)) def main(argv): if len(argv) < 2: print("Usage: python {} <trace-file>".format(argv[0])) sys.exit(1) max_seq = 7 stats, total = parse(argv[1], max_seq) for i in range(max_seq): print() print("Most common of length {}".format(i+1)) print() print_most_common(stats[i], i, total) if __name__ == '__main__': main(sys.argv)