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