OILS / metrics / native-code.sh View on Github | oils.pub

197 lines, 88 significant
1#!/usr/bin/env bash
2#
3# Usage:
4# metrics/native-code.sh <function name>
5
6set -o nounset
7set -o pipefail
8set -o errexit
9
10source build/dev-shell.sh # put bloaty in $PATH, R_LIBS_USER
11
12readonly OVM_BASE_DIR=_tmp/metrics/ovm
13readonly OIL_BASE_DIR=_tmp/metrics/oils-for-unix
14
15pylibc-symbols() {
16 symbols _devbuild/py-ext/x86_64/libc.so
17}
18
19fastlex-symbols() {
20 symbols _devbuild/py-ext/x86_64/fastlex.so
21}
22
23print-symbols() {
24 local obj=$1
25 ls -l $obj
26 echo
27
28 # Summary
29 bloaty $obj
30 echo
31
32 # Top symbols
33 # fastlex_MatchToken is 21.2 KiB. That doesn't seem to large compared to
34 # the 14K line output?
35 bloaty -d symbols $obj
36 echo
37
38 nm $obj
39 echo
40}
41
42# Big functions:
43# - PyEval_EvalFrameEx (38 KiB)
44# - fastlex_MatchOSHToken (22.5 KiB)
45# - convertitem() in args.py (9.04 KiB)
46# - PyString_Format() in args.py (6.84 KiB)
47#
48# Easy removals:
49# - marshal_dumps and marshal_dump! We never use those.
50# - Remove all docstrings!!! Like sys_doc.
51
52compileunits() {
53 # Hm there doesn't seem to be a way to do this without
54 local file=${1:-_build/oils-ref/ovm-dbg}
55
56 #local file=_build/oils-ref/ovm-opt
57 #local sym=_build/oils-ref/ovm-opt.symbols
58
59 bloaty --tsv -n 0 -d compileunits $file
60}
61
62symbols() {
63 # NOTE: This is different than the release binary!
64 # ovm-opt.stripped doesn't show a report.
65 local file=${1:-_build/oils-ref/ovm-opt}
66
67 # Full output
68 # 3,588 lines!
69 bloaty --tsv -n 0 -d symbols $file
70}
71
72R-report() {
73 metrics/native-code.R "$@"
74}
75
76build-ovm() {
77 # 2022-12: hack for ./configure, because line_input failed to compile without
78 # HAVE_READLINE See _build/oils-ref/module_init.c
79 # TODO: This metric should either be DELETED, or automated in the CI, so it
80 # doesn't break
81
82 ./configure
83
84 make _build/oils-ref/ovm-{dbg,opt}
85}
86
87collect-and-report() {
88 local base_dir=$1
89 local dbg=$2
90 local opt=$3
91
92 mkdir -p $base_dir
93
94 print-symbols $opt > $base_dir/symbols.txt
95
96 symbols $opt > $base_dir/symbols.tsv
97
98 # Really 'translation units', but bloaty gives it that name.
99 compileunits $dbg > $base_dir/compileunits.tsv
100
101 head $base_dir/symbols.tsv $base_dir/compileunits.tsv
102
103 # Hack for now
104 if Rscript -e 'print("hi from R")'; then
105 R-report metrics $base_dir $dbg $opt | tee $base_dir/overview.txt
106 else
107 echo 'R not detected' | tee $base_dir/overview.txt
108 fi
109}
110
111oils-for-unix() {
112 ### Report on the ones we just built
113
114 # Use DWARF 4 for bloaty, as we do in
115 # devtools/release.sh _build-oils-benchmark-data
116 CXXFLAGS=-gdwarf-4 soil/cpp-tarball.sh build-like-ninja dbg opt
117 #soil/cpp-tarball.sh build-like-ninja dbg opt
118
119 collect-and-report $OIL_BASE_DIR _bin/cxx-{dbg,opt}/oils-for-unix
120
121 ls -l $OIL_BASE_DIR
122}
123
124compare-gcc-clang() {
125 ### Run by Soil 'cpp-coverage' task, because it has clang
126
127 local -a targets=(
128 _bin/{clang,cxx}-opt/bin/oils_for_unix.mycpp.stripped
129 _bin/{clang,cxx}-opt/bin/oils_for_unix.mycpp-souffle.stripped
130 _bin/cxx-{opt+bumpleak,opt+bumproot,opt+bigint}/bin/oils_for_unix.mycpp.stripped
131 _bin/{clang,cxx}-opt/yaks/yaks_main.mycpp.stripped
132 #_bin/cxx-{opt+bumpleak,opt+bumproot}/yaks/yaks_main.mycpp.stripped
133 )
134 ninja "${targets[@]}"
135
136 mkdir -p _tmp/metrics
137 ls -l --sort=none "${targets[@]}" | tee _tmp/metrics/compare-gcc-clang.txt
138}
139
140readonly OILS_VERSION=$(head -n 1 oils-version.txt)
141
142run-for-release() {
143 # 2024-08: Not building with DWARF 4
144 if false; then
145 build-ovm
146
147 local dbg=_build/oils-ref/ovm-dbg
148 local opt=_build/oils-ref/ovm-opt
149
150 collect-and-report $OVM_BASE_DIR $dbg $opt
151 fi
152
153 # TODO: consolidate with benchmarks/common.sh, OSH_CPP_TWO
154 # For some reason _bin/cxx-opt/ and _bin/cxx-opt-sh can differ by a few bytes
155 local bin_dir="../benchmark-data/src/oils-for-unix-$OILS_VERSION"
156 collect-and-report $OIL_BASE_DIR $bin_dir/_bin/cxx-{dbg,opt}-sh/oils-for-unix
157}
158
159dupe-strings() {
160 ### Check for NUL-terminated strings
161
162 python2 -c '
163import collections
164import re
165import sys
166
167with open(sys.argv[1]) as f:
168 contents = f.read()
169strs = re.split("\\0", contents)
170
171printable = re.compile("[ -~]+$")
172
173d = collections.Counter()
174for s in strs:
175 if len(s) > 1 and printable.match(s):
176 d[s] += 1
177
178for s, count in d.most_common()[:50]:
179 if count == 1:
180 break
181 print("%5d %r" % (count, s))
182
183' "$@"
184}
185
186# Results:
187# Found StrFromC() and len() duplication
188
189oil-dupe-strings() {
190 local bin=_bin/cxx-opt/bin/oils_for_unix.mycpp.stripped
191 #local bin=_bin/clang-opt/oils-for-unix.stripped
192 ninja $bin
193
194 dupe-strings $bin
195}
196
197"$@"