1 /* BlockMap.java -- Container for information on GC maintained memory blocks.
2    Copyright (C) 2007  Free Software Foundation
3 
4    This file is part of libgcj.
5 
6 This software is copyrighted work licensed under the terms of the
7 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
8 details.  */
9 
10 package gnu.gcj.tools.gc_analyze;
11 
12 import java.io.BufferedReader;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Map;
16 import java.util.TreeMap;
17 
18 class BlockMap
19 {
20   static final int HBLKSIZE = 4096;
21 
22   class SizeKind implements Comparable<SizeKind>
23   {
24     int size;
25     int kind;
26 
SizeKind(int size, int kind)27     public SizeKind(int size, int kind)
28     {
29       this.size = size;
30       this.kind = kind;
31     }
32 
compareTo(SizeKind b)33     public int compareTo(SizeKind b)
34     {
35       if (this.size != b.size)
36         return this.size - b.size;
37       return this.kind - b.kind;
38     }
39   }
40 
41   class PtrMarks
42   {
43     long ptr;
44     int marks;
45 
PtrMarks(long ptr, int marks)46     public PtrMarks(long ptr, int marks)
47     {
48       this.ptr = ptr;
49       this.marks = marks;
50     }
51   }
52 
53   private TreeMap<SizeKind, ArrayList<PtrMarks>> map =
54     new TreeMap<SizeKind, ArrayList<PtrMarks>>();
55 
BlockMap(BufferedReader reader)56   public BlockMap(BufferedReader reader) throws IOException
57   {
58     for (;;)
59       {
60         String s = reader.readLine();
61         if (s == null)
62           break;
63         if (s.charAt(0) == '#')
64           continue;
65         if (s.indexOf("Begin block map") >= 0)
66           {
67             for (;;)
68               {
69                 s = reader.readLine();
70                 if (s.charAt(0) == '#')
71                   continue;
72                 if (s.indexOf("End block map") >= 0)
73                   return;
74                 String[] items = s.split(",");
75                 long ptr = 0;
76                 int kind = 0, size = 0, marks = 0;
77                 for (int i=0; i<items.length; i++)
78                   {
79                     String[] x = items[i].split(" ");
80                     String last = x[x.length - 1];
81                     switch (i)
82                       {
83                       case 0:
84                         ptr = MemoryMap.parseHexLong(last.substring(2));
85                         break;
86                       case 1:
87                         kind = Integer.parseInt(last);
88                         break;
89                       case 2:
90                         size = Integer.parseInt(last);
91                         break;
92                       case 3:
93                         marks = Integer.parseInt(last);
94                         break;
95                       }
96                   }
97                 SizeKind sk = new SizeKind(size, kind);
98                 ArrayList<PtrMarks> m = map.get(sk);
99                 if (m == null)
100                     {
101                         m = new ArrayList<PtrMarks>();
102                         map.put(sk, m);
103                     }
104                 PtrMarks pm = new PtrMarks(ptr, marks);
105                 m.add(pm);
106               } // inner loop
107           } // started inner loop
108       } // outer loop - finding begin
109   } // memoryMap
110 
dump()111   public void dump()
112   {
113     System.out.println();
114     System.out.println();
115     System.out.println("*** Used Blocks ***\n");
116     System.out.println();
117     System.out.println("  Size     Kind            Blocks     Used       Free       Wasted");
118     System.out.println("-------  -------------    ------- ---------- ----------    -------");
119 
120     int total_blocks = 0, total_used = 0, total_free = 0, total_wasted = 0;
121 
122     for (Map.Entry<SizeKind, ArrayList<PtrMarks>> me : map.entrySet())
123       {
124         SizeKind sk = me.getKey();
125 
126         System.out.println(MemoryAnalyze.format(sk.size, 7) + "  "
127                            + MemoryAnalyze.kindToName(sk.kind));
128 
129         int sub_blocks = 0, sub_used = 0, sub_free = 0, sub_wasted = 0;
130         int sub_count = 0;
131 
132         ArrayList<PtrMarks> v = me.getValue();
133 
134         for (PtrMarks pm : v)
135           {
136             int bytes = sk.size;
137             int blocks = (sk.size + HBLKSIZE - 1) / HBLKSIZE;
138             int used;
139             int free;
140             int wasted;
141 
142             if (bytes < HBLKSIZE)
143               {
144                 used = bytes * pm.marks;
145                 free = bytes * (HBLKSIZE / bytes - pm.marks);
146                 wasted = HBLKSIZE - HBLKSIZE / bytes * bytes;
147               }
148             else
149               {
150                 if (pm.marks != 0)
151                   {
152                     used = bytes;
153                     free = 0;
154                     wasted = (bytes + HBLKSIZE - 1)
155                       / HBLKSIZE * HBLKSIZE - used;
156                   }
157                 else
158                   {
159                     used = 0;
160                     free = bytes;
161                     wasted = 0;
162                   }
163               }
164 
165             StringBuilder sb = new StringBuilder();
166             sb.append("                            ");
167             sb.append(MemoryAnalyze.format(blocks, 5));
168             sb.append("  ");
169             sb.append(MemoryAnalyze.format(used, 9));
170             sb.append("  ");
171             sb.append(MemoryAnalyze.format(free, 9));
172             sb.append("  ");
173             sb.append(MemoryAnalyze.format(wasted, 9));
174             System.out.println(sb);
175 
176             sub_blocks += blocks;
177             sub_used += used;
178             sub_free += free;
179             sub_wasted += wasted;
180             sub_count++;
181 
182             total_blocks += blocks;
183             total_used += used;
184             total_free += free;
185             total_wasted += wasted;
186           } // blocks with size/kind
187         if (sub_count > 1)
188           {
189             System.out.println(
190                                "                          ------- ---------- ----------    -------");
191             StringBuilder sb = new StringBuilder();
192             sb.append("                            ");
193             sb.append(MemoryAnalyze.format(sub_blocks, 5));
194             sb.append("  ");
195             sb.append(MemoryAnalyze.format(sub_used, 9));
196             sb.append("  ");
197             sb.append(MemoryAnalyze.format(sub_free, 9));
198             sb.append("  ");
199             sb.append(MemoryAnalyze.format(sub_wasted, 9));
200             System.out.println(sb);
201           }
202       } // size/kind
203 
204     System.out.println("-------  -------------    ------- ---------- ----------    -------");
205     StringBuilder sb = new StringBuilder();
206     sb.append("                            ");
207     sb.append(MemoryAnalyze.format(total_blocks, 5));
208     sb.append("  ");
209     sb.append(MemoryAnalyze.format(total_used, 9));
210     sb.append("  ");
211     sb.append(MemoryAnalyze.format(total_free, 9));
212     sb.append("  ");
213     sb.append(MemoryAnalyze.format(total_wasted, 9));
214     System.out.println(sb);
215     System.out.println("Total bytes = "
216                        + MemoryAnalyze.format(total_blocks * HBLKSIZE, 10));
217   }
218 }
219