OLD | NEW |
| (Empty) |
1 #!/usr/bin/perl | |
2 # Copyright (c) 2012 The Chromium 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 # Read a memtrace logfile from stdin and group memory allocations by logical | |
7 # code component. The code component is guessed from the callstack, and | |
8 # is something like {v8, sqlite, disk cache, skia, etc..} | |
9 # | |
10 # Usage: | |
11 # | |
12 # summary.pl | |
13 # | |
14 # [STDIN] -- The memwatcher.logXXXX file to summarize. | |
15 # | |
16 | |
17 sub process_stdin() { | |
18 my %leaks = (); | |
19 my $total_bytes = 0; | |
20 | |
21 while(<STDIN>) { | |
22 my $line = $_; | |
23 chomp($line); | |
24 my $bytes, $loc; | |
25 ($bytes, $loc) = ($line =~ m/[ \t]*([0-9]*)[ \t]*[0-9\.%]*[ \t]*(.*)/); | |
26 chomp($loc); | |
27 while(<STDIN>) { | |
28 my $cont = $_; | |
29 chomp($cont); | |
30 last if $cont =~ m/=====/; | |
31 $loc .= "\n" . $cont; | |
32 } | |
33 my $location_blame = ""; | |
34 | |
35 # print "Found: $bytes, $loc\n"; | |
36 | |
37 if ($loc =~ m/v8::internal::Snapshot::Deserialize/) { | |
38 $location_blame = "v8 Snapshot Deserialize"; | |
39 } elsif ($loc =~ m/RenderStyle::create/) { | |
40 $location_blame = "RenderStyle::create"; | |
41 } elsif ($loc =~ m/v8::internal::OldSpace::SlowAllocateRaw/) { | |
42 $location_blame = "v8 OldSpace"; | |
43 } elsif ($loc =~ m/sqlite/) { | |
44 $location_blame = "sqlite"; | |
45 } elsif ($loc =~ m/ TransportDIB::Map/) { | |
46 $location_blame = "Shared Memory Backing Store"; | |
47 } elsif ($loc =~ m/imagedecoder/) { | |
48 $location_blame = "img decoder"; | |
49 } elsif ($loc =~ m/SkBitmap/) { | |
50 $location_blame = "skia"; | |
51 } elsif ($loc =~ m/disk_cache/) { | |
52 $location_blame = "disk cache"; | |
53 } elsif ($loc =~ m/skia/) { | |
54 $location_blame = "skia"; | |
55 } elsif ($loc =~ m/:WSA/) { | |
56 $location_blame = "net"; | |
57 } elsif ($loc =~ m/dns/) { | |
58 $location_blame = "net"; | |
59 } elsif ($loc =~ m/trunk\\net/) { | |
60 $location_blame = "net"; | |
61 } elsif ($loc =~ m/WinHttp/) { | |
62 $location_blame = "WinHttp"; | |
63 } elsif ($loc =~ m/:I_Crypt/) { | |
64 $location_blame = "WinHttpSSL"; | |
65 } elsif ($loc =~ m/CryptGetTls/) { | |
66 $location_blame = "WinHttpSSL"; | |
67 } elsif ($loc =~ m/WinVerifyTrust/) { | |
68 $location_blame = "WinHttpSSL"; | |
69 } elsif ($loc =~ m/Cert/) { | |
70 $location_blame = "WinHttpSSL"; | |
71 } elsif ($loc =~ m/plugin/) { | |
72 $location_blame = "plugin"; | |
73 } elsif ($loc =~ m/NP_/) { | |
74 $location_blame = "plugin"; | |
75 } elsif ($loc =~ m/hunspell/) { | |
76 $location_blame = "hunspell"; | |
77 } elsif ($loc =~ m/TextCodec/) { | |
78 $location_blame = "fonts"; | |
79 } elsif ($loc =~ m/glyph/) { | |
80 $location_blame = "fonts"; | |
81 } elsif ($loc =~ m/cssparser/) { | |
82 $location_blame = "webkit css"; | |
83 } elsif ($loc =~ m/::CSS/) { | |
84 $location_blame = "webkit css"; | |
85 } elsif ($loc =~ m/Arena/) { | |
86 $location_blame = "webkit arenas"; | |
87 } elsif ($loc =~ m/WebCore::.*ResourceLoader::addData/) { | |
88 $location_blame = "WebCore *ResourceLoader addData"; | |
89 } elsif ($loc =~ m/OnUpdateVisitedLinks/) { | |
90 $location_blame = "OnUpdateVisitedLinks"; | |
91 } elsif ($loc =~ m/IPC/) { | |
92 $location_blame = "ipc"; | |
93 } elsif ($loc =~ m/trunk\\chrome\\browser/) { | |
94 $location_blame = "browser"; | |
95 } elsif ($loc =~ m/trunk\\chrome\\renderer/) { | |
96 $location_blame = "renderer"; | |
97 } elsif ($loc =~ m/webcore\\html/) { | |
98 $location_blame = "webkit webcore html"; | |
99 } elsif ($loc =~ m/webkit.*string/) { | |
100 $location_blame = "webkit strings"; | |
101 } elsif ($loc =~ m/htmltokenizer/) { | |
102 $location_blame = "webkit HTMLTokenizer"; | |
103 } elsif ($loc =~ m/javascriptcore/) { | |
104 $location_blame = "webkit javascriptcore"; | |
105 } elsif ($loc =~ m/webkit/) { | |
106 $location_blame = "webkit other"; | |
107 } elsif ($loc =~ m/safe_browsing/) { | |
108 $location_blame = "safe_browsing"; | |
109 } elsif ($loc =~ m/VisitedLinkMaster/) { | |
110 $location_blame = "VisitedLinkMaster"; | |
111 } elsif ($loc =~ m/NewDOMUI/) { | |
112 $location_blame = "NewDOMUI"; | |
113 } elsif ($loc =~ m/RegistryControlledDomainService/) { | |
114 $location_blame = "RegistryControlledDomainService"; | |
115 } elsif ($loc =~ m/URLRequestChromeJob::DataAvailable/) { | |
116 $location_blame = "URLRequestChromeJob DataAvailable"; | |
117 } else { | |
118 $location_blame = "unknown"; | |
119 } | |
120 | |
121 # Surface large outliers in an "interesting" group. | |
122 my $interesting_group = "unknown"; | |
123 my $interesting_size = 10000000; # Make this smaller as needed. | |
124 # TODO(jar): Add this as a pair of shell arguments. | |
125 if ($bytes > $interesting_size && $location_blame eq $interesting_group) { | |
126 # Create a special group for the exact stack that contributed so much. | |
127 $location_blame = $loc; | |
128 } | |
129 | |
130 $total_bytes += $bytes; | |
131 $leaks{$location_blame} += $bytes; | |
132 } | |
133 | |
134 # now dump our hash table | |
135 my $sum = 0; | |
136 my @keys = sort { $leaks{$b} <=> $leaks{$a} }keys %leaks; | |
137 for ($i=0; $i<@keys; $i++) { | |
138 my $key = @keys[$i]; | |
139 printf "%11s\t(%3.2f%%)\t%s\n", comma_print($leaks{$key}), (100* $leaks{$key
} / $total_bytes), $key; | |
140 $sum += $leaks{$key}; | |
141 } | |
142 printf("TOTAL: %s\n", comma_print($sum)); | |
143 } | |
144 | |
145 # Insert commas into an integer after each three digits for printing. | |
146 sub comma_print { | |
147 my $num = "$_[0]"; | |
148 $num =~ s/(\d{1,3}?)(?=(\d{3})+$)/$1,/g; | |
149 return $num; | |
150 } | |
151 | |
152 # ----- Main ------------------------------------------------ | |
153 | |
154 process_stdin(); | |
OLD | NEW |