1#!/usr/bin/env python3 2# Copyright 2021 the V8 project authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6# Processes {stdout} output generated by --trace-wasm-compilation-times 7# for easier consumption by human readers. 8 9import sys 10 11def SizeInternal(number, suffix): 12 if suffix == "": return "%d" % number 13 if number < 10: return "%.1f%s" % (number, suffix) 14 return "%d%s" % (number, suffix) 15 16def Size(number): 17 if (number < 1024): return SizeInternal(number, "") 18 number /= 1024 19 if (number < 1024): return SizeInternal(number, "K") 20 number /= 1024 21 if (number < 1024): return SizeInternal(number, "M") 22 number /= 1024 23 if (number < 1024): return SizeInternal(number, "G") 24 return SizeInternal(number / 1024, "T") 25 26modules = {} 27max_module = 0 28total_tf_time = 0 29total_tf_size = 0 30 31def RegisterName(raw): 32 global max_module 33 parts = raw.split("#") 34 m = parts[0] 35 if m not in modules: 36 modules[m] = max_module 37 max_module += 1 38 39def Name(raw): 40 parts = raw.split("#") 41 if len(modules) == 1: return "#%s" % parts[1] 42 return "m%d#%s" % (modules[parts[0]], parts[1]) 43 44class Function: 45 def __init__(self, index): 46 self.index = index 47 self.has_lo = False 48 self.has_tf = False 49 self.time_lo = -1 50 self.time_tf = -1 51 self.mem_lo = -1 52 self.mem_tf_max = -1 53 self.mem_tf_total = -1 54 self.name = "" 55 self.size_wasm = -1 56 self.size_lo = -1 57 self.size_tf = -1 58 59 def AddLine(self, words): 60 assert self.index == words[2], "wrong function" 61 if words[4] == "TurboFan,": 62 self.AddTFLine(words) 63 elif words[4] == "Liftoff,": 64 self.AddLiftoffLine(words) 65 else: 66 raise Exception("unknown compiler: %s" % words[4]) 67 68 def AddTFLine(self, words): 69 assert not self.has_tf, "duplicate TF line for %s" % self.index 70 self.has_tf = True 71 # 0 1 2 3 4 5 6 7 8 9 10 11 72 # Compiled function #6 using TurboFan, took 0 ms and 14440 / 44656 73 # 12 13 14 15 16 17 18 19 74 # max/total bytes; bodysize 12 codesize 24 name wasm-function#6 75 self.time_tf = int(words[6]) 76 self.mem_tf_max = int(words[9]) 77 self.mem_tf_total = int(words[11]) 78 self.size_tf = int(words[17]) 79 self.name = words[19] 80 81 def AddLiftoffLine(self, words): 82 assert self.index == words[2], "wrong function" 83 assert not self.has_lo, "duplicate Liftoff line for %s" % self.index 84 self.has_lo = True 85 # 0 1 2 3 4 5 6 7 8 9 10 11 12 86 # Compiled function #6 using Liftoff, took 0 ms and 968 bytes; bodysize 4 87 # 13 14 88 # codesize 68 89 self.time_lo = int(words[6]) 90 self.mem_lo = int(words[9]) 91 self.size_lo = int(words[14]) 92 self.size_wasm = int(words[12]) 93 94 def __str__(self): 95 return "%s: time %d %d mem %s %s %s size %s %s %s name %s" % ( 96 Name(self.index), self.time_lo, self.time_tf, 97 Size(self.mem_lo), Size(self.mem_tf_max), Size(self.mem_tf_total), 98 Size(self.size_wasm), Size(self.size_lo), Size(self.size_tf), self.name 99 ) 100 101funcs_dict = {} 102funcs_list = [] 103 104if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help", "help"): 105 print("Pass output file (generated with --trace-wasm-compilation-times) as " 106 "argument") 107 sys.exit(1) 108 109with open(sys.argv[1], "r") as f: 110 for line in f.readlines(): 111 words = line.strip().split(" ") 112 if words[0] != "Compiled" or words[1] != "function": 113 continue 114 name = words[2] 115 RegisterName(name) 116 if name in funcs_dict: 117 func = funcs_dict[name] 118 else: 119 func = Function(name) 120 funcs_dict[name] = func 121 funcs_list.append(func) 122 func.AddLine(words) 123 124funcs_list.sort(key=lambda fun: fun.time_tf) 125for f in funcs_list: 126 print(f) 127 if f.time_tf > 0: total_tf_time += f.time_tf 128 if f.size_tf > 0: total_tf_size += f.size_tf 129 130print("Total TF time: %d" % total_tf_time) 131print("Total TF size: %d" % total_tf_size) 132