This commit is contained in:
Alejandro Murillo 2015-05-14 12:05:33 -07:00
commit 937fb712ee
91 changed files with 138 additions and 12610 deletions

View File

@ -33,9 +33,6 @@ $(eval $(call SetupLauncher,jdeps, \
$(eval $(call SetupLauncher,jimage,\
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "jdk.tools.jimage.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,jhat, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "com.sun.tools.hat.Main"$(COMMA) }'))
$(eval $(call SetupLauncher,native2ascii, \
-DJAVA_ARGS='{ "-J-ms8m"$(COMMA) "sun.tools.native2ascii.Main"$(COMMA) }'))

View File

@ -27,6 +27,12 @@ include LibCommon.gmk
################################################################################
ifeq ($(OPENJDK_TARGET_OS), windows)
# In (at least) VS2013 and later, -DPSAPI_VERSION=1 is needed to generate
# a binary that is compatible with windows versions older than 7/2008R2.
# See MSDN documentation for GetProcessMemoryInfo for more information.
LIBATTACH_CFLAGS := -DPSAPI_VERSION=1
endif
$(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
LIBRARY := attach, \
@ -35,7 +41,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBATTACH, \
OPTIMIZATION := LOW, \
CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) \
-I$(SUPPORT_OUTPUTDIR)/headers/jdk.attach \
$(LIBJAVA_HEADER_FLAGS), \
$(LIBJAVA_HEADER_FLAGS) $(LIBATTACH_CFLAGS), \
CFLAGS_windows := /Gy, \
MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libattach/mapfile-$(OPENJDK_TARGET_OS), \
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \

View File

@ -39,10 +39,12 @@ LIBMANAGEMENT_EXT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/inc
$(LIBJAVA_HEADER_FLAGS) \
#
# In (at least) VS2013 and later, -DPSAPI_VERSION=1 is needed to generate
# a binary that is compatible with windows versions older than 7/2008R2.
# See MSDN documentation for GetProcessMemoryInfo for more information.
BUILD_LIBMANAGEMENT_EXT_CFLAGS += -DPSAPI_VERSION=1
ifeq ($(OPENJDK_TARGET_OS), windows)
# In (at least) VS2013 and later, -DPSAPI_VERSION=1 is needed to generate
# a binary that is compatible with windows versions older than 7/2008R2.
# See MSDN documentation for GetProcessMemoryInfo for more information.
LIBMANAGEMENT_EXT_CFLAGS += -DPSAPI_VERSION=1
endif
LIBMANAGEMENT_EXT_OPTIMIZATION := HIGH
ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), )

View File

@ -24,6 +24,7 @@ jdk.httpserver
jdk.jfr
jdk.management
jdk.management.cmm
jdk.management.resource
jdk.naming.rmi
jdk.sctp
jdk.security.auth

View File

@ -241,7 +241,7 @@ public abstract class AttachProvider {
* (using the zero-arg constructor) at the first invocation of this method.
* The list returned by the first invocation of this method is the list
* of providers. Subsequent invocations of this method return a list of the same
* providers. The list is unmodifable.
* providers. The list is unmodifiable.
*
* @return A list of the installed attach providers.
*/
@ -264,8 +264,8 @@ public abstract class AttachProvider {
ThreadDeath td = (ThreadDeath)t;
throw td;
}
// Ignore errors and exceptions
System.err.println(t);
// Log errors and exceptions since we cannot return them
t.printStackTrace();
}
}
}

View File

@ -1,212 +0,0 @@
/*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat;
import java.io.IOException;
import java.io.File;
import com.sun.tools.hat.internal.model.Snapshot;
import com.sun.tools.hat.internal.model.ReachableExcludesImpl;
import com.sun.tools.hat.internal.server.QueryListener;
/**
*
* @author Bill Foote
*/
public class Main {
private static String VERSION_STRING = "jhat version 2.0";
private static void usage(String message) {
if ( message != null ) {
System.err.println("ERROR: " + message);
}
System.err.println("Usage: jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>");
System.err.println();
System.err.println("\t-J<flag> Pass <flag> directly to the runtime system. For");
System.err.println("\t\t\t example, -J-mx512m to use a maximum heap size of 512MB");
System.err.println("\t-stack false: Turn off tracking object allocation call stack.");
System.err.println("\t-refs false: Turn off tracking of references to objects");
System.err.println("\t-port <port>: Set the port for the HTTP server. Defaults to 7000");
System.err.println("\t-exclude <file>: Specify a file that lists data members that should");
System.err.println("\t\t\t be excluded from the reachableFrom query.");
System.err.println("\t-baseline <file>: Specify a baseline object dump. Objects in");
System.err.println("\t\t\t both heap dumps with the same ID and same class will");
System.err.println("\t\t\t be marked as not being \"new\".");
System.err.println("\t-debug <int>: Set debug level.");
System.err.println("\t\t\t 0: No debug output");
System.err.println("\t\t\t 1: Debug hprof file parsing");
System.err.println("\t\t\t 2: Debug hprof file parsing, no server");
System.err.println("\t-version Report version number");
System.err.println("\t-h|-help Print this help and exit");
System.err.println("\t<file> The file to read");
System.err.println();
System.err.println("For a dump file that contains multiple heap dumps,");
System.err.println("you may specify which dump in the file");
System.err.println("by appending \"#<number>\" to the file name, i.e. \"foo.hprof#3\".");
System.err.println();
System.err.println("All boolean options default to \"true\"");
System.exit(1);
}
//
// Convert s to a boolean. If it's invalid, abort the program.
//
private static boolean booleanValue(String s) {
if ("true".equalsIgnoreCase(s)) {
return true;
} else if ("false".equalsIgnoreCase(s)) {
return false;
} else {
usage("Boolean value must be true or false");
return false; // Never happens
}
}
public static void main(String[] args) {
if (args.length < 1) {
usage("No arguments supplied");
}
boolean parseonly = false;
int portNumber = 7000;
boolean callStack = true;
boolean calculateRefs = true;
String baselineDump = null;
String excludeFileName = null;
int debugLevel = 0;
for (int i = 0; ; i += 2) {
if (i > (args.length - 1)) {
usage("Option parsing error");
}
if ("-version".equals(args[i])) {
System.out.print(VERSION_STRING);
System.out.println(" (java version " + System.getProperty("java.version") + ")");
System.exit(0);
}
if ("-h".equals(args[i]) || "-help".equals(args[i])) {
usage(null);
}
if (i == (args.length - 1)) {
break;
}
String key = args[i];
String value = args[i+1];
if ("-stack".equals(key)) {
callStack = booleanValue(value);
} else if ("-refs".equals(key)) {
calculateRefs = booleanValue(value);
} else if ("-port".equals(key)) {
portNumber = Integer.parseInt(value, 10);
} else if ("-exclude".equals(key)) {
excludeFileName = value;
} else if ("-baseline".equals(key)) {
baselineDump = value;
} else if ("-debug".equals(key)) {
debugLevel = Integer.parseInt(value, 10);
} else if ("-parseonly".equals(key)) {
// Undocumented option. To be used for testing purpose only
parseonly = booleanValue(value);
}
}
String fileName = args[args.length - 1];
Snapshot model = null;
File excludeFile = null;
if (excludeFileName != null) {
excludeFile = new File(excludeFileName);
if (!excludeFile.exists()) {
System.out.println("Exclude file " + excludeFile
+ " does not exist. Aborting.");
System.exit(1);
}
}
System.out.println("Reading from " + fileName + "...");
try {
model = com.sun.tools.hat.internal.parser.Reader.readFile(fileName, callStack, debugLevel);
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
} catch (RuntimeException ex) {
ex.printStackTrace();
System.exit(1);
}
System.out.println("Snapshot read, resolving...");
model.resolve(calculateRefs);
System.out.println("Snapshot resolved.");
if (excludeFile != null) {
model.setReachableExcludes(new ReachableExcludesImpl(excludeFile));
}
if (baselineDump != null) {
System.out.println("Reading baseline snapshot...");
Snapshot baseline = null;
try {
baseline = com.sun.tools.hat.internal.parser.Reader.readFile(baselineDump, false,
debugLevel);
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
} catch (RuntimeException ex) {
ex.printStackTrace();
System.exit(1);
}
baseline.resolve(false);
System.out.println("Discovering new objects...");
model.markNewRelativeTo(baseline);
baseline = null; // Guard against conservative GC
}
if ( debugLevel == 2 ) {
System.out.println("No server, -debug 2 was used.");
System.exit(0);
}
if (parseonly) {
// do not start web server.
System.out.println("-parseonly is true, exiting..");
System.exit(0);
}
QueryListener listener = new QueryListener(portNumber);
listener.setModel(model);
Thread t = new Thread(listener, "Query Listener");
t.setPriority(Thread.NORM_PRIORITY+1);
t.start();
System.out.println("Started HTTP server on port " + portNumber);
System.out.println("Server is ready.");
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* A visitor for a JavaThing. @see JavaObject#visitReferencedObjects()
*
*/
abstract public class AbstractJavaHeapObjectVisitor
implements JavaHeapObjectVisitor {
abstract public void visit(JavaHeapObject other);
/**
* Should the given field be excluded from the set of things visited?
* @return true if it should.
*/
public boolean exclude(JavaClass clazz, JavaField f) {
return false;
}
/**
* @return true iff exclude might ever return true
*/
public boolean mightExclude() {
return false;
}
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Primitive array type codes as defined by VM specification.
*
*/
public interface ArrayTypeCodes {
// Typecodes for array elements.
// Refer to newarray instruction in VM Spec.
public static final int T_BOOLEAN = 4;
public static final int T_CHAR = 5;
public static final int T_FLOAT = 6;
public static final int T_DOUBLE = 7;
public static final int T_BYTE = 8;
public static final int T_SHORT = 9;
public static final int T_INT = 10;
public static final int T_LONG = 11;
}

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* This is used to represent values that the program doesn't really understand.
* This includes the null vlaue, and unresolved references (which shouldn't
* happen in well-formed hprof files).
*
*
* @author Bill Foote
*/
public class HackJavaValue extends JavaValue {
private String value;
private int size;
public HackJavaValue(String value, int size) {
this.value = value;
this.size = size;
}
public String toString() {
return value;
}
public int getSize() {
return size;
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents a boolean (i.e. a boolean field in an instance).
*
* @author Bill Foote
*/
public class JavaBoolean extends JavaValue {
boolean value;
public JavaBoolean(boolean value) {
this.value = value;
}
public String toString() {
return "" + value;
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents an byte (i.e. a byte field in an instance).
*
* @author Bill Foote
*/
public class JavaByte extends JavaValue {
byte value;
public JavaByte(byte value) {
this.value = value;
}
public String toString() {
return "0x" + Integer.toString(((int) value) & 0xff, 16);
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents a char (i.e. a char field in an instance).
*
* @author Bill Foote
*/
public class JavaChar extends JavaValue {
char value;
public JavaChar(char value) {
this.value = value;
}
public String toString() {
return "" + value;
}
}

View File

@ -1,503 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.util.Vector;
import java.util.Enumeration;
import com.sun.tools.hat.internal.util.CompositeEnumeration;
import com.sun.tools.hat.internal.parser.ReadBuffer;
/**
*
* @author Bill Foote
*/
public class JavaClass extends JavaHeapObject {
// my id
private long id;
// my name
private String name;
// These are JavaObjectRef before resolve
private JavaThing superclass;
private JavaThing loader;
private JavaThing signers;
private JavaThing protectionDomain;
// non-static fields
private JavaField[] fields;
// static fields
private JavaStatic[] statics;
private static final JavaClass[] EMPTY_CLASS_ARRAY = new JavaClass[0];
// my subclasses
private JavaClass[] subclasses = EMPTY_CLASS_ARRAY;
// my instances
private Vector<JavaHeapObject> instances = new Vector<JavaHeapObject>();
// Who I belong to. Set on resolve.
private Snapshot mySnapshot;
// Size of an instance, including VM overhead
private int instanceSize;
// Total number of fields including inherited ones
private int totalNumFields;
public JavaClass(long id, String name, long superclassId, long loaderId,
long signersId, long protDomainId,
JavaField[] fields, JavaStatic[] statics,
int instanceSize) {
this.id = id;
this.name = name;
this.superclass = new JavaObjectRef(superclassId);
this.loader = new JavaObjectRef(loaderId);
this.signers = new JavaObjectRef(signersId);
this.protectionDomain = new JavaObjectRef(protDomainId);
this.fields = fields;
this.statics = statics;
this.instanceSize = instanceSize;
}
public JavaClass(String name, long superclassId, long loaderId,
long signersId, long protDomainId,
JavaField[] fields, JavaStatic[] statics,
int instanceSize) {
this(-1L, name, superclassId, loaderId, signersId,
protDomainId, fields, statics, instanceSize);
}
public final JavaClass getClazz() {
return mySnapshot.getJavaLangClass();
}
public final int getIdentifierSize() {
return mySnapshot.getIdentifierSize();
}
public final int getMinimumObjectSize() {
return mySnapshot.getMinimumObjectSize();
}
public void resolve(Snapshot snapshot) {
if (mySnapshot != null) {
return;
}
mySnapshot = snapshot;
resolveSuperclass(snapshot);
if (superclass != null) {
((JavaClass) superclass).addSubclass(this);
}
loader = loader.dereference(snapshot, null);
signers = signers.dereference(snapshot, null);
protectionDomain = protectionDomain.dereference(snapshot, null);
for (int i = 0; i < statics.length; i++) {
statics[i].resolve(this, snapshot);
}
snapshot.getJavaLangClass().addInstance(this);
super.resolve(snapshot);
return;
}
/**
* Resolve our superclass. This might be called well before
* all instances are available (like when reading deferred
* instances in a 1.2 dump file :-) Calling this is sufficient
* to be able to explore this class' fields.
*/
public void resolveSuperclass(Snapshot snapshot) {
if (superclass == null) {
// We must be java.lang.Object, so we have no superclass.
} else {
totalNumFields = fields.length;
superclass = superclass.dereference(snapshot, null);
if (superclass == snapshot.getNullThing()) {
superclass = null;
} else {
try {
JavaClass sc = (JavaClass) superclass;
sc.resolveSuperclass(snapshot);
totalNumFields += sc.totalNumFields;
} catch (ClassCastException ex) {
System.out.println("Warning! Superclass of " + name + " is " + superclass);
superclass = null;
}
}
}
}
public boolean isString() {
return mySnapshot.getJavaLangString() == this;
}
public boolean isClassLoader() {
return mySnapshot.getJavaLangClassLoader().isAssignableFrom(this);
}
/**
* Get a numbered field from this class
*/
public JavaField getField(int i) {
if (i < 0 || i >= fields.length) {
throw new Error("No field " + i + " for " + name);
}
return fields[i];
}
/**
* Get the total number of fields that are part of an instance of
* this class. That is, include superclasses.
*/
public int getNumFieldsForInstance() {
return totalNumFields;
}
/**
* Get a numbered field from all the fields that are part of instance
* of this class. That is, include superclasses.
*/
public JavaField getFieldForInstance(int i) {
if (superclass != null) {
JavaClass sc = (JavaClass) superclass;
if (i < sc.totalNumFields) {
return sc.getFieldForInstance(i);
}
i -= sc.totalNumFields;
}
return getField(i);
}
/**
* Get the class responsible for field i, where i is a field number that
* could be passed into getFieldForInstance.
*
* @see JavaClass.getFieldForInstance()
*/
public JavaClass getClassForField(int i) {
if (superclass != null) {
JavaClass sc = (JavaClass) superclass;
if (i < sc.totalNumFields) {
return sc.getClassForField(i);
}
}
return this;
}
public long getId() {
return id;
}
public String getName() {
return name;
}
public boolean isArray() {
return name.indexOf('[') != -1;
}
public Enumeration<JavaHeapObject> getInstances(boolean includeSubclasses) {
if (includeSubclasses) {
Enumeration<JavaHeapObject> res = instances.elements();
for (int i = 0; i < subclasses.length; i++) {
res = new CompositeEnumeration(res,
subclasses[i].getInstances(true));
}
return res;
} else {
return instances.elements();
}
}
/**
* @return a count of the instances of this class
*/
public int getInstancesCount(boolean includeSubclasses) {
int result = instances.size();
if (includeSubclasses) {
for (int i = 0; i < subclasses.length; i++) {
result += subclasses[i].getInstancesCount(includeSubclasses);
}
}
return result;
}
public JavaClass[] getSubclasses() {
return subclasses;
}
/**
* This can only safely be called after resolve()
*/
public JavaClass getSuperclass() {
return (JavaClass) superclass;
}
/**
* This can only safely be called after resolve()
*/
public JavaThing getLoader() {
return loader;
}
/**
* This can only safely be called after resolve()
*/
public boolean isBootstrap() {
return loader == mySnapshot.getNullThing();
}
/**
* This can only safely be called after resolve()
*/
public JavaThing getSigners() {
return signers;
}
/**
* This can only safely be called after resolve()
*/
public JavaThing getProtectionDomain() {
return protectionDomain;
}
public JavaField[] getFields() {
return fields;
}
/**
* Includes superclass fields
*/
public JavaField[] getFieldsForInstance() {
Vector<JavaField> v = new Vector<JavaField>();
addFields(v);
JavaField[] result = new JavaField[v.size()];
for (int i = 0; i < v.size(); i++) {
result[i] = v.elementAt(i);
}
return result;
}
public JavaStatic[] getStatics() {
return statics;
}
// returns value of static field of given name
public JavaThing getStaticField(String name) {
for (int i = 0; i < statics.length; i++) {
JavaStatic s = statics[i];
if (s.getField().getName().equals(name)) {
return s.getValue();
}
}
return null;
}
public String toString() {
return "class " + name;
}
public int compareTo(JavaThing other) {
if (other instanceof JavaClass) {
return name.compareTo(((JavaClass) other).name);
}
return super.compareTo(other);
}
/**
* @return true iff a variable of type this is assignable from an instance
* of other
*/
public boolean isAssignableFrom(JavaClass other) {
if (this == other) {
return true;
} else if (other == null) {
return false;
} else {
return isAssignableFrom((JavaClass) other.superclass);
// Trivial tail recursion: I have faith in javac.
}
}
/**
* Describe the reference that this thing has to target. This will only
* be called if target is in the array returned by getChildrenForRootset.
*/
public String describeReferenceTo(JavaThing target, Snapshot ss) {
for (int i = 0; i < statics.length; i++) {
JavaField f = statics[i].getField();
if (f.hasId()) {
JavaThing other = statics[i].getValue();
if (other == target) {
return "static field " + f.getName();
}
}
}
return super.describeReferenceTo(target, ss);
}
/**
* @return the size of an instance of this class. Gives 0 for an array
* type.
*/
public int getInstanceSize() {
return instanceSize + mySnapshot.getMinimumObjectSize();
}
/**
* @return The size of all instances of this class. Correctly handles
* arrays.
*/
public long getTotalInstanceSize() {
int count = instances.size();
if (count == 0 || !isArray()) {
return count * instanceSize;
}
// array class and non-zero count, we have to
// get the size of each instance and sum it
long result = 0;
for (int i = 0; i < count; i++) {
JavaThing t = (JavaThing) instances.elementAt(i);
result += t.getSize();
}
return result;
}
/**
* @return the size of this object
*/
public int getSize() {
JavaClass cl = mySnapshot.getJavaLangClass();
if (cl == null) {
return 0;
} else {
return cl.getInstanceSize();
}
}
public void visitReferencedObjects(JavaHeapObjectVisitor v) {
super.visitReferencedObjects(v);
JavaHeapObject sc = getSuperclass();
if (sc != null) v.visit(getSuperclass());
JavaThing other;
other = getLoader();
if (other instanceof JavaHeapObject) {
v.visit((JavaHeapObject)other);
}
other = getSigners();
if (other instanceof JavaHeapObject) {
v.visit((JavaHeapObject)other);
}
other = getProtectionDomain();
if (other instanceof JavaHeapObject) {
v.visit((JavaHeapObject)other);
}
for (int i = 0; i < statics.length; i++) {
JavaField f = statics[i].getField();
if (!v.exclude(this, f) && f.hasId()) {
other = statics[i].getValue();
if (other instanceof JavaHeapObject) {
v.visit((JavaHeapObject) other);
}
}
}
}
// package-privates below this point
final ReadBuffer getReadBuffer() {
return mySnapshot.getReadBuffer();
}
final void setNew(JavaHeapObject obj, boolean flag) {
mySnapshot.setNew(obj, flag);
}
final boolean isNew(JavaHeapObject obj) {
return mySnapshot.isNew(obj);
}
final StackTrace getSiteTrace(JavaHeapObject obj) {
return mySnapshot.getSiteTrace(obj);
}
final void addReferenceFromRoot(Root root, JavaHeapObject obj) {
mySnapshot.addReferenceFromRoot(root, obj);
}
final Root getRoot(JavaHeapObject obj) {
return mySnapshot.getRoot(obj);
}
final Snapshot getSnapshot() {
return mySnapshot;
}
void addInstance(JavaHeapObject inst) {
instances.addElement(inst);
}
// Internals only below this point
private void addFields(Vector<JavaField> v) {
if (superclass != null) {
((JavaClass) superclass).addFields(v);
}
for (int i = 0; i < fields.length; i++) {
v.addElement(fields[i]);
}
}
private void addSubclassInstances(Vector<JavaHeapObject> v) {
for (int i = 0; i < subclasses.length; i++) {
subclasses[i].addSubclassInstances(v);
}
for (int i = 0; i < instances.size(); i++) {
v.addElement(instances.elementAt(i));
}
}
private void addSubclass(JavaClass sub) {
JavaClass newValue[] = new JavaClass[subclasses.length + 1];
System.arraycopy(subclasses, 0, newValue, 0, subclasses.length);
newValue[subclasses.length] = sub;
subclasses = newValue;
}
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents a double (i.e. a double field in an instance).
*
* @author Bill Foote
*/
public class JavaDouble extends JavaValue {
double value;
public JavaDouble(double value) {
this.value = value;
}
public String toString() {
return Double.toString(value);
}
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
*
* @author Bill Foote
*/
public class JavaField {
private String name;
private String signature;
public JavaField(String name, String signature) {
this.name = name;
this.signature = signature;
}
/**
* @return true if the type of this field is something that has an ID.
* int fields, for exampe, don't.
*/
public boolean hasId() {
char ch = signature.charAt(0);
return (ch == '[' || ch == 'L');
}
public String getName() {
return name;
}
public String getSignature() {
return signature;
}
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents a float (i.e. a float field in an instance).
*
* @author Bill Foote
*/
public class JavaFloat extends JavaValue {
float value;
public JavaFloat(float value) {
this.value = value;
}
public String toString() {
return Float.toString(value);
}
}

View File

@ -1,207 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import com.sun.tools.hat.internal.util.Misc;
/**
*
* @author Bill Foote
*/
/**
* Represents an object that's allocated out of the Java heap. It occupies
* memory in the VM, and is the sort of thing that in a JDK 1.1 VM had
* a handle. It can be a
* JavaClass, a JavaObjectArray, a JavaValueArray or a JavaObject.
*/
public abstract class JavaHeapObject extends JavaThing {
//
// Who we refer to. This is heavily optimized for space, because it's
// well worth trading a bit of speed for less swapping.
// referers and referersLen go through two phases: Building and
// resolved. When building, referers might have duplicates, but can
// be appended to. When resolved, referers has no duplicates or
// empty slots.
//
private JavaThing[] referers = null;
private int referersLen = 0; // -1 when resolved
public abstract JavaClass getClazz();
public abstract int getSize();
public abstract long getId();
/**
* Do any initialization this thing needs after its data is read in.
* Subclasses that override this should call super.resolve().
*/
public void resolve(Snapshot snapshot) {
StackTrace trace = snapshot.getSiteTrace(this);
if (trace != null) {
trace.resolve(snapshot);
}
}
//
// Eliminate duplicates from referers, and size the array exactly.
// This sets us up to answer queries. See the comments around the
// referers data member for details.
//
void setupReferers() {
if (referersLen > 1) {
// Copy referers to map, screening out duplicates
Map<JavaThing, JavaThing> map = new HashMap<JavaThing, JavaThing>();
for (int i = 0; i < referersLen; i++) {
if (map.get(referers[i]) == null) {
map.put(referers[i], referers[i]);
}
}
// Now copy into the array
referers = new JavaThing[map.size()];
map.keySet().toArray(referers);
}
referersLen = -1;
}
/**
* @return the id of this thing as hex string
*/
public String getIdString() {
return Misc.toHex(getId());
}
public String toString() {
return getClazz().getName() + "@" + getIdString();
}
/**
* @return the StackTrace of the point of allocation of this object,
* or null if unknown
*/
public StackTrace getAllocatedFrom() {
return getClazz().getSiteTrace(this);
}
public boolean isNew() {
return getClazz().isNew(this);
}
void setNew(boolean flag) {
getClazz().setNew(this, flag);
}
/**
* Tell the visitor about all of the objects we refer to
*/
public void visitReferencedObjects(JavaHeapObjectVisitor v) {
v.visit(getClazz());
}
void addReferenceFrom(JavaHeapObject other) {
if (referersLen == 0) {
referers = new JavaThing[1]; // It was null
} else if (referersLen == referers.length) {
JavaThing[] copy = new JavaThing[(3 * (referersLen + 1)) / 2];
System.arraycopy(referers, 0, copy, 0, referersLen);
referers = copy;
}
referers[referersLen++] = other;
// We just append to referers here. Measurements have shown that
// around 10% to 30% are duplicates, so it's better to just append
// blindly and screen out all the duplicates at once.
}
void addReferenceFromRoot(Root r) {
getClazz().addReferenceFromRoot(r, this);
}
/**
* If the rootset includes this object, return a Root describing one
* of the reasons why.
*/
public Root getRoot() {
return getClazz().getRoot(this);
}
/**
* Tell who refers to us.
*
* @return an Enumeration of JavaHeapObject instances
*/
public Enumeration<JavaThing> getReferers() {
if (referersLen != -1) {
throw new RuntimeException("not resolved: " + getIdString());
}
return new Enumeration<JavaThing>() {
private int num = 0;
public boolean hasMoreElements() {
return referers != null && num < referers.length;
}
public JavaThing nextElement() {
return referers[num++];
}
};
}
/**
* Given other, which the caller promises is in referers, determines if
* the reference is only a weak reference.
*/
public boolean refersOnlyWeaklyTo(Snapshot ss, JavaThing other) {
return false;
}
/**
* Describe the reference that this thing has to target. This will only
* be called if target is in the array returned by getChildrenForRootset.
*/
public String describeReferenceTo(JavaThing target, Snapshot ss) {
return "??";
}
public boolean isHeapAllocated() {
return true;
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* A visitor for a JavaThing. @see JavaObject#visitReferencedObjects()
*
* @author Bill Foote
*/
public interface JavaHeapObjectVisitor {
public void visit(JavaHeapObject other);
/**
* Should the given field be excluded from the set of things visited?
* @return true if it should.
*/
public boolean exclude(JavaClass clazz, JavaField f);
/**
* @return true iff exclude might ever return true
*/
public boolean mightExclude();
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents an integer (i.e. an int field in an instance).
*
* @author Bill Foote
*/
public class JavaInt extends JavaValue {
int value;
public JavaInt(int value) {
this.value = value;
}
public String toString() {
return "" + value;
}
}

View File

@ -1,176 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.io.IOException;
import com.sun.tools.hat.internal.parser.ReadBuffer;
/*
* Base class for lazily read Java heap objects.
*/
public abstract class JavaLazyReadObject extends JavaHeapObject {
// file offset from which this object data starts
private final long offset;
protected JavaLazyReadObject(long offset) {
this.offset = offset;
}
public final int getSize() {
return getValueLength() + getClazz().getMinimumObjectSize();
}
protected final long getOffset() {
return offset;
}
// return the length of the data for this object
protected final int getValueLength() {
try {
return readValueLength();
} catch (IOException exp) {
System.err.println("lazy read failed at offset " + offset);
exp.printStackTrace();
return 0;
}
}
// get this object's content as byte array
protected final byte[] getValue() {
try {
return readValue();
} catch (IOException exp) {
System.err.println("lazy read failed at offset " + offset);
exp.printStackTrace();
return Snapshot.EMPTY_BYTE_ARRAY;
}
}
// get ID of this object
public final long getId() {
try {
ReadBuffer buf = getClazz().getReadBuffer();
int idSize = getClazz().getIdentifierSize();
if (idSize == 4) {
return ((long)buf.getInt(offset)) & Snapshot.SMALL_ID_MASK;
} else {
return buf.getLong(offset);
}
} catch (IOException exp) {
System.err.println("lazy read failed at offset " + offset);
exp.printStackTrace();
return -1;
}
}
protected abstract int readValueLength() throws IOException;
protected abstract byte[] readValue() throws IOException;
// make Integer or Long for given object ID
protected static Number makeId(long id) {
if ((id & ~Snapshot.SMALL_ID_MASK) == 0) {
return (int)id;
} else {
return id;
}
}
// get ID as long value from Number
protected static long getIdValue(Number num) {
long id = num.longValue();
if (num instanceof Integer) {
id &= Snapshot.SMALL_ID_MASK;
}
return id;
}
// read object ID from given index from given byte array
protected final long objectIdAt(int index, byte[] data) {
int idSize = getClazz().getIdentifierSize();
if (idSize == 4) {
return ((long)intAt(index, data)) & Snapshot.SMALL_ID_MASK;
} else {
return longAt(index, data);
}
}
// utility methods to read primitive types from byte array
protected static byte byteAt(int index, byte[] value) {
return value[index];
}
protected static boolean booleanAt(int index, byte[] value) {
return (value[index] & 0xff) == 0? false: true;
}
protected static char charAt(int index, byte[] value) {
int b1 = ((int) value[index++] & 0xff);
int b2 = ((int) value[index++] & 0xff);
return (char) ((b1 << 8) + b2);
}
protected static short shortAt(int index, byte[] value) {
int b1 = ((int) value[index++] & 0xff);
int b2 = ((int) value[index++] & 0xff);
return (short) ((b1 << 8) + b2);
}
protected static int intAt(int index, byte[] value) {
int b1 = ((int) value[index++] & 0xff);
int b2 = ((int) value[index++] & 0xff);
int b3 = ((int) value[index++] & 0xff);
int b4 = ((int) value[index++] & 0xff);
return ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
}
protected static long longAt(int index, byte[] value) {
long val = 0;
for (int j = 0; j < 8; j++) {
val = val << 8;
int b = ((int)value[index++]) & 0xff;
val |= b;
}
return val;
}
protected static float floatAt(int index, byte[] value) {
int val = intAt(index, value);
return Float.intBitsToFloat(val);
}
protected static double doubleAt(int index, byte[] value) {
long val = longAt(index, value);
return Double.longBitsToDouble(val);
}
}

View File

@ -1,53 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents a long (i.e. a long field in an instance).
*
* @author Bill Foote
*/
public class JavaLong extends JavaValue {
long value;
public JavaLong(long value) {
this.value = value;
}
public String toString() {
return Long.toString(value);
}
}

View File

@ -1,334 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.io.IOException;
import com.sun.tools.hat.internal.parser.ReadBuffer;
/**
* Represents Java instance
*
* @author Bill Foote
*/
public class JavaObject extends JavaLazyReadObject {
private Object clazz; // Number before resolve
// JavaClass after resolve
/**
* Construct a new JavaObject.
*
* @param classID id of the class object
* @param offset The offset of field data
*/
public JavaObject(long classID, long offset) {
super(offset);
this.clazz = makeId(classID);
}
public void resolve(Snapshot snapshot) {
if (clazz instanceof JavaClass) {
return;
}
if (clazz instanceof Number) {
long classID = getIdValue((Number)clazz);
clazz = snapshot.findThing(classID);
if (! (clazz instanceof JavaClass)) {
warn("Class " + Long.toHexString(classID) + " not found, " +
"adding fake class!");
int length;
ReadBuffer buf = snapshot.getReadBuffer();
int idSize = snapshot.getIdentifierSize();
long lenOffset = getOffset() + 2*idSize + 4;
try {
length = buf.getInt(lenOffset);
} catch (IOException exp) {
throw new RuntimeException(exp);
}
clazz = snapshot.addFakeInstanceClass(classID, length);
}
} else {
throw new InternalError("should not reach here");
}
JavaClass cl = (JavaClass) clazz;
cl.resolve(snapshot);
// while resolving, parse fields in verbose mode.
// but, getFields calls parseFields in non-verbose mode
// to avoid printing warnings repeatedly.
parseFields(getValue(), true);
cl.addInstance(this);
super.resolve(snapshot);
}
/**
* Are we the same type as other? We are iff our clazz is the
* same type as other's.
*/
public boolean isSameTypeAs(JavaThing other) {
if (!(other instanceof JavaObject)) {
return false;
}
JavaObject oo = (JavaObject) other;
return getClazz().equals(oo.getClazz());
}
/**
* Return our JavaClass object. This may only be called after resolve.
*/
public JavaClass getClazz() {
return (JavaClass) clazz;
}
public JavaThing[] getFields() {
// pass false to verbose mode so that dereference
// warnings are not printed.
return parseFields(getValue(), false);
}
// returns the value of field of given name
public JavaThing getField(String name) {
JavaThing[] flds = getFields();
JavaField[] instFields = getClazz().getFieldsForInstance();
for (int i = 0; i < instFields.length; i++) {
if (instFields[i].getName().equals(name)) {
return flds[i];
}
}
return null;
}
public int compareTo(JavaThing other) {
if (other instanceof JavaObject) {
JavaObject oo = (JavaObject) other;
return getClazz().getName().compareTo(oo.getClazz().getName());
}
return super.compareTo(other);
}
public void visitReferencedObjects(JavaHeapObjectVisitor v) {
super.visitReferencedObjects(v);
JavaThing[] flds = getFields();
for (int i = 0; i < flds.length; i++) {
if (flds[i] != null) {
if (v.mightExclude()
&& v.exclude(getClazz().getClassForField(i),
getClazz().getFieldForInstance(i)))
{
// skip it
} else if (flds[i] instanceof JavaHeapObject) {
v.visit((JavaHeapObject) flds[i]);
}
}
}
}
public boolean refersOnlyWeaklyTo(Snapshot ss, JavaThing other) {
if (ss.getWeakReferenceClass() != null) {
final int referentFieldIndex = ss.getReferentFieldIndex();
if (ss.getWeakReferenceClass().isAssignableFrom(getClazz())) {
//
// REMIND: This introduces a dependency on the JDK
// implementation that is undesirable.
JavaThing[] flds = getFields();
for (int i = 0; i < flds.length; i++) {
if (i != referentFieldIndex && flds[i] == other) {
return false;
}
}
return true;
}
}
return false;
}
/**
* Describe the reference that this thing has to target. This will only
* be called if target is in the array returned by getChildrenForRootset.
*/
public String describeReferenceTo(JavaThing target, Snapshot ss) {
JavaThing[] flds = getFields();
for (int i = 0; i < flds.length; i++) {
if (flds[i] == target) {
JavaField f = getClazz().getFieldForInstance(i);
return "field " + f.getName();
}
}
return super.describeReferenceTo(target, ss);
}
public String toString() {
if (getClazz().isString()) {
JavaThing value = getField("value");
if (value instanceof JavaValueArray) {
return ((JavaValueArray)value).valueString();
} else {
return "null";
}
} else {
return super.toString();
}
}
// Internals only below this point
/*
* Java instance record (HPROF_GC_INSTANCE_DUMP) looks as below:
*
* object ID
* stack trace serial number (int)
* class ID
* data length (int)
* byte[length]
*/
protected final int readValueLength() throws IOException {
JavaClass cl = getClazz();
int idSize = cl.getIdentifierSize();
long lengthOffset = getOffset() + 2*idSize + 4;
return cl.getReadBuffer().getInt(lengthOffset);
}
protected final byte[] readValue() throws IOException {
JavaClass cl = getClazz();
int idSize = cl.getIdentifierSize();
ReadBuffer buf = cl.getReadBuffer();
long offset = getOffset() + 2*idSize + 4;
int length = buf.getInt(offset);
if (length == 0) {
return Snapshot.EMPTY_BYTE_ARRAY;
} else {
byte[] res = new byte[length];
buf.get(offset + 4, res);
return res;
}
}
private JavaThing[] parseFields(byte[] data, boolean verbose) {
JavaClass cl = getClazz();
int target = cl.getNumFieldsForInstance();
JavaField[] fields = cl.getFields();
JavaThing[] fieldValues = new JavaThing[target];
Snapshot snapshot = cl.getSnapshot();
int idSize = snapshot.getIdentifierSize();
int fieldNo = 0;
// In the dump file, the fields are stored in this order:
// fields of most derived class (immediate class) are stored
// first and then the super class and so on. In this object,
// fields are stored in the reverse ("natural") order. i.e.,
// fields of most super class are stored first.
// target variable is used to compensate for the fact that
// the dump file starts field values from the leaf working
// upwards in the inheritance hierarchy, whereas JavaObject
// starts with the top of the inheritance hierarchy and works down.
target -= fields.length;
JavaClass currClass = cl;
int index = 0;
for (int i = 0; i < fieldValues.length; i++, fieldNo++) {
while (fieldNo >= fields.length) {
currClass = currClass.getSuperclass();
fields = currClass.getFields();
fieldNo = 0;
target -= fields.length;
}
JavaField f = fields[fieldNo];
char sig = f.getSignature().charAt(0);
switch (sig) {
case 'L':
case '[': {
long id = objectIdAt(index, data);
index += idSize;
JavaObjectRef ref = new JavaObjectRef(id);
fieldValues[target+fieldNo] = ref.dereference(snapshot, f, verbose);
break;
}
case 'Z': {
byte value = byteAt(index, data);
index++;
fieldValues[target+fieldNo] = new JavaBoolean(value != 0);
break;
}
case 'B': {
byte value = byteAt(index, data);
index++;
fieldValues[target+fieldNo] = new JavaByte(value);
break;
}
case 'S': {
short value = shortAt(index, data);
index += 2;
fieldValues[target+fieldNo] = new JavaShort(value);
break;
}
case 'C': {
char value = charAt(index, data);
index += 2;
fieldValues[target+fieldNo] = new JavaChar(value);
break;
}
case 'I': {
int value = intAt(index, data);
index += 4;
fieldValues[target+fieldNo] = new JavaInt(value);
break;
}
case 'J': {
long value = longAt(index, data);
index += 8;
fieldValues[target+fieldNo] = new JavaLong(value);
break;
}
case 'F': {
float value = floatAt(index, data);
index += 4;
fieldValues[target+fieldNo] = new JavaFloat(value);
break;
}
case 'D': {
double value = doubleAt(index, data);
index += 8;
fieldValues[target+fieldNo] = new JavaDouble(value);
break;
}
default:
throw new RuntimeException("invalid signature: " + sig);
}
}
return fieldValues;
}
private void warn(String msg) {
System.out.println("WARNING: " + msg);
}
}

View File

@ -1,172 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.io.IOException;
import com.sun.tools.hat.internal.parser.ReadBuffer;
/**
* @author Bill Foote
*/
public class JavaObjectArray extends JavaLazyReadObject {
private Object clazz; // Long before resolve, the class after resolve
public JavaObjectArray(long classID, long offset) {
super(offset);
this.clazz = makeId(classID);
}
public JavaClass getClazz() {
return (JavaClass) clazz;
}
public void resolve(Snapshot snapshot) {
if (clazz instanceof JavaClass) {
return;
}
long classID = getIdValue((Number)clazz);
if (snapshot.isNewStyleArrayClass()) {
// Modern heap dumps do this
JavaThing t = snapshot.findThing(classID);
if (t instanceof JavaClass) {
clazz = (JavaClass) t;
}
}
if (!(clazz instanceof JavaClass)) {
JavaThing t = snapshot.findThing(classID);
if (t != null && t instanceof JavaClass) {
JavaClass el = (JavaClass) t;
String nm = el.getName();
if (!nm.startsWith("[")) {
nm = "L" + el.getName() + ";";
}
clazz = snapshot.getArrayClass(nm);
}
}
if (!(clazz instanceof JavaClass)) {
clazz = snapshot.getOtherArrayType();
}
((JavaClass)clazz).addInstance(this);
super.resolve(snapshot);
}
public JavaThing[] getValues() {
return getElements();
}
public JavaThing[] getElements() {
Snapshot snapshot = getClazz().getSnapshot();
byte[] data = getValue();
final int idSize = snapshot.getIdentifierSize();
final int numElements = data.length / idSize;
JavaThing[] elements = new JavaThing[numElements];
int index = 0;
for (int i = 0; i < elements.length; i++) {
long id = objectIdAt(index, data);
index += idSize;
elements[i] = snapshot.findThing(id);
}
return elements;
}
public int compareTo(JavaThing other) {
if (other instanceof JavaObjectArray) {
return 0;
}
return super.compareTo(other);
}
public int getLength() {
return getValueLength() / getClazz().getIdentifierSize();
}
public void visitReferencedObjects(JavaHeapObjectVisitor v) {
super.visitReferencedObjects(v);
JavaThing[] elements = getElements();
for (int i = 0; i < elements.length; i++) {
if (elements[i] != null && elements[i] instanceof JavaHeapObject) {
v.visit((JavaHeapObject) elements[i]);
}
}
}
/**
* Describe the reference that this thing has to target. This will only
* be called if target is in the array returned by getChildrenForRootset.
*/
public String describeReferenceTo(JavaThing target, Snapshot ss) {
JavaThing[] elements = getElements();
for (int i = 0; i < elements.length; i++) {
if (elements[i] == target) {
return "Element " + i + " of " + this;
}
}
return super.describeReferenceTo(target, ss);
}
/*
* Java object array record (HPROF_GC_OBJ_ARRAY_DUMP)
* looks as below:
*
* object ID
* stack trace serial number (int)
* array length (int)
* array class ID
* array element IDs
*/
protected final int readValueLength() throws IOException {
JavaClass cl = getClazz();
ReadBuffer buf = cl.getReadBuffer();
int idSize = cl.getIdentifierSize();
long offset = getOffset() + idSize + 4;
int len = buf.getInt(offset);
return len * cl.getIdentifierSize();
}
protected final byte[] readValue() throws IOException {
JavaClass cl = getClazz();
ReadBuffer buf = cl.getReadBuffer();
int idSize = cl.getIdentifierSize();
long offset = getOffset() + idSize + 4;
int len = buf.getInt(offset);
if (len == 0) {
return Snapshot.EMPTY_BYTE_ARRAY;
} else {
byte[] res = new byte[len * idSize];
buf.get(offset + 4 + idSize, res);
return res;
}
}
}

View File

@ -1,97 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import com.sun.tools.hat.internal.util.Misc;
/**
* A forward reference to an object. This is an intermediate representation
* for a JavaThing, when we have the thing's ID, but we might not have read
* the thing yet.
*
* @author Bill Foote
*/
public class JavaObjectRef extends JavaThing {
private long id;
public JavaObjectRef(long id) {
this.id = id;
}
public long getId() {
return id;
}
public boolean isHeapAllocated() {
return true;
}
public JavaThing dereference(Snapshot snapshot, JavaField field) {
return dereference(snapshot, field, true);
}
public JavaThing dereference(Snapshot snapshot, JavaField field, boolean verbose) {
if (field != null && !field.hasId()) {
// If this happens, we must be a field that represents an int.
// (This only happens with .bod-style files)
return new JavaLong(id);
}
if (id == 0) {
return snapshot.getNullThing();
}
JavaThing result = snapshot.findThing(id);
if (result == null) {
if (!snapshot.getUnresolvedObjectsOK() && verbose) {
String msg = "WARNING: Failed to resolve object id "
+ Misc.toHex(id);
if (field != null) {
msg += " for field " + field.getName()
+ " (signature " + field.getSignature() + ")";
}
System.out.println(msg);
// Thread.dumpStack();
}
result = new HackJavaValue("Unresolved object "
+ Misc.toHex(id), 0);
}
return result;
}
public int getSize() {
return 0;
}
public String toString() {
return "Unresolved object " + Misc.toHex(id);
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents a short (i.e. a short field in an instance).
*
* @author Bill Foote
*/
public class JavaShort extends JavaValue {
short value;
public JavaShort(short value) {
this.value = value;
}
public String toString() {
return "" + value;
}
}

View File

@ -1,79 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
*
* @author Bill Foote
*/
/**
* Represents the value of a static field of a JavaClass
*/
public class JavaStatic {
private JavaField field;
private JavaThing value;
public JavaStatic(JavaField field, JavaThing value) {
this.field = field;
this.value = value;
}
public void resolve(JavaClass clazz, Snapshot snapshot) {
long id = -1;
if (value instanceof JavaObjectRef) {
id = ((JavaObjectRef)value).getId();
}
value = value.dereference(snapshot, field);
if (value.isHeapAllocated() &&
clazz.getLoader() == snapshot.getNullThing()) {
// static fields are only roots if they are in classes
// loaded by the root classloader.
JavaHeapObject ho = (JavaHeapObject) value;
String s = "Static reference from " + clazz.getName()
+ "." + field.getName();
snapshot.addRoot(new Root(id, clazz.getId(),
Root.JAVA_STATIC, s));
}
}
public JavaField getField() {
return field;
}
public JavaThing getValue() {
return value;
}
}

View File

@ -1,99 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.util.Enumeration;
import java.util.Hashtable;
/**
*
* @author Bill Foote
*/
/**
* Represents a java "Thing". A thing is anything that can be the value of
* a field. This includes JavaHeapObject, JavaObjectRef, and JavaValue.
*/
public abstract class JavaThing {
protected JavaThing() {
}
/**
* If this is a forward reference, figure out what it really
* refers to.
*
* @param snapshot The snapshot this is for
* @param field The field this thing represents. If null, it is
* assumed this thing is an object (and never a value).
*/
public JavaThing dereference(Snapshot shapshot, JavaField field) {
return this;
}
/**
* Are we the same type as other?
*
* @see JavaObject.isSameTypeAs()
*/
public boolean isSameTypeAs(JavaThing other) {
return getClass() == other.getClass();
}
/**
* @return true iff this represents a heap-allocated object
*/
abstract public boolean isHeapAllocated();
/**
* @return the size of this object, in bytes, including VM overhead
*/
abstract public int getSize();
/**
* @return a human-readable string representation of this thing
*/
abstract public String toString();
/**
* Compare our string representation to other's
* @see java.lang.String.compareTo()
*/
public int compareTo(JavaThing other) {
return toString().compareTo(other.toString());
}
}

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Abstract base class for all value types (ints, longs, floats, etc.)
*
* @author Bill Foote
*/
public abstract class JavaValue extends JavaThing {
protected JavaValue() {
}
public boolean isHeapAllocated() {
return false;
}
abstract public String toString();
public int getSize() {
// The size of a value is already accounted for in the class
// that has the data member.
return 0;
}
}

View File

@ -1,433 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import com.sun.tools.hat.internal.parser.ReadBuffer;
import java.io.IOException;
/**
* An array of values, that is, an array of ints, boolean, floats or the like.
*
* @author Bill Foote
*/
public class JavaValueArray extends JavaLazyReadObject
/*imports*/ implements ArrayTypeCodes {
private static String arrayTypeName(byte sig) {
switch (sig) {
case 'B':
return "byte[]";
case 'Z':
return "boolean[]";
case 'C':
return "char[]";
case 'S':
return "short[]";
case 'I':
return "int[]";
case 'F':
return "float[]";
case 'J':
return "long[]";
case 'D':
return "double[]";
default:
throw new RuntimeException("invalid array element sig: " + sig);
}
}
private static int elementSize(byte type) {
switch (type) {
case T_BYTE:
case T_BOOLEAN:
return 1;
case T_CHAR:
case T_SHORT:
return 2;
case T_INT:
case T_FLOAT:
return 4;
case T_LONG:
case T_DOUBLE:
return 8;
default:
throw new RuntimeException("invalid array element type: " + type);
}
}
/*
* Java primitive array record (HPROF_GC_PRIM_ARRAY_DUMP) looks
* as below:
*
* object ID
* stack trace serial number (int)
* length of the instance data (int)
* element type (byte)
* array data
*/
protected final int readValueLength() throws IOException {
JavaClass cl = getClazz();
ReadBuffer buf = cl.getReadBuffer();
int idSize = cl.getIdentifierSize();
long offset = getOffset() + idSize + 4;
// length of the array
int len = buf.getInt(offset);
// typecode of array element type
byte type = buf.getByte(offset + 4);
return len * elementSize(type);
}
protected final byte[] readValue() throws IOException {
JavaClass cl = getClazz();
ReadBuffer buf = cl.getReadBuffer();
int idSize = cl.getIdentifierSize();
long offset = getOffset() + idSize + 4;
// length of the array
int length = buf.getInt(offset);
// typecode of array element type
byte type = buf.getByte(offset + 4);
if (length == 0) {
return Snapshot.EMPTY_BYTE_ARRAY;
} else {
length *= elementSize(type);
byte[] res = new byte[length];
buf.get(offset + 5, res);
return res;
}
}
// JavaClass set only after resolve.
private JavaClass clazz;
// This field contains elementSignature byte and
// divider to be used to calculate length. Note that
// length of content byte[] is not same as array length.
// Actual array length is (byte[].length / divider)
private int data;
// First 8 bits of data is used for element signature
private static final int SIGNATURE_MASK = 0x0FF;
// Next 8 bits of data is used for length divider
private static final int LENGTH_DIVIDER_MASK = 0x0FF00;
// Number of bits to shift to get length divider
private static final int LENGTH_DIVIDER_SHIFT = 8;
public JavaValueArray(byte elementSignature, long offset) {
super(offset);
this.data = (elementSignature & SIGNATURE_MASK);
}
public JavaClass getClazz() {
return clazz;
}
public void visitReferencedObjects(JavaHeapObjectVisitor v) {
super.visitReferencedObjects(v);
}
public void resolve(Snapshot snapshot) {
if (clazz instanceof JavaClass) {
return;
}
byte elementSig = getElementType();
clazz = snapshot.findClass(arrayTypeName(elementSig));
if (clazz == null) {
clazz = snapshot.getArrayClass("" + ((char) elementSig));
}
getClazz().addInstance(this);
super.resolve(snapshot);
}
public int getLength() {
int divider = (data & LENGTH_DIVIDER_MASK) >>> LENGTH_DIVIDER_SHIFT;
if (divider == 0) {
byte elementSignature = getElementType();
switch (elementSignature) {
case 'B':
case 'Z':
divider = 1;
break;
case 'C':
case 'S':
divider = 2;
break;
case 'I':
case 'F':
divider = 4;
break;
case 'J':
case 'D':
divider = 8;
break;
default:
throw new RuntimeException("unknown primitive type: " +
elementSignature);
}
data |= (divider << LENGTH_DIVIDER_SHIFT);
}
return (getValueLength() / divider);
}
public Object getElements() {
final int len = getLength();
final byte et = getElementType();
byte[] data = getValue();
int index = 0;
switch (et) {
case 'Z': {
boolean[] res = new boolean[len];
for (int i = 0; i < len; i++) {
res[i] = booleanAt(index, data);
index++;
}
return res;
}
case 'B': {
byte[] res = new byte[len];
for (int i = 0; i < len; i++) {
res[i] = byteAt(index, data);
index++;
}
return res;
}
case 'C': {
char[] res = new char[len];
for (int i = 0; i < len; i++) {
res[i] = charAt(index, data);
index += 2;
}
return res;
}
case 'S': {
short[] res = new short[len];
for (int i = 0; i < len; i++) {
res[i] = shortAt(index, data);
index += 2;
}
return res;
}
case 'I': {
int[] res = new int[len];
for (int i = 0; i < len; i++) {
res[i] = intAt(index, data);
index += 4;
}
return res;
}
case 'J': {
long[] res = new long[len];
for (int i = 0; i < len; i++) {
res[i] = longAt(index, data);
index += 8;
}
return res;
}
case 'F': {
float[] res = new float[len];
for (int i = 0; i < len; i++) {
res[i] = floatAt(index, data);
index += 4;
}
return res;
}
case 'D': {
double[] res = new double[len];
for (int i = 0; i < len; i++) {
res[i] = doubleAt(index, data);
index += 8;
}
return res;
}
default: {
throw new RuntimeException("unknown primitive type?");
}
}
}
public byte getElementType() {
return (byte) (data & SIGNATURE_MASK);
}
private void checkIndex(int index) {
if (index < 0 || index >= getLength()) {
throw new ArrayIndexOutOfBoundsException(index);
}
}
private void requireType(char type) {
if (getElementType() != type) {
throw new RuntimeException("not of type : " + type);
}
}
public boolean getBooleanAt(int index) {
checkIndex(index);
requireType('Z');
return booleanAt(index, getValue());
}
public byte getByteAt(int index) {
checkIndex(index);
requireType('B');
return byteAt(index, getValue());
}
public char getCharAt(int index) {
checkIndex(index);
requireType('C');
return charAt(index << 1, getValue());
}
public short getShortAt(int index) {
checkIndex(index);
requireType('S');
return shortAt(index << 1, getValue());
}
public int getIntAt(int index) {
checkIndex(index);
requireType('I');
return intAt(index << 2, getValue());
}
public long getLongAt(int index) {
checkIndex(index);
requireType('J');
return longAt(index << 3, getValue());
}
public float getFloatAt(int index) {
checkIndex(index);
requireType('F');
return floatAt(index << 2, getValue());
}
public double getDoubleAt(int index) {
checkIndex(index);
requireType('D');
return doubleAt(index << 3, getValue());
}
public String valueString() {
return valueString(true);
}
public String valueString(boolean bigLimit) {
// Char arrays deserve special treatment
StringBuilder result;
byte[] value = getValue();
int max = value.length;
byte elementSignature = getElementType();
if (elementSignature == 'C') {
result = new StringBuilder();
for (int i = 0; i < value.length; ) {
char val = charAt(i, value);
result.append(val);
i += 2;
}
} else {
int limit = 8;
if (bigLimit) {
limit = 1000;
}
result = new StringBuilder("{");
int num = 0;
for (int i = 0; i < value.length; ) {
if (num > 0) {
result.append(", ");
}
if (num >= limit) {
result.append("... ");
break;
}
num++;
switch (elementSignature) {
case 'Z': {
boolean val = booleanAt(i, value);
if (val) {
result.append("true");
} else {
result.append("false");
}
i++;
break;
}
case 'B': {
int val = 0xFF & byteAt(i, value);
result.append("0x").append(Integer.toString(val, 16));
i++;
break;
}
case 'S': {
short val = shortAt(i, value);
i += 2;
result.append(val);
break;
}
case 'I': {
int val = intAt(i, value);
i += 4;
result.append(val);
break;
}
case 'J': { // long
long val = longAt(i, value);
result.append(val);
i += 8;
break;
}
case 'F': {
float val = floatAt(i, value);
result.append(val);
i += 4;
break;
}
case 'D': { // double
double val = doubleAt(i, value);
result.append(val);
i += 8;
break;
}
default: {
throw new RuntimeException("unknown primitive type?");
}
}
}
result.append('}');
}
return result.toString();
}
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* This represents a set of data members that should be excluded from the
* reachable objects query. This is useful to exclude observers from the
* transitive closure of objects reachable from a given object, allowing
* some kind of real determination of the "size" of that object.
*
*/
public interface ReachableExcludes {
/**
* @return true iff the given field is on the hitlist of excluded
* fields.
*/
public boolean isExcluded(String fieldName);
}

View File

@ -1,105 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Hashtable;
/**
* This represents a set of data members that should be excluded from the
* reachable objects query.
* This is useful to exclude observers from the
* transitive closure of objects reachable from a given object, allowing
* some kind of real determination of the "size" of that object.
*
* @author Bill Foote
*/
public class ReachableExcludesImpl implements ReachableExcludes {
private File excludesFile;
private long lastModified;
private Hashtable<String, String> methods; // Used as a bag
/**
* Create a new ReachableExcludesImpl over the given file. The file will be
* re-read whenever the timestamp changes.
*/
public ReachableExcludesImpl(File excludesFile) {
this.excludesFile = excludesFile;
readFile();
}
private void readFileIfNeeded() {
if (excludesFile.lastModified() != lastModified) {
synchronized(this) {
if (excludesFile.lastModified() != lastModified) {
readFile();
}
}
}
}
private void readFile() {
long lm = excludesFile.lastModified();
Hashtable<String, String> m = new Hashtable<String, String>();
try {
BufferedReader r = new BufferedReader(new InputStreamReader(
new FileInputStream(excludesFile)));
String method;
while ((method = r.readLine()) != null) {
m.put(method, method);
}
lastModified = lm;
methods = m; // We want this to be atomic
} catch (IOException ex) {
System.out.println("Error reading " + excludesFile + ": " + ex);
}
}
/**
* @return true iff the given field is on the histlist of excluded
* fields.
*/
public boolean isExcluded(String fieldName) {
readFileIfNeeded();
return methods.get(fieldName) != null;
}
}

View File

@ -1,148 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import com.sun.tools.hat.internal.util.ArraySorter;
import com.sun.tools.hat.internal.util.Comparer;
/**
* @author A. Sundararajan
*/
public class ReachableObjects {
public ReachableObjects(JavaHeapObject root,
final ReachableExcludes excludes) {
this.root = root;
final Hashtable<JavaHeapObject, JavaHeapObject> bag = new Hashtable<JavaHeapObject, JavaHeapObject>();
final Hashtable<String, String> fieldsExcluded = new Hashtable<String, String>(); //Bag<String>
final Hashtable<String, String> fieldsUsed = new Hashtable<String, String>(); // Bag<String>
JavaHeapObjectVisitor visitor = new AbstractJavaHeapObjectVisitor() {
public void visit(JavaHeapObject t) {
// Size is zero for things like integer fields
if (t != null && t.getSize() > 0 && bag.get(t) == null) {
bag.put(t, t);
t.visitReferencedObjects(this);
}
}
public boolean mightExclude() {
return excludes != null;
}
public boolean exclude(JavaClass clazz, JavaField f) {
if (excludes == null) {
return false;
}
String nm = clazz.getName() + "." + f.getName();
if (excludes.isExcluded(nm)) {
fieldsExcluded.put(nm, nm);
return true;
} else {
fieldsUsed.put(nm, nm);
return false;
}
}
};
// Put the closure of root and all objects reachable from root into
// bag (depth first), but don't include root:
visitor.visit(root);
bag.remove(root);
// Now grab the elements into a vector, and sort it in decreasing size
JavaThing[] things = new JavaThing[bag.size()];
int i = 0;
for (Enumeration<JavaHeapObject> e = bag.elements(); e.hasMoreElements(); ) {
things[i++] = (JavaThing) e.nextElement();
}
ArraySorter.sort(things, new Comparer() {
public int compare(Object lhs, Object rhs) {
JavaThing left = (JavaThing) lhs;
JavaThing right = (JavaThing) rhs;
int diff = right.getSize() - left.getSize();
if (diff != 0) {
return diff;
}
return left.compareTo(right);
}
});
this.reachables = things;
this.totalSize = root.getSize();
for (i = 0; i < things.length; i++) {
this.totalSize += things[i].getSize();
}
excludedFields = getElements(fieldsExcluded);
usedFields = getElements(fieldsUsed);
}
public JavaHeapObject getRoot() {
return root;
}
public JavaThing[] getReachables() {
return reachables;
}
public long getTotalSize() {
return totalSize;
}
public String[] getExcludedFields() {
return excludedFields;
}
public String[] getUsedFields() {
return usedFields;
}
private String[] getElements(Hashtable<?, ?> ht) {
Object[] keys = ht.keySet().toArray();
int len = keys.length;
String[] res = new String[len];
System.arraycopy(keys, 0, res, 0, len);
ArraySorter.sortArrayOfStrings(res);
return res;
}
private JavaHeapObject root;
private JavaThing[] reachables;
private String[] excludedFields;
private String[] usedFields;
private long totalSize;
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
* Represents a chain of references to some target object
*
* @author Bill Foote
*/
public class ReferenceChain {
JavaHeapObject obj; // Object referred to
ReferenceChain next; // Next in chain
public ReferenceChain(JavaHeapObject obj, ReferenceChain next) {
this.obj = obj;
this.next = next;
}
public JavaHeapObject getObj() {
return obj;
}
public ReferenceChain getNext() {
return next;
}
public int getDepth() {
int count = 1;
ReferenceChain tmp = next;
while (tmp != null) {
count++;
tmp = tmp.next;
}
return count;
}
}

View File

@ -1,174 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import com.sun.tools.hat.internal.util.Misc;
/**
*
* @author Bill Foote
*/
/**
* Represents a member of the rootset, that is, one of the objects that
* the GC starts from when marking reachable objects.
*/
public class Root {
private long id; // ID of the JavaThing we refer to
private long refererId; // Thread or Class responsible for this, or 0
private int index = -1; // Index in Snapshot.roots
private int type;
private String description;
private JavaHeapObject referer = null;
private StackTrace stackTrace = null;
// Values for type. Higher values are more interesting -- see getType().
// See also getTypeName()
public final static int INVALID_TYPE = 0;
public final static int UNKNOWN = 1;
public final static int SYSTEM_CLASS = 2;
public final static int NATIVE_LOCAL = 3;
public final static int NATIVE_STATIC = 4;
public final static int THREAD_BLOCK = 5;
public final static int BUSY_MONITOR = 6;
public final static int JAVA_LOCAL = 7;
public final static int NATIVE_STACK = 8;
public final static int JAVA_STATIC = 9;
public Root(long id, long refererId, int type, String description) {
this(id, refererId, type, description, null);
}
public Root(long id, long refererId, int type, String description,
StackTrace stackTrace) {
this.id = id;
this.refererId = refererId;
this.type = type;
this.description = description;
this.stackTrace = stackTrace;
}
public long getId() {
return id;
}
public String getIdString() {
return Misc.toHex(id);
}
public String getDescription() {
if ("".equals(description)) {
return getTypeName() + " Reference";
} else {
return description;
}
}
/**
* Return type. We guarantee that more interesting roots will have
* a type that is numerically higher.
*/
public int getType() {
return type;
}
public String getTypeName() {
switch(type) {
case INVALID_TYPE: return "Invalid (?!?)";
case UNKNOWN: return "Unknown";
case SYSTEM_CLASS: return "System Class";
case NATIVE_LOCAL: return "JNI Local";
case NATIVE_STATIC: return "JNI Global";
case THREAD_BLOCK: return "Thread Block";
case BUSY_MONITOR: return "Busy Monitor";
case JAVA_LOCAL: return "Java Local";
case NATIVE_STACK: return "Native Stack (possibly Java local)";
case JAVA_STATIC: return "Java Static";
default: return "??";
}
}
/**
* Given two Root instances, return the one that is most interesting.
*/
public Root mostInteresting(Root other) {
if (other.type > this.type) {
return other;
} else {
return this;
}
}
/**
* Get the object that's responsible for this root, if there is one.
* This will be null, a Thread object, or a Class object.
*/
public JavaHeapObject getReferer() {
return referer;
}
/**
* @return the stack trace responsible for this root, or null if there
* is none.
*/
public StackTrace getStackTrace() {
return stackTrace;
}
/**
* @return The index of this root in Snapshot.roots
*/
public int getIndex() {
return index;
}
void resolve(Snapshot ss) {
if (refererId != 0) {
referer = ss.findThing(refererId);
}
if (stackTrace != null) {
stackTrace.resolve(ss);
}
}
void setIndex(int i) {
index = i;
}
}

View File

@ -1,630 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
import java.lang.ref.SoftReference;
import java.util.*;
import com.sun.tools.hat.internal.parser.ReadBuffer;
import com.sun.tools.hat.internal.util.Misc;
/**
*
* @author Bill Foote
*/
/**
* Represents a snapshot of the Java objects in the VM at one instant.
* This is the top-level "model" object read out of a single .hprof or .bod
* file.
*/
public class Snapshot {
public static long SMALL_ID_MASK = 0x0FFFFFFFFL;
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
private static final JavaField[] EMPTY_FIELD_ARRAY = new JavaField[0];
private static final JavaStatic[] EMPTY_STATIC_ARRAY = new JavaStatic[0];
// all heap objects
private Hashtable<Number, JavaHeapObject> heapObjects =
new Hashtable<Number, JavaHeapObject>();
private Hashtable<Number, JavaClass> fakeClasses =
new Hashtable<Number, JavaClass>();
// all Roots in this Snapshot
private Vector<Root> roots = new Vector<Root>();
// name-to-class map
private Map<String, JavaClass> classes =
new TreeMap<String, JavaClass>();
// new objects relative to a baseline - lazily initialized
private volatile Map<JavaHeapObject, Boolean> newObjects;
// allocation site traces for all objects - lazily initialized
private volatile Map<JavaHeapObject, StackTrace> siteTraces;
// object-to-Root map for all objects
private Map<JavaHeapObject, Root> rootsMap =
new HashMap<JavaHeapObject, Root>();
// soft cache of finalizeable objects - lazily initialized
private SoftReference<Vector<?>> finalizablesCache;
// represents null reference
private JavaThing nullThing;
// java.lang.ref.Reference class
private JavaClass weakReferenceClass;
// index of 'referent' field in java.lang.ref.Reference class
private int referentFieldIndex;
// java.lang.Class class
private JavaClass javaLangClass;
// java.lang.String class
private JavaClass javaLangString;
// java.lang.ClassLoader class
private JavaClass javaLangClassLoader;
// unknown "other" array class
private volatile JavaClass otherArrayType;
// Stuff to exclude from reachable query
private ReachableExcludes reachableExcludes;
// the underlying heap dump buffer
private ReadBuffer readBuf;
// True iff some heap objects have isNew set
private boolean hasNewSet;
private boolean unresolvedObjectsOK;
// whether object array instances have new style class or
// old style (element) class.
private boolean newStyleArrayClass;
// object id size in the heap dump
private int identifierSize = 4;
// minimum object size - accounts for object header in
// most Java virtual machines - we assume 2 identifierSize
// (which is true for Sun's hotspot JVM).
private int minimumObjectSize;
public Snapshot(ReadBuffer buf) {
nullThing = new HackJavaValue("<null>", 0);
readBuf = buf;
}
public void setSiteTrace(JavaHeapObject obj, StackTrace trace) {
if (trace != null && trace.getFrames().length != 0) {
initSiteTraces();
siteTraces.put(obj, trace);
}
}
public StackTrace getSiteTrace(JavaHeapObject obj) {
if (siteTraces != null) {
return siteTraces.get(obj);
} else {
return null;
}
}
public void setNewStyleArrayClass(boolean value) {
newStyleArrayClass = value;
}
public boolean isNewStyleArrayClass() {
return newStyleArrayClass;
}
public void setIdentifierSize(int size) {
identifierSize = size;
minimumObjectSize = 2 * size;
}
public int getIdentifierSize() {
return identifierSize;
}
public int getMinimumObjectSize() {
return minimumObjectSize;
}
public void addHeapObject(long id, JavaHeapObject ho) {
heapObjects.put(makeId(id), ho);
}
public void addRoot(Root r) {
r.setIndex(roots.size());
roots.addElement(r);
}
public void addClass(long id, JavaClass c) {
addHeapObject(id, c);
putInClassesMap(c);
}
JavaClass addFakeInstanceClass(long classID, int instSize) {
// Create a fake class name based on ID.
String name = "unknown-class<@" + Misc.toHex(classID) + ">";
// Create fake fields convering the given instance size.
// Create as many as int type fields and for the left over
// size create byte type fields.
int numInts = instSize / 4;
int numBytes = instSize % 4;
JavaField[] fields = new JavaField[numInts + numBytes];
int i;
for (i = 0; i < numInts; i++) {
fields[i] = new JavaField("unknown-field-" + i, "I");
}
for (i = 0; i < numBytes; i++) {
fields[i + numInts] = new JavaField("unknown-field-" +
i + numInts, "B");
}
// Create fake instance class
JavaClass c = new JavaClass(name, 0, 0, 0, 0, fields,
EMPTY_STATIC_ARRAY, instSize);
// Add the class
addFakeClass(makeId(classID), c);
return c;
}
/**
* @return true iff it's possible that some JavaThing instances might
* isNew set
*
* @see JavaThing.isNew()
*/
public boolean getHasNewSet() {
return hasNewSet;
}
//
// Used in the body of resolve()
//
private static class MyVisitor extends AbstractJavaHeapObjectVisitor {
JavaHeapObject t;
public void visit(JavaHeapObject other) {
other.addReferenceFrom(t);
}
}
// To show heap parsing progress, we print a '.' after this limit
private static final int DOT_LIMIT = 5000;
/**
* Called after reading complete, to initialize the structure
*/
public void resolve(boolean calculateRefs) {
System.out.println("Resolving " + heapObjects.size() + " objects...");
// First, resolve the classes. All classes must be resolved before
// we try any objects, because the objects use classes in their
// resolution.
javaLangClass = findClass("java.lang.Class");
if (javaLangClass == null) {
System.out.println("WARNING: hprof file does not include java.lang.Class!");
javaLangClass = new JavaClass("java.lang.Class", 0, 0, 0, 0,
EMPTY_FIELD_ARRAY, EMPTY_STATIC_ARRAY, 0);
addFakeClass(javaLangClass);
}
javaLangString = findClass("java.lang.String");
if (javaLangString == null) {
System.out.println("WARNING: hprof file does not include java.lang.String!");
javaLangString = new JavaClass("java.lang.String", 0, 0, 0, 0,
EMPTY_FIELD_ARRAY, EMPTY_STATIC_ARRAY, 0);
addFakeClass(javaLangString);
}
javaLangClassLoader = findClass("java.lang.ClassLoader");
if (javaLangClassLoader == null) {
System.out.println("WARNING: hprof file does not include java.lang.ClassLoader!");
javaLangClassLoader = new JavaClass("java.lang.ClassLoader", 0, 0, 0, 0,
EMPTY_FIELD_ARRAY, EMPTY_STATIC_ARRAY, 0);
addFakeClass(javaLangClassLoader);
}
for (JavaHeapObject t : heapObjects.values()) {
if (t instanceof JavaClass) {
t.resolve(this);
}
}
// Now, resolve everything else.
for (JavaHeapObject t : heapObjects.values()) {
if (!(t instanceof JavaClass)) {
t.resolve(this);
}
}
heapObjects.putAll(fakeClasses);
fakeClasses.clear();
weakReferenceClass = findClass("java.lang.ref.Reference");
if (weakReferenceClass == null) { // JDK 1.1.x
weakReferenceClass = findClass("sun.misc.Ref");
referentFieldIndex = 0;
} else {
JavaField[] fields = weakReferenceClass.getFieldsForInstance();
for (int i = 0; i < fields.length; i++) {
if ("referent".equals(fields[i].getName())) {
referentFieldIndex = i;
break;
}
}
}
if (calculateRefs) {
calculateReferencesToObjects();
System.out.print("Eliminating duplicate references");
System.out.flush();
// This println refers to the *next* step
}
int count = 0;
for (JavaHeapObject t : heapObjects.values()) {
t.setupReferers();
++count;
if (calculateRefs && count % DOT_LIMIT == 0) {
System.out.print(".");
System.out.flush();
}
}
if (calculateRefs) {
System.out.println("");
}
// to ensure that Iterator.remove() on getClasses()
// result will throw exception..
classes = Collections.unmodifiableMap(classes);
}
private void calculateReferencesToObjects() {
System.out.print("Chasing references, expect "
+ (heapObjects.size() / DOT_LIMIT) + " dots");
System.out.flush();
int count = 0;
MyVisitor visitor = new MyVisitor();
for (JavaHeapObject t : heapObjects.values()) {
visitor.t = t;
// call addReferenceFrom(t) on all objects t references:
t.visitReferencedObjects(visitor);
++count;
if (count % DOT_LIMIT == 0) {
System.out.print(".");
System.out.flush();
}
}
System.out.println();
for (Root r : roots) {
r.resolve(this);
JavaHeapObject t = findThing(r.getId());
if (t != null) {
t.addReferenceFromRoot(r);
}
}
}
public void markNewRelativeTo(Snapshot baseline) {
hasNewSet = true;
for (JavaHeapObject t : heapObjects.values()) {
boolean isNew;
long thingID = t.getId();
if (thingID == 0L || thingID == -1L) {
isNew = false;
} else {
JavaThing other = baseline.findThing(t.getId());
if (other == null) {
isNew = true;
} else {
isNew = !t.isSameTypeAs(other);
}
}
t.setNew(isNew);
}
}
public Enumeration<JavaHeapObject> getThings() {
return heapObjects.elements();
}
public JavaHeapObject findThing(long id) {
Number idObj = makeId(id);
JavaHeapObject jho = heapObjects.get(idObj);
return jho != null? jho : fakeClasses.get(idObj);
}
public JavaHeapObject findThing(String id) {
return findThing(Misc.parseHex(id));
}
public JavaClass findClass(String name) {
if (name.startsWith("0x")) {
return (JavaClass) findThing(name);
} else {
return classes.get(name);
}
}
/**
* Return an Iterator of all of the classes in this snapshot.
**/
public Iterator<JavaClass> getClasses() {
// note that because classes is a TreeMap
// classes are already sorted by name
return classes.values().iterator();
}
public JavaClass[] getClassesArray() {
JavaClass[] res = new JavaClass[classes.size()];
classes.values().toArray(res);
return res;
}
public synchronized Enumeration<?> getFinalizerObjects() {
Vector<?> obj;
if (finalizablesCache != null &&
(obj = finalizablesCache.get()) != null) {
return obj.elements();
}
JavaClass clazz = findClass("java.lang.ref.Finalizer");
JavaObject queue = (JavaObject) clazz.getStaticField("queue");
JavaThing tmp = queue.getField("head");
Vector<JavaHeapObject> finalizables = new Vector<JavaHeapObject>();
if (tmp != getNullThing()) {
JavaObject head = (JavaObject) tmp;
while (true) {
JavaHeapObject referent = (JavaHeapObject) head.getField("referent");
JavaThing next = head.getField("next");
if (next == getNullThing() || next.equals(head)) {
break;
}
head = (JavaObject) next;
finalizables.add(referent);
}
}
finalizablesCache = new SoftReference<Vector<?>>(finalizables);
return finalizables.elements();
}
public Enumeration<Root> getRoots() {
return roots.elements();
}
public Root[] getRootsArray() {
Root[] res = new Root[roots.size()];
roots.toArray(res);
return res;
}
public Root getRootAt(int i) {
return roots.elementAt(i);
}
public ReferenceChain[]
rootsetReferencesTo(JavaHeapObject target, boolean includeWeak) {
Vector<ReferenceChain> fifo = new Vector<ReferenceChain>(); // This is slow... A real fifo would help
// Must be a fifo to go breadth-first
Hashtable<JavaHeapObject, JavaHeapObject> visited = new Hashtable<JavaHeapObject, JavaHeapObject>();
// Objects are added here right after being added to fifo.
Vector<ReferenceChain> result = new Vector<ReferenceChain>();
visited.put(target, target);
fifo.addElement(new ReferenceChain(target, null));
while (fifo.size() > 0) {
ReferenceChain chain = fifo.elementAt(0);
fifo.removeElementAt(0);
JavaHeapObject curr = chain.getObj();
if (curr.getRoot() != null) {
result.addElement(chain);
// Even though curr is in the rootset, we want to explore its
// referers, because they might be more interesting.
}
Enumeration<JavaThing> referers = curr.getReferers();
while (referers.hasMoreElements()) {
JavaHeapObject t = (JavaHeapObject) referers.nextElement();
if (t != null && !visited.containsKey(t)) {
if (includeWeak || !t.refersOnlyWeaklyTo(this, curr)) {
visited.put(t, t);
fifo.addElement(new ReferenceChain(t, chain));
}
}
}
}
ReferenceChain[] realResult = new ReferenceChain[result.size()];
for (int i = 0; i < result.size(); i++) {
realResult[i] = result.elementAt(i);
}
return realResult;
}
public boolean getUnresolvedObjectsOK() {
return unresolvedObjectsOK;
}
public void setUnresolvedObjectsOK(boolean v) {
unresolvedObjectsOK = v;
}
public JavaClass getWeakReferenceClass() {
return weakReferenceClass;
}
public int getReferentFieldIndex() {
return referentFieldIndex;
}
public JavaThing getNullThing() {
return nullThing;
}
public void setReachableExcludes(ReachableExcludes e) {
reachableExcludes = e;
}
public ReachableExcludes getReachableExcludes() {
return reachableExcludes;
}
// package privates
void addReferenceFromRoot(Root r, JavaHeapObject obj) {
Root root = rootsMap.get(obj);
if (root == null) {
rootsMap.put(obj, r);
} else {
rootsMap.put(obj, root.mostInteresting(r));
}
}
Root getRoot(JavaHeapObject obj) {
return rootsMap.get(obj);
}
JavaClass getJavaLangClass() {
return javaLangClass;
}
JavaClass getJavaLangString() {
return javaLangString;
}
JavaClass getJavaLangClassLoader() {
return javaLangClassLoader;
}
JavaClass getOtherArrayType() {
if (otherArrayType == null) {
synchronized(this) {
if (otherArrayType == null) {
addFakeClass(new JavaClass("[<other>", 0, 0, 0, 0,
EMPTY_FIELD_ARRAY, EMPTY_STATIC_ARRAY,
0));
otherArrayType = findClass("[<other>");
}
}
}
return otherArrayType;
}
JavaClass getArrayClass(String elementSignature) {
JavaClass clazz;
synchronized(classes) {
clazz = findClass("[" + elementSignature);
if (clazz == null) {
clazz = new JavaClass("[" + elementSignature, 0, 0, 0, 0,
EMPTY_FIELD_ARRAY, EMPTY_STATIC_ARRAY, 0);
addFakeClass(clazz);
// This is needed because the JDK only creates Class structures
// for array element types, not the arrays themselves. For
// analysis, though, we need to pretend that there's a
// JavaClass for the array type, too.
}
}
return clazz;
}
ReadBuffer getReadBuffer() {
return readBuf;
}
void setNew(JavaHeapObject obj, boolean isNew) {
initNewObjects();
if (isNew) {
newObjects.put(obj, Boolean.TRUE);
}
}
boolean isNew(JavaHeapObject obj) {
if (newObjects != null) {
return newObjects.get(obj) != null;
} else {
return false;
}
}
// Internals only below this point
private Number makeId(long id) {
if (identifierSize == 4) {
return (int)id;
} else {
return id;
}
}
private void putInClassesMap(JavaClass c) {
String name = c.getName();
if (classes.containsKey(name)) {
// more than one class can have the same name
// if so, create a unique name by appending
// - and id string to it.
name += "-" + c.getIdString();
}
classes.put(c.getName(), c);
}
private void addFakeClass(JavaClass c) {
putInClassesMap(c);
c.resolve(this);
}
private void addFakeClass(Number id, JavaClass c) {
fakeClasses.put(id, c);
addFakeClass(c);
}
private synchronized void initNewObjects() {
if (newObjects == null) {
synchronized (this) {
if (newObjects == null) {
newObjects = new HashMap<JavaHeapObject, Boolean>();
}
}
}
}
private synchronized void initSiteTraces() {
if (siteTraces == null) {
synchronized (this) {
if (siteTraces == null) {
siteTraces = new HashMap<JavaHeapObject, StackTrace>();
}
}
}
}
}

View File

@ -1,101 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
*
* @author Bill Foote
*/
/**
* Represents a stack frame.
*/
public class StackFrame {
//
// Values for the lineNumber data member. These are the same
// as the values used in the JDK 1.2 heap dump file.
//
public final static int LINE_NUMBER_UNKNOWN = -1;
public final static int LINE_NUMBER_COMPILED = -2;
public final static int LINE_NUMBER_NATIVE = -3;
private String methodName;
private String methodSignature;
private String className;
private String sourceFileName;
private int lineNumber;
public StackFrame(String methodName, String methodSignature,
String className, String sourceFileName, int lineNumber) {
this.methodName = methodName;
this.methodSignature = methodSignature;
this.className = className;
this.sourceFileName = sourceFileName;
this.lineNumber = lineNumber;
}
public void resolve(Snapshot snapshot) {
}
public String getMethodName() {
return methodName;
}
public String getMethodSignature() {
return methodSignature;
}
public String getClassName() {
return className;
}
public String getSourceFileName() {
return sourceFileName;
}
public String getLineNumber() {
switch(lineNumber) {
case LINE_NUMBER_UNKNOWN:
return "(unknown)";
case LINE_NUMBER_COMPILED:
return "(compiled method)";
case LINE_NUMBER_NATIVE:
return "(native method)";
default:
return Integer.toString(lineNumber, 10);
}
}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.model;
/**
*
* @author Bill Foote
*/
/**
* Represents a stack trace, that is, an ordered collection of stack frames.
*/
public class StackTrace {
private StackFrame[] frames;
public StackTrace(StackFrame[] frames) {
this.frames = frames;
}
/**
* @param depth. The minimum reasonable depth is 1.
*
* @return a (possibly new) StackTrace that is limited to depth.
*/
public StackTrace traceForDepth(int depth) {
if (depth >= frames.length) {
return this;
} else {
StackFrame[] f = new StackFrame[depth];
System.arraycopy(frames, 0, f, 0, depth);
return new StackTrace(f);
}
}
public void resolve(Snapshot snapshot) {
for (int i = 0; i < frames.length; i++) {
frames[i].resolve(snapshot);
}
}
public StackFrame[] getFrames() {
return frames;
}
}

View File

@ -1,311 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.oql;
import com.sun.tools.hat.internal.model.*;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
/**
* This is Object Query Language Interpreter
*
*/
public class OQLEngine {
static {
try {
// Do we have javax.script support?
// create ScriptEngineManager
Class<?> managerClass = Class.forName("javax.script.ScriptEngineManager");
Object manager = managerClass.newInstance();
// create JavaScript engine
Method getEngineMethod = managerClass.getMethod("getEngineByName",
new Class<?>[] { String.class });
Object jse = getEngineMethod.invoke(manager, new Object[] {"js"});
oqlSupported = (jse != null);
} catch (Exception exp) {
oqlSupported = false;
}
}
// check OQL is supported or not before creating OQLEngine
public static boolean isOQLSupported() {
return oqlSupported;
}
public OQLEngine(Snapshot snapshot) {
if (!isOQLSupported()) {
throw new UnsupportedOperationException("OQL not supported");
}
init(snapshot);
}
/**
Query is of the form
select &lt;java script code to select&gt;
[ from [instanceof] &lt;class name&gt; [&lt;identifier&gt;]
[ where &lt;java script boolean expression&gt; ]
]
*/
public synchronized void executeQuery(String query, ObjectVisitor visitor)
throws OQLException {
debugPrint("query : " + query);
StringTokenizer st = new StringTokenizer(query);
if (st.hasMoreTokens()) {
String first = st.nextToken();
if (! first.equals("select") ) {
// Query does not start with 'select' keyword.
// Just treat it as plain JavaScript and eval it.
try {
Object res = evalScript(query);
visitor.visit(res);
} catch (Exception e) {
throw new OQLException(e);
}
return;
}
} else {
throw new OQLException("query syntax error: no 'select' clause");
}
String selectExpr = "";
boolean seenFrom = false;
while (st.hasMoreTokens()) {
String tok = st.nextToken();
if (tok.equals("from")) {
seenFrom = true;
break;
}
selectExpr += " " + tok;
}
if (selectExpr.equals("")) {
throw new OQLException("query syntax error: 'select' expression can not be empty");
}
String className = null;
boolean isInstanceOf = false;
String whereExpr = null;
String identifier = null;
if (seenFrom) {
if (st.hasMoreTokens()) {
String tmp = st.nextToken();
if (tmp.equals("instanceof")) {
isInstanceOf = true;
if (! st.hasMoreTokens()) {
throw new OQLException("no class name after 'instanceof'");
}
className = st.nextToken();
} else {
className = tmp;
}
} else {
throw new OQLException("query syntax error: class name must follow 'from'");
}
if (st.hasMoreTokens()) {
identifier = st.nextToken();
if (identifier.equals("where")) {
throw new OQLException("query syntax error: identifier should follow class name");
}
if (st.hasMoreTokens()) {
String tmp = st.nextToken();
if (! tmp.equals("where")) {
throw new OQLException("query syntax error: 'where' clause expected after 'from' clause");
}
whereExpr = "";
while (st.hasMoreTokens()) {
whereExpr += " " + st.nextToken();
}
if (whereExpr.equals("")) {
throw new OQLException("query syntax error: 'where' clause cannot have empty expression");
}
}
} else {
throw new OQLException("query syntax error: identifier should follow class name");
}
}
executeQuery(new OQLQuery(selectExpr, isInstanceOf, className,
identifier, whereExpr), visitor);
}
private void executeQuery(OQLQuery q, ObjectVisitor visitor)
throws OQLException {
JavaClass clazz = null;
if (q.className != null) {
clazz = snapshot.findClass(q.className);
if (clazz == null) {
throw new OQLException(q.className + " is not found!");
}
}
StringBuffer buf = new StringBuffer();
buf.append("function __select__(");
if (q.identifier != null) {
buf.append(q.identifier);
}
buf.append(") { return ");
buf.append(q.selectExpr.replace('\n', ' '));
buf.append("; }");
String selectCode = buf.toString();
debugPrint(selectCode);
String whereCode = null;
if (q.whereExpr != null) {
buf = new StringBuffer();
buf.append("function __where__(");
buf.append(q.identifier);
buf.append(") { return ");
buf.append(q.whereExpr.replace('\n', ' '));
buf.append("; }");
whereCode = buf.toString();
}
debugPrint(whereCode);
// compile select expression and where condition
try {
evalMethod.invoke(engine, new Object[] { selectCode });
if (whereCode != null) {
evalMethod.invoke(engine, new Object[] { whereCode });
}
if (q.className != null) {
Enumeration<JavaHeapObject> objects = clazz.getInstances(q.isInstanceOf);
while (objects.hasMoreElements()) {
JavaHeapObject obj = objects.nextElement();
Object[] args = new Object[] { wrapJavaObject(obj) };
boolean b = (whereCode == null);
if (!b) {
Object res = call("__where__", args);
if (res instanceof Boolean) {
b = ((Boolean)res).booleanValue();
} else if (res instanceof Number) {
b = ((Number)res).intValue() != 0;
} else {
b = (res != null);
}
}
if (b) {
Object select = call("__select__", args);
if (visitor.visit(select)) return;
}
}
} else {
// simple "select <expr>" query
Object select = call("__select__", new Object[] {});
visitor.visit(select);
}
} catch (Exception e) {
throw new OQLException(e);
}
}
public Object evalScript(String script) throws Exception {
return evalMethod.invoke(engine, new Object[] { script });
}
public Object wrapJavaObject(JavaHeapObject obj) throws Exception {
return call("wrapJavaObject", new Object[] { obj });
}
public Object toHtml(Object obj) throws Exception {
return call("toHtml", new Object[] { obj });
}
public Object call(String func, Object[] args) throws Exception {
return invokeMethod.invoke(engine, new Object[] { func, args });
}
private static void debugPrint(String msg) {
if (debug) System.out.println(msg);
}
private void init(Snapshot snapshot) throws RuntimeException {
this.snapshot = snapshot;
try {
// create ScriptEngineManager
Class<?> managerClass = Class.forName("javax.script.ScriptEngineManager");
Object manager = managerClass.newInstance();
// create JavaScript engine
Method getEngineMethod = managerClass.getMethod("getEngineByName",
new Class<?>[] { String.class });
engine = getEngineMethod.invoke(manager, new Object[] {"js"});
// initialize engine with init file (hat.js)
InputStream strm = getInitStream();
Class<?> engineClass = Class.forName("javax.script.ScriptEngine");
evalMethod = engineClass.getMethod("eval",
new Class<?>[] { Reader.class });
evalMethod.invoke(engine, new Object[] {new InputStreamReader(strm)});
// initialize ScriptEngine.eval(String) and
// Invocable.invokeFunction(String, Object[]) methods.
Class<?> invocableClass = Class.forName("javax.script.Invocable");
evalMethod = engineClass.getMethod("eval",
new Class<?>[] { String.class });
invokeMethod = invocableClass.getMethod("invokeFunction",
new Class<?>[] { String.class, Object[].class });
// initialize ScriptEngine.put(String, Object) method
Method putMethod = engineClass.getMethod("put",
new Class<?>[] { String.class, Object.class });
// call ScriptEngine.put to initialize built-in heap object
putMethod.invoke(engine, new Object[] {
"heap", call("wrapHeapSnapshot", new Object[] { snapshot })
});
} catch (Exception e) {
if (debug) e.printStackTrace();
throw new RuntimeException(e);
}
}
private InputStream getInitStream() {
return getClass().getResourceAsStream("/com/sun/tools/hat/resources/hat.js");
}
private Object engine;
private Method evalMethod;
private Method invokeMethod;
private Snapshot snapshot;
private static boolean debug = false;
private static boolean oqlSupported;
}

View File

@ -1,52 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.oql;
/**
* OQLException is thrown if OQL execution results in error
*
*/
@SuppressWarnings("serial") // JDK implementation class
public class OQLException extends Exception {
public OQLException(String msg) {
super(msg);
}
public OQLException(String msg, Throwable cause) {
super(msg, cause);
}
public OQLException(Throwable cause) {
super(cause);
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.oql;
/**
* This represents a parsed OQL query
*
*/
class OQLQuery {
OQLQuery(String selectExpr, boolean isInstanceOf,
String className, String identifier, String whereExpr) {
this.selectExpr = selectExpr;
this.isInstanceOf = isInstanceOf;
this.className = className;
this.identifier = identifier;
this.whereExpr = whereExpr;
}
String selectExpr;
boolean isInstanceOf;
String className;
String identifier;
String whereExpr;
}

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.oql;
/**
* This visitor is supplied to OQLEngine.executeQuery
* to receive result set objects one by one.
*
*/
public interface ObjectVisitor {
// return true to terminate the result set callback earlier
public boolean visit(Object o);
}

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.parser;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* Implementation of ReadBuffer using a RandomAccessFile
*
* @author A. Sundararajan
*/
class FileReadBuffer implements ReadBuffer {
// underlying file to read
private RandomAccessFile file;
FileReadBuffer(RandomAccessFile file) {
this.file = file;
}
private void seek(long pos) throws IOException {
file.getChannel().position(pos);
}
public synchronized void get(long pos, byte[] buf) throws IOException {
seek(pos);
file.read(buf);
}
public synchronized char getChar(long pos) throws IOException {
seek(pos);
return file.readChar();
}
public synchronized byte getByte(long pos) throws IOException {
seek(pos);
return (byte) file.read();
}
public synchronized short getShort(long pos) throws IOException {
seek(pos);
return file.readShort();
}
public synchronized int getInt(long pos) throws IOException {
seek(pos);
return file.readInt();
}
public synchronized long getLong(long pos) throws IOException {
seek(pos);
return file.readLong();
}
}

View File

@ -1,892 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.parser;
import java.io.*;
import java.util.Date;
import java.util.Hashtable;
import com.sun.tools.hat.internal.model.ArrayTypeCodes;
import com.sun.tools.hat.internal.model.*;
/**
* Object that's used to read a hprof file.
*
* @author Bill Foote
*/
public class HprofReader extends Reader /* imports */ implements ArrayTypeCodes {
final static int MAGIC_NUMBER = 0x4a415641;
// That's "JAVA", the first part of "JAVA PROFILE ..."
private final static String[] VERSIONS = {
" PROFILE 1.0\0",
" PROFILE 1.0.1\0",
" PROFILE 1.0.2\0",
};
private final static int VERSION_JDK12BETA3 = 0;
private final static int VERSION_JDK12BETA4 = 1;
private final static int VERSION_JDK6 = 2;
// 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:
//
static final int HPROF_UTF8 = 0x01;
static final int HPROF_LOAD_CLASS = 0x02;
static final int HPROF_UNLOAD_CLASS = 0x03;
static final int HPROF_FRAME = 0x04;
static final int HPROF_TRACE = 0x05;
static final int HPROF_ALLOC_SITES = 0x06;
static final int HPROF_HEAP_SUMMARY = 0x07;
static final int HPROF_START_THREAD = 0x0a;
static final int HPROF_END_THREAD = 0x0b;
static final int HPROF_HEAP_DUMP = 0x0c;
static final int HPROF_CPU_SAMPLES = 0x0d;
static final int HPROF_CONTROL_SETTINGS = 0x0e;
static final int HPROF_LOCKSTATS_WAIT_TIME = 0x10;
static final int HPROF_LOCKSTATS_HOLD_TIME = 0x11;
static final int HPROF_GC_ROOT_UNKNOWN = 0xff;
static final int HPROF_GC_ROOT_JNI_GLOBAL = 0x01;
static final int HPROF_GC_ROOT_JNI_LOCAL = 0x02;
static final int HPROF_GC_ROOT_JAVA_FRAME = 0x03;
static final int HPROF_GC_ROOT_NATIVE_STACK = 0x04;
static final int HPROF_GC_ROOT_STICKY_CLASS = 0x05;
static final int HPROF_GC_ROOT_THREAD_BLOCK = 0x06;
static final int HPROF_GC_ROOT_MONITOR_USED = 0x07;
static final int HPROF_GC_ROOT_THREAD_OBJ = 0x08;
static final int HPROF_GC_CLASS_DUMP = 0x20;
static final int HPROF_GC_INSTANCE_DUMP = 0x21;
static final int HPROF_GC_OBJ_ARRAY_DUMP = 0x22;
static final int HPROF_GC_PRIM_ARRAY_DUMP = 0x23;
static final int HPROF_HEAP_DUMP_SEGMENT = 0x1c;
static final int HPROF_HEAP_DUMP_END = 0x2c;
private final static int T_CLASS = 2;
private int version; // The version of .hprof being read
private int debugLevel;
private long currPos; // Current position in the file
private int dumpsToSkip;
private boolean callStack; // If true, read the call stack of objects
private int identifierSize; // Size, in bytes, of identifiers.
private Hashtable<Long, String> names;
// 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.
private Hashtable<Integer, ThreadObject> threadObjects;
// Hashtable<Long, String>, maps class object ID to class name
// (with / converted to .)
private Hashtable<Long, String> classNameFromObjectID;
// Hashtable<Integer, Integer>, maps class serial # to class object ID
private Hashtable<Integer, String> classNameFromSerialNo;
// Hashtable<Long, StackFrame> maps stack frame ID to StackFrame.
// Null if we're not tracking them.
private Hashtable<Long, StackFrame> stackFrames;
// Hashtable<Integer, StackTrace> maps stack frame ID to StackTrace
// Null if we're not tracking them.
private Hashtable<Integer, StackTrace> stackTraces;
private Snapshot snapshot;
public HprofReader(String fileName, PositionDataInputStream in,
int dumpNumber, boolean callStack, int debugLevel)
throws IOException {
super(in);
RandomAccessFile file = new RandomAccessFile(fileName, "r");
this.snapshot = new Snapshot(MappedReadBuffer.create(file));
this.dumpsToSkip = dumpNumber - 1;
this.callStack = callStack;
this.debugLevel = debugLevel;
names = new Hashtable<Long, String>();
threadObjects = new Hashtable<Integer, ThreadObject>(43);
classNameFromObjectID = new Hashtable<Long, String>();
if (callStack) {
stackFrames = new Hashtable<Long, StackFrame>(43);
stackTraces = new Hashtable<Integer, StackTrace>(43);
classNameFromSerialNo = new Hashtable<Integer, String>();
}
}
public Snapshot read() throws IOException {
currPos = 4; // 4 because of the magic number
version = readVersionHeader();
identifierSize = in.readInt();
snapshot.setIdentifierSize(identifierSize);
if (version >= VERSION_JDK12BETA4) {
snapshot.setNewStyleArrayClass(true);
} else {
snapshot.setNewStyleArrayClass(false);
}
currPos += 4;
if (identifierSize != 4 && identifierSize != 8) {
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.");
}
System.out.println("Dump file created " + (new Date(in.readLong())));
currPos += 8;
for (;;) {
int type;
try {
type = in.readUnsignedByte();
} catch (EOFException ignored) {
break;
}
in.readInt(); // Timestamp of this record
// Length of record: readInt() will return negative value for record
// length >2GB. so store 32bit value in long to keep it unsigned.
long length = in.readInt() & 0xffffffffL;
if (debugLevel > 0) {
System.out.println("Read record type " + type
+ ", length " + length
+ " at position " + toHex(currPos));
}
if (length < 0) {
throw new IOException("Bad record length of " + length
+ " at byte " + toHex(currPos+5)
+ " of file.");
}
currPos += 9 + length;
switch (type) {
case HPROF_UTF8: {
long id = readID();
byte[] chars = new byte[(int)length - identifierSize];
in.readFully(chars);
names.put(id, new String(chars));
break;
}
case HPROF_LOAD_CLASS: {
int serialNo = in.readInt(); // Not used
long classID = readID();
int stackTraceSerialNo = in.readInt();
long classNameID = readID();
Long classIdI = classID;
String nm = getNameFromID(classNameID).replace('/', '.');
classNameFromObjectID.put(classIdI, nm);
if (classNameFromSerialNo != null) {
classNameFromSerialNo.put(serialNo, nm);
}
break;
}
case HPROF_HEAP_DUMP: {
if (dumpsToSkip <= 0) {
try {
readHeapDump(length, currPos);
} catch (EOFException exp) {
handleEOF(exp, snapshot);
}
if (debugLevel > 0) {
System.out.println(" Finished processing instances in heap dump.");
}
return snapshot;
} else {
dumpsToSkip--;
skipBytes(length);
}
break;
}
case HPROF_HEAP_DUMP_END: {
if (version >= VERSION_JDK6) {
if (dumpsToSkip <= 0) {
skipBytes(length); // should be no-op
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
warn("Ignoring unrecognized record type " + type);
}
skipBytes(length); // should be no-op
break;
}
case HPROF_HEAP_DUMP_SEGMENT: {
if (version >= VERSION_JDK6) {
if (dumpsToSkip <= 0) {
try {
// read the dump segment
readHeapDump(length, currPos);
} catch (EOFException exp) {
handleEOF(exp, snapshot);
}
} else {
// all segments comprising the heap dump will be skipped
skipBytes(length);
}
} else {
// HPROF_HEAP_DUMP_SEGMENT only recognized in >= 1.0.2
warn("Ignoring unrecognized record type " + type);
skipBytes(length);
}
break;
}
case HPROF_FRAME: {
if (stackFrames == null) {
skipBytes(length);
} else {
long id = readID();
String methodName = getNameFromID(readID());
String methodSig = getNameFromID(readID());
String sourceFile = getNameFromID(readID());
int classSer = in.readInt();
String className = classNameFromSerialNo.get(classSer);
int lineNumber = in.readInt();
if (lineNumber < StackFrame.LINE_NUMBER_NATIVE) {
warn("Weird stack frame line number: " + lineNumber);
lineNumber = StackFrame.LINE_NUMBER_UNKNOWN;
}
stackFrames.put(id,
new StackFrame(methodName, methodSig,
className, sourceFile,
lineNumber));
}
break;
}
case HPROF_TRACE: {
if (stackTraces == null) {
skipBytes(length);
} else {
int serialNo = in.readInt();
int threadSeq = in.readInt(); // Not used
StackFrame[] frames = new StackFrame[in.readInt()];
for (int i = 0; i < frames.length; i++) {
long fid = readID();
frames[i] = stackFrames.get(fid);
if (frames[i] == null) {
throw new IOException("Stack frame " + toHex(fid) + " not found");
}
}
stackTraces.put(serialNo,
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:
case HPROF_LOCKSTATS_WAIT_TIME:
case HPROF_LOCKSTATS_HOLD_TIME:
{
// Ignore these record types
skipBytes(length);
break;
}
default: {
skipBytes(length);
warn("Ignoring unrecognized record type " + type);
}
}
}
return snapshot;
}
private void skipBytes(long length) throws IOException {
in.skipBytes((int)length);
}
private int readVersionHeader() throws IOException {
int candidatesLeft = VERSIONS.length;
boolean[] matched = new boolean[VERSIONS.length];
for (int i = 0; i < candidatesLeft; i++) {
matched[i] = true;
}
int pos = 0;
while (candidatesLeft > 0) {
char c = (char) in.readByte();
currPos++;
for (int i = 0; i < VERSIONS.length; i++) {
if (matched[i]) {
if (c != VERSIONS[i].charAt(pos)) { // Not matched
matched[i] = false;
--candidatesLeft;
} else if (pos == VERSIONS[i].length() - 1) { // Full match
return i;
}
}
}
++pos;
}
throw new IOException("Version string not recognized at byte " + (pos+3));
}
private void readHeapDump(long bytesLeft, long posAtEnd) throws IOException {
while (bytesLeft > 0) {
int type = in.readUnsignedByte();
if (debugLevel > 0) {
System.out.println(" Read heap sub-record type " + type
+ " at position "
+ toHex(posAtEnd - bytesLeft));
}
bytesLeft--;
switch(type) {
case HPROF_GC_ROOT_UNKNOWN: {
long id = readID();
bytesLeft -= identifierSize;
snapshot.addRoot(new Root(id, 0, Root.UNKNOWN, ""));
break;
}
case HPROF_GC_ROOT_THREAD_OBJ: {
long id = readID();
int threadSeq = in.readInt();
int stackSeq = in.readInt();
bytesLeft -= identifierSize + 8;
threadObjects.put(threadSeq,
new ThreadObject(id, stackSeq));
break;
}
case HPROF_GC_ROOT_JNI_GLOBAL: {
long id = readID();
long globalRefId = readID(); // Ignored, for now
bytesLeft -= 2*identifierSize;
snapshot.addRoot(new Root(id, 0, Root.NATIVE_STATIC, ""));
break;
}
case HPROF_GC_ROOT_JNI_LOCAL: {
long id = readID();
int threadSeq = in.readInt();
int depth = in.readInt();
bytesLeft -= identifierSize + 8;
ThreadObject to = getThreadObjectFromSequence(threadSeq);
StackTrace st = getStackTraceFromSerial(to.stackSeq);
if (st != null) {
st = st.traceForDepth(depth+1);
}
snapshot.addRoot(new Root(id, to.threadId,
Root.NATIVE_LOCAL, "", st));
break;
}
case HPROF_GC_ROOT_JAVA_FRAME: {
long id = readID();
int threadSeq = in.readInt();
int depth = in.readInt();
bytesLeft -= identifierSize + 8;
ThreadObject to = getThreadObjectFromSequence(threadSeq);
StackTrace st = getStackTraceFromSerial(to.stackSeq);
if (st != null) {
st = st.traceForDepth(depth+1);
}
snapshot.addRoot(new Root(id, to.threadId,
Root.JAVA_LOCAL, "", st));
break;
}
case HPROF_GC_ROOT_NATIVE_STACK: {
long id = readID();
int threadSeq = in.readInt();
bytesLeft -= identifierSize + 4;
ThreadObject to = getThreadObjectFromSequence(threadSeq);
StackTrace st = getStackTraceFromSerial(to.stackSeq);
snapshot.addRoot(new Root(id, to.threadId,
Root.NATIVE_STACK, "", st));
break;
}
case HPROF_GC_ROOT_STICKY_CLASS: {
long id = readID();
bytesLeft -= identifierSize;
snapshot.addRoot(new Root(id, 0, Root.SYSTEM_CLASS, ""));
break;
}
case HPROF_GC_ROOT_THREAD_BLOCK: {
long id = readID();
int threadSeq = in.readInt();
bytesLeft -= identifierSize + 4;
ThreadObject to = getThreadObjectFromSequence(threadSeq);
StackTrace st = getStackTraceFromSerial(to.stackSeq);
snapshot.addRoot(new Root(id, to.threadId,
Root.THREAD_BLOCK, "", st));
break;
}
case HPROF_GC_ROOT_MONITOR_USED: {
long id = readID();
bytesLeft -= identifierSize;
snapshot.addRoot(new Root(id, 0, Root.BUSY_MONITOR, ""));
break;
}
case HPROF_GC_CLASS_DUMP: {
int bytesRead = readClass();
bytesLeft -= bytesRead;
break;
}
case HPROF_GC_INSTANCE_DUMP: {
int bytesRead = readInstance();
bytesLeft -= bytesRead;
break;
}
case HPROF_GC_OBJ_ARRAY_DUMP: {
int bytesRead = readArray(false);
bytesLeft -= bytesRead;
break;
}
case HPROF_GC_PRIM_ARRAY_DUMP: {
int bytesRead = readArray(true);
bytesLeft -= bytesRead;
break;
}
default: {
throw new IOException("Unrecognized heap dump sub-record type: " + type);
}
}
}
if (bytesLeft != 0) {
warn("Error reading heap dump or heap dump segment: Byte count is " + bytesLeft + " instead of 0");
skipBytes(bytesLeft);
}
if (debugLevel > 0) {
System.out.println(" Finished heap sub-records.");
}
}
private long readID() throws IOException {
return (identifierSize == 4)?
(Snapshot.SMALL_ID_MASK & (long)in.readInt()) : in.readLong();
}
//
// 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
//
private int readValue(JavaThing[] resultArr) throws IOException {
byte type = in.readByte();
return 1 + readValueForType(type, resultArr);
}
private int readValueForType(byte type, JavaThing[] resultArr)
throws IOException {
if (version >= VERSION_JDK12BETA4) {
type = signatureFromTypeId(type);
}
return readValueForTypeSignature(type, resultArr);
}
private int readValueForTypeSignature(byte type, JavaThing[] resultArr)
throws IOException {
switch (type) {
case '[':
case 'L': {
long id = readID();
if (resultArr != null) {
resultArr[0] = new JavaObjectRef(id);
}
return identifierSize;
}
case 'Z': {
int b = in.readByte();
if (b != 0 && b != 1) {
warn("Illegal boolean value read");
}
if (resultArr != null) {
resultArr[0] = new JavaBoolean(b != 0);
}
return 1;
}
case 'B': {
byte b = in.readByte();
if (resultArr != null) {
resultArr[0] = new JavaByte(b);
}
return 1;
}
case 'S': {
short s = in.readShort();
if (resultArr != null) {
resultArr[0] = new JavaShort(s);
}
return 2;
}
case 'C': {
char ch = in.readChar();
if (resultArr != null) {
resultArr[0] = new JavaChar(ch);
}
return 2;
}
case 'I': {
int val = in.readInt();
if (resultArr != null) {
resultArr[0] = new JavaInt(val);
}
return 4;
}
case 'J': {
long val = in.readLong();
if (resultArr != null) {
resultArr[0] = new JavaLong(val);
}
return 8;
}
case 'F': {
float val = in.readFloat();
if (resultArr != null) {
resultArr[0] = new JavaFloat(val);
}
return 4;
}
case 'D': {
double val = in.readDouble();
if (resultArr != null) {
resultArr[0] = new JavaDouble(val);
}
return 8;
}
default: {
throw new IOException("Bad value signature: " + type);
}
}
}
private ThreadObject getThreadObjectFromSequence(int threadSeq)
throws IOException {
ThreadObject to = threadObjects.get(threadSeq);
if (to == null) {
throw new IOException("Thread " + threadSeq +
" not found for JNI local ref");
}
return to;
}
private String getNameFromID(long id) throws IOException {
return getNameFromID(Long.valueOf(id));
}
private String getNameFromID(Long id) throws IOException {
if (id.longValue() == 0L) {
return "";
}
String result = names.get(id);
if (result == null) {
warn("Name not found at " + toHex(id.longValue()));
return "unresolved name " + toHex(id.longValue());
}
return result;
}
private StackTrace getStackTraceFromSerial(int ser) throws IOException {
if (stackTraces == null) {
return null;
}
StackTrace result = stackTraces.get(ser);
if (result == null) {
warn("Stack trace not found for serial # " + ser);
}
return result;
}
//
// Handle a HPROF_GC_CLASS_DUMP
// Return number of bytes read
//
private int readClass() throws IOException {
long id = readID();
StackTrace stackTrace = getStackTraceFromSerial(in.readInt());
long superId = readID();
long classLoaderId = readID();
long signersId = readID();
long protDomainId = readID();
long reserved1 = readID();
long reserved2 = readID();
int instanceSize = in.readInt();
int bytesRead = 7 * identifierSize + 8;
int numConstPoolEntries = in.readUnsignedShort();
bytesRead += 2;
for (int i = 0; i < numConstPoolEntries; i++) {
int index = in.readUnsignedShort(); // unused
bytesRead += 2;
bytesRead += readValue(null); // We ignore the values
}
int numStatics = in.readUnsignedShort();
bytesRead += 2;
JavaThing[] valueBin = new JavaThing[1];
JavaStatic[] statics = new JavaStatic[numStatics];
for (int i = 0; i < numStatics; i++) {
long nameId = readID();
bytesRead += identifierSize;
byte type = in.readByte();
bytesRead++;
bytesRead += readValueForType(type, valueBin);
String fieldName = getNameFromID(nameId);
if (version >= VERSION_JDK12BETA4) {
type = signatureFromTypeId(type);
}
String signature = "" + ((char) type);
JavaField f = new JavaField(fieldName, signature);
statics[i] = new JavaStatic(f, valueBin[0]);
}
int numFields = in.readUnsignedShort();
bytesRead += 2;
JavaField[] fields = new JavaField[numFields];
for (int i = 0; i < numFields; i++) {
long nameId = readID();
bytesRead += identifierSize;
byte type = in.readByte();
bytesRead++;
String fieldName = getNameFromID(nameId);
if (version >= VERSION_JDK12BETA4) {
type = signatureFromTypeId(type);
}
String signature = "" + ((char) type);
fields[i] = new JavaField(fieldName, signature);
}
String name = classNameFromObjectID.get(id);
if (name == null) {
warn("Class name not found for " + toHex(id));
name = "unknown-name@" + toHex(id);
}
JavaClass c = new JavaClass(id, name, superId, classLoaderId, signersId,
protDomainId, fields, statics,
instanceSize);
snapshot.addClass(id, c);
snapshot.setSiteTrace(c, stackTrace);
return bytesRead;
}
private String toHex(long addr) {
return com.sun.tools.hat.internal.util.Misc.toHex(addr);
}
//
// Handle a HPROF_GC_INSTANCE_DUMP
// Return number of bytes read
//
private int readInstance() throws IOException {
long start = in.position();
long id = readID();
StackTrace stackTrace = getStackTraceFromSerial(in.readInt());
long classID = readID();
int bytesFollowing = in.readInt();
int bytesRead = (2 * identifierSize) + 8 + bytesFollowing;
JavaObject jobj = new JavaObject(classID, start);
skipBytes(bytesFollowing);
snapshot.addHeapObject(id, jobj);
snapshot.setSiteTrace(jobj, stackTrace);
return bytesRead;
}
//
// Handle a HPROF_GC_OBJ_ARRAY_DUMP or HPROF_GC_PRIM_ARRAY_DUMP
// Return number of bytes read
//
private int readArray(boolean isPrimitive) throws IOException {
long start = in.position();
long id = readID();
StackTrace stackTrace = getStackTraceFromSerial(in.readInt());
int num = in.readInt();
int bytesRead = identifierSize + 8;
long elementClassID;
if (isPrimitive) {
elementClassID = in.readByte();
bytesRead++;
} else {
elementClassID = readID();
bytesRead += identifierSize;
}
// Check for primitive arrays:
byte primitiveSignature = 0x00;
int elSize = 0;
if (isPrimitive || version < VERSION_JDK12BETA4) {
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;
}
}
if (version >= VERSION_JDK12BETA4 && primitiveSignature == 0x00) {
throw new IOException("Unrecognized typecode: "
+ elementClassID);
}
}
if (primitiveSignature != 0x00) {
int size = elSize * num;
bytesRead += size;
JavaValueArray va = new JavaValueArray(primitiveSignature, start);
skipBytes(size);
snapshot.addHeapObject(id, va);
snapshot.setSiteTrace(va, stackTrace);
} else {
int sz = num * identifierSize;
bytesRead += sz;
JavaObjectArray arr = new JavaObjectArray(elementClassID, start);
skipBytes(sz);
snapshot.addHeapObject(id, arr);
snapshot.setSiteTrace(arr, stackTrace);
}
return bytesRead;
}
private byte signatureFromTypeId(byte typeId) throws IOException {
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: {
throw new IOException("Invalid type id of " + typeId);
}
}
}
private void handleEOF(EOFException exp, Snapshot snapshot) {
if (debugLevel > 0) {
exp.printStackTrace();
}
warn("Unexpected EOF. Will miss information...");
// we have EOF, we have to tolerate missing references
snapshot.setUnresolvedObjectsOK(true);
}
private void warn(String msg) {
System.out.println("WARNING: " + msg);
}
//
// A trivial data-holder class for HPROF_GC_ROOT_THREAD_OBJ.
//
private class ThreadObject {
long threadId;
int stackSeq;
ThreadObject(long threadId, int stackSeq) {
this.threadId = threadId;
this.stackSeq = stackSeq;
}
}
}

View File

@ -1,114 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.parser;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
/**
* Implementation of ReadBuffer using mapped file buffer
*
* @author A. Sundararajan
*/
class MappedReadBuffer implements ReadBuffer {
private MappedByteBuffer buf;
MappedReadBuffer(MappedByteBuffer buf) {
this.buf = buf;
}
// factory method to create correct ReadBuffer for a given file
static ReadBuffer create(RandomAccessFile file) throws IOException {
FileChannel ch = file.getChannel();
long size = ch.size();
// if file size is more than 2 GB and when file mapping is
// configured (default), use mapped file reader
if (canUseFileMap() && (size <= Integer.MAX_VALUE)) {
MappedByteBuffer buf;
try {
buf = ch.map(FileChannel.MapMode.READ_ONLY, 0, size);
ch.close();
return new MappedReadBuffer(buf);
} catch (IOException exp) {
exp.printStackTrace();
System.err.println("File mapping failed, will use direct read");
// fall through
}
} // else fall through
return new FileReadBuffer(file);
}
private static boolean canUseFileMap() {
// set jhat.disableFileMap to any value other than "false"
// to disable file mapping
String prop = System.getProperty("jhat.disableFileMap");
return prop == null || prop.equals("false");
}
private void seek(long pos) throws IOException {
assert pos <= Integer.MAX_VALUE : "position overflow";
buf.position((int)pos);
}
public synchronized void get(long pos, byte[] res) throws IOException {
seek(pos);
buf.get(res);
}
public synchronized char getChar(long pos) throws IOException {
seek(pos);
return buf.getChar();
}
public synchronized byte getByte(long pos) throws IOException {
seek(pos);
return buf.get();
}
public synchronized short getShort(long pos) throws IOException {
seek(pos);
return buf.getShort();
}
public synchronized int getInt(long pos) throws IOException {
seek(pos);
return buf.getInt();
}
public synchronized long getLong(long pos) throws IOException {
seek(pos);
return buf.getLong();
}
}

View File

@ -1,64 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.parser;
import java.io.DataInputStream;
import java.io.InputStream;
/**
* A DataInputStream that keeps track of total bytes read
* (in effect 'position' in stream) so far.
*
*/
public class PositionDataInputStream extends DataInputStream {
public PositionDataInputStream(InputStream in) {
super(in instanceof PositionInputStream?
in : new PositionInputStream(in));
}
public boolean markSupported() {
return false;
}
public void mark(int readLimit) {
throw new UnsupportedOperationException("mark");
}
public void reset() {
throw new UnsupportedOperationException("reset");
}
public long position() {
return ((PositionInputStream)in).position();
}
}

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.parser;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* InputStream that keeps track of total bytes read (in effect
* 'position' in stream) from the input stream.
*
*/
public class PositionInputStream extends FilterInputStream {
private long position = 0L;
public PositionInputStream(InputStream in) {
super(in);
}
public int read() throws IOException {
int res = super.read();
if (res != -1) position++;
return res;
}
public int read(byte[] b, int off, int len) throws IOException {
int res = super.read(b, off, len);
if (res != -1) position += res;
return res;
}
public long skip(long n) throws IOException {
long res = super.skip(n);
position += res;
return res;
}
public boolean markSupported() {
return false;
}
public void mark(int readLimit) {
throw new UnsupportedOperationException("mark");
}
public void reset() {
throw new UnsupportedOperationException("reset");
}
public long position() {
return position;
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.parser;
import java.io.IOException;
/**
* Positionable read only buffer
*
* @author A. Sundararajan
*/
public interface ReadBuffer {
// read methods - only byte array and int primitive types.
// read position has to be specified always.
public void get(long pos, byte[] buf) throws IOException;
public char getChar(long pos) throws IOException;
public byte getByte(long pos) throws IOException;
public short getShort(long pos) throws IOException;
public int getInt(long pos) throws IOException;
public long getLong(long pos) throws IOException;
}

View File

@ -1,100 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.parser;
import java.io.*;
import com.sun.tools.hat.internal.model.*;
/**
* Abstract base class for reading object dump files. A reader need not be
* thread-safe.
*
* @author Bill Foote
*/
public abstract class Reader {
protected PositionDataInputStream in;
protected Reader(PositionDataInputStream in) {
this.in = in;
}
/**
* Read a snapshot from a data input stream. It is assumed that the magic
* number has already been read.
*/
abstract public Snapshot read() throws IOException;
/**
* Read a snapshot from a file.
*
* @param heapFile The name of a file containing a heap dump
* @param callStack If true, read the call stack of allocaation sites
*/
public static Snapshot readFile(String heapFile, boolean callStack,
int debugLevel)
throws IOException {
int dumpNumber = 1;
int pos = heapFile.lastIndexOf('#');
if (pos > -1) {
String num = heapFile.substring(pos+1, heapFile.length());
try {
dumpNumber = Integer.parseInt(num, 10);
} catch (java.lang.NumberFormatException ex) {
String msg = "In file name \"" + heapFile
+ "\", a dump number was "
+ "expected after the :, but \""
+ num + "\" was found instead.";
System.err.println(msg);
throw new IOException(msg);
}
heapFile = heapFile.substring(0, pos);
}
PositionDataInputStream in = new PositionDataInputStream(
new BufferedInputStream(new FileInputStream(heapFile)));
try {
int i = in.readInt();
if (i == HprofReader.MAGIC_NUMBER) {
Reader r
= new HprofReader(heapFile, in, dumpNumber,
callStack, debugLevel);
return r.read();
} else {
throw new IOException("Unrecognized magic number: " + i);
}
} finally {
in.close();
}
}
}

View File

@ -1,150 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
import java.util.Iterator;
/**
*
* @author Bill Foote
*/
class AllClassesQuery extends QueryHandler {
boolean excludePlatform;
boolean oqlSupported;
public AllClassesQuery(boolean excludePlatform, boolean oqlSupported) {
this.excludePlatform = excludePlatform;
this.oqlSupported = oqlSupported;
}
public void run() {
if (excludePlatform) {
startHtml("All Classes (excluding platform)");
} else {
startHtml("All Classes (including platform)");
}
Iterator<JavaClass> classes = snapshot.getClasses();
String lastPackage = null;
while (classes.hasNext()) {
JavaClass clazz = classes.next();
if (excludePlatform && PlatformClasses.isPlatformClass(clazz)) {
// skip this..
continue;
}
String name = clazz.getName();
int pos = name.lastIndexOf('.');
String pkg;
if (name.startsWith("[")) { // Only in ancient heap dumps
pkg = "<Arrays>";
} else if (pos == -1) {
pkg = "<Default Package>";
} else {
pkg = name.substring(0, pos);
}
if (!pkg.equals(lastPackage)) {
out.print("<h2>Package ");
print(pkg);
out.println("</h2>");
}
lastPackage = pkg;
printClass(clazz);
if (clazz.getId() != -1) {
print(" [" + clazz.getIdString() + "]");
}
out.println("<br>");
}
out.println("<h2>Other Queries</h2>");
out.println("<ul>");
out.println("<li>");
printAnchorStart();
if (excludePlatform) {
out.print("allClassesWithPlatform/\">");
print("All classes including platform");
} else {
out.print("\">");
print("All classes excluding platform");
}
out.println("</a>");
out.println("<li>");
printAnchorStart();
out.print("showRoots/\">");
print("Show all members of the rootset");
out.println("</a>");
out.println("<li>");
printAnchorStart();
out.print("showInstanceCounts/includePlatform/\">");
print("Show instance counts for all classes (including platform)");
out.println("</a>");
out.println("<li>");
printAnchorStart();
out.print("showInstanceCounts/\">");
print("Show instance counts for all classes (excluding platform)");
out.println("</a>");
out.println("<li>");
printAnchorStart();
out.print("histo/\">");
print("Show heap histogram");
out.println("</a>");
out.println("<li>");
printAnchorStart();
out.print("finalizerSummary/\">");
print("Show finalizer summary");
out.println("</a>");
if (oqlSupported) {
out.println("<li>");
printAnchorStart();
out.print("oql/\">");
print("Execute Object Query Language (OQL) query");
out.println("</a>");
}
out.println("</ul>");
endHtml();
}
}

View File

@ -1,108 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import java.util.Vector;
import com.sun.tools.hat.internal.model.*;
import com.sun.tools.hat.internal.util.ArraySorter;
import com.sun.tools.hat.internal.util.Comparer;
/**
*
* @author Bill Foote
*/
class AllRootsQuery extends QueryHandler {
public AllRootsQuery() {
}
public void run() {
startHtml("All Members of the Rootset");
Root[] roots = snapshot.getRootsArray();
ArraySorter.sort(roots, new Comparer() {
public int compare(Object lhs, Object rhs) {
Root left = (Root) lhs;
Root right = (Root) rhs;
int d = left.getType() - right.getType();
if (d != 0) {
return -d; // More interesting values are *higher*
}
return left.getDescription().compareTo(right.getDescription());
}
});
int lastType = Root.INVALID_TYPE;
for (int i= 0; i < roots.length; i++) {
Root root = roots[i];
if (root.getType() != lastType) {
lastType = root.getType();
out.print("<h2>");
print(root.getTypeName() + " References");
out.println("</h2>");
}
printRoot(root);
if (root.getReferer() != null) {
out.print("<small> (from ");
printThingAnchorTag(root.getReferer().getId());
print(root.getReferer().toString());
out.print(")</a></small>");
}
out.print(" :<br>");
JavaThing t = snapshot.findThing(root.getId());
if (t != null) { // It should always be
print("--> ");
printThing(t);
out.println("<br>");
}
}
out.println("<h2>Other Queries</h2>");
out.println("<ul>");
out.println("<li>");
printAnchorStart();
out.print("\">");
print("Show All Classes");
out.println("</a>");
out.println("</ul>");
endHtml();
}
}

View File

@ -1,190 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
import com.sun.tools.hat.internal.util.ArraySorter;
import com.sun.tools.hat.internal.util.Comparer;
import java.util.Enumeration;
/**
*
* @author Bill Foote
*/
class ClassQuery extends QueryHandler {
public ClassQuery() {
}
public void run() {
startHtml("Class " + query);
JavaClass clazz = snapshot.findClass(query);
if (clazz == null) {
error("class not found: " + query);
} else {
printFullClass(clazz);
}
endHtml();
}
protected void printFullClass(JavaClass clazz) {
out.print("<h1>");
print(clazz.toString());
out.println("</h1>");
out.println("<h2>Superclass:</h2>");
printClass(clazz.getSuperclass());
out.println("<h2>Loader Details</h2>");
out.println("<h3>ClassLoader:</h3>");
printThing(clazz.getLoader());
out.println("<h3>Signers:</h3>");
printThing(clazz.getSigners());
out.println("<h3>Protection Domain:</h3>");
printThing(clazz.getProtectionDomain());
out.println("<h2>Subclasses:</h2>");
JavaClass[] sc = clazz.getSubclasses();
for (int i = 0; i < sc.length; i++) {
out.print(" ");
printClass(sc[i]);
out.println("<br>");
}
out.println("<h2>Instance Data Members:</h2>");
JavaField[] ff = clazz.getFields().clone();
ArraySorter.sort(ff, new Comparer() {
public int compare(Object lhs, Object rhs) {
JavaField left = (JavaField) lhs;
JavaField right = (JavaField) rhs;
return left.getName().compareTo(right.getName());
}
});
for (int i = 0; i < ff.length; i++) {
out.print(" ");
printField(ff[i]);
out.println("<br>");
}
out.println("<h2>Static Data Members:</h2>");
JavaStatic[] ss = clazz.getStatics();
for (int i = 0; i < ss.length; i++) {
printStatic(ss[i]);
out.println("<br>");
}
out.println("<h2>Instances</h2>");
printAnchorStart();
print("instances/" + encodeForURL(clazz));
out.print("\">");
out.println("Exclude subclasses</a><br>");
printAnchorStart();
print("allInstances/" + encodeForURL(clazz));
out.print("\">");
out.println("Include subclasses</a><br>");
if (snapshot.getHasNewSet()) {
out.println("<h2>New Instances</h2>");
printAnchorStart();
print("newInstances/" + encodeForURL(clazz));
out.print("\">");
out.println("Exclude subclasses</a><br>");
printAnchorStart();
print("allNewInstances/" + encodeForURL(clazz));
out.print("\">");
out.println("Include subclasses</a><br>");
}
out.println("<h2>References summary by Type</h2>");
printAnchorStart();
print("refsByType/" + encodeForURL(clazz));
out.print("\">");
out.println("References summary by type</a>");
printReferencesTo(clazz);
}
protected void printReferencesTo(JavaHeapObject obj) {
if (obj.getId() == -1) {
return;
}
out.println("<h2>References to this object:</h2>");
out.flush();
Enumeration<JavaThing> referers = obj.getReferers();
while (referers.hasMoreElements()) {
JavaHeapObject ref = (JavaHeapObject) referers.nextElement();
printThing(ref);
print (" : " + ref.describeReferenceTo(obj, snapshot));
// If there are more than one references, this only gets the
// first one.
out.println("<br>");
}
out.println("<h2>Other Queries</h2>");
out.println("Reference Chains from Rootset");
long id = obj.getId();
out.print("<ul><li>");
printAnchorStart();
out.print("roots/");
printHex(id);
out.print("\">");
out.println("Exclude weak refs</a>");
out.print("<li>");
printAnchorStart();
out.print("allRoots/");
printHex(id);
out.print("\">");
out.println("Include weak refs</a></ul>");
printAnchorStart();
out.print("reachableFrom/");
printHex(id);
out.print("\">");
out.println("Objects reachable from here</a><br>");
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
import java.util.*;
public class FinalizerObjectsQuery extends QueryHandler {
public void run() {
Enumeration<?> objs = snapshot.getFinalizerObjects();
startHtml("Objects pending finalization");
out.println("<a href='/finalizerSummary/'>Finalizer summary</a>");
out.println("<h1>Objects pending finalization</h1>");
while (objs.hasMoreElements()) {
printThing((JavaHeapObject)objs.nextElement());
out.println("<br>");
}
endHtml();
}
}

View File

@ -1,128 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
import java.util.*;
public class FinalizerSummaryQuery extends QueryHandler {
public void run() {
Enumeration<?> objs = snapshot.getFinalizerObjects();
startHtml("Finalizer Summary");
out.println("<p align='center'>");
out.println("<b><a href='/'>All Classes (excluding platform)</a></b>");
out.println("</p>");
printFinalizerSummary(objs);
endHtml();
}
private static class HistogramElement {
public HistogramElement(JavaClass clazz) {
this.clazz = clazz;
}
public void updateCount() {
this.count++;
}
public int compare(HistogramElement other) {
long diff = other.count - count;
return (diff == 0L)? 0 : ((diff > 0L)? +1 : -1);
}
public JavaClass getClazz() {
return clazz;
}
public long getCount() {
return count;
}
private JavaClass clazz;
private long count;
}
private void printFinalizerSummary(Enumeration<?> objs) {
int count = 0;
Map<JavaClass, HistogramElement> map = new HashMap<JavaClass, HistogramElement>();
while (objs.hasMoreElements()) {
JavaHeapObject obj = (JavaHeapObject) objs.nextElement();
count++;
JavaClass clazz = obj.getClazz();
if (! map.containsKey(clazz)) {
map.put(clazz, new HistogramElement(clazz));
}
HistogramElement element = map.get(clazz);
element.updateCount();
}
out.println("<p align='center'>");
out.println("<b>");
out.println("Total ");
if (count != 0) {
out.print("<a href='/finalizerObjects/'>instances</a>");
} else {
out.print("instances");
}
out.println(" pending finalization: ");
out.print(count);
out.println("</b></p><hr>");
if (count == 0) {
return;
}
// calculate and print histogram
HistogramElement[] elements = new HistogramElement[map.size()];
map.values().toArray(elements);
Arrays.sort(elements, new Comparator<HistogramElement>() {
public int compare(HistogramElement o1, HistogramElement o2) {
return o1.compare(o2);
}
});
out.println("<table border=1 align=center>");
out.println("<tr><th>Count</th><th>Class</th></tr>");
for (int j = 0; j < elements.length; j++) {
out.println("<tr><td>");
out.println(elements[j].getCount());
out.println("</td><td>");
printClass(elements[j].getClazz());
out.println("</td><tr>");
}
out.println("</table>");
}
}

View File

@ -1,99 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.JavaClass;
import java.util.Arrays;
import java.util.Comparator;
/**
* Prints histogram sortable by class name, count and size.
*
*/
public class HistogramQuery extends QueryHandler {
public void run() {
JavaClass[] classes = snapshot.getClassesArray();
Comparator<JavaClass> comparator;
if (query.equals("count")) {
comparator = new Comparator<JavaClass>() {
public int compare(JavaClass first, JavaClass second) {
long diff = (second.getInstancesCount(false) -
first.getInstancesCount(false));
return (diff == 0)? 0: ((diff < 0)? -1 : + 1);
}
};
} else if (query.equals("class")) {
comparator = new Comparator<JavaClass>() {
public int compare(JavaClass first, JavaClass second) {
return first.getName().compareTo(second.getName());
}
};
} else {
// default sort is by total size
comparator = new Comparator<JavaClass>() {
public int compare(JavaClass first, JavaClass second) {
long diff = (second.getTotalInstanceSize() -
first.getTotalInstanceSize());
return (diff == 0)? 0: ((diff < 0)? -1 : + 1);
}
};
}
Arrays.sort(classes, comparator);
startHtml("Heap Histogram");
out.println("<p align='center'>");
out.println("<b><a href='/'>All Classes (excluding platform)</a></b>");
out.println("</p>");
out.println("<table align=center border=1>");
out.println("<tr><th><a href='/histo/class'>Class</a></th>");
out.println("<th><a href='/histo/count'>Instance Count</a></th>");
out.println("<th><a href='/histo/size'>Total Size</a></th></tr>");
for (int i = 0; i < classes.length; i++) {
JavaClass clazz = classes[i];
out.println("<tr><td>");
printClass(clazz);
out.println("</td>");
out.println("<td>");
out.println(clazz.getInstancesCount(false));
out.println("</td>");
out.println("<td>");
out.println(clazz.getTotalInstanceSize());
out.println("</td></tr>");
}
out.println("</table>");
endHtml();
}
}

View File

@ -1,220 +0,0 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
/**
* Reads a single HTTP query from a socket, and starts up a QueryHandler
* to server it.
*
* @author Bill Foote
*/
import java.net.Socket;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import com.sun.tools.hat.internal.model.Snapshot;
import com.sun.tools.hat.internal.oql.OQLEngine;
import com.sun.tools.hat.internal.util.Misc;
public class HttpReader implements Runnable {
private Socket socket;
private PrintWriter out;
private Snapshot snapshot;
private OQLEngine engine;
public HttpReader (Socket s, Snapshot snapshot, OQLEngine engine) {
this.socket = s;
this.snapshot = snapshot;
this.engine = engine;
}
public void run() {
InputStream in = null;
try {
in = new BufferedInputStream(socket.getInputStream());
out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())));
out.println("HTTP/1.0 200 OK");
out.println("Cache-Control: no-cache");
out.println("Pragma: no-cache");
out.println();
if (in.read() != 'G' || in.read() != 'E'
|| in.read() != 'T' || in.read() != ' ') {
outputError("Protocol error");
}
int data;
StringBuilder queryBuf = new StringBuilder();
while ((data = in.read()) != -1 && data != ' ') {
char ch = (char) data;
queryBuf.append(ch);
}
String query = queryBuf.toString();
query = java.net.URLDecoder.decode(query, "UTF-8");
QueryHandler handler = null;
if (snapshot == null) {
outputError("The heap snapshot is still being read.");
return;
} else if (query.equals("/")) {
handler = new AllClassesQuery(true, engine != null);
handler.setUrlStart("");
handler.setQuery("");
} else if (query.startsWith("/oql/")) {
if (engine != null) {
handler = new OQLQuery(engine);
handler.setUrlStart("");
handler.setQuery(query.substring(5));
}
} else if (query.startsWith("/oqlhelp/")) {
if (engine != null) {
handler = new OQLHelp();
handler.setUrlStart("");
handler.setQuery("");
}
} else if (query.equals("/allClassesWithPlatform/")) {
handler = new AllClassesQuery(false, engine != null);
handler.setUrlStart("../");
handler.setQuery("");
} else if (query.equals("/showRoots/")) {
handler = new AllRootsQuery();
handler.setUrlStart("../");
handler.setQuery("");
} else if (query.equals("/showInstanceCounts/includePlatform/")) {
handler = new InstancesCountQuery(false);
handler.setUrlStart("../../");
handler.setQuery("");
} else if (query.equals("/showInstanceCounts/")) {
handler = new InstancesCountQuery(true);
handler.setUrlStart("../");
handler.setQuery("");
} else if (query.startsWith("/instances/")) {
handler = new InstancesQuery(false);
handler.setUrlStart("../");
handler.setQuery(query.substring(11));
} else if (query.startsWith("/newInstances/")) {
handler = new InstancesQuery(false, true);
handler.setUrlStart("../");
handler.setQuery(query.substring(14));
} else if (query.startsWith("/allInstances/")) {
handler = new InstancesQuery(true);
handler.setUrlStart("../");
handler.setQuery(query.substring(14));
} else if (query.startsWith("/allNewInstances/")) {
handler = new InstancesQuery(true, true);
handler.setUrlStart("../");
handler.setQuery(query.substring(17));
} else if (query.startsWith("/object/")) {
handler = new ObjectQuery();
handler.setUrlStart("../");
handler.setQuery(query.substring(8));
} else if (query.startsWith("/class/")) {
handler = new ClassQuery();
handler.setUrlStart("../");
handler.setQuery(query.substring(7));
} else if (query.startsWith("/roots/")) {
handler = new RootsQuery(false);
handler.setUrlStart("../");
handler.setQuery(query.substring(7));
} else if (query.startsWith("/allRoots/")) {
handler = new RootsQuery(true);
handler.setUrlStart("../");
handler.setQuery(query.substring(10));
} else if (query.startsWith("/reachableFrom/")) {
handler = new ReachableQuery();
handler.setUrlStart("../");
handler.setQuery(query.substring(15));
} else if (query.startsWith("/rootStack/")) {
handler = new RootStackQuery();
handler.setUrlStart("../");
handler.setQuery(query.substring(11));
} else if (query.startsWith("/histo/")) {
handler = new HistogramQuery();
handler.setUrlStart("../");
handler.setQuery(query.substring(7));
} else if (query.startsWith("/refsByType/")) {
handler = new RefsByTypeQuery();
handler.setUrlStart("../");
handler.setQuery(query.substring(12));
} else if (query.startsWith("/finalizerSummary/")) {
handler = new FinalizerSummaryQuery();
handler.setUrlStart("../");
handler.setQuery("");
} else if (query.startsWith("/finalizerObjects/")) {
handler = new FinalizerObjectsQuery();
handler.setUrlStart("../");
handler.setQuery("");
}
if (handler != null) {
handler.setOutput(out);
handler.setSnapshot(snapshot);
handler.run();
} else {
outputError("Query '" + query + "' not implemented");
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (out != null) {
out.close();
}
try {
if (in != null) {
in.close();
}
} catch (IOException ignored) {
}
try {
socket.close();
} catch (IOException ignored) {
}
}
}
private void outputError(String msg) {
out.println();
out.println("<html><body bgcolor=\"#ffffff\">");
out.println(Misc.encodeHtml(msg));
out.println("</body></html>");
}
}

View File

@ -1,169 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
import com.sun.tools.hat.internal.util.ArraySorter;
import com.sun.tools.hat.internal.util.Comparer;
import java.util.Enumeration;
/**
*
* @author Bill Foote
*/
class InstancesCountQuery extends QueryHandler {
private boolean excludePlatform;
public InstancesCountQuery(boolean excludePlatform) {
this.excludePlatform = excludePlatform;
}
public void run() {
if (excludePlatform) {
startHtml("Instance Counts for All Classes (excluding platform)");
} else {
startHtml("Instance Counts for All Classes (including platform)");
}
JavaClass[] classes = snapshot.getClassesArray();
if (excludePlatform) {
int num = 0;
for (int i = 0; i < classes.length; i++) {
if (! PlatformClasses.isPlatformClass(classes[i])) {
classes[num++] = classes[i];
}
}
JavaClass[] tmp = new JavaClass[num];
System.arraycopy(classes, 0, tmp, 0, tmp.length);
classes = tmp;
}
ArraySorter.sort(classes, new Comparer() {
public int compare(Object lhso, Object rhso) {
JavaClass lhs = (JavaClass) lhso;
JavaClass rhs = (JavaClass) rhso;
int diff = lhs.getInstancesCount(false)
- rhs.getInstancesCount(false);
if (diff != 0) {
return -diff; // Sort from biggest to smallest
}
String left = lhs.getName();
String right = rhs.getName();
if (left.startsWith("[") != right.startsWith("[")) {
// Arrays at the end
if (left.startsWith("[")) {
return 1;
} else {
return -1;
}
}
return left.compareTo(right);
}
});
String lastPackage = null;
long totalSize = 0;
long instances = 0;
for (int i = 0; i < classes.length; i++) {
JavaClass clazz = classes[i];
int count = clazz.getInstancesCount(false);
print("" + count);
printAnchorStart();
print("instances/" + encodeForURL(classes[i]));
out.print("\"> ");
if (count == 1) {
print("instance");
} else {
print("instances");
}
out.print("</a> ");
if (snapshot.getHasNewSet()) {
Enumeration<JavaHeapObject> objects = clazz.getInstances(false);
int newInst = 0;
while (objects.hasMoreElements()) {
JavaHeapObject obj = objects.nextElement();
if (obj.isNew()) {
newInst++;
}
}
print("(");
printAnchorStart();
print("newInstances/" + encodeForURL(classes[i]));
out.print("\">");
print("" + newInst + " new");
out.print("</a>) ");
}
print("of ");
printClass(classes[i]);
out.println("<br>");
instances += count;
totalSize += classes[i].getTotalInstanceSize();
}
out.println("<h2>Total of " + instances + " instances occupying " + totalSize + " bytes.</h2>");
out.println("<h2>Other Queries</h2>");
out.println("<ul>");
out.print("<li>");
printAnchorStart();
if (!excludePlatform) {
out.print("showInstanceCounts/\">");
print("Show instance counts for all classes (excluding platform)");
} else {
out.print("showInstanceCounts/includePlatform/\">");
print("Show instance counts for all classes (including platform)");
}
out.println("</a>");
out.print("<li>");
printAnchorStart();
out.print("allClassesWithPlatform/\">");
print("Show All Classes (including platform)");
out.println("</a>");
out.print("<li>");
printAnchorStart();
out.print("\">");
print("Show All Classes (excluding platform)");
out.println("</a>");
out.println("</ul>");
endHtml();
}
}

View File

@ -1,92 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
import java.util.Enumeration;
/**
*
* @author Bill Foote
*/
class InstancesQuery extends QueryHandler {
private boolean includeSubclasses;
private boolean newObjects;
public InstancesQuery(boolean includeSubclasses) {
this.includeSubclasses = includeSubclasses;
}
public InstancesQuery(boolean includeSubclasses, boolean newObjects) {
this.includeSubclasses = includeSubclasses;
this.newObjects = newObjects;
}
public void run() {
JavaClass clazz = snapshot.findClass(query);
String instancesOf;
if (newObjects)
instancesOf = "New instances of ";
else
instancesOf = "Instances of ";
if (includeSubclasses) {
startHtml(instancesOf + query + " (including subclasses)");
} else {
startHtml(instancesOf + query);
}
if (clazz == null) {
error("Class not found");
} else {
out.print("<strong>");
printClass(clazz);
out.print("</strong><br><br>");
Enumeration<JavaHeapObject> objects = clazz.getInstances(includeSubclasses);
long totalSize = 0;
long instances = 0;
while (objects.hasMoreElements()) {
JavaHeapObject obj = objects.nextElement();
if (newObjects && !obj.isNew())
continue;
printThing(obj);
out.println("<br>");
totalSize += obj.getSize();
instances++;
}
out.println("<h2>Total of " + instances + " instances occupying " + totalSize + " bytes.</h2>");
}
endHtml();
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import java.io.*;
/**
* This handles Object Query Language (OQL) help.
*
* @author A. Sundararajan
*/
class OQLHelp extends QueryHandler {
public OQLHelp() {
}
public void run() {
InputStream is = getClass().getResourceAsStream("/com/sun/tools/hat/resources/oqlhelp.html");
int ch = -1;
try {
is = new BufferedInputStream(is);
while ( (ch = is.read()) != -1) {
out.print((char)ch);
}
} catch (Exception exp) {
printException(exp);
}
}
}

View File

@ -1,104 +0,0 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.oql.*;
/**
* This handles Object Query Language (OQL) queries.
*
* @author A. Sundararajan
*/
class OQLQuery extends QueryHandler {
public OQLQuery(OQLEngine engine) {
this.engine = engine;
}
public void run() {
startHtml("Object Query Language (OQL) query");
String oql = null;
if (query != null && !query.equals("")) {
int index = query.indexOf("?query=");
if (index != -1 && query.length() > 7) {
oql = query.substring(index + 7);
}
}
out.println("<p align='center'><table>");
out.println("<tr><td><b>");
out.println("<a href='/'>All Classes (excluding platform)</a>");
out.println("</b></td>");
out.println("<td><b><a href='/oqlhelp/'>OQL Help</a></b></td></tr>");
out.println("</table></p>");
out.println("<form action='/oql/' method='get'>");
out.println("<p align='center'>");
out.println("<textarea name='query' cols=80 rows=10>");
if (oql != null) {
println(oql);
}
out.println("</textarea>");
out.println("</p>");
out.println("<p align='center'>");
out.println("<input type='submit' value='Execute'></input>");
out.println("</p>");
out.println("</form>");
if (oql != null) {
executeQuery(oql);
}
endHtml();
}
private void executeQuery(String q) {
try {
out.println("<table border='1'>");
engine.executeQuery(q, new ObjectVisitor() {
public boolean visit(Object o) {
out.println("<tr><td>");
try {
out.println(engine.toHtml(o));
} catch (Exception e) {
printException(e);
}
out.println("</td></tr>");
return false;
}
});
out.println("</table>");
} catch (OQLException exp) {
printException(exp);
}
}
private OQLEngine engine;
}

View File

@ -1,146 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import java.util.Enumeration;
import com.sun.tools.hat.internal.model.*;
import com.sun.tools.hat.internal.util.ArraySorter;
import com.sun.tools.hat.internal.util.Comparer;
/**
*
* @author Bill Foote
*/
class ObjectQuery extends ClassQuery {
// We inherit printFullClass from ClassQuery
public ObjectQuery() {
}
public void run() {
startHtml("Object at " + query);
long id = parseHex(query);
JavaHeapObject thing = snapshot.findThing(id);
//
// In the following, I suppose we really should use a visitor
// pattern. I'm not that strongly motivated to do this, however:
// This is the only typecase there is, and the default for an
// unrecognized type is to do something reasonable.
//
if (thing == null) {
error("object not found");
} else if (thing instanceof JavaClass) {
printFullClass((JavaClass) thing);
} else if (thing instanceof JavaValueArray) {
print(((JavaValueArray) thing).valueString(true));
printAllocationSite(thing);
printReferencesTo(thing);
} else if (thing instanceof JavaObjectArray) {
printFullObjectArray((JavaObjectArray) thing);
printAllocationSite(thing);
printReferencesTo(thing);
} else if (thing instanceof JavaObject) {
printFullObject((JavaObject) thing);
printAllocationSite(thing);
printReferencesTo(thing);
} else {
// We should never get here
print(thing.toString());
printReferencesTo(thing);
}
endHtml();
}
private void printFullObject(JavaObject obj) {
out.print("<h1>instance of ");
print(obj.toString());
out.print(" <small>(" + obj.getSize() + " bytes)</small>");
out.println("</h1>\n");
out.println("<h2>Class:</h2>");
printClass(obj.getClazz());
out.println("<h2>Instance data members:</h2>");
final JavaThing[] things = obj.getFields();
final JavaField[] fields = obj.getClazz().getFieldsForInstance();
Integer[] hack = new Integer[things.length];
for (int i = 0; i < things.length; i++) {
hack[i] = i;
}
ArraySorter.sort(hack, new Comparer() {
public int compare(Object lhs, Object rhs) {
JavaField left = fields[((Integer) lhs).intValue()];
JavaField right = fields[((Integer) rhs).intValue()];
return left.getName().compareTo(right.getName());
}
});
for (int i = 0; i < things.length; i++) {
int index = hack[i].intValue();
printField(fields[index]);
out.print(" : ");
printThing(things[index]);
out.println("<br>");
}
}
private void printFullObjectArray(JavaObjectArray arr) {
JavaThing[] elements = arr.getElements();
out.println("<h1>Array of " + elements.length + " objects</h1>");
out.println("<h2>Class:</h2>");
printClass(arr.getClazz());
out.println("<h2>Values</h2>");
for (int i = 0; i < elements.length; i++) {
out.print("" + i + " : ");
printThing(elements[i]);
out.println("<br>");
}
}
//
// Print the StackTrace where this was allocated
//
private void printAllocationSite(JavaHeapObject obj) {
StackTrace trace = obj.getAllocatedFrom();
if (trace == null || trace.getFrames().length == 0) {
return;
}
out.println("<h2>Object allocated from:</h2>");
printStackTrace(trace);
}
}

View File

@ -1,119 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.JavaClass;
import com.sun.tools.hat.internal.model.Snapshot;
import java.util.LinkedList;
import java.io.InputStream;
import java.io.Reader;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
/**
* This class is a helper that determines if a class is a "platform"
* class or not. It's a platform class if its name starts with one of
* the prefixes to be found in /com/sun/tools/hat/resources/platform_names.txt.
*
* @author Bill Foote
*/
public class PlatformClasses {
static String[] names = null;
public static synchronized String[] getNames() {
if (names == null) {
LinkedList<String> list = new LinkedList<String>();
InputStream str
= PlatformClasses.class
.getResourceAsStream("/com/sun/tools/hat/resources/platform_names.txt");
if (str != null) {
try {
BufferedReader rdr
= new BufferedReader(new InputStreamReader(str));
for (;;) {
String s = rdr.readLine();
if (s == null) {
break;
} else if (s.length() > 0) {
list.add(s);
}
}
rdr.close();
str.close();
} catch (IOException ex) {
ex.printStackTrace();
// Shouldn't happen, and if it does, continuing
// is the right thing to do anyway.
}
}
names = list.toArray(new String[list.size()]);
}
return names;
}
public static boolean isPlatformClass(JavaClass clazz) {
// all classes loaded by bootstrap loader are considered
// platform classes. In addition, the older name based filtering
// is also done for compatibility.
if (clazz.isBootstrap()) {
return true;
}
String name = clazz.getName();
// skip even the array classes of the skipped classes.
if (name.startsWith("[")) {
int index = name.lastIndexOf('[');
if (index != -1) {
if (name.charAt(index + 1) != 'L') {
// some primitive array.
return true;
}
// skip upto 'L' after the last '['.
name = name.substring(index + 2);
}
}
String[] nms = getNames();
for (int i = 0; i < nms.length; i++) {
if (name.startsWith(nms[i])) {
return true;
}
}
return false;
}
}

View File

@ -1,239 +0,0 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import java.io.PrintWriter;
import com.sun.tools.hat.internal.model.*;
import com.sun.tools.hat.internal.util.Misc;
import java.io.StringWriter;
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;
/**
*
* @author Bill Foote
*/
abstract class QueryHandler {
protected String urlStart;
protected String query;
protected PrintWriter out;
protected Snapshot snapshot;
abstract void run();
void setUrlStart(String s) {
urlStart = s;
}
void setQuery(String s) {
query = s;
}
void setOutput(PrintWriter o) {
this.out = o;
}
void setSnapshot(Snapshot ss) {
this.snapshot = ss;
}
protected String encodeForURL(String s) {
try {
s = URLEncoder.encode(s, "UTF-8");
} catch (UnsupportedEncodingException ex) {
// Should never happen
ex.printStackTrace();
}
return s;
}
protected void startHtml(String title) {
out.print("<html><title>");
print(title);
out.println("</title>");
out.println("<body bgcolor=\"#ffffff\"><center><h1>");
print(title);
out.println("</h1></center>");
}
protected void endHtml() {
out.println("</body></html>");
}
protected void error(String msg) {
println(msg);
}
protected void printAnchorStart() {
out.print("<a href=\"");
out.print(urlStart);
}
protected void printThingAnchorTag(long id) {
printAnchorStart();
out.print("object/");
printHex(id);
out.print("\">");
}
protected void printObject(JavaObject obj) {
printThing(obj);
}
protected void printThing(JavaThing thing) {
if (thing == null) {
out.print("null");
return;
}
if (thing instanceof JavaHeapObject) {
JavaHeapObject ho = (JavaHeapObject) thing;
long id = ho.getId();
if (id != -1L) {
if (ho.isNew())
out.println("<strong>");
printThingAnchorTag(id);
}
print(thing.toString());
if (id != -1) {
if (ho.isNew())
out.println("[new]</strong>");
out.print(" (" + ho.getSize() + " bytes)");
out.println("</a>");
}
} else {
print(thing.toString());
}
}
protected void printRoot(Root root) {
StackTrace st = root.getStackTrace();
boolean traceAvailable = (st != null) && (st.getFrames().length != 0);
if (traceAvailable) {
printAnchorStart();
out.print("rootStack/");
printHex(root.getIndex());
out.print("\">");
}
print(root.getDescription());
if (traceAvailable) {
out.print("</a>");
}
}
protected void printClass(JavaClass clazz) {
if (clazz == null) {
out.println("null");
return;
}
printAnchorStart();
out.print("class/");
print(encodeForURL(clazz));
out.print("\">");
print(clazz.toString());
out.println("</a>");
}
protected String encodeForURL(JavaClass clazz) {
if (clazz.getId() == -1) {
return encodeForURL(clazz.getName());
} else {
return clazz.getIdString();
}
}
protected void printField(JavaField field) {
print(field.getName() + " (" + field.getSignature() + ")");
}
protected void printStatic(JavaStatic member) {
JavaField f = member.getField();
printField(f);
out.print(" : ");
if (f.hasId()) {
JavaThing t = member.getValue();
printThing(t);
} else {
print(member.getValue().toString());
}
}
protected void printStackTrace(StackTrace trace) {
StackFrame[] frames = trace.getFrames();
for (int i = 0; i < frames.length; i++) {
StackFrame f = frames[i];
String clazz = f.getClassName();
out.print("<font color=purple>");
print(clazz);
out.print("</font>");
print("." + f.getMethodName() + "(" + f.getMethodSignature() + ")");
out.print(" <bold>:</bold> ");
print(f.getSourceFileName() + " line " + f.getLineNumber());
out.println("<br>");
}
}
protected void printException(Throwable t) {
println(t.getMessage());
out.println("<pre>");
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
print(sw.toString());
out.println("</pre>");
}
protected void printHex(long addr) {
if (snapshot.getIdentifierSize() == 4) {
out.print(Misc.toHex((int)addr));
} else {
out.print(Misc.toHex(addr));
}
}
protected long parseHex(String value) {
return Misc.parseHex(value);
}
protected void print(String str) {
out.print(Misc.encodeHtml(str));
}
protected void println(String str) {
out.println(Misc.encodeHtml(str));
}
}

View File

@ -1,111 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
/**
*
* @author Bill Foote
*/
import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.Writer;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.BufferedOutputStream;
import com.sun.tools.hat.internal.model.Snapshot;
import com.sun.tools.hat.internal.oql.OQLEngine;
public class QueryListener implements Runnable {
private Snapshot snapshot;
private OQLEngine engine;
private int port;
public QueryListener(int port) {
this.port = port;
this.snapshot = null; // Client will setModel when it's ready
this.engine = null; // created when snapshot is set
}
public void setModel(Snapshot ss) {
this.snapshot = ss;
if (OQLEngine.isOQLSupported()) {
this.engine = new OQLEngine(ss);
}
}
public void run() {
try {
waitForRequests();
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
}
}
private void waitForRequests() throws IOException {
ServerSocket ss = new ServerSocket(port);
Thread last = null;
for (;;) {
Socket s = ss.accept();
Thread t = new Thread(new HttpReader(s, snapshot, engine));
if (snapshot == null) {
t.setPriority(Thread.NORM_PRIORITY+1);
} else {
t.setPriority(Thread.NORM_PRIORITY-1);
if (last != null) {
try {
last.setPriority(Thread.NORM_PRIORITY-2);
} catch (Throwable ignored) {
}
// If the thread is no longer alive, we'll get a
// NullPointerException
}
}
t.start();
last = t;
}
}
}

View File

@ -1,90 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
/**
*
* @author Bill Foote
*/
class ReachableQuery extends QueryHandler {
// We inherit printFullClass from ClassQuery
public ReachableQuery() {
}
public void run() {
startHtml("Objects Reachable From " + query);
long id = parseHex(query);
JavaHeapObject root = snapshot.findThing(id);
ReachableObjects ro = new ReachableObjects(root,
snapshot.getReachableExcludes());
// Now, print out the sorted list, but start with root
long totalSize = ro.getTotalSize();
JavaThing[] things = ro.getReachables();
long instances = things.length;
out.print("<strong>");
printThing(root);
out.println("</strong><br>");
out.println("<br>");
for (int i = 0; i < things.length; i++) {
printThing(things[i]);
out.println("<br>");
}
printFields(ro.getUsedFields(), "Data Members Followed");
printFields(ro.getExcludedFields(), "Excluded Data Members");
out.println("<h2>Total of " + instances + " instances occupying " + totalSize + " bytes.</h2>");
endHtml();
}
private void printFields(String[] fields, String title) {
if (fields.length == 0) {
return;
}
out.print("<h3>");
print(title);
out.println("</h3>");
for (int i = 0; i < fields.length; i++) {
print(fields[i]);
out.println("<br>");
}
}
}

View File

@ -1,138 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
import java.util.*;
/**
* References by type summary
*
*/
public class RefsByTypeQuery extends QueryHandler {
public void run() {
JavaClass clazz = snapshot.findClass(query);
if (clazz == null) {
error("class not found: " + query);
} else {
Map<JavaClass, Long> referrersStat = new HashMap<JavaClass, Long>();
final Map<JavaClass, Long> refereesStat = new HashMap<JavaClass, Long>();
Enumeration<JavaHeapObject> instances = clazz.getInstances(false);
while (instances.hasMoreElements()) {
JavaHeapObject instance = instances.nextElement();
if (instance.getId() == -1) {
continue;
}
Enumeration<JavaThing> e = instance.getReferers();
while (e.hasMoreElements()) {
JavaHeapObject ref = (JavaHeapObject)e.nextElement();
JavaClass cl = ref.getClazz();
if (cl == null) {
System.out.println("null class for " + ref);
continue;
}
Long count = referrersStat.get(cl);
if (count == null) {
count = 1L;
} else {
count = count + 1L;
}
referrersStat.put(cl, count);
}
instance.visitReferencedObjects(
new AbstractJavaHeapObjectVisitor() {
public void visit(JavaHeapObject obj) {
JavaClass cl = obj.getClazz();
Long count = refereesStat.get(cl);
if (count == null) {
count = 1L;
} else {
count = count + 1L;
}
refereesStat.put(cl, count);
}
}
);
} // for each instance
startHtml("References by Type");
out.println("<p align='center'>");
printClass(clazz);
if (clazz.getId() != -1) {
println("[" + clazz.getIdString() + "]");
}
out.println("</p>");
if (referrersStat.size() != 0) {
out.println("<h3 align='center'>Referrers by Type</h3>");
print(referrersStat);
}
if (refereesStat.size() != 0) {
out.println("<h3 align='center'>Referees by Type</h3>");
print(refereesStat);
}
endHtml();
} // clazz != null
} // run
private void print(final Map<JavaClass, Long> map) {
out.println("<table border='1' align='center'>");
Set<JavaClass> keys = map.keySet();
JavaClass[] classes = new JavaClass[keys.size()];
keys.toArray(classes);
Arrays.sort(classes, new Comparator<JavaClass>() {
public int compare(JavaClass first, JavaClass second) {
Long count1 = map.get(first);
Long count2 = map.get(second);
return count2.compareTo(count1);
}
});
out.println("<tr><th>Class</th><th>Count</th></tr>");
for (int i = 0; i < classes.length; i++) {
JavaClass clazz = classes[i];
out.println("<tr><td>");
out.print("<a href='/refsByType/");
print(clazz.getIdString());
out.print("'>");
print(clazz.getName());
out.println("</a>");
out.println("</td><td>");
out.println(map.get(clazz));
out.println("</td></tr>");
}
out.println("</table>");
}
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import com.sun.tools.hat.internal.model.*;
/**
* Query to show the StackTrace for a given root
*
* @author Bill Foote
*/
class RootStackQuery extends QueryHandler {
public RootStackQuery() {
}
public void run() {
int index = (int) parseHex(query);
Root root = snapshot.getRootAt(index);
if (root == null) {
error("Root at " + index + " not found");
return;
}
StackTrace st = root.getStackTrace();
if (st == null || st.getFrames().length == 0) {
error("No stack trace for " + root.getDescription());
return;
}
startHtml("Stack Trace for " + root.getDescription());
out.println("<p>");
printStackTrace(st);
out.println("</p>");
endHtml();
}
}

View File

@ -1,147 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.server;
import java.util.Vector;
import com.sun.tools.hat.internal.model.*;
import com.sun.tools.hat.internal.util.ArraySorter;
import com.sun.tools.hat.internal.util.Comparer;
/**
*
* @author Bill Foote
*/
class RootsQuery extends QueryHandler {
private boolean includeWeak;
public RootsQuery(boolean includeWeak) {
this.includeWeak = includeWeak;
}
public void run() {
long id = parseHex(query);
JavaHeapObject target = snapshot.findThing(id);
if (target == null) {
startHtml("Object not found for rootset");
error("object not found");
endHtml();
return;
}
if (includeWeak) {
startHtml("Rootset references to " + target
+ " (includes weak refs)");
} else {
startHtml("Rootset references to " + target
+ " (excludes weak refs)");
}
out.flush();
ReferenceChain[] refs
= snapshot.rootsetReferencesTo(target, includeWeak);
ArraySorter.sort(refs, new Comparer() {
public int compare(Object lhs, Object rhs) {
ReferenceChain left = (ReferenceChain) lhs;
ReferenceChain right = (ReferenceChain) rhs;
Root leftR = left.getObj().getRoot();
Root rightR = right.getObj().getRoot();
int d = leftR.getType() - rightR.getType();
if (d != 0) {
return -d; // More interesting values are *higher*
}
return left.getDepth() - right.getDepth();
}
});
out.print("<h1>References to ");
printThing(target);
out.println("</h1>");
int lastType = Root.INVALID_TYPE;
for (int i= 0; i < refs.length; i++) {
ReferenceChain ref = refs[i];
Root root = ref.getObj().getRoot();
if (root.getType() != lastType) {
lastType = root.getType();
out.print("<h2>");
print(root.getTypeName() + " References");
out.println("</h2>");
}
out.print("<h3>");
printRoot(root);
if (root.getReferer() != null) {
out.print("<small> (from ");
printThingAnchorTag(root.getReferer().getId());
print(root.getReferer().toString());
out.print(")</a></small>");
}
out.print(" :</h3>");
while (ref != null) {
ReferenceChain next = ref.getNext();
JavaHeapObject obj = ref.getObj();
print("--> ");
printThing(obj);
if (next != null) {
print(" (" +
obj.describeReferenceTo(next.getObj(), snapshot)
+ ":)");
}
out.println("<br>");
ref = next;
}
}
out.println("<h2>Other queries</h2>");
if (includeWeak) {
printAnchorStart();
out.print("roots/");
printHex(id);
out.print("\">");
out.println("Exclude weak refs</a><br>");
endHtml();
}
if (!includeWeak) {
printAnchorStart();
out.print("allRoots/");
printHex(id);
out.print("\">");
out.println("Include weak refs</a><br>");
}
}
}

View File

@ -1,147 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.util;
import java.util.*;
/**
* A singleton utility class that sorts an array of objects.
* <p>
* Use:
* <pre>
*
* Stuff[] arr = ...;
* ArraySorter.sort(arr, new Comparer() {
* public int compare(Object lhs, Object rhs) {
* return ((String) lhs).compareTo((String) rhs);
* }
* });
* </pre>
*
* @author Bill Foote
*/
public class ArraySorter {
/**
* Sort the given array, using c for comparison
**/
static public void sort(Object[] arr, Comparer c) {
quickSort(arr, c, 0, arr.length-1);
}
/**
* Sort an array of strings, using String.compareTo()
**/
static public void sortArrayOfStrings(Object[] arr) {
sort(arr, new Comparer() {
public int compare(Object lhs, Object rhs) {
return ((String) lhs).compareTo((String) rhs);
}
});
}
static private void swap(Object[] arr, int a, int b) {
Object tmp = arr[a];
arr[a] = arr[b];
arr[b] = tmp;
}
//
// Sorts arr between from and to, inclusive. This is a quick, off-the-top-
// of-my-head quicksort: I haven't put any thought into optimizing it.
// I _did_ put thought into making sure it's safe (it will always
// terminate). Worst-case it's O(n^2), but it will usually run in
// in O(n log n). It's well-behaved if the list is already sorted,
// or nearly so.
//
static private void quickSort(Object[] arr, Comparer c, int from, int to) {
if (to <= from)
return;
int mid = (from + to) / 2;
if (mid != from)
swap(arr, mid, from);
Object pivot = arr[from]; // Simple-minded, but reasonable
int highestBelowPivot = from - 1;
int low = from+1;
int high = to;
// We now move low and high toward each other, maintaining the
// invariants:
// arr[i] <= pivot for all i < low
// arr[i] > pivot for all i > high
// As long as these invariants hold, and every iteration makes
// progress, we are safe.
while (low <= high) {
int cmp = c.compare(arr[low], pivot);
if (cmp <= 0) { // arr[low] <= pivot
if (cmp < 0) {
highestBelowPivot = low;
}
low++;
} else {
int c2;
for (;;) {
// arr[high] > pivot:
c2 = c.compare(arr[high], pivot);
if (c2 > 0) {
high--;
if (low > high) {
break;
}
} else {
break;
}
}
// At this point, low is never == high, BTW
if (low <= high) {
swap(arr, low, high);
if (c2 < 0) {
highestBelowPivot = low;
}
low++;
high--;
}
}
}
// At this point, low == high+1
// Now we just need to sort from from..highestBelowPivot
// and from high+1..to
if (highestBelowPivot > from) {
// pivot == pivot, so ensure algorithm terminates
swap(arr, from, highestBelowPivot);
quickSort(arr, c, from, highestBelowPivot-1);
}
quickSort(arr, c, high+1, to);
}
}

View File

@ -1,49 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.util;
/**
* Base class for comparison of two objects.
* @see VectorSorter
*
* @author Bill Foote
*/
abstract public class Comparer {
/**
* @return a number <, == or > 0 depending on lhs compared to rhs
* @see java.lang.String.compareTo
**/
abstract public int compare(Object lhs, Object rhs);
}

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.util;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import com.sun.tools.hat.internal.model.JavaHeapObject;
public class CompositeEnumeration implements Enumeration<JavaHeapObject> {
Enumeration<JavaHeapObject> e1;
Enumeration<JavaHeapObject> e2;
public CompositeEnumeration(Enumeration<JavaHeapObject> e1, Enumeration<JavaHeapObject> e2) {
this.e1 = e1;
this.e2 = e2;
}
public boolean hasMoreElements() {
return e1.hasMoreElements() || e2.hasMoreElements();
}
public JavaHeapObject nextElement() {
if (e1.hasMoreElements()) {
return e1.nextElement();
}
if (e2.hasMoreElements()) {
return e2.nextElement();
}
throw new NoSuchElementException();
}
}

View File

@ -1,112 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.util;
import java.util.*;
/**
* Miscellaneous functions I couldn't think of a good place to put.
*
* @author Bill Foote
*/
public class Misc {
private static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public final static String toHex(int addr) {
char[] buf = new char[8];
int i = 0;
for (int s = 28; s >= 0; s -= 4) {
buf[i++] = digits[(addr >> s) & 0xf];
}
return "0x" + new String(buf);
}
public final static String toHex(long addr) {
return "0x" + Long.toHexString(addr);
}
public final static long parseHex(String value) {
long result = 0;
if (value.length() < 2 || value.charAt(0) != '0' ||
value.charAt(1) != 'x') {
return -1L;
}
for(int i = 2; i < value.length(); i++) {
result *= 16;
char ch = value.charAt(i);
if (ch >= '0' && ch <= '9') {
result += (ch - '0');
} else if (ch >= 'a' && ch <= 'f') {
result += (ch - 'a') + 10;
} else if (ch >= 'A' && ch <= 'F') {
result += (ch - 'A') + 10;
} else {
throw new NumberFormatException("" + ch
+ " is not a valid hex digit");
}
}
return result;
}
public static String encodeHtml(String str) {
final int len = str.length();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < len; i++) {
char ch = str.charAt(i);
if (ch == '<') {
sb.append("&lt;");
} else if (ch == '>') {
sb.append("&gt;");
} else if (ch == '"') {
sb.append("&quot;");
} else if (ch == '\'') {
sb.append("&#039;");
} else if (ch == '&') {
sb.append("&amp;");
} else if (ch < ' ') {
sb.append("&#").append((int)ch).append(';');
} else {
int c = (ch & 0xFFFF);
if (c > 127) {
sb.append("&#").append(c).append(';');
} else {
sb.append(ch);
}
}
}
return sb.toString();
}
}

View File

@ -1,148 +0,0 @@
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* 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
* at JavaSoft/Sun.
*/
package com.sun.tools.hat.internal.util;
import java.util.*;
/**
* A singleton utility class that sorts a vector.
* <p>
* Use:
* <pre>
*
* Vector v = <a vector of, say, String objects>;
* VectorSorter.sort(v, new Comparer() {
* public int compare(Object lhs, Object rhs) {
* return ((String) lhs).compareTo((String) rhs);
* }
* });
* </pre>
*
* @author Bill Foote
*/
public class VectorSorter {
/**
* Sort the given vector, using c for comparison
**/
static public void sort(Vector<Object> v, Comparer c) {
quickSort(v, c, 0, v.size()-1);
}
/**
* Sort a vector of strings, using String.compareTo()
**/
static public void sortVectorOfStrings(Vector<Object> v) {
sort(v, new Comparer() {
public int compare(Object lhs, Object rhs) {
return ((String) lhs).compareTo((String) rhs);
}
});
}
static private void swap(Vector<Object> v, int a, int b) {
Object tmp = v.elementAt(a);
v.setElementAt(v.elementAt(b), a);
v.setElementAt(tmp, b);
}
//
// Sorts v between from and to, inclusive. This is a quick, off-the-top-
// of-my-head quicksort: I haven't put any thought into optimizing it.
// I _did_ put thought into making sure it's safe (it will always
// terminate). Worst-case it's O(n^2), but it will usually run in
// in O(n log n). It's well-behaved if the list is already sorted,
// or nearly so.
//
static private void quickSort(Vector<Object> v, Comparer c, int from, int to) {
if (to <= from)
return;
int mid = (from + to) / 2;
if (mid != from)
swap(v, mid, from);
Object pivot = v.elementAt(from);
// Simple-minded, but reasonable
int highestBelowPivot = from - 1;
int low = from+1;
int high = to;
// We now move low and high toward eachother, maintaining the
// invariants:
// v[i] <= pivot for all i < low
// v[i] > pivot for all i > high
// As long as these invariants hold, and every iteration makes
// progress, we are safe.
while (low <= high) {
int cmp = c.compare(v.elementAt(low), pivot);
if (cmp <= 0) { // v[low] <= pivot
if (cmp < 0) {
highestBelowPivot = low;
}
low++;
} else {
int c2;
for (;;) {
c2 = c.compare(v.elementAt(high), pivot);
// v[high] > pivot:
if (c2 > 0) {
high--;
if (low > high) {
break;
}
} else {
break;
}
}
// At this point, low is never == high
if (low <= high) {
swap(v, low, high);
if (c2 < 0) {
highestBelowPivot = low;
}
low++;
high--;
}
}
}
// Now we just need to sort from from..highestBelowPivot
// and from high+1..to
if (highestBelowPivot > from) {
// pivot == pivot, so ensure algorithm terminates
swap(v, from, highestBelowPivot);
quickSort(v, c, from, highestBelowPivot-1);
}
quickSort(v, c, high+1, to);
}
}

View File

@ -1,808 +0,0 @@
<!--
Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
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.
-->
<html>
<head>
<style>
.key { color: red; font-weight: bold }
</style>
<title>
Object Query Language (OQL)
</title>
</head>
<body>
<h1>Object Query Language (OQL)</h1>
<p>
OQL is SQL-like query language to query Java heap. OQL allows to filter/select information
wanted from Java heap. While pre-defined queries such as "show all instances of class X"
are already supported by HAT, OQL adds more flexibility. OQL is based on JavaScript expression
language.
</p>
<p>
OQL query is of the form
<pre>
<code>
<span class="key">select</span> &lt;JavaScript expression to select&gt;
[ <span class="key">from</span> [<span class="key">instanceof</span>] &lt;class name&gt; &lt;identifier&gt;
[ <span class="key">where</span> &lt;JavaScript boolean expression to filter&gt; ] ]
</code>
</pre>
where class name is fully qualified Java class name (example: java.net.URL) or array class name.
[C is char array name, [Ljava.io.File; is name of java.io.File[] and so on.
Note that fully qualified class name does not always uniquely identify a
Java class at runtime. There may be more than one Java class with the same
name but loaded by different loaders. So, class name is permitted to be
id string of the class object.
If <span class="key">instanceof</span> keyword is used, subtype objects are selected. If this
keyword is not specified, only the instances of exact class specified are selected. Both
<span class="key">from</span> and <span class="key">where</span> clauses are optional.
</p>
<p>
In <span class="key">select</span> and (optional) <span class="key">where</span> clauses, the expression
used in JavaScript expression. Java heap objects are wrapped as convenient script objects so that
fields may be accessed in natural syntax. For example, Java fields can be accessed with obj.field_name
syntax and array elements can be accessed with array[index] syntax. Each Java object selected is
bound to a JavaScript variable of the identifier name specified in <span class="key">from</span> clause.
</p>
<h2>OQL Examples</h2>
<ul>
<li>select all Strings of length 100 or more
<pre>
<code>
select s from java.lang.String s where s.value.length >= 100
</code>
</pre>
<li>select all int arrays of length 256 or more
<pre>
<code>
select a from [I a where a.length >= 256
</code>
</pre>
<li>show content of Strings that match a regular expression
<pre>
<code>
select s.value.toString() from java.lang.String s
where /java/.test(s.value.toString())
</code>
</pre>
<li>show path value of all File objects
<pre>
<code</b>
select file.path.value.toString() from java.io.File file
</code>
</pre>
<li>show names of all ClassLoader classes
<pre>
<code>
select <a href="#classof">classof</a>(cl).name
from instanceof java.lang.ClassLoader cl
</code>
</pre>
<li>show instances of the Class identified by given id string
<pre>
<code>
select o from instanceof 0xd404b198 o
</code>
</pre>
Note that 0xd404b198 is id of a Class (in a session). This is found by
looking at the id shown in that class's page.
</ul>
<h2>OQL built-in objects, functions</h2>
<h3>heap object</h3>
The <b>heap</b> built-in object supports the following methods:
<ul>
<li><b>heap.forEachClass</b> -- calls a callback function for each Java Class
<pre>
<code>
heap.forEachClass(callback);
</code>
</pre>
<li><b>heap.forEachObject</b> -- calls a callback function for each Java object
<pre>
<code>
heap.forEachObject(callback, clazz, includeSubtypes);
</code>
</pre>
<code>clazz</code> is the class whose instances are selected. If not specified, defaults to java.lang.Object. <code>includeSubtypes</code> is a boolean flag
that specifies whether to include subtype instances or not. Default value of
this flag is true.
<a name="findClass"></a>
<li><b>heap.findClass</b> -- finds Java Class of given name
<pre>
<code>
heap.findClass(className);
</code>
</pre>
where <code>className</code> is name of the class to find. The resulting Class
object has following properties:
<ul>
<li>name - name of the class.
<li>superclass - Class object for super class (or null if java.lang.Object).
<li>statics - name, value pairs for static fields of the Class.
<li>fields - array of field objects. field object has name, signature
properties.
<li>loader - ClassLoader object that loaded this class.
<li>signers - signers that signed this class.
<li>protectionDomain - protection domain to which this class belongs.
</ul>
Class objects have the following methods:
<ul>
<li>isSubclassOf - tests whether given class is direct or indirect
subclass of this class or not.
<li>isSuperclassOf - tests whether given Class is direct or indirect
superclass of this class or not.
<li>subclasses - returns array of direct and indirect subclasses.
<li>superclasses - returns array of direct and indirect superclasses.
</ul>
<a name="findObject"></a>
<li><b>heap.findObject</b> -- finds object from given object id
<pre>
<code>
heap.findObject(stringIdOfObject);
</code>
</pre>
<a name="classes"></a>
<li><b>heap.classes</b> -- returns an enumeration of all Java classes
<a name="objects"></a>
<li><b>heap.objects</b> -- returns an enumeration of Java objects
<pre>
<code>
heap.objects(clazz, [includeSubtypes], [filter])
</code>
</pre>
<code>clazz</code> is the class whose instances are selected. If not specified, defaults to java.lang.Object. <code>includeSubtypes</code> is a boolean flag
that specifies whether to include subtype instances or not. Default value of
this flag is true. This method accepts an optional filter expression to filter
the result set of objects.
<a name="finalizables"></a>
<li><b>heap.finalizables</b> -- returns an enumeration of Java objects that are
pending to be finalized.
<li><b>heap.livepaths</b> -- return an array of paths by which a given object
is alive. This method accepts optional second parameter that is a boolean
flag. This flag tells whether to include paths with weak reference(s) or not.
By default, paths with weak reference(s) are not included.
<pre>
<code>
select heap.livepaths(s) from java.lang.String s
</code>
</pre>
Each element of this array itself is another array. The later array is
contains an objects that are in the 'reference chain' of the path.
<li><b>heap.roots</b> -- returns an Enumeration of Roots of the heap.
<a name="rootobj"></a>
Each Root object has the following properties:
<ul>
<li>id - String id of the object that is referred by this root
<li>type - descriptive type of Root (JNI Global, JNI Local, Java Static etc)
<li>description - String description of the Root
<li>referrer - Thread Object or Class object that is responsible for this root or null
</ul>
</ul>
Examples:
<ul>
<li>access static field 'props' of class java.lang.System
<pre>
<code>
select heap.findClass("java.lang.System").statics.props
</code>
</pre>
<li>get number of fields of java.lang.String class
<pre>
<code>
select heap.findClass("java.lang.String").fields.length
</code>
</pre>
<li> find the object whose object id is given
<pre>
<code>
select heap.findObject("0xf3800b58")
</code>
</pre>
<li>select all classes that have name pattern java.net.*
<pre>
<code>
select <a href="#filter">filter</a>(heap.classes(), "/java.net./.test(it.name)")
</code>
</pre>
</ul>
<h3>functions on individual objects</h3>
<ul>
<li><a href="#allocTrace">allocTrace(jobject)</a>
<li><a href="#classof">classof(jobject)</a>
<li><a href="#forEachReferrer">forEachReferrer(callback, jobject)</a>
<li><a href="#identical">identical(o1, o2)</a>
<li><a href="#objectid">objectid(jobject)</a>
<li><a href="#reachables">reachables(jobject, excludedFields)</a>
<li><a href="#referrers">referrers(jobject)</a>
<li><a href="#referees">referees(jobject)</a>
<li><a href="#refers">refers(jobject)</a>
<li><a href="#root">root(jobject)</a>
<li><a href="#sizeof">sizeof(jobject)</a>
<li><a href="#toHtml">toHtml(obj)</a>
</ul>
<a name="allocTrace"></a>
<h4>allocTrace function</h4>
This returns allocation site trace of a given Java object if available.
allocTrace returns array of frame objects. Each frame object has the following
properties:
<ul>
<li>className - name of the Java class whose method is running in the frame.
<li>methodName - name of the Java method running in the frame.
<li>methodSignature - signature of the Java method running in the frame.
<li>sourceFileName - name of source file of the Java class running in the frame.
<li>lineNumber - source line number within the method.
</ul>
<a name="classof"></a>
<h4>classof function</h4>
Returns Class object of a given Java Object. The result object supports the
following properties:
<ul>
<li>name - name of the class.
<li>superclass - Class object for super class (or null if java.lang.Object).
<li>statics - name, value pairs for static fields of the Class.
<li>fields - array of field objects. Field objects have name, signature
properties.
<li>loader - ClassLoader object that loaded this class.
<li>signers - signers that signed this class.
<li>protectionDomain - protection domain to which this class belongs.
</ul>
Class objects have the following methods:
<ul>
<li>isSubclassOf - tests whether given class is direct or indirect
subclass of this class or not.
<li>isSuperclassOf - tests whether given Class is direct or indirect
superclass of this class or not.
<li>subclasses - returns array of direct and indirect subclasses.
<li>superclasses - returns array of direct and indirect superclasses.
</ul>
Examples:
<ul>
<li>show class name of each Reference type object
<pre>
<code>
select classof(o).name from instanceof java.lang.ref.Reference o
</code>
<li>show all subclasses of java.io.InputStream
<pre>
<code>
select heap.findClass("java.io.InputStream").subclasses()
</code>
<li>show all superclasses of java.io.BufferedInputStream
<pre>
<code>
select heap.findClass("java.io.BufferedInputStream").superclasses()
</code>
</pre>
</ul>
<a name="forEachReferrer"></a>
<h4>forEachReferrer function</h4>
calls a callback function for each referrer of a given Java object.
<a name="identical"></a>
<h4>identical function</h4>
<p>
Returns whether two given Java objects are identical or not.
</p>
Example:
<pre>
<code>
select identical(heap.findClass("Foo").statics.bar, heap.findClass("AnotherClass").statics.bar)
</code>
</pre>
<a name="objectid"></a>
<h4>objectid function</h4>
<p>
Returns String id of a given Java object. This id can be passed to
<a href="#findObject">heap.findObject</a> and may also be used to compare
objects for identity.
</p>
Example:
<pre>
<code>
select objectid(o) from java.lang.Object o
</code>
</pre>
<a name="reachables"></a>
<h4>reachables function</h4>
<p>
Returns an array of Java objects that are transitively referred from the
given Java object. Optionally accepts a second parameter that is comma
separated field names to be excluded from reachability computation.
Fields are written in class_name.field_name pattern.
</p>
Examples:
<ul>
<li>print all reachable objects from each Properties instance.
<pre>
<code>
select reachables(p) from java.util.Properties p
</code>
</pre>
<li>print all reachables from each java.net.URL but omit the objects reachable
via the fields specified.
<pre>
<code>
select reachables(u, 'java.net.URL.handler') from java.net.URL u
</code>
</pre>
</ul>
<a name="referrers"></a>
<h4>referrers function</h4>
<p>
Returns an enumeration of Java objects that hold reference to a given Java
object.
</p>
Examples:
<ul>
<li> print number of referrers for each java.lang.Object instance
<pre>
<code>
select count(referrers(o)) from java.lang.Object o
</code>
</pre>
<li>print referrers for each java.io.File object
<pre>
<code>
select referrers(f) from java.io.File f
</code>
</pre>
<li>print URL objects only if referred by 2 or more
<pre>
<code>
select u from java.net.URL u where count(referrers(u)) > 2
</code>
</pre>
</ul>
<a name="referees"></a>
<h4>referees function</h4>
<p>
Returns an array of Java objects to which the given Java
object directly refers to.
</p>
Example: to print all static reference fields of java.io.File class
<pre>
<code>
select referees(<a href="#findClass">heap.findClass</a>("java.io.File"))
</code>
</pre>
<a name="refers"></a>
<h4>refers function</h4>
<p>
Returns whether first Java object refers to second Java object or not.
</p>
<a name="root"></a>
<h4>root function</h4>
<p>
If given object is a member of root set of objects, this function returns
a descriptive <a href="#rootobj">Root object</a> describing why it is so.
If given object is not a root, then this function returns null.
</p>
<a name="sizeof"></a>
<h4>sizeof function</h4>
Returns size of the given Java object in bytes
Example:
<pre>
<code>
select sizeof(o) from [I o
</code>
</pre>
<a name="toHtml"></a>
<h4>toHtml function</h4>
Returns HTML string for the given Java object. Note that this is called
automatically for objects selected by select expression. But, it may be useful
to print more complex output.
Example: print hyperlink in bold font weight
<pre>
<code>
select "&lt;b&gt;" + toHtml(o) + "&lt;/b&gt;" from java.lang.Object o
</code>
</pre>
<h3>Selecting multiple values</h3>
<p>
Multiple values can be selected using JavaScript object literals or arrays.
</p>
Example: show name and thread for each thread object
<pre>
<code>
select { name: t.name? t.name.toString() : "null", thread: t }
from instanceof java.lang.Thread t
</code>
</pre>
<h3>array/iterator/enumeration manipulation functions</h3>
<p>
These functions accept an array/iterator/enumeration and an
expression string [or a callback function] as input. These functions iterate
the array/iterator/enumeration and apply the expression (or function) on
each element. Note that JavaScript objects are associative arrays. So,
these functions may also be used with arbitrary JavaScript objects.
</p>
<ul>
<li><a href="#concat">concat(array1/enumeration1, array2/enumeration2)</a>
<li><a href="#contains">contains(array/enumeration, expression)</a>
<li><a href="#count">count(array/enumeration, expression)</a>
<li><a href="#filter">filter(array/enumeration, expression)</a>
<li><a href="#length">length(array/enumeration)</a>
<li><a href="#map">map(array/enumeration, expression)</a>
<li><a href="#max">max(array/enumeration, [expression])</a>
<li><a href="#min">min(array/enumeration, [expression])</a>
<li><a href="#sort">sort(array/enumeration, [expression])</a>
<li><a href="#sum">sum(array/enumeration, [expression])</a>
<li><a href="#toArray">toArray(array/enumeration)</a>
<li><a href="#unique">unique(array/enumeration, [expression])</a>
</ul>
<a name="concat"></a>
<h4>concat function</h4>
<p>
Concatenates two arrays or enumerations (i.e., returns composite
enumeration).
</p>
<a name="contains"></a>
<h4>contains function</h4>
<p>
Returns whether the given array/enumeration contains an element
the given boolean expression specified in code. The code evaluated
can refer to the following built-in variables.
</p>
<ul>
<li>it -> currently visited element
<li>index -> index of the current element
<li>array -> array/enumeration that is being iterated
</ul>
Example: select all Properties objects that are referred by
some static field some class.
<pre>
<code>
select p from java.util.Properties p
where contains(<a href="#referrers">referrers</a>(p), "<a href="#classof">classof</a>(it).name == 'java.lang.Class'")
</code>
</pre>
<a name="count"></a>
<h4>count function</h4>
<p>
count function returns the count of elements of the input array/enumeration
that satisfy the given boolean expression. The boolean expression code can
refer to the following built-in variables.
</p>
<ul>
<li>it -> currently visited element
<li>index -> index of the current element
<li>array -> array/enumeration that is being iterated
</ul>
Example: print number of classes that have specific name pattern
<pre>
<code>
select count(<a href="#classes">heap.classes()</a>, "/java.io./.test(it.name)")
</code>
</pre>
<a name="filter"></a>
<h4>filter function</h4>
<p>
filter function returns an array/enumeration that contains elements
of the input array/enumeration that satisfy the given boolean
expression. The boolean expression code can refer to the following built-in
variables.
</p>
<ul>
<li>it -> currently visited element
<li>index -> index of the current element
<li>array -> array/enumeration that is being iterated
<li>result -> result array/enumeration
</ul>
Examples:
<ul>
<li>show all classes that have java.io.* name pattern
<pre>
<code>
select filter(<a href="#classes">heap.classes</a>(), "/java.io./.test(it.name)")
</code>
</pre>
<li> show all referrers of URL object where the referrer is not from
java.net package
<pre>
<code>
select filter(<a href="#referrers">referrers</a>(u), "! /java.net./.test(<a href="#classof">classof</a>(it).name)")
from java.net.URL u
</code>
</pre>
</ul>
<a name="length"></a>
<h4>length function</h4>
<p>
length function returns number of elements of an array/enumeration.
</p>
<a name="map"></a>
<h4>map function</h4>
<p>
Transforms the given array/enumeration by evaluating given code
on each element. The code evaluated can refer to the following built-in
variables.
</p>
<ul>
<li>it -> currently visited element
<li>index -> index of the current element
<li>array -> array/enumeration that is being iterated
<li>result -> result array/enumeration
</ul>
<p>
map function returns an array/enumeration of values created by repeatedly
calling code on each element of input array/enumeration.
</p>
Example: show all static fields of java.io.File with name and value
<pre>
<code>
select map(<a href="#findClass">heap.findClass</a>("java.io.File").statics, "index + '=' + <a href="#toHtml">toHtml</a>(it)")
</code>
</pre>
<a name="max"></a>
<h4>max function</h4>
<p>
returns the maximum element of the given array/enumeration.
Optionally accepts code expression to compare elements of the array.
By default numerical comparison is used. The comparison expression can
use the following built-in variables:
</p>
<ul>
<li>lhs -> left side element for comparison
<li>rhs -> right side element for comparison
</ul>
Examples:
<ul>
<li>find the maximum length of any String instance
<pre>
<code>
select max(map(heap.objects('java.lang.String', false), 'it.value.length'))
</code>
</pre>
<li>find string instance that has the maximum length
<pre>
<code>
select max(heap.objects('java.lang.String'), 'lhs.value.length > rhs.value.length')
</code>
</pre>
</ul>
<a name="min"></a>
<h4>min function</h4>
<p>
returns the minimum element of the given array/enumeration. Optionally
accepts code expression to compare elements of the array. By default numerical
comparison is used. The comparison expression can use the following built-in
variables:
</p>
<ul>
<li>lhs -> left side element for comparison
<li>rhs -> right side element for comparison
</ul>
Examples:
<ul>
<li>find the minimum size of any Vector instance
<pre>
<code>
select min(map(heap.objects('java.util.Vector', false), 'it.elementData.length'))
</code>
</pre>
<li>find Vector instance that has the maximum length
<pre>
<code>
select min(heap.objects('java.util.Vector'), 'lhs.elementData.length < rhs.elementData.length')
</code>
</ul>
<a name="sort"></a>
<h4>sort function</h4>
<p>
sorts given array/enumeration. Optionally accepts code expression to
compare elements of the array. By default numerical comparison is used.
The comparison expression can use the following built-in variables:
</p>
<ul>
<li>lhs -> left side element for comparison
<li>rhs -> right side element for comparison
</ul>
Examples:
<ul>
<li> print all char[] objects in the order of size.
<pre>
<code>
select sort(<a href="#objects">heap.objects</a>('[C'), '<a href="#sizeof">sizeof</a>(lhs) - sizeof(rhs)')
</code>
</pre>
<li> print all char[] objects in the order of size but print
size as well.
<pre>
<code>
select <a href="#map">map</a>(sort(<a href="#objects">heap.objects</a>('[C'), '<a href="#sizeof">sizeof</a>(lhs) - sizeof(rhs)'), '{ size: sizeof(it), obj: it }')
</code>
</pre>
</ul>
<a name="sum"></a>
<h4>sum function</h4>
<p>
This function returns the sum of all the elements of the given input array or
enumeration. Optionally, accepts an expression as second param. This is used
to map the input elements before summing those.
</p>
Example: return sum of sizes of the reachable objects from each Properties object
<pre>
<code>
select sum(<a href="#map">map</a>(<a href="#reachables">reachables</a>(p), '<a href="#sizeof">sizeof</a>(it)'))
from java.util.Properties p
// or omit the map as in ...
select sum(<a href="#reachables">reachables</a>(p), '<a href="#sizeof">sizeof</a>(it)')
from java.util.Properties p
</code>
</code>
</pre>
<a name="toArray"></a>
<h4>toArray function</h4>
<p>
This function returns an array that contains elements of the input
array/enumeration.
</p>
<a name="unique"></a>
<h4>unique function</h4>
<p>
This function returns an array/enumeration containing unique elements of the
given input array/enumeration
</p>
Example: select unique char[] instances referenced from Strings. Note that
more than one String instance can share the same char[] for the content.
<pre>
<code>
// number of unique char[] instances referenced from any String
select count(unique(map(heap.objects('java.lang.String'), 'it.value')))
// total number of Strings
select count(heap.objects('java.lang.String'))
</code>
</pre>
<h3>More complex examples</h3>
<h4>Print histogram of each class loader and number of classes loaded by it</h4>
<pre>
<code>
select <a href="#map">map</a>(<a href="#sort">sort</a>(map(heap.objects('java.lang.ClassLoader'),
'{ loader: it, count: it.classes.elementCount }'), 'lhs.count < rhs.count'),
'toHtml(it) + "&lt;br&gt;"')
</code>
</pre>
<p>
The above query uses the fact that, <b>java.lang.ClassLoader</b> has a private
field called <b>classes</b> of type <b>java.util.Vector</b> and Vector has a
private field named <b>elementCount</b> that is number of elements in the
vector. We select multiple values (loader, count) using JavaScript object
literal and map function. We sort the result by count (i.e., number of classes
loaded) using sort function with comparison expression.
</p>
<h4>Show parent-child chain for each class loader instance</h4>
<pre>
<code>
select <a href="#map">map</a>(heap.objects('java.lang.ClassLoader'),
function (it) {
var res = '';
while (it != null) {
res += toHtml(it) + "-&gt;";
it = it.parent;
}
res += "null";
return res + "&lt;br&gt;";
})
</code>
</pre>
<p>
Note that we use <b>parent</b> field of <b>java.lang.ClassLoader</b> class
and walk until parent is null using the callback function to map call.
</p>
<h4>Printing value of all System properties</h4>
<pre>
<code>
select <a href="#map">map</a>(<a href="#filter">filter(<a href="#findClass">heap.findClass</a>('java.lang.System').statics.props.table, 'it != null'),
function (it) {
var res = "";
while (it != null) {
res += it.key.value.toString() + '=' +
it.value.value.toString() + '&lt;br&gt;';
it = it.next;
}
return res;
});
</code>
</pre>
<p>
The above query uses the following facts:
<ul>
<li>java.lang.System has static field by name 'props' of type java.util.Properties.
<li>java.util.Properties has field by 'table' of type java.util.Hashtable$Entry
(this field is inherited from java.util.Hashtable). This is the hashtable
buckets array.
<li>java.util.Hashtable$Entry has 'key', 'value' and 'next' fields. Each
entry points the next entry (or null) in the same hashtable bucket.
<li>java.lang.String class has 'value' field of type char[].
</ul>
<p>
<b>Note that this query (and many other queries) may not be stable - because
private fields of Java platform classes may be modified/removed without any
notification! (implementation detail)</b>. But, using such queries on user
classes may be safe - given that user has the control over the classes.
</p>
</body>
</html>

View File

@ -1,29 +0,0 @@
boolean[
char[
float[
double[
byte[
short[
int[
long[
sun.
java.
javax.accessibility
javax.crypto.
javax.imageio.
javax.naming.
javax.net.
javax.print.
javax.rmi.
javax.security.
javax.sound.
javax.sql.
javax.swing.
javax.transaction.
javax.xml.parsers.
javax.xml.transform.
org.ietf.jgss.
org.omg.
org.w3c.dom.
org.xml.sax.

View File

@ -379,4 +379,10 @@ sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java generic-all
# 8064572 8060736 8062938
sun/jvmstat/monitor/MonitoredVm/CR6672135.java generic-all
# 8079273
demo/jvmti/hprof/CpuOldTest.java generic-all
demo/jvmti/hprof/CpuTimesTest.java generic-all
demo/jvmti/hprof/OptionsTest.java generic-all
demo/jvmti/hprof/StackMapTableTest.java generic-all
############################################################################

View File

@ -84,14 +84,19 @@ public class BadHandshakeTest {
class_name,
pb,
(line) -> {
// The first thing that will get read is
// Listening for transport dt_socket at address: xxxxx
// which shows the debuggee is ready to accept connections.
success.set(line.contains("Listening for transport dt_socket at address:"));
// If the first line contains 'Address already in use'
// that means the debuggee has failed to start due to busy port
bindFailed.set(line.contains("Address already in use"));
return true;
// 'Listening for transport dt_socket at address: xxxxx'
// indicates the debuggee is ready to accept connections
if (line.contains("Listening for transport dt_socket at address:")) {
success.set(true);
return true;
}
// 'Address already in use' indicates
// the debuggee has failed to start due to busy port.
if (line.contains("Address already in use")) {
bindFailed.set(true);
return true;
}
return false;
},
Integer.MAX_VALUE,
TimeUnit.MILLISECONDS

View File

@ -21,134 +21,35 @@
* questions.
*/
import static jdk.testlibrary.Asserts.assertFalse;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.ProcessTools;
/*
* @test NoLaunchOptionTest.java
* @bug 4554734 4724714
* @summary Test for -Xrunjdwp:[onthrow,onuncaught] suboptions require launch suboption
* @author Tim Bell
*
* @modules jdk.jdi
* @run compile -g NoLaunchOptionTest.java
* @build VMConnection
* @run driver NoLaunchOptionTest
* @test NoLaunchOptionTest.java
* @bug 4554734 4724714
* @summary Test for -Xrunjdwp:[onthrow,onuncaught] suboptions require launch suboption
* @author Tim Bell
* @library /lib/testlibrary
* @modules jdk.jdi
* @run compile -g NoLaunchOptionTest.java
* @build jdk.testlibrary.* VMConnection
* @run driver NoLaunchOptionTest
*/
import java.net.ServerSocket;
public class NoLaunchOptionTest extends Object {
private Process subprocess;
private int subprocessStatus;
private static final String CR = System.getProperty("line.separator");
private static final int BUFFERSIZE = 4096;
public static final int RETSTAT = 0;
public static final int STDOUT = 1;
public static final int STDERR = 2;
/**
* Run an arbitrary command and return the results to caller.
*
* @param an array of String containing the command
* to run and any flags or parameters to the command.
*
* @return completion status, stderr and stdout as array of String
* Look for:
* return status in result[NoLaunchOptionTest.RETSTAT]
* standard out in result[NoLaunchOptionTest.STDOUT]
* standard err in result[NoLaunchOptionTest.STDERR]
*
*/
public String[] run (String[] cmdStrings) {
StringBuffer stdoutBuffer = new StringBuffer();
StringBuffer stderrBuffer = new StringBuffer();
System.out.print(CR + "runCommand method about to execute: ");
for (int iNdx = 0; iNdx < cmdStrings.length; iNdx++) {
System.out.print(" ");
System.out.print(cmdStrings[iNdx]);
}
System.out.println(CR);
try {
Process process = Runtime.getRuntime().exec(cmdStrings);
/*
* Gather up the output of the subprocess using non-blocking
* reads so we can get both the subprocess stdout and the
* subprocess stderr without overfilling any buffers.
*/
java.io.BufferedInputStream is =
new java.io.BufferedInputStream(process.getInputStream());
int isLen = 0;
byte[] isBuf = new byte[BUFFERSIZE];
java.io.BufferedInputStream es =
new java.io.BufferedInputStream(process.getErrorStream());
int esLen = 0;
byte[] esBuf = new byte[BUFFERSIZE];
do {
isLen = is.read(isBuf);
if (isLen > 0) {
stdoutBuffer.append(
new String(isBuf, 0, isLen));
}
esLen = es.read(esBuf);
if (esLen > 0) {
stderrBuffer.append(
new String(esBuf, 0, esLen));
}
} while ((isLen > -1) || (esLen > -1));
try {
process.waitFor();
subprocessStatus = process.exitValue();
process = null;
} catch(java.lang.InterruptedException e) {
System.err.println("InterruptedException: " + e);
}
} catch(java.io.IOException ex) {
System.err.println("IO error: " + ex);
}
String[] result =
new String[] {
Integer.toString(subprocessStatus),
stdoutBuffer.toString(),
stderrBuffer.toString()
};
System.out.println(CR + "--- Return code was: " +
CR + result[RETSTAT]);
System.out.println(CR + "--- Return stdout was: " +
CR + result[STDOUT]);
System.out.println(CR + "--- Return stderr was: " +
CR + result[STDERR]);
return result;
}
public static void main(String[] args) throws Exception {
// find a free port
ServerSocket ss = new ServerSocket(0);
int port = ss.getLocalPort();
ss.close();
String address = String.valueOf(port);
String[] cmd = VMConnection.insertDebuggeeVMOptions(new String[] {
"-agentlib:jdwp=transport=dt_socket,address=5555," +
"onthrow=java.lang.ClassNotFoundException,suspend=n",
"NotAClass" });
String javaExe = System.getProperty("java.home") +
java.io.File.separator + "bin" +
java.io.File.separator + "java";
String targetClass = "NotAClass";
String cmds [] = {javaExe,
"-agentlib:jdwp=transport=dt_socket,address=" +
address + "," +
"onthrow=java.lang.ClassNotFoundException,suspend=n",
targetClass};
NoLaunchOptionTest myTest = new NoLaunchOptionTest();
String results [] = myTest.run(VMConnection.insertDebuggeeVMOptions(cmds));
if ((results[RETSTAT].equals("1")) &&
(results[STDERR].contains("ERROR:"))) {
System.out.println("Test passed: status = 1 with warning messages " +
"is expected and normal for this test");
} else {
throw new Exception("Test failed: unspecified test failure");
}
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(cmd);
OutputAnalyzer output = ProcessTools.executeProcess(pb);
System.out.println(output.getOutput());
assertFalse(output.getExitValue() == 0, "Exit code should not be 0");
output.shouldContain("ERROR: JDWP Specify launch=<command line> when using onthrow or onuncaught suboption");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -21,22 +21,55 @@
* questions.
*/
/*
*
* @bug 6455258
* @summary Sanity test for com.sun.management.HotSpotDiagnosticMXBean.dumpHeap
* method
*/
import static jdk.testlibrary.Asserts.assertTrue;
import static jdk.testlibrary.Asserts.fail;
import java.io.File;
import java.lang.management.*;
import java.util.List;
import javax.management.MBeanServer;
import jdk.test.lib.hprof.HprofParser;
import jdk.testlibrary.ProcessTools;
import com.sun.management.HotSpotDiagnosticMXBean;
/*
* @test
* @bug 6455258
* @summary Sanity test for com.sun.management.HotSpotDiagnosticMXBean.dumpHeap method
* @library /lib/testlibrary
* @library /../../test/lib/share/classes
* @build jdk.testlibrary.*
* @build jdk.test.lib.hprof.*
* @build jdk.test.lib.hprof.module.*
* @build jdk.test.lib.hprof.parser.*
* @build jdk.test.lib.hprof.utils.*
* @run main DumpHeap
*/
public class DumpHeap {
public static void main(String[] argv) throws Exception {
List<HotSpotDiagnosticMXBean> list = ManagementFactory.getPlatformMXBeans(HotSpotDiagnosticMXBean.class);
System.out.println("Dumping to file: " + argv[0] + " ....");
list.get(0).dumpHeap(argv[0], true);
public static void main(String[] args) throws Exception {
List<HotSpotDiagnosticMXBean> list = ManagementFactory.getPlatformMXBeans(HotSpotDiagnosticMXBean.class);
File dump = new File(ProcessTools.getProcessId() + ".hprof");
if (dump.exists()) {
dump.delete();
}
System.out.println("Dumping to file: " + dump.getAbsolutePath());
list.get(0).dumpHeap(dump.getAbsolutePath(), true);
verifyDumpFile(dump);
dump.delete();
}
private static void verifyDumpFile(File dump) {
assertTrue(dump.exists() && dump.isFile(), "Could not create dump file");
try {
HprofParser.parse(dump);
} catch (Exception e) {
e.printStackTrace();
fail("Could not parse dump file");
}
}
}

View File

@ -1,60 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# 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.
#
# @test
# @bug 6455258
# @summary Sanity test for com.sun.management.HotSpotDiagnosticMXBean.dumpHeap
# method
#
# @modules jdk.management
# @build DumpHeap
# @run shell DumpHeap.sh
if [ "${TESTJAVA}" = "" ] ; then
echo "--Error: TESTJAVA must be defined as the pathname of a jdk to test."
exit 1
fi
if [ "${COMPILEJAVA}" = "" ] ; then
COMPILEJAVA="${TESTJAVA}"
fi
failed=0
# we use the pid of this shell process to name the heap dump output file.
DUMPFILE="java_pid$$.hprof"
${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES \
DumpHeap ${DUMPFILE} || exit 2
# check that heap dump is parsable
${COMPILEJAVA}/bin/jhat ${TESTTOOLVMOPTS} -parseonly true ${DUMPFILE}
if [ $? != 0 ]; then failed=1; fi
# dump file is large so remove it
rm ${DUMPFILE}
exit $failed

View File

@ -111,6 +111,8 @@ public class CustomLauncherTest {
try {
String[] launcher = getLauncher();
if (launcher == null) return; // launcher not available for the tested platform; skip
System.out.println("Starting custom launcher:");
System.out.println("=========================");
System.out.println(" launcher : " + launcher[0]);

View File

@ -1,210 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# 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.
#
# Support functions to start, stop, wait for or kill a given SimpleApplication
# Starts a given app as background process, usage:
# startApplication <class> port-file [args...]
#
# The following variables are set:
#
# appJavaPid - application's Java pid
# appOtherPid - pid associated with the app other than appJavaPid
# appPidList - all pids associated with the app
# appOutput - file containing stdout and stderr from the app
#
# Waits for at least one line of output from the app to indicate
# that it is up and running.
#
startApplication()
{
appOutput="${TESTCLASSES}/Application.out"
${JAVA} -XX:+UsePerfData -classpath "${TESTCLASSPATH:-${TESTCLASSES}}" "$@" > "$appOutput" 2>&1 &
appJavaPid="$!"
appOtherPid=
appPidList="$appJavaPid"
echo "INFO: waiting for $1 to initialize..."
_cnt=0
while true; do
# if the app doesn't start then the JavaTest/JTREG timeout will
# kick in so this isn't really a endless loop
sleep 1
out=`tail -1 "$appOutput"`
if [ -n "$out" ]; then
# we got some output from the app so it's running
break
fi
_cnt=`expr $_cnt + 1`
echo "INFO: waited $_cnt second(s) ..."
done
unset _cnt
if $isWindows; then
# Windows requires special handling
appOtherPid="$appJavaPid"
if $isCygwin; then
appJavaPid=`ps -p "$appOtherPid" \
| sed -n '
# See if $appOtherPid is in PID column; there are sometimes
# non-blanks in column 1 (I and S observed so far)
/^.'"${PATTERN_WS}${PATTERN_WS}*${appOtherPid}${PATTERN_WS}"'/{
# strip PID column
s/^.'"${PATTERN_WS}${PATTERN_WS}*${appOtherPid}${PATTERN_WS}${PATTERN_WS}"'*//
# strip PPID column
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip PGID column
s/^[1-9][0-9]*'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip everything after WINPID column
s/'"${PATTERN_WS}"'.*//
p
q
}
'`
echo "INFO: Cygwin pid=$appOtherPid maps to Windows pid=$appJavaPid"
else
# show PID, PPID and COMM columns only
appJavaPid=`ps -o pid,ppid,comm \
| sed -n '
# see if appOtherPid is in either PID or PPID columns
/'"${PATTERN_WS}${appOtherPid}${PATTERN_WS}"'/{
# see if this is a java command
/java'"${PATTERN_EOL}"'/{
# strip leading white space
s/^'"${PATTERN_WS}${PATTERN_WS}"'*//
# strip everything after the first word
s/'"${PATTERN_WS}"'.*//
# print the pid and we are done
p
q
}
}
'`
echo "INFO: MKS shell pid=$appOtherPid; Java pid=$appJavaPid"
fi
if [ -z "$appJavaPid" ]; then
echo "ERROR: could not find app's Java pid." >&2
killApplication
exit 2
fi
appPidList="$appOtherPid $appJavaPid"
fi
echo "INFO: $1 is process $appJavaPid"
echo "INFO: $1 output is in $appOutput"
}
# Stops a simple application by invoking ShutdownSimpleApplication
# class with a specific port-file, usage:
# stopApplication port-file
#
# Note: When this function returns, the SimpleApplication (or a subclass)
# may still be running because the application has not yet reached the
# shutdown check.
#
stopApplication()
{
$JAVA -XX:+UsePerfData -classpath "${TESTCLASSPATH:-${TESTCLASSES}}" ShutdownSimpleApplication $1
}
# Wait for a simple application to stop running.
#
waitForApplication() {
if [ $isWindows = false ]; then
# non-Windows is easy; just one process
echo "INFO: waiting for $appJavaPid"
set +e
wait "$appJavaPid"
set -e
elif $isCygwin; then
# Cygwin pid and not the Windows pid
echo "INFO: waiting for $appOtherPid"
set +e
wait "$appOtherPid"
set -e
else # implied isMKS
# MKS has intermediate shell and Java process
echo "INFO: waiting for $appJavaPid"
# appJavaPid can be empty if pid search in startApplication() failed
if [ -n "$appJavaPid" ]; then
# only need to wait for the Java process
set +e
wait "$appJavaPid"
set -e
fi
fi
}
# Kills a simple application by sending a SIGTERM to the appropriate
# process(es); on Windows SIGQUIT (-9) is used.
#
killApplication()
{
if [ $isWindows = false ]; then
# non-Windows is easy; just one process
echo "INFO: killing $appJavaPid"
set +e
kill -TERM "$appJavaPid" # try a polite SIGTERM first
sleep 2
# send SIGQUIT (-9) just in case SIGTERM didn't do it
# but don't show any complaints
kill -QUIT "$appJavaPid" > /dev/null 2>&1
wait "$appJavaPid"
set -e
elif $isCygwin; then
# Cygwin pid and not the Windows pid
echo "INFO: killing $appOtherPid"
set +e
kill -9 "$appOtherPid"
wait "$appOtherPid"
set -e
else # implied isMKS
# MKS has intermediate shell and Java process
echo "INFO: killing $appPidList"
set +e
kill -9 $appPidList
set -e
# appJavaPid can be empty if pid search in startApplication() failed
if [ -n "$appJavaPid" ]; then
# only need to wait for the Java process
set +e
wait "$appJavaPid"
set -e
fi
fi
}

View File

@ -1,131 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# 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.
#
# Common setup for tool tests and other tests that use jtools.
# Checks that TESTJAVA, TESTSRC, and TESTCLASSES environment variables are set.
#
# Creates the following constants for use by the caller:
# JAVA - java launcher
# JHAT - jhat utility
# JINFO - jinfo utility
# JMAP - jmap utility
# JPS - jps utility
# JSTACK - jstack utility
# JCMD - jcmd utility
# OS - operating system name
# PATTERN_EOL - grep or sed end-of-line pattern
# PATTERN_WS - grep or sed whitespace pattern
# PS - path separator (";" or ":")
#
# Sets the following variables:
#
# isCygwin - true if environment is Cygwin
# isMKS - true if environment is MKS
# isLinux - true if OS is Linux
# isSolaris - true if OS is Solaris
# isWindows - true if OS is Windows
# isMacos - true if OS is Macos X
# isAIX - true if OS is AIX
if [ -z "${TESTJAVA}" ]; then
echo "ERROR: TESTJAVA not set. Test cannot execute. Failed."
exit 1
fi
if [ -z "${TESTSRC}" ]; then
echo "ERROR: TESTSRC not set. Test cannot execute. Failed."
exit 1
fi
if [ -z "${TESTCLASSES}" ]; then
echo "ERROR: TESTCLASSES not set. Test cannot execute. Failed."
exit 1
fi
# only enable these after checking the expected incoming env variables
set -eu
JAVA="${TESTJAVA}/bin/java"
JHAT="${TESTJAVA}/bin/jhat"
JINFO="${TESTJAVA}/bin/jinfo"
JMAP="${TESTJAVA}/bin/jmap"
JPS="${TESTJAVA}/bin/jps"
JSTACK="${TESTJAVA}/bin/jstack"
JCMD="${TESTJAVA}/bin/jcmd"
isCygwin=false
isMKS=false
isLinux=false
isSolaris=false
isUnknownOS=false
isWindows=false
isMacos=false
isAIX=false
OS=`uname -s`
# start with some UNIX like defaults
PATTERN_EOL='$'
# blank and tab
PATTERN_WS='[ ]'
PS=":"
case "$OS" in
CYGWIN* )
OS="Windows"
PATTERN_EOL='[ ]*$'
# blank and tab
PATTERN_WS='[ \t]'
isCygwin=true
isWindows=true
;;
Linux )
OS="Linux"
isLinux=true
;;
Darwin )
OS="Mac OS X"
isMacos=true
;;
SunOS )
OS="Solaris"
isSolaris=true
;;
AIX )
OS="AIX"
isAIX=true
;;
Windows* )
OS="Windows"
PATTERN_EOL='[ ]*$'
PS=";"
isWindows=true
;;
* )
isUnknownOS=true
;;
esac

View File

@ -1,76 +0,0 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
/*
* Used to shutdown SimpleApplication (or a subclass). The argument to
* this class is the name of a file that contains the TCP port number
* on which SimpleApplication (or a subclass) is listening.
*
* Note: When this program returns, the SimpleApplication (or a subclass)
* may still be running because the application has not yet reached the
* shutdown check.
*/
import java.net.Socket;
import java.net.InetSocketAddress;
import java.io.File;
import java.io.FileInputStream;
public class ShutdownSimpleApplication {
public static void main(String args[]) throws Exception {
if (args.length != 1) {
throw new RuntimeException("Usage: ShutdownSimpleApplication" +
" port-file");
}
// read the (TCP) port number from the given file
File f = new File(args[0]);
FileInputStream fis = new FileInputStream(f);
byte b[] = new byte[8];
int n = fis.read(b);
if (n < 1) {
throw new RuntimeException("Empty port-file");
}
fis.close();
String str = new String(b, 0, n, "UTF-8");
System.out.println("INFO: Port number of SimpleApplication: " + str);
int port = Integer.parseInt(str);
// Now connect to the port (which will shutdown application)
System.out.println("INFO: Connecting to port " + port +
" to shutdown SimpleApplication ...");
System.out.flush();
Socket s = new Socket();
s.connect( new InetSocketAddress(port) );
s.close();
System.out.println("INFO: done connecting to SimpleApplication.");
System.out.flush();
System.exit(0);
}
}

View File

@ -1,120 +0,0 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
/*
* A simple application used by unit tests. The first argument to this
* class is the name of a file to which a TCP port number can be written.
*
* By default, this class does nothing other than bind to a TCP port,
* write the TCP port number to a file, and wait for an incoming connection
* in order to complete the application shutdown protocol.
*/
import java.net.Socket;
import java.net.ServerSocket;
import java.io.File;
import java.io.FileOutputStream;
public class SimpleApplication {
private static SimpleApplication myApp; // simple app or a subclass
private static String myAppName; // simple app name
private static int myPort; // coordination port #
private static ServerSocket mySS; // coordination socket
// protected so a subclass can extend it; not public so creation is
// limited.
protected SimpleApplication() {
// save simple app (or subclass) name for messages
myAppName = getClass().getName();
}
// return the simple application (or a subclass)
final public static SimpleApplication getMyApp() {
return myApp;
}
// set the simple application (for use by a subclass)
final public static void setMyApp(SimpleApplication _myApp) {
myApp = _myApp;
}
// execute the application finish protocol
final public void doMyAppFinish(String[] args) throws Exception {
System.out.println("INFO: " + myAppName + " is waiting on port: " +
myPort);
System.out.flush();
// wait for test harness to connect
Socket s = mySS.accept();
s.close();
mySS.close();
System.out.println("INFO: " + myAppName + " is shutting down.");
System.out.flush();
}
// execute the application start protocol
final public void doMyAppStart(String[] args) throws Exception {
if (args.length < 1) {
throw new RuntimeException("Usage: " + myAppName +
" port-file [arg(s)]");
}
// bind to a random port
mySS = new ServerSocket(0);
myPort = mySS.getLocalPort();
// Write the port number to the given file
File f = new File(args[0]);
FileOutputStream fos = new FileOutputStream(f);
fos.write( Integer.toString(myPort).getBytes("UTF-8") );
fos.close();
System.out.println("INFO: " + myAppName + " created socket on port: " +
myPort);
System.out.flush();
}
// execute the app work (subclass can override this)
public void doMyAppWork(String[] args) throws Exception {
}
public static void main(String[] args) throws Exception {
if (myApp == null) {
// create myApp since a subclass hasn't done so
myApp = new SimpleApplication();
}
myApp.doMyAppStart(args); // do the app start protocol
System.out.println("INFO: " + myAppName + " is calling doMyAppWork()");
System.out.flush();
myApp.doMyAppWork(args); // do the app work
System.out.println("INFO: " + myAppName + " returned from" +
" doMyAppWork()");
System.out.flush();
myApp.doMyAppFinish(args); // do the app finish protocol
System.exit(0);
}
}

View File

@ -1,59 +0,0 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
/*
* An example subclass of SimpleApplication that illustrates how to
* override the doMyAppWork() method.
*/
public class SleeperApplication extends SimpleApplication {
public static int DEFAULT_SLEEP_TIME = 60; // time is in seconds
// execute the sleeper app work
public void doMyAppWork(String[] args) throws Exception {
int sleep_time = DEFAULT_SLEEP_TIME;
// args[0] is the port-file
if (args.length < 2) {
System.out.println("INFO: using default sleep time of "
+ sleep_time + " seconds.");
} else {
try {
sleep_time = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
throw new RuntimeException("Error: '" + args[1] +
"': is not a valid seconds value.");
}
}
Thread.sleep(sleep_time * 1000); // our "work" is to sleep
}
public static void main(String[] args) throws Exception {
SleeperApplication myApp = new SleeperApplication();
SimpleApplication.setMyApp(myApp);
SimpleApplication.main(args);
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
import java.io.File;
import java.util.Arrays;
import jdk.testlibrary.Asserts;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.ProcessTools;
/* @test
* @bug 5102009
* @summary Sanity test of jhat functionality
* @library /lib/testlibrary
* @modules java.management
* @build jdk.testlibarary.*
* @compile -g HelloWorld.java
* @run main HatHeapDump1Test
*/
public class HatHeapDump1Test {
private static final String TEST_CLASSES = System.getProperty("test.classes", ".");
public static void main(String args[]) throws Exception {
String className = "HelloWorld";
File dumpFile = new File(className + ".hdump");
// Generate a heap dump
ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder("-cp",
TEST_CLASSES,
"-Xcheck:jni",
"-Xverify:all",
"-agentlib:hprof=heap=dump,format=b,file=" + dumpFile.getAbsolutePath(),
className);
OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
System.out.println(output.getOutput());
output.shouldHaveExitValue(0);
output.shouldContain("Dumping Java heap ... done");
Asserts.assertTrue(dumpFile.exists() && dumpFile.isFile(), "Invalid dump file " + dumpFile.getAbsolutePath());
// Run jhat to analyze the heap dump
output = jhat("-debug", "2", dumpFile.getAbsolutePath());
output.shouldHaveExitValue(0);
output.shouldContain("Snapshot resolved");
output.shouldContain("-debug 2 was used");
output.shouldNotContain("ERROR");
dumpFile.delete();
}
private static OutputAnalyzer jhat(String... toolArgs) throws Exception {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhat");
if (toolArgs != null) {
for (String toolArg : toolArgs) {
launcher.addToolArg(toolArg);
}
}
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(launcher.getCommand());
System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
System.out.println(output.getOutput());
return output;
}
}

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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.
*/
/*
*
* Sample target application.
*
*/
public class HelloWorld {
public static void main(String args[]) {
/* Use a generic type */
java.util.List<String> l = new java.util.ArrayList<String>();
String.format("%s", "");
/* Just some code with branches */
try {
if ( args.length == 0 ) {
System.out.println("No arguments passed in");
} else {
System.out.println("Some arguments passed in");
}
} catch ( Throwable e ) {
System.out.println("ERROR: System.out.println() did a throw");
} finally {
System.out.println("Hello, world!");
}
}
}

View File

@ -1,69 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# 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.
#
# @test
# @summary Testing jhat parsing against pre-created dump files.
# see also: README.TXT
# @library ../common
# @run shell ParseTest.sh
. ${TESTSRC}/../common/CommonSetup.sh
# all return statuses are checked in this test
set +e
failed=0
DUMPFILE="minimal.bin"
${JHAT} -parseonly true ${TESTSRC}/${DUMPFILE}
if [ $? != 0 ]; then failed=1; fi
DUMPFILE="jmap.bin"
${JHAT} -parseonly true ${TESTSRC}/${DUMPFILE}
if [ $? != 0 ]; then failed=1; fi
DUMPFILE="hprof.bin"
${JHAT} -parseonly true ${TESTSRC}/${DUMPFILE}
if [ $? != 0 ]; then failed=1; fi
# try something that is not heapdump and expect to fail!
DUMPFILE="ParseTest.sh"
${JHAT} -parseonly true ${TESTSRC}/${DUMPFILE}
if [ $? = 0 ]; then failed=1; fi
# try something that does not exist and expect to fail!
DUMPFILE="FileThatDoesNotExist"
${JHAT} -parseonly true ${TESTSRC}/${DUMPFILE}
if [ $? = 0 ]; then failed=1; fi
exit $failed

View File

@ -1,16 +0,0 @@
#
jhat heap dump parsing tests:
There are three hprof binary format dump files in this directory.
These dumps were created by jmap and hprof profiler against a
simple infinite looping Java program.
1. minimal.bin - minimal dump that has nothing! - not even java.lang.Class!
- This was created by java -Xrunhprof:format=b,heap=sites MainClass.
2. jmap.bin - created by jmap -dump option
3. hprof.bin - created by java -Xrunhprof:heap=all,format=b MainClass
We can run jhat -parseonly true <dump-file> against these dumps.

View File

@ -21,10 +21,13 @@
* questions.
*/
import static jdk.testlibrary.Asserts.assertTrue;
import static jdk.testlibrary.Asserts.fail;
import java.io.File;
import java.util.Arrays;
import static jdk.testlibrary.Asserts.*;
import jdk.test.lib.hprof.HprofParser;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.OutputAnalyzer;
import jdk.testlibrary.ProcessTools;
@ -34,8 +37,13 @@ import jdk.testlibrary.ProcessTools;
* @bug 6321286
* @summary Unit test for jmap utility
* @library /lib/testlibrary
* @library /../../test/lib/share/classes
* @modules java.management
* @build jdk.testlibrary.*
* @build jdk.test.lib.hprof.*
* @build jdk.test.lib.hprof.module.*
* @build jdk.test.lib.hprof.parser.*
* @build jdk.test.lib.hprof.utils.*
* @run main BasicJMapTest
*/
public class BasicJMapTest {
@ -60,24 +68,38 @@ public class BasicJMapTest {
}
private static void testDump() throws Exception {
File dump = new File("java_pid$" + ProcessTools.getProcessId() + ".hprof");
OutputAnalyzer output = jmap("-dump:format=b,file=" + dump.getName());
output.shouldHaveExitValue(0);
output.shouldContain("Heap dump file created");
verifyDumpFile(dump);
dump(false);
}
private static void testDumpLive() throws Exception {
File dump = new File("java_pid$" + ProcessTools.getProcessId() + ".hprof");
OutputAnalyzer output = jmap("-dump:live,format=b,file=" + dump.getName());
dump(true);
}
private static void dump(boolean live) throws Exception {
File dump = new File("jmap.dump." + System.currentTimeMillis() + ".hprof");
if (dump.exists()) {
dump.delete();
}
OutputAnalyzer output;
if (live) {
output = jmap("-dump:live,format=b,file=" + dump.getName());
} else {
output = jmap("-dump:format=b,file=" + dump.getName());
}
output.shouldHaveExitValue(0);
output.shouldContain("Heap dump file created");
verifyDumpFile(dump);
dump.delete();
}
private static void verifyDumpFile(File dump) {
assertTrue(dump.exists() && dump.isFile(), "Could not create dump file");
dump.delete();
assertTrue(dump.exists() && dump.isFile(), "Could not create dump file " + dump.getAbsolutePath());
try {
HprofParser.parse(dump);
} catch (Exception e) {
e.printStackTrace();
fail("Could not parse dump file " + dump.getAbsolutePath());
}
}
private static OutputAnalyzer jmap(String... toolArgs) throws Exception {