[project @ 1997-03-13 09:10:17 by sof]
[ghc-hetmet.git] / ghc / utils / stat2resid / parse-gcstats.prl
1 #!/local/sun4/bin/perl
2 #
3 # Subroutines to parses a ghc Garbage Collection stats file
4 #
5 #%gcstats = &parse_stats($ARGV[0]);
6 #&print_stats(">-", %gcstats);
7 #exit 0;
8
9 sub to_num {
10     local ($text) = @_;
11     return($1 * 1000000000 + $2 * 1000000 + $3 * 1000 + $4)
12         if ( $text =~ /^(\d*),(\d*),(\d*),(\d*)$/ );
13     return($1 * 1000000 + $2 * 1000 + $3)
14         if ( $text =~ /^(\d*),(\d*),(\d*)$/ );
15     return($1 * 1000 + $2)
16         if ( $text =~ /^(\d*),(\d*)$/ );
17     return($1)
18         if ( $text =~ /^(\d*)$/ );
19     die "Error converting $text\n";
20 }
21
22 sub from_num {
23     local ($num) = @_;
24     local ($b, $m, $t, $o) = (int($num/1000000000), int($num/1000000)%1000,
25                               int($num/1000)%1000, $num%1000);
26     return(sprintf("%d,%03d,%03d,%03d", $b, $m, $t, $o)) if $b > 0;
27     return(sprintf("%d,%03d,%03d", $m, $t, $o))          if $m > 0;
28     return(sprintf("%d,%03d", $t, $o))                   if $t > 0;
29     return(sprintf("%d", $o))                            if $o > 0;
30 }
31
32 sub parse_stats {
33     local($filename) = @_;
34     local($tot_alloc, $tot_gc_user, $tot_mut_user, $tot_user,
35                       $tot_gc_elap, $tot_mut_elap, $tot_elap);
36     local($statsfile, $line, $row, $col, $val);
37     local(@stats, @hdr1, @hdr2, @line_vals);
38     local(%the_stats);
39     local(*STATS);
40
41     open(STATS, $filename) || die "Cant open $filename \n";
42     @stats = <STATS>;
43
44     do {$line = shift(@stats);} until ($line !~ /^$/);
45     chop($line);
46     ($the_stats{"command"}, $the_stats{"args"}) = split(' ', $line, 2);
47
48     do {$line = shift(@stats);} until ($line !~ /^$/);
49     $line =~ /Collector:\s*([A-Z]+)\s*HeapSize:\s*([\d,]+)/;
50     $the_stats{"collector"} = $1;
51     $the_stats{"heapsize"}  = &to_num($2);
52
53     do {$line = shift(@stats);} until ($line !~ /^$/);
54     chop($line);
55     @hdr1 = split(' ', $line);
56     $line = shift(@stats);
57     chop($line);
58     @hdr2 = split(' ', $line);
59
60     $row = 0;
61     $tot_alloc = 0;
62     $tot_gc_user = 0; 
63     $tot_gc_elap = 0; 
64     $tot_mut_user = 0; 
65     $tot_mut_elap = 0; 
66     $tot_user = 0;
67     $tot_elap = 0;
68
69     while (($line = shift(@stats)) !~ /^\s*\d+\s*$/) {
70         chop($line);
71         @line_vals = split(' ', $line);
72
73         $col = -1;
74         word:
75             while(++$col <= $#line_vals) {
76         
77             $val = $line_vals[$col];
78             $_ = @hdr1[$col] . @hdr2[$col];
79
80             /^Allocbytes$/      && do { $tot_alloc += $val;
81                                         $the_stats{"alloc_$row"} = $val;
82                                         next word; };
83
84             /^Collectbytes$/    && do { $the_stats{"collect_$row"} = $val;
85                                         next word; };
86
87             /^Livebytes$/       && do { $the_stats{"live_$row"} = $val;
88                                         next word; };
89
90             /^Residency$/       && do { next word; };
91
92             /^GCuser$/          && do { $tot_gc_user += $val;
93                                         $the_stats{"gc_user_$row"} = $val;
94                                         next word; };
95
96             /^GCelap$/          && do { $tot_gc_elap += $val;
97                                         $the_stats{"gc_elap_$row"} = $val;
98                                         next word; };
99
100             /^TOTuser$/         && do { $the_stats{"mut_user_$row"} =
101                                                 $val - $tot_user - $the_stats{"gc_user_$row"};
102                                         $tot_mut_user += $the_stats{"mut_user_$row"};
103                                         $tot_user = $val;
104                                         next word; };
105
106             /^TOTelap$/         && do { $the_stats{"mut_elap_$row"} =
107                                                 $val - $tot_elap - $the_stats{"gc_elap_$row"};
108                                         $tot_mut_elap += $the_stats{"mut_elap_$row"};
109                                         $tot_elap = $val;
110                                         next word; };
111
112             /^PageGC$/          && do { $the_stats{"gc_pflts_$row"} = $val;
113                                         next word; };
114
115             /^FltsMUT$/         && do { $the_stats{"mut_pflts_$row"} = $val;
116                                         next word; };
117
118             /^Collection/       && do { $the_stats{"mode_$row"} = $val;
119                                         next word; };
120
121             /^Astkbytes$/       && do {next word; };
122             /^Bstkbytes$/       && do {next word; };
123             /^CafNo$/           && do {next word; };
124             /^Cafbytes$/        && do {next word; };
125
126             /^NoAstk$/          && do {next word; };
127             /^ofBstk$/          && do {next word; };
128             /^RootsReg$/        && do {next word; };
129             /^OldGen$/          && do {next word; };
130             /^RootsCaf$/        && do {next word; };
131             /^Sizebytes$/       && do {next word; };
132             /^Resid\%heap$/     && do {next word; };
133
134             /^$/                && do {next word; };
135
136             print STDERR "Unknown: $_ = $val\n";
137         };
138
139         $row++;
140     };
141     $tot_alloc += $line;
142     $the_stats{"alloc_$row"} = $line;
143
144 arg: while($_ = $stats[0]) {
145     shift(@stats);
146
147     /^\s*([\d,]+) bytes alloc/  && do { local($a) = &to_num($1);
148                                         $a == $tot_alloc || die "Total $a != $tot_alloc \n";
149                                         $the_stats{"alloc_total"} = $tot_alloc;
150                                         next arg; };
151
152     /^\s*([\d]+) garbage/       && do { $1 == $row || die "GCNo $1 != $row \n";
153                                         $the_stats{"gc_no"} = $row;
154                                         next arg; };
155
156     /Total time\s+([\d\.]+)s\s+\(\s*([\d.]+)s elapsed\)/ && do {
157                                         $the_stats{"user_total"} = $1;
158                                         $the_stats{"elap_total"} = $2;
159                                         $the_stats{"mut_user_total"} = $1 - $tot_gc_user;
160                                         $the_stats{"mut_elap_total"} = $2 - $tot_gc_elap;
161                                         $the_stats{"mut_user_$row"} = $1 - $tot_gc_user - $tot_mut_user;
162                                         $the_stats{"mut_elap_$row"} = $2 - $tot_gc_elap - $tot_mut_elap;
163                                         next arg; };
164
165     /GC\s+time\s+([\d\.]+)s\s+\(\s*([\d.]+)s elapsed\)/ && do {
166                                         # $1 == $tot_gc_user || die "GCuser $1 != $tot_gc_user \n";
167                                         # $2 == $tot_gc_elap || die "GCelap $2 != $tot_gc_elap \n";
168                                         $the_stats{"gc_user_total"} = $tot_gc_user;
169                                         $the_stats{"gc_elap_total"} = $tot_gc_elap;
170                                         next arg; };
171     
172     /MUT\s+time/                && do { next arg; };
173     /INIT\s+time/               && do { next arg; };
174     /^\s*([\d,]+) bytes maximum residency/ && do { next arg; };
175
176     /\%GC time/                 && do { next arg; };
177     /Alloc rate/                && do { next arg; };
178     /Productivity/              && do { next arg; };
179     /^$/                        && do { next arg; };
180     /^\#/                       && do { next arg; };  # Allows comments to follow
181     
182     print STDERR "Unmatched line: $_";
183     }
184
185     close(STATS);
186     %the_stats;
187 }
188
189 sub print_stats {
190     local ($filename, %out_stats) = @_;
191     local($statsfile, $row);
192
193     open($statsfile, $filename) || die "Cant open $filename \n";
194     select($statsfile);
195
196     print $out_stats{"command"}, " ", $out_stats{"args"}, "\n\n";
197     print "Collector: ", $out_stats{"collector"}, "  HeapSize: ", &from_num($out_stats{"heapsize"}), " (bytes)\n\n";
198
199     $row = 0;
200     while ($row < $out_stats{"gc_no"}) {
201         printf  "%7d %7d %7d %5.2f %5.2f %5.2f %5.2f %4d %4d  %s\n",
202                 $out_stats{"alloc_$row"},
203                 $out_stats{"collect_$row"},
204                 $out_stats{"live_$row"},
205                 $out_stats{"gc_user_$row"},
206                 $out_stats{"gc_elap_$row"},
207                 $out_stats{"mut_user_$row"},
208                 $out_stats{"mut_elap_$row"},
209                 $out_stats{"gc_pflts_$row"},
210                 $out_stats{"mut_pflts_$row"},
211                 $out_stats{"mode_$row"};
212         $row++;
213     };
214     printf "%7d %s %5.2f %5.2f \n\n",
215            $out_stats{"alloc_$row"}, " " x 27,
216            $out_stats{"mut_user_$row"},
217            $out_stats{"mut_elap_$row"};
218
219     printf "Total Alloc: %s\n", &from_num($out_stats{"alloc_total"});
220     printf "      GC No: %d\n\n", $out_stats{"gc_no"};
221
222     printf "  MUT User: %6.2fs\n", $out_stats{"mut_user_total"};
223     printf "   GC User: %6.2fs\n", $out_stats{"gc_user_total"};
224     printf "Total User: %6.2fs\n\n", $out_stats{"user_total"};
225
226     printf "  MUT Elap: %6.2fs\n", $out_stats{"mut_elap_total"};
227     printf "   GC Elap: %6.2fs\n", $out_stats{"gc_elap_total"};
228     printf "Total Elap: %6.2fs\n", $out_stats{"elap_total"};
229
230     close($statsfile);
231 }
232
233 1;