Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/tools/avgCompTime.pl
6000 views
1
##############################################################################
2
# Copyright (c) 2019, 2019 IBM Corp. and others
3
#
4
# This program and the accompanying materials are made available under
5
# the terms of the Eclipse Public License 2.0 which accompanies this
6
# distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
# or the Apache License, Version 2.0 which accompanies this distribution and
8
# is available at https://www.apache.org/licenses/LICENSE-2.0.
9
#
10
# This Source Code may also be made available under the following
11
# Secondary Licenses when the conditions for such availability set
12
# forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
# General Public License, version 2 with the GNU Classpath
14
# Exception [1] and GNU General Public License, version 2 with the
15
# OpenJDK Assembly Exception [2].
16
#
17
# [1] https://www.gnu.org/software/classpath/license.html
18
# [2] http://openjdk.java.net/legal/assembly-exception.html
19
#
20
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
##############################################################################
22
23
#script to compute the average compilation time for methods in the vlog
24
25
use strict;
26
use File::Find;
27
28
my $compTimeThreshold = 1000000; # 100 ms
29
30
if (@ARGV < 1) {
31
die "must provide at least one parameter: vlog_file\n";
32
}
33
34
35
# hash of methods; each entry is an array of lines containing all occurrences of that method in the vlog
36
my %methodHash;
37
38
39
# process each file given as argument
40
my $totalCompTime = 0;
41
foreach (map { glob } @ARGV) {
42
my $compTime = processVlog($_);
43
$totalCompTime += $compTime/1000; # convert to ms
44
}
45
print "total compilation time = $totalCompTime ms\n";
46
47
48
49
50
sub UpdateStats {
51
$_[1] += 1; # update samples
52
$_[2] += $_[0]; # update totalTime
53
if ($_[0] > $_[3]) { #update MAX
54
$_[3] = $_[0];
55
}
56
if ($_[0] < $_[4]) { #update MIN
57
$_[4] = $_[0];
58
}
59
}
60
61
# subroutine to print the stats for an array
62
sub PrintStats {
63
my ($hotness, $samples, $sum, $maxVal, $minVal, $stddev) = @_;
64
if ($samples > 0) {
65
# samples max sum avg min
66
printf "$hotness\t%d\t%.1f\t%.1f\t\t%.0f\t\t%.0f\n", $samples, $maxVal/1000, $sum/1000, $sum/$samples, $minVal;
67
}
68
}
69
70
71
sub processVlog {
72
# samples, sum, max, min, stddev
73
my @noopt= (0,0,0,10000000,0);
74
my @aotload= (0,0,0,10000000,0);
75
my @aotcold= (0,0,0,10000000,0);
76
my @aotwarm= (0,0,0,10000000,0);
77
my @aothot= (0,0,0,10000000,0);
78
my @cold= (0,0,0,10000000,0);
79
my @warm= (0,0,0,10000000,0);
80
my @hot= (0,0,0,10000000,0);
81
my @phot= (0,0,0,10000000,0);
82
my @veryhot= (0,0,0,10000000,0);
83
my @pveryhot= (0,0,0,10000000,0);
84
my @scorching= (0,0,0,10000000,0);
85
my @jni= (0,0,0,10000000,0);
86
my @unknown= (0,0,0,10000000,0);
87
my @failures= (0,0,0,10000000,0);
88
my @allt= (0,0,0,10000000,0);
89
my $numGCR = 0;
90
my $numGCRNoServer = 0;
91
my $numPushy = 0;
92
my $numDLT = 0;
93
my $numSync = 0;
94
my $numColdUpgrade = 0;
95
my $numForcedAOTUpgrade = 0;
96
my $numAOTUpgrade = 0;
97
my $numNonAOTUpgrade = 0;
98
my $numInvalidate = 0;
99
my $numFailures = 0;
100
my $max = 0;
101
my $maxLine = "";
102
my $maxQSZ = "";
103
my $numAOTLoadsNotRecompiled = 0;
104
my $lastTimestamp = 0; # in ms since JVM start
105
# clear the hash
106
%methodHash = ();
107
108
my $vlog_filename = shift;
109
open(VLOG, $vlog_filename) || die "Cannot open $vlog_filename: $!\n";
110
my @vlog_lines = <VLOG>; # read all lines from VLOG
111
112
# process each line from the file
113
foreach my $line (@vlog_lines) {
114
# filter the lines that start with +.
115
my $compLevel = "";
116
my $methodName = "";
117
my $usec = 0;
118
my $matchFound = 0;
119
if ($line =~ /\+ \((.+)\) (\S+) \@ .+ time=(\d+)us/) {
120
$compLevel = $1;
121
$methodName = $2;
122
$usec = $3;
123
$matchFound = 1;
124
}
125
# Note that AOT loads have a different format:
126
elsif ($line =~ /\+ \(AOT load\) (\S+).+\@ /) {
127
$compLevel = "AOT load";
128
$methodName = $1;
129
$matchFound = 1;
130
}
131
# If the method name is very long there might be no space between the method name and location in memory
132
elsif ($line =~ /\+ \((.+)\) (\S+)0x[0-9A-F].+time=(\d+)us/) {
133
$compLevel = $1;
134
$methodName = $2;
135
$usec = $3;
136
$matchFound = 1;
137
}
138
elsif($line =~ /^\! (\S+) time=(\d+)us/) {
139
$usec = $2;
140
&UpdateStats($usec, @allt);
141
&UpdateStats($usec, @failures);
142
}
143
144
145
if ($matchFound) {
146
147
if ($usec > $max) {
148
$max = $usec;
149
$maxLine = $line;
150
}
151
152
# add the method to a hash where the method name is the key
153
if (exists $methodHash{$methodName}) {
154
# retrieve the array ref from the hash and then do a push
155
push(@{$methodHash{$methodName}}, $line);
156
}
157
else { # first instance in the hash
158
# add an anonymous array ref to the hash
159
$methodHash{$methodName} = [$line];
160
}
161
162
if ($usec > $compTimeThreshold) {
163
print $line;
164
}
165
166
&UpdateStats($usec, @allt);
167
if ($line =~ / JNI /) {
168
&UpdateStats($usec, @jni);
169
}elsif ($compLevel eq "warm") {
170
&UpdateStats($usec, @warm);
171
}elsif ($compLevel eq "cold") {
172
&UpdateStats($usec, @cold);
173
}elsif ($compLevel eq "AOT load") {
174
&UpdateStats($usec, @aotload);
175
}elsif ($compLevel eq "AOT cold") {
176
&UpdateStats($usec, @aotcold);
177
}elsif ($compLevel eq "AOT warm") {
178
&UpdateStats($usec, @aotwarm);
179
}elsif ($compLevel eq "AOT hot") {
180
&UpdateStats($usec, @aothot);
181
}elsif ($compLevel eq "hot") {
182
&UpdateStats($usec, @hot);
183
}elsif ($compLevel eq "profiled hot") {
184
&UpdateStats($usec, @phot);
185
}elsif ($compLevel eq "very-hot") {
186
&UpdateStats($usec, @veryhot);
187
}elsif ($compLevel eq "profiled very-hot") {
188
&UpdateStats($usec, @pveryhot);
189
}elsif ($compLevel eq "scorching") {
190
&UpdateStats($usec, @scorching);
191
}elsif ($compLevel eq "no-opt") {
192
&UpdateStats($usec, @noopt);
193
}else {
194
&UpdateStats($usec, @unknown);
195
}
196
# look at the reason for recompilation
197
if ($line =~ / G /) {
198
$numGCR++;
199
}
200
elsif ($line =~ / g /) {
201
$numGCRNoServer++;
202
}
203
elsif ($line =~ / P /) {
204
$numPushy++;
205
}
206
elsif ($line =~ / I /) {
207
$numInvalidate++;
208
}
209
elsif ($line =~ / C /) {
210
$numColdUpgrade++;
211
}
212
if ($line =~ / A /) {
213
$numForcedAOTUpgrade++;
214
}
215
if ($line =~ / sync /) {
216
$numSync++;
217
}
218
if ($line =~ / DLT /) {
219
$numDLT++;
220
}
221
if ($line =~ /Q\_SZ=(\d+)/) {
222
if ($1 > $maxQSZ) {
223
$maxQSZ = $1;
224
}
225
}
226
}
227
elsif ($line =~ /^\! /) { # lines starting with !
228
$numFailures++;
229
}
230
elsif ($line =~ /^\+/) { # lines that start with '+' and haven't been tracked by now are errors
231
print "Unaccounted line: $line";
232
}
233
# Track timestamps
234
if ($line =~ /\st=\s*(\d+)\s/) {
235
$lastTimestamp = $1;
236
}
237
}
238
print "$vlog_filename\n";
239
print "\tSamples MAX(ms) TOTAL(ms)\tAVG(usec)\tMIN(usec)\n";
240
&PrintStats("Total", @allt);
241
&PrintStats("aotl", @aotload);
242
&PrintStats("noopt", @noopt);
243
&PrintStats("cold", @cold);
244
&PrintStats("aotc", @aotcold);
245
&PrintStats("aotw", @aotwarm);
246
&PrintStats("aoth", @aothot);
247
&PrintStats("warm", @warm);
248
&PrintStats("hot", @hot);
249
&PrintStats("phot", @phot);
250
&PrintStats("vhot", @veryhot);
251
&PrintStats("pvhot", @pveryhot);
252
&PrintStats("scorc", @scorching);
253
&PrintStats("jni", @jni);
254
&PrintStats("unkn", @unknown);
255
&PrintStats("fails", @failures);
256
257
258
# compute how many upgrades come from AOT and how many from JIT
259
for my $methodName (keys %methodHash) { # for each method
260
my $compArrayRef = $methodHash{$methodName}; # get its table of compilations
261
my $numComp = scalar(@$compArrayRef); # number of compilations for this method
262
for (my $i = $numComp-1; $i >= 0; $i--) { # for each compilation of said method
263
if ($compArrayRef->[$i] =~ / C /) { # if the compilation is a cold upgrade
264
#print $compArrayRef->[$i];
265
if ($i == 0) { # cold upgrades cannot appear first because thei are recompilations
266
print "Some error occurred for" . $compArrayRef->[$i];
267
} else {
268
if ($compArrayRef->[$i-1] =~ /\+ \(AOT load\)/) {
269
$numAOTUpgrade++;
270
} else {
271
$numNonAOTUpgrade++;
272
}
273
#print $compArrayRef->[$i-1] . "\n";
274
}
275
next;
276
}
277
}
278
# now look to see how many AOT loads were recompiled
279
if ($compArrayRef->[0] =~ /AOT load/) { # this is an AOT load
280
# if there are other compilations, then they are recompilations
281
if ($numComp == 1) {
282
$numAOTLoadsNotRecompiled++;
283
}
284
}
285
}
286
287
288
print "MAXLINE=$maxLine";
289
print "numCGR recompilations = $numGCR\n";
290
print "numgcr recompilations = $numGCRNoServer\n";
291
print "pushy recompilations = $numPushy\n";
292
print "coldupgr recompilations = $numColdUpgrade (AOT=$numAOTUpgrade, JIT=$numNonAOTUpgrade\n";
293
print "forcedAOTupgrades = $numForcedAOTUpgrade\n";
294
print "numAOTLoadsNotRecompiled= $numAOTLoadsNotRecompiled\n";
295
print "inv recompilations = $numInvalidate\n";
296
print "sync compilations = $numSync\n";
297
print "DLT compilations = $numDLT\n";
298
print "numFailures = $numFailures\n";
299
print "max_Q_SZ = $maxQSZ\n";
300
print "lastTimestamp = $lastTimestamp\n";
301
302
303
return $allt[1];
304
}
305
306
307