jdk/src/share/classes/com/sun/tools/hat/internal/parser/HprofReader.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 468 642c8c0be52e
permissions -rw-r--r--
Initial load
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * The contents of this file are subject to the Sun Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 * Version 1.0 (the "License"); you may not use this file except in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * compliance with the License. A copy of the License is available at
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 * http://www.sun.com/, and in the file LICENSE.html in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * doc directory.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * The Original Code is HAT. The Initial Developer of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * Original Code is Bill Foote, with contributions from others
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * at JavaSoft/Sun. Portions created by Bill Foote and others
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * at Javasoft/Sun are Copyright (C) 1997-2004. All Rights Reserved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * In addition to the formal license, I ask that you don't
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * change the history or donations files without permission.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
package com.sun.tools.hat.internal.parser;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.io.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.util.Date;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.util.Hashtable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import com.sun.tools.hat.internal.model.ArrayTypeCodes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import com.sun.tools.hat.internal.model.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * Object that's used to read a hprof file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * @author      Bill Foote
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    final static int MAGIC_NUMBER = 0x4a415641;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    // That's "JAVA", the first part of "JAVA PROFILE ..."
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    private final static String[] VERSIONS = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
            " PROFILE 1.0\0",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
            " PROFILE 1.0.1\0",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
            " PROFILE 1.0.2\0",
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    private final static int VERSION_JDK12BETA3 = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    private final static int VERSION_JDK12BETA4 = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    private final static int VERSION_JDK6       = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    // These version numbers are indices into VERSIONS.  The instance data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    // member version is set to one of these, and it drives decisions when
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    // reading the file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    // Version 1.0.1 added HPROF_GC_PRIM_ARRAY_DUMP, which requires no
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    // version-sensitive parsing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    // Version 1.0.1 changed the type of a constant pool entry from a signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    // to a typecode.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    // Version 1.0.2 added HPROF_HEAP_DUMP_SEGMENT and HPROF_HEAP_DUMP_END
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    // to allow a large heap to be dumped as a sequence of heap dump segments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    // The HPROF agent in J2SE 1.2 through to 5.0 generate a version 1.0.1
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    // file. In Java SE 6.0 the version is either 1.0.1 or 1.0.2 depending on
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    // the size of the heap (normally it will be 1.0.1 but for multi-GB
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    // heaps the heap dump will not fit in a HPROF_HEAP_DUMP record so the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    // dump is generated as version 1.0.2).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    // Record types:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    static final int HPROF_UTF8          = 0x01;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    static final int HPROF_LOAD_CLASS    = 0x02;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    static final int HPROF_UNLOAD_CLASS  = 0x03;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    static final int HPROF_FRAME         = 0x04;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    static final int HPROF_TRACE         = 0x05;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    static final int HPROF_ALLOC_SITES   = 0x06;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    static final int HPROF_HEAP_SUMMARY  = 0x07;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    static final int HPROF_START_THREAD  = 0x0a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    static final int HPROF_END_THREAD    = 0x0b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    static final int HPROF_HEAP_DUMP     = 0x0c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    static final int HPROF_CPU_SAMPLES   = 0x0d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    static final int HPROF_CONTROL_SETTINGS = 0x0e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    static final int HPROF_LOCKSTATS_WAIT_TIME = 0x10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    static final int HPROF_LOCKSTATS_HOLD_TIME = 0x11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    static final int HPROF_GC_ROOT_UNKNOWN       = 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    static final int HPROF_GC_ROOT_JNI_GLOBAL    = 0x01;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    static final int HPROF_GC_ROOT_JNI_LOCAL     = 0x02;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    static final int HPROF_GC_ROOT_JAVA_FRAME    = 0x03;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    static final int HPROF_GC_ROOT_NATIVE_STACK  = 0x04;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    static final int HPROF_GC_ROOT_STICKY_CLASS  = 0x05;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    static final int HPROF_GC_ROOT_THREAD_BLOCK  = 0x06;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    static final int HPROF_GC_ROOT_MONITOR_USED  = 0x07;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    static final int HPROF_GC_ROOT_THREAD_OBJ    = 0x08;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    static final int HPROF_GC_CLASS_DUMP         = 0x20;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    static final int HPROF_GC_INSTANCE_DUMP      = 0x21;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    static final int HPROF_GC_OBJ_ARRAY_DUMP         = 0x22;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    static final int HPROF_GC_PRIM_ARRAY_DUMP         = 0x23;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    static final int HPROF_HEAP_DUMP_SEGMENT     = 0x1c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    static final int HPROF_HEAP_DUMP_END         = 0x2c;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    private final static int T_CLASS = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    private int version;        // The version of .hprof being read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    private int debugLevel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    private int currPos;        // Current position in the file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    private int dumpsToSkip;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    private boolean callStack;  // If true, read the call stack of objects
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    private int identifierSize;         // Size, in bytes, of identifiers.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    private Hashtable<Long, String> names;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    // Hashtable<Integer, ThreadObject>, used to map the thread sequence number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    // (aka "serial number") to the thread object ID for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    // HPROF_GC_ROOT_THREAD_OBJ.  ThreadObject is a trivial inner class,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    // at the end of this file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    private Hashtable<Integer, ThreadObject> threadObjects;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    // Hashtable<Long, String>, maps class object ID to class name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    // (with / converted to .)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    private Hashtable<Long, String> classNameFromObjectID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    // Hashtable<Integer, Integer>, maps class serial # to class object ID
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    private Hashtable<Integer, String> classNameFromSerialNo;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    // Hashtable<Long, StackFrame> maps stack frame ID to StackFrame.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    // Null if we're not tracking them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    private Hashtable<Long, StackFrame> stackFrames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
    // Hashtable<Integer, StackTrace> maps stack frame ID to StackTrace
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    // Null if we're not tracking them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    private Hashtable<Integer, StackTrace> stackTraces;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    private Snapshot snapshot;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    public HprofReader(String fileName, PositionDataInputStream in,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
                       int dumpNumber, boolean callStack, int debugLevel)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
                       throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        super(in);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        RandomAccessFile file = new RandomAccessFile(fileName, "r");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        this.snapshot = new Snapshot(MappedReadBuffer.create(file));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        this.dumpsToSkip = dumpNumber - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        this.callStack = callStack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        this.debugLevel = debugLevel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        names = new Hashtable<Long, String>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        threadObjects = new Hashtable<Integer, ThreadObject>(43);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        classNameFromObjectID = new Hashtable<Long, String>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        if (callStack) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
            stackFrames = new Hashtable<Long, StackFrame>(43);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            stackTraces = new Hashtable<Integer, StackTrace>(43);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            classNameFromSerialNo = new Hashtable<Integer, String>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    public Snapshot read() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        currPos = 4;    // 4 because of the magic number
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        version = readVersionHeader();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        identifierSize = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        snapshot.setIdentifierSize(identifierSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        if (version >= VERSION_JDK12BETA4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            snapshot.setNewStyleArrayClass(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            snapshot.setNewStyleArrayClass(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        currPos += 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        if (identifierSize != 4 && identifierSize != 8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            throw new IOException("I'm sorry, but I can't deal with an identifier size of " + identifierSize + ".  I can only deal with 4 or 8.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        System.out.println("Dump file created " + (new Date(in.readLong())));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
        currPos += 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        for (;;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            int type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                type = in.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            } catch (EOFException ignored) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
            in.readInt();       // Timestamp of this record
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            int length = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            if (debugLevel > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                System.out.println("Read record type " + type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                                   + ", length " + length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
                                   + " at position " + toHex(currPos));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            if (length < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                throw new IOException("Bad record length of " + length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                                      + " at byte " + toHex(currPos+5)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                                      + " of file.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            currPos += 9 + length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                case HPROF_UTF8: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                    byte[] chars = new byte[length - identifierSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                    in.readFully(chars);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                    names.put(new Long(id), new String(chars));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                case HPROF_LOAD_CLASS: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                    int serialNo = in.readInt();        // Not used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                    long classID = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                    int stackTraceSerialNo = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
                    long classNameID = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                    Long classIdI = new Long(classID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                    String nm = getNameFromID(classNameID).replace('/', '.');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                    classNameFromObjectID.put(classIdI, nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                    if (classNameFromSerialNo != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                        classNameFromSerialNo.put(new Integer(serialNo), nm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                case HPROF_HEAP_DUMP: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                    if (dumpsToSkip <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                            readHeapDump(length, currPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                        } catch (EOFException exp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                            handleEOF(exp, snapshot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
                        if (debugLevel > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                            System.out.println("    Finished processing instances in heap dump.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                        return snapshot;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                        dumpsToSkip--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                        skipBytes(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
                case HPROF_HEAP_DUMP_END: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                    if (version >= VERSION_JDK6) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                        if (dumpsToSkip <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                            skipBytes(length);  // should be no-op
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                            return snapshot;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                            // skip this dump (of the end record for a sequence of dump segments)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                            dumpsToSkip--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                        // HPROF_HEAP_DUMP_END only recognized in >= 1.0.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                        warn("Ignoring unrecognized record type " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                    skipBytes(length);  // should be no-op
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                case HPROF_HEAP_DUMP_SEGMENT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                    if (version >= VERSION_JDK6) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                        if (dumpsToSkip <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                                // read the dump segment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                                readHeapDump(length, currPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                            } catch (EOFException exp) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                                handleEOF(exp, snapshot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                            // all segments comprising the heap dump will be skipped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                            skipBytes(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                        // HPROF_HEAP_DUMP_SEGMENT only recognized in >= 1.0.2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                        warn("Ignoring unrecognized record type " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                        skipBytes(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                case HPROF_FRAME: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                    if (stackFrames == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                        skipBytes(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                        long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                        String methodName = getNameFromID(readID());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                        String methodSig = getNameFromID(readID());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                        String sourceFile = getNameFromID(readID());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                        int classSer = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                        String className = classNameFromSerialNo.get(new Integer(classSer));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                        int lineNumber = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                        if (lineNumber < StackFrame.LINE_NUMBER_NATIVE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                            warn("Weird stack frame line number:  " + lineNumber);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                            lineNumber = StackFrame.LINE_NUMBER_UNKNOWN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                        stackFrames.put(new Long(id),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                                        new StackFrame(methodName, methodSig,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                                                       className, sourceFile,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                                                       lineNumber));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                case HPROF_TRACE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                    if (stackTraces == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                        skipBytes(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                        int serialNo = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                        int threadSeq = in.readInt();   // Not used
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                        StackFrame[] frames = new StackFrame[in.readInt()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                        for (int i = 0; i < frames.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                            long fid = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                            frames[i] = stackFrames.get(new Long(fid));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                            if (frames[i] == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                                throw new IOException("Stack frame " + toHex(fid) + " not found");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                        stackTraces.put(new Integer(serialNo),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                                        new StackTrace(frames));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                case HPROF_UNLOAD_CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                case HPROF_ALLOC_SITES:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                case HPROF_START_THREAD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                case HPROF_END_THREAD:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                case HPROF_HEAP_SUMMARY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                case HPROF_CPU_SAMPLES:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                case HPROF_CONTROL_SETTINGS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                case HPROF_LOCKSTATS_WAIT_TIME:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                case HPROF_LOCKSTATS_HOLD_TIME:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                    // Ignore these record types
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
                    skipBytes(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
                default: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
                    skipBytes(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
                    warn("Ignoring unrecognized record type " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        return snapshot;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    private void skipBytes(int length) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        in.skipBytes(length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    private int readVersionHeader() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        int candidatesLeft = VERSIONS.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
        boolean[] matched = new boolean[VERSIONS.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        for (int i = 0; i < candidatesLeft; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            matched[i] = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        int pos = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        while (candidatesLeft > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            char c = (char) in.readByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            currPos++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            for (int i = 0; i < VERSIONS.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                if (matched[i]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                    if (c != VERSIONS[i].charAt(pos)) {   // Not matched
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                        matched[i] = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                        --candidatesLeft;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                    } else if (pos == VERSIONS[i].length() - 1) {  // Full match
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                        return i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            ++pos;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        throw new IOException("Version string not recognized at byte " + (pos+3));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
    private void readHeapDump(int bytesLeft, int posAtEnd) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        while (bytesLeft > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            int type = in.readUnsignedByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            if (debugLevel > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                System.out.println("    Read heap sub-record type " + type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                                   + " at position "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                                   + toHex(posAtEnd - bytesLeft));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            bytesLeft--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            switch(type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
                case HPROF_GC_ROOT_UNKNOWN: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
                    bytesLeft -= identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
                    snapshot.addRoot(new Root(id, 0, Root.UNKNOWN, ""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
                case HPROF_GC_ROOT_THREAD_OBJ: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
                    int threadSeq = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
                    int stackSeq = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                    bytesLeft -= identifierSize + 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                    threadObjects.put(new Integer(threadSeq),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
                                      new ThreadObject(id, stackSeq));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                case HPROF_GC_ROOT_JNI_GLOBAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
                    long globalRefId = readID();        // Ignored, for now
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
                    bytesLeft -= 2*identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                    snapshot.addRoot(new Root(id, 0, Root.NATIVE_STATIC, ""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
                case HPROF_GC_ROOT_JNI_LOCAL: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
                    int threadSeq = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
                    int depth = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                    bytesLeft -= identifierSize + 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                    ThreadObject to = getThreadObjectFromSequence(threadSeq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                    StackTrace st = getStackTraceFromSerial(to.stackSeq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
                    if (st != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                        st = st.traceForDepth(depth+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                    snapshot.addRoot(new Root(id, to.threadId,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                                              Root.NATIVE_LOCAL, "", st));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                case HPROF_GC_ROOT_JAVA_FRAME: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                    int threadSeq = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                    int depth = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                    bytesLeft -= identifierSize + 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                    ThreadObject to = getThreadObjectFromSequence(threadSeq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                    StackTrace st = getStackTraceFromSerial(to.stackSeq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                    if (st != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                        st = st.traceForDepth(depth+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                    snapshot.addRoot(new Root(id, to.threadId,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                                              Root.JAVA_LOCAL, "", st));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                case HPROF_GC_ROOT_NATIVE_STACK: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                    int threadSeq = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                    bytesLeft -= identifierSize + 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                    ThreadObject to = getThreadObjectFromSequence(threadSeq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                    StackTrace st = getStackTraceFromSerial(to.stackSeq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                    snapshot.addRoot(new Root(id, to.threadId,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                                              Root.NATIVE_STACK, "", st));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                case HPROF_GC_ROOT_STICKY_CLASS: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                    bytesLeft -= identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                    snapshot.addRoot(new Root(id, 0, Root.SYSTEM_CLASS, ""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
                case HPROF_GC_ROOT_THREAD_BLOCK: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                    int threadSeq = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                    bytesLeft -= identifierSize + 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                    ThreadObject to = getThreadObjectFromSequence(threadSeq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                    StackTrace st = getStackTraceFromSerial(to.stackSeq);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                    snapshot.addRoot(new Root(id, to.threadId,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                                     Root.THREAD_BLOCK, "", st));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                case HPROF_GC_ROOT_MONITOR_USED: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                    long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                    bytesLeft -= identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                    snapshot.addRoot(new Root(id, 0, Root.BUSY_MONITOR, ""));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
                case HPROF_GC_CLASS_DUMP: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
                    int bytesRead = readClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                    bytesLeft -= bytesRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                case HPROF_GC_INSTANCE_DUMP: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                    int bytesRead = readInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
                    bytesLeft -= bytesRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                case HPROF_GC_OBJ_ARRAY_DUMP: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                    int bytesRead = readArray(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                    bytesLeft -= bytesRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                case HPROF_GC_PRIM_ARRAY_DUMP: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                    int bytesRead = readArray(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
                    bytesLeft -= bytesRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                default: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                    throw new IOException("Unrecognized heap dump sub-record type:  " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
        if (bytesLeft != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            warn("Error reading heap dump or heap dump segment:  Byte count is " + bytesLeft + " instead of 0");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            skipBytes(bytesLeft);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
        if (debugLevel > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
            System.out.println("    Finished heap sub-records.");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
    private long readID() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
        return (identifierSize == 4)?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            (Snapshot.SMALL_ID_MASK & (long)in.readInt()) : in.readLong();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    // Read a java value.  If result is non-null, it's expected to be an
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
    // array of one element.  We use it to fake multiple return values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
    // @returns the number of bytes read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
    private int readValue(JavaThing[] resultArr) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
        byte type = in.readByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
        return 1 + readValueForType(type, resultArr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
    private int readValueForType(byte type, JavaThing[] resultArr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
        if (version >= VERSION_JDK12BETA4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            type = signatureFromTypeId(type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
        return readValueForTypeSignature(type, resultArr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    private int readValueForTypeSignature(byte type, JavaThing[] resultArr)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
            case '[':
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
            case 'L': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                    resultArr[0] = new JavaObjectRef(id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                return identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            case 'Z': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                int b = in.readByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                if (b != 0 && b != 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                    warn("Illegal boolean value read");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                    resultArr[0] = new JavaBoolean(b != 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
            case 'B': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                byte b = in.readByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                    resultArr[0] = new JavaByte(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
            case 'S': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                short s = in.readShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                    resultArr[0] = new JavaShort(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                return 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
            case 'C': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                char ch = in.readChar();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                    resultArr[0] = new JavaChar(ch);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                return 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            case 'I': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                int val = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                    resultArr[0] = new JavaInt(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                return 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
            case 'J': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                long val = in.readLong();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
                    resultArr[0] = new JavaLong(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                return 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            case 'F': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                float val = in.readFloat();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
                    resultArr[0] = new JavaFloat(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
                return 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            case 'D': {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                double val = in.readDouble();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                if (resultArr != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                    resultArr[0] = new JavaDouble(val);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
                return 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            default: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                throw new IOException("Bad value signature:  " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    private ThreadObject getThreadObjectFromSequence(int threadSeq)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        ThreadObject to = threadObjects.get(new Integer(threadSeq));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        if (to == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
            throw new IOException("Thread " + threadSeq +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                                  " not found for JNI local ref");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        return to;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    private String getNameFromID(long id) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        return getNameFromID(new Long(id));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
    private String getNameFromID(Long id) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        if (id.longValue() == 0L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
            return "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        String result = names.get(id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            warn("Name not found at " + toHex(id.longValue()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            return "unresolved name " + toHex(id.longValue());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
    private StackTrace getStackTraceFromSerial(int ser) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
        if (stackTraces == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        StackTrace result = stackTraces.get(new Integer(ser));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
        if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
            warn("Stack trace not found for serial # " + ser);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    // Handle a HPROF_GC_CLASS_DUMP
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
    // Return number of bytes read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
    private int readClass() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
        long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        StackTrace stackTrace = getStackTraceFromSerial(in.readInt());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
        long superId = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        long classLoaderId = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
        long signersId = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        long protDomainId = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        long reserved1 = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        long reserved2 = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
        int instanceSize = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        int bytesRead = 7 * identifierSize + 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        int numConstPoolEntries = in.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        bytesRead += 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        for (int i = 0; i < numConstPoolEntries; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            int index = in.readUnsignedShort(); // unused
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            bytesRead += 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            bytesRead += readValue(null);       // We ignore the values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        int numStatics = in.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
        bytesRead += 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
        JavaThing[] valueBin = new JavaThing[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        JavaStatic[] statics = new JavaStatic[numStatics];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
        for (int i = 0; i < numStatics; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            long nameId = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
            bytesRead += identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            byte type = in.readByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
            bytesRead++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            bytesRead += readValueForType(type, valueBin);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
            String fieldName = getNameFromID(nameId);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
            if (version >= VERSION_JDK12BETA4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                type = signatureFromTypeId(type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
            String signature = "" + ((char) type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
            JavaField f = new JavaField(fieldName, signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            statics[i] = new JavaStatic(f, valueBin[0]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
        int numFields = in.readUnsignedShort();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        bytesRead += 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
        JavaField[] fields = new JavaField[numFields];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        for (int i = 0; i < numFields; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            long nameId = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            bytesRead += identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            byte type = in.readByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            bytesRead++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
            String fieldName = getNameFromID(nameId);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
            if (version >= VERSION_JDK12BETA4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                type = signatureFromTypeId(type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
            String signature = "" + ((char) type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
            fields[i] = new JavaField(fieldName, signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
        String name = classNameFromObjectID.get(new Long(id));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
        if (name == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            warn("Class name not found for " + toHex(id));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            name = "unknown-name@" + toHex(id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
        JavaClass c = new JavaClass(id, name, superId, classLoaderId, signersId,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                                    protDomainId, fields, statics,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                                    instanceSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        snapshot.addClass(id, c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
        snapshot.setSiteTrace(c, stackTrace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
        return bytesRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    private String toHex(long addr) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
        return com.sun.tools.hat.internal.util.Misc.toHex(addr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
    // Handle a HPROF_GC_INSTANCE_DUMP
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
    // Return number of bytes read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
    private int readInstance() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        long start = in.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
        long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
        StackTrace stackTrace = getStackTraceFromSerial(in.readInt());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
        long classID = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
        int bytesFollowing = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        int bytesRead = (2 * identifierSize) + 8 + bytesFollowing;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        JavaObject jobj = new JavaObject(classID, start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        skipBytes(bytesFollowing);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        snapshot.addHeapObject(id, jobj);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
        snapshot.setSiteTrace(jobj, stackTrace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        return bytesRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
    // Handle a HPROF_GC_OBJ_ARRAY_DUMP or HPROF_GC_PRIM_ARRAY_DUMP
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
    // Return number of bytes read
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
    private int readArray(boolean isPrimitive) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        long start = in.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
        long id = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        StackTrace stackTrace = getStackTraceFromSerial(in.readInt());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        int num = in.readInt();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        int bytesRead = identifierSize + 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        long elementClassID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        if (isPrimitive) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
            elementClassID = in.readByte();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
            bytesRead++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
            elementClassID = readID();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
            bytesRead += identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
        // Check for primitive arrays:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        byte primitiveSignature = 0x00;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
        int elSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        if (isPrimitive || version < VERSION_JDK12BETA4) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            switch ((int)elementClassID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                case T_BOOLEAN: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                    primitiveSignature = (byte) 'Z';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
                    elSize = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                case T_CHAR: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                    primitiveSignature = (byte) 'C';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                    elSize = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                case T_FLOAT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                    primitiveSignature = (byte) 'F';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                    elSize = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
                case T_DOUBLE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
                    primitiveSignature = (byte) 'D';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
                    elSize = 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
                case T_BYTE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
                    primitiveSignature = (byte) 'B';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
                    elSize = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                case T_SHORT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
                    primitiveSignature = (byte) 'S';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
                    elSize = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
                case T_INT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                    primitiveSignature = (byte) 'I';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
                    elSize = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                case T_LONG: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                    primitiveSignature = (byte) 'J';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                    elSize = 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
            if (version >= VERSION_JDK12BETA4 && primitiveSignature == 0x00) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                throw new IOException("Unrecognized typecode:  "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                                        + elementClassID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        if (primitiveSignature != 0x00) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            int size = elSize * num;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            bytesRead += size;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
            JavaValueArray va = new JavaValueArray(primitiveSignature, start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            skipBytes(size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            snapshot.addHeapObject(id, va);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
            snapshot.setSiteTrace(va, stackTrace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
            int sz = num * identifierSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
            bytesRead += sz;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
            JavaObjectArray arr = new JavaObjectArray(elementClassID, start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
            skipBytes(sz);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            snapshot.addHeapObject(id, arr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
            snapshot.setSiteTrace(arr, stackTrace);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        return bytesRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    private byte signatureFromTypeId(byte typeId) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
        switch (typeId) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
            case T_CLASS: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
                return (byte) 'L';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
            case T_BOOLEAN: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
                return (byte) 'Z';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
            case T_CHAR: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                return (byte) 'C';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
            case T_FLOAT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                return (byte) 'F';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
            case T_DOUBLE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                return (byte) 'D';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
            case T_BYTE: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                return (byte) 'B';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
            case T_SHORT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                return (byte) 'S';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            case T_INT: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
                return (byte) 'I';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
            case T_LONG: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                return (byte) 'J';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
            default: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                throw new IOException("Invalid type id of " + typeId);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
    private void handleEOF(EOFException exp, Snapshot snapshot) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        if (debugLevel > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
            exp.printStackTrace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
        warn("Unexpected EOF. Will miss information...");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
        // we have EOF, we have to tolerate missing references
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
        snapshot.setUnresolvedObjectsOK(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
    private void warn(String msg) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
        System.out.println("WARNING: " + msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
    // A trivial data-holder class for HPROF_GC_ROOT_THREAD_OBJ.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
    //
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
    private class ThreadObject {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
        long threadId;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        int stackSeq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
        ThreadObject(long threadId, int stackSeq) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
            this.threadId = threadId;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
            this.stackSeq = stackSeq;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
}