/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* The Original Code is HAT. The Initial Developer of the
* Original Code is Bill Foote, with contributions from others
*/
/**
* Object that's used to read a hprof file.
*
* @author Bill Foote
*/
// That's "JAVA", the first part of "JAVA PROFILE ..."
" PROFILE 1.0\0",
" PROFILE 1.0.1\0",
" PROFILE 1.0.2\0",
};
// These version numbers are indices into VERSIONS. The instance data
// member version is set to one of these, and it drives decisions when
// reading the file.
//
// Version 1.0.1 added HPROF_GC_PRIM_ARRAY_DUMP, which requires no
// version-sensitive parsing.
//
// Version 1.0.1 changed the type of a constant pool entry from a signature
// to a typecode.
//
// Version 1.0.2 added HPROF_HEAP_DUMP_SEGMENT and HPROF_HEAP_DUMP_END
// to allow a large heap to be dumped as a sequence of heap dump segments.
//
// The HPROF agent in J2SE 1.2 through to 5.0 generate a version 1.0.1
// file. In Java SE 6.0 the version is either 1.0.1 or 1.0.2 depending on
// the size of the heap (normally it will be 1.0.1 but for multi-GB
// heaps the heap dump will not fit in a HPROF_HEAP_DUMP record so the
// dump is generated as version 1.0.2).
//
// Record types:
//
private int debugLevel;
private int dumpsToSkip;
// Hashtable<Integer, ThreadObject>, used to map the thread sequence number
// (aka "serial number") to the thread object ID for
// HPROF_GC_ROOT_THREAD_OBJ. ThreadObject is a trivial inner class,
// at the end of this file.
// Hashtable<Long, String>, maps class object ID to class name
// (with / converted to .)
// Hashtable<Integer, Integer>, maps class serial # to class object ID
// Hashtable<Long, StackFrame> maps stack frame ID to StackFrame.
// Null if we're not tracking them.
// Hashtable<Integer, StackTrace> maps stack frame ID to StackTrace
// Null if we're not tracking them.
throws IOException {
super(in);
this.debugLevel = debugLevel;
if (callStack) {
}
}
version = readVersionHeader();
if (version >= VERSION_JDK12BETA4) {
snapshot.setNewStyleArrayClass(true);
} else {
snapshot.setNewStyleArrayClass(false);
}
currPos += 4;
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.");
}
currPos += 8;
for (;;) {
int type;
try {
} catch (EOFException ignored) {
break;
}
// Length of record: readInt() will return negative value for record
// length >2GB. so store 32bit value in long to keep it unsigned.
if (debugLevel > 0) {
+ ", length " + length
}
if (length < 0) {
+ " of file.");
}
switch (type) {
case HPROF_UTF8: {
break;
}
case HPROF_LOAD_CLASS: {
long classNameID = readID();
if (classNameFromSerialNo != null) {
}
break;
}
case HPROF_HEAP_DUMP: {
if (dumpsToSkip <= 0) {
try {
} catch (EOFException exp) {
}
if (debugLevel > 0) {
}
return snapshot;
} else {
dumpsToSkip--;
}
break;
}
case HPROF_HEAP_DUMP_END: {
if (version >= VERSION_JDK6) {
if (dumpsToSkip <= 0) {
return snapshot;
} else {
// skip this dump (of the end record for a sequence of dump segments)
dumpsToSkip--;
}
} else {
// HPROF_HEAP_DUMP_END only recognized in >= 1.0.2
}
break;
}
case HPROF_HEAP_DUMP_SEGMENT: {
if (version >= VERSION_JDK6) {
if (dumpsToSkip <= 0) {
try {
// read the dump segment
} catch (EOFException exp) {
}
} else {
// all segments comprising the heap dump will be skipped
}
} else {
// HPROF_HEAP_DUMP_SEGMENT only recognized in >= 1.0.2
}
break;
}
case HPROF_FRAME: {
if (stackFrames == null) {
} else {
}
lineNumber));
}
break;
}
case HPROF_TRACE: {
if (stackTraces == null) {
} else {
}
}
new StackTrace(frames));
}
break;
}
case HPROF_UNLOAD_CLASS:
case HPROF_ALLOC_SITES:
case HPROF_START_THREAD:
case HPROF_END_THREAD:
case HPROF_HEAP_SUMMARY:
case HPROF_CPU_SAMPLES:
case HPROF_CONTROL_SETTINGS:
{
// Ignore these record types
break;
}
default: {
}
}
}
return snapshot;
}
}
for (int i = 0; i < candidatesLeft; i++) {
matched[i] = true;
}
int pos = 0;
while (candidatesLeft > 0) {
currPos++;
if (matched[i]) {
matched[i] = false;
return i;
}
}
}
++pos;
}
}
while (bytesLeft > 0) {
if (debugLevel > 0) {
+ " at position "
}
bytesLeft--;
switch(type) {
case HPROF_GC_ROOT_UNKNOWN: {
break;
}
case HPROF_GC_ROOT_THREAD_OBJ: {
break;
}
case HPROF_GC_ROOT_JNI_GLOBAL: {
break;
}
case HPROF_GC_ROOT_JNI_LOCAL: {
}
break;
}
case HPROF_GC_ROOT_JAVA_FRAME: {
}
break;
}
case HPROF_GC_ROOT_NATIVE_STACK: {
break;
}
case HPROF_GC_ROOT_STICKY_CLASS: {
break;
}
case HPROF_GC_ROOT_THREAD_BLOCK: {
break;
}
case HPROF_GC_ROOT_MONITOR_USED: {
break;
}
case HPROF_GC_CLASS_DUMP: {
break;
}
case HPROF_GC_INSTANCE_DUMP: {
int bytesRead = readInstance();
break;
}
case HPROF_GC_OBJ_ARRAY_DUMP: {
break;
}
case HPROF_GC_PRIM_ARRAY_DUMP: {
break;
}
default: {
}
}
}
if (bytesLeft != 0) {
}
if (debugLevel > 0) {
}
}
return (identifierSize == 4)?
}
//
// Read a java value. If result is non-null, it's expected to be an
// array of one element. We use it to fake multiple return values.
// @returns the number of bytes read
//
}
throws IOException {
if (version >= VERSION_JDK12BETA4) {
}
}
throws IOException {
switch (type) {
case '[':
case 'L': {
}
return identifierSize;
}
case 'Z': {
if (b != 0 && b != 1) {
warn("Illegal boolean value read");
}
}
return 1;
}
case 'B': {
}
return 1;
}
case 'S': {
}
return 2;
}
case 'C': {
}
return 2;
}
case 'I': {
}
return 4;
}
case 'J': {
}
return 8;
}
case 'F': {
}
return 4;
}
case 'D': {
}
return 8;
}
default: {
}
}
}
throws IOException {
" not found for JNI local ref");
}
return to;
}
}
return "";
}
}
return result;
}
if (stackTraces == null) {
return null;
}
}
return result;
}
//
// Handle a HPROF_GC_CLASS_DUMP
// Return number of bytes read
//
long classLoaderId = readID();
long protDomainId = readID();
bytesRead += 2;
for (int i = 0; i < numConstPoolEntries; i++) {
bytesRead += 2;
}
bytesRead += 2;
for (int i = 0; i < numStatics; i++) {
bytesRead++;
if (version >= VERSION_JDK12BETA4) {
}
}
bytesRead += 2;
for (int i = 0; i < numFields; i++) {
bytesRead++;
if (version >= VERSION_JDK12BETA4) {
}
}
}
return bytesRead;
}
}
//
// Handle a HPROF_GC_INSTANCE_DUMP
// Return number of bytes read
//
return bytesRead;
}
//
// Handle a HPROF_GC_OBJ_ARRAY_DUMP or HPROF_GC_PRIM_ARRAY_DUMP
// Return number of bytes read
//
long elementClassID;
if (isPrimitive) {
bytesRead++;
} else {
elementClassID = readID();
}
// Check for primitive arrays:
byte primitiveSignature = 0x00;
int elSize = 0;
switch ((int)elementClassID) {
case T_BOOLEAN: {
primitiveSignature = (byte) 'Z';
elSize = 1;
break;
}
case T_CHAR: {
primitiveSignature = (byte) 'C';
elSize = 2;
break;
}
case T_FLOAT: {
primitiveSignature = (byte) 'F';
elSize = 4;
break;
}
case T_DOUBLE: {
primitiveSignature = (byte) 'D';
elSize = 8;
break;
}
case T_BYTE: {
primitiveSignature = (byte) 'B';
elSize = 1;
break;
}
case T_SHORT: {
primitiveSignature = (byte) 'S';
elSize = 2;
break;
}
case T_INT: {
primitiveSignature = (byte) 'I';
elSize = 4;
break;
}
case T_LONG: {
primitiveSignature = (byte) 'J';
elSize = 8;
break;
}
}
throw new IOException("Unrecognized typecode: "
+ elementClassID);
}
}
if (primitiveSignature != 0x00) {
} else {
}
return bytesRead;
}
switch (typeId) {
case T_CLASS: {
return (byte) 'L';
}
case T_BOOLEAN: {
return (byte) 'Z';
}
case T_CHAR: {
return (byte) 'C';
}
case T_FLOAT: {
return (byte) 'F';
}
case T_DOUBLE: {
return (byte) 'D';
}
case T_BYTE: {
return (byte) 'B';
}
case T_SHORT: {
return (byte) 'S';
}
case T_INT: {
return (byte) 'I';
}
case T_LONG: {
return (byte) 'J';
}
default: {
}
}
}
if (debugLevel > 0) {
}
warn("Unexpected EOF. Will miss information...");
// we have EOF, we have to tolerate missing references
snapshot.setUnresolvedObjectsOK(true);
}
}
//
// A trivial data-holder class for HPROF_GC_ROOT_THREAD_OBJ.
//
private class ThreadObject {
long threadId;
int stackSeq;
}
}
}