OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [gnu/] [gcj/] [tools/] [gc_analyze/] [MemoryAnalyze.java] - Blame information for rev 756

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 756 jeremybenn
/* MemoryAnalyze.java -- Analyzes a libgcj heap dump.
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 gnu.classpath.tools.getopt.FileArgumentCallback;
13
import gnu.classpath.tools.getopt.Option;
14
import gnu.classpath.tools.getopt.OptionException;
15
import gnu.classpath.tools.getopt.Parser;
16
 
17
import java.io.BufferedReader;
18
import java.io.FileInputStream;
19
import java.io.IOException;
20
import java.io.InputStreamReader;
21
import java.text.NumberFormat;
22
import java.util.ArrayList;
23
import java.util.Collections;
24
import java.util.Comparator;
25
import java.util.HashMap;
26
import java.util.Iterator;
27
import java.util.Map;
28
 
29
class MemoryAnalyze
30
{
31
  public MemoryAnalyze()
32
  {
33
  }
34
 
35
  private static NumberFormat numberFormat;
36
  private static boolean verbose;
37
  static String format(long number, int digits)
38
  {
39
    if (numberFormat == null)
40
      {
41
        numberFormat = NumberFormat.getNumberInstance();
42
        numberFormat.setGroupingUsed(true);
43
      }
44
    String temp = numberFormat.format(number);
45
    int spaces = digits - temp.length();
46
    if (spaces < 0)
47
      spaces = 0;
48
    return "                                ".substring(0,spaces) + temp;
49
  }
50
 
51
  static void sorted_report(String description,
52
                            int total_space,
53
                            ArrayList<String> list,
54
                            Comparator<String> comparator)
55
  {
56
    System.out.println("*** " + description + " ***");
57
    System.out.println();
58
    System.out.println("  Total Size       Count       Size    Description");
59
    System.out.println("--------------     -----    --------   -----------------------------------");
60
    Collections.sort(list, comparator);
61
    for (Iterator it = list.iterator(); it.hasNext(); )
62
      {
63
        String v = (String)it.next();
64
        System.out.println(stripend(v));
65
      }
66
    System.out.println("--------------     -----    --------   -----------------------------------");
67
    System.out.println(format(total_space, 14));
68
    System.out.println();
69
    System.out.println();
70
  }
71
 
72
  private static String stripend(String s)
73
  {
74
    int n = s.lastIndexOf(" /");
75
    if (n > 0)
76
      return s.substring(0,n);
77
    return s;
78
  }
79
 
80
  static  class SubstringComparator implements Comparator<String>
81
  {
82
    private int begin, end;
83
    private boolean reverse;
84
 
85
    SubstringComparator(int begin, int end, boolean reverse)
86
    {
87
      this.begin = begin;
88
      this.end = end;
89
      this.reverse = reverse;
90
    }
91
 
92
    public int compare(String s1, String s2)
93
    {
94
      if (end == 0)
95
        s1 = s1.substring(begin);
96
      else
97
        s1 = s1.substring(begin, end);
98
 
99
      if (end == 0)
100
        s2 = s2.substring(begin);
101
      else
102
        s2 = s2.substring(begin, end);
103
      int i = s1.compareTo(s2);
104
      if (reverse)
105
        return -i;
106
      return i;
107
    }
108
  }
109
 
110
  static class OptionParser extends Parser
111
  {
112
    int filesFound;
113
 
114
    OptionParser()
115
    {
116
      super("gc-analyze",
117
            "gc-analyze (" + System.getProperty("java.vm.version") + ")");
118
 
119
      add(new Option('d',
120
                     "Directory containing runtime objects",
121
                     "directory")
122
        {
123
          public void parsed(String argument) throws OptionException
124
          {
125
            ToolPrefix.pathPrefix = argument;
126
          }
127
        });
128
 
129
      add(new Option('p',
130
                     "Binary tool prefix, prepended to nm and readelf to "
131
                     + "obtain target specific versions of these commands",
132
                     "prefix")
133
        {
134
          public void parsed(String argument) throws OptionException
135
          {
136
            ToolPrefix.toolPrefix = argument;
137
          }
138
        });
139
 
140
      add(new Option("verbose", 'v',
141
                     "Verbose output; requires filename.bytes")
142
        {
143
          public void parsed(String argument) throws OptionException
144
          {
145
            verbose = true;
146
          }
147
        });
148
 
149
      setHeader("usage: gc-analyze [-v] [-p tool-prefix] [-d <directory>] "
150
                + "filename");
151
    }
152
 
153
    protected void validate() throws OptionException
154
    {
155
      if (filesFound != 1)
156
        throw new OptionException("Must specify exactly one filename");
157
    }
158
 
159
    public String[] parse(String[] inArgs)
160
    {
161
      final ArrayList<String> fileResult = new ArrayList<String>();
162
      parse(inArgs, new FileArgumentCallback()
163
        {
164
          public void notifyFile(String fileArgument)
165
          {
166
            filesFound++;
167
            fileResult.add(fileArgument);
168
          }
169
        });
170
      return fileResult.toArray(new String[1]);
171
    }
172
  }
173
 
174
  public static void main(String[] args)
175
  {
176
    class Info
177
    {
178
      int size;
179
      int count;
180
    }
181
    int total_space = 0;
182
 
183
    Parser optionParser = new OptionParser();
184
 
185
    String rest[] = optionParser.parse(args);
186
 
187
    String filename = rest[0];
188
 
189
    try
190
      {
191
        BufferedReader reader =
192
          new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
193
        SymbolLookup lookup = new SymbolLookup(reader, filename + ".bytes");
194
        ObjectMap objectMap = new ObjectMap(reader);
195
        BlockMap blockMap = new BlockMap(reader);
196
        reader.close();
197
 
198
        // add info to item(s)
199
        // add item.klass
200
        for (Map.Entry<Long, ObjectMap.ObjectItem> me : objectMap)
201
        {
202
            ObjectMap.ObjectItem item = me.getValue();
203
 
204
            // try to get a klass (happens with intern'ed strings...)
205
            if (item.klass==0)
206
              {
207
                BytePtr p = lookup.getBytePtr(item.ptr, item.size);
208
                if (p!=null)
209
                  {
210
                    long vtable = p.getWord(0);
211
                    String sym =
212
                        lookup.getSymbolViaVtable(vtable - 2 * lookup.memoryMap.wordSize);
213
                    if (sym != null)
214
                      {
215
                        item.typeName = SymbolTable.demangleVTName(sym);
216
                      }
217
                    else if (vtable != 0)
218
                      {
219
                        // get klass from vtable
220
                        p = lookup.getBytePtr(vtable,
221
                                              lookup.memoryMap.wordSize);
222
                        if (p != null)
223
                          {
224
                            long klass = p.getWord(0);
225
                            item.klass = klass;
226
                          }
227
                      }
228
                  }
229
              }
230
 
231
            // figure out strings
232
            String class_name;
233
            if (null == item.typeName)
234
              {
235
                class_name =
236
                  MemoryAnalyze.getSymbolPretty(lookup, item, false);
237
                item.typeName = class_name;
238
              }
239
            else
240
              {
241
                class_name = item.typeName;
242
              }
243
            System.out.print("class_name=[" + class_name + "]");
244
 
245
            if (class_name.compareTo("_ZTVN4java4lang6StringE")==0
246
                || class_name.compareTo("java.lang.String")==0)
247
              {
248
                BytePtr p = lookup.getBytePtr(item.ptr, item.size);
249
                long data = p.getWord(1);
250
                int boffset = p.getInt(2 * p.intsPerWord());
251
                int count = p.getInt(1 + 2 * p.intsPerWord());
252
                int hash = p.getInt(2 + 2 * p.intsPerWord());
253
                BytePtr chars = lookup.getBytePtr(data+boffset, count * 2);
254
                StringBuffer sb = new StringBuffer(count);
255
                for (int qq = 0; qq<count; qq++)
256
                  sb.append((char)chars.getShort(qq));
257
                int newhash = sb.toString().hashCode();
258
                if (newhash!=hash)
259
                  {
260
                    p.setInt(4, newhash);
261
                  }
262
 
263
                item.string = sb.toString();
264
                System.out.println(" value = \"" + item.string + "\"");
265
                if (data != item.ptr)
266
                  {
267
                    ObjectMap.ObjectItem next = objectMap.get(data);
268
                    if (next != null)
269
                      next.stringData = true;
270
                    else
271
                      System.out.println("String [" + item.string + "] at "
272
                                         + Long.toHexString(item.ptr)
273
                                         + " can't find array at "
274
                                         + Long.toHexString(data));
275
                  }
276
              }
277
            else if (null != item.string)
278
              System.out.println(" value = \"" + item.string + "\"");
279
            else
280
              System.out.println();
281
          }
282
 
283
 
284
        HashMap<String, Info> map = new HashMap<String, Info>();
285
        for (Map.Entry<Long, ObjectMap.ObjectItem> me : objectMap)
286
          {
287
            ObjectMap.ObjectItem item = me.getValue();
288
            String name = getSymbolPretty(lookup, item, true);
289
            Info info = map.get(name);
290
            if (info == null)
291
              {
292
                info = new Info();
293
                info.count = 0;
294
                info.size = item.size;
295
                map.put(name, info);
296
              }
297
            info.count++;
298
            total_space += item.size;
299
          }
300
 
301
        ArrayList<String> list = new ArrayList<String>();
302
        for (Iterator it = map.entrySet().iterator(); it.hasNext(); )
303
          {
304
            Map.Entry me = (Map.Entry)it.next();
305
            String name = (String)me.getKey();
306
            Info info = (Info)me.getValue();
307
 
308
            StringBuffer sb = new StringBuffer();
309
            sb.append(format(info.count * info.size * 100 / total_space,
310
                             3));
311
            sb.append("%");
312
            sb.append(format(info.count * info.size, 10));
313
            sb.append(" = ");
314
            sb.append(format(info.count, 7));
315
            sb.append(" * ");
316
            sb.append(format(info.size, 9));
317
            sb.append(" - ");
318
            sb.append(name);
319
            list.add(sb.toString());
320
          }
321
 
322
        sorted_report("Memory Usage Sorted by Total Size",
323
                      total_space, list, new SubstringComparator(5,14,true));
324
        sorted_report("Memory Usage Sorted by Description",
325
                      total_space, list, new SubstringComparator(39,0,false));
326
        sorted_report("Memory Usage Sorted by Count",
327
                      total_space, list, new SubstringComparator(17,25,true));
328
        sorted_report("Memory Usage Sorted by Size",
329
                      total_space, list, new SubstringComparator(28,37,true));
330
 
331
        blockMap.dump();
332
 
333
        // dump raw memory
334
        if (verbose)
335
          {
336
            // analyze references
337
            for (Map.Entry<Long, ObjectMap.ObjectItem> me : objectMap)
338
              {
339
                long ptr = me.getKey();
340
                ObjectMap.ObjectItem item = me.getValue();
341
                BytePtr p = lookup.getBytePtr(ptr, item.size);
342
                if (p == null)
343
                  System.out.println("can't find ptr 0x"
344
                                     + Long.toHexString(ptr));
345
                else if (item.kind != 0) // not GC_PTRFREE
346
                  for (int i = 1;
347
                       i < item.size / lookup.memoryMap.wordSize; i++)
348
                    {
349
                      long maybe_ptr = p.getWord(i);
350
                      ObjectMap.ObjectItem item2 = objectMap.get(maybe_ptr);
351
                      if (item2 != null)
352
                        {
353
                          item2.pointed_by.add(item);
354
                          item.points_to.add(item2);
355
                        }
356
                    }
357
              }
358
            System.out.println();
359
            System.out.println("*** All Objects ***");
360
            System.out.println();
361
 
362
            for (Map.Entry<Long, ObjectMap.ObjectItem> me : objectMap)
363
            {
364
              long ptr = me.getKey();
365
              ObjectMap.ObjectItem item = me.getValue();
366
              String name = getSymbolPretty(lookup, item, false);
367
              System.out.print("0x" + Long.toHexString(ptr) + " - " + name
368
                               + " (" + item.size + ")");
369
              if (item.string != null)
370
                System.out.println(" \"" + item.string + "\"");
371
              else
372
                System.out.println();
373
 
374
              BytePtr p = lookup.getBytePtr(ptr, item.size);
375
 
376
              if (p == null)
377
                System.out.println(
378
                  "can't find memory; recently allocated from free list?");
379
              else
380
                p.dump();
381
 
382
              item.points_to.dump("  points to:", lookup);
383
              item.pointed_by.dump("  pointed to by:", lookup);
384
              System.out.println();
385
            }
386
          }
387
      }
388
    catch (IOException e)
389
      {
390
        e.printStackTrace();
391
      }
392
  }
393
 
394
  public static String kindToName(int kind)
395
  {
396
    String name;
397
    switch (kind)
398
      {
399
      case 0:
400
        name = "GC_PTRFREE";
401
        break;
402
      case 1:
403
        name = "GC_NORMAL";
404
        break;
405
      case 2:
406
        name = "GC_UNCOLLECTABLE";
407
        break;
408
      case 3:
409
        name = "GC_AUUNCOLLCTABLE";
410
        break;
411
      case 4:
412
        name = "(Java)";
413
        break;
414
      case 5:
415
        name = "(Java Debug)";
416
        break;
417
      case 6:
418
        name = "(Java Array)";
419
        break;
420
      default:
421
        name = "(Kind " + kind + ")";
422
        break;
423
      }
424
    return name;
425
  }
426
 
427
  public static String getSymbolPretty(SymbolLookup lookup,
428
                                       ObjectMap.ObjectItem item,
429
                                       boolean bsize)
430
    throws IOException
431
  {
432
 
433
    String name = item.typeName;
434
 
435
    if (name == null)
436
      name = lookup.getSymbol(item.klass);
437
 
438
    if (name == null)
439
      {
440
        String v = lookup.decodeUTF8(item.ptr, item.size);
441
        if (null != v)
442
          {
443
            name = "UTF8Const";
444
            item.string = v;
445
          }
446
      }
447
 
448
    if (name == null)
449
      {
450
        name = kindToName(item.kind);
451
      }
452
    if (item.kind==6)
453
      name += "[" + format(item.data, 0) + "]";
454
    if (bsize)
455
      name = name + " / " + format(item.size, 7);
456
    return name;
457
  }
458
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.