/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* The Original Code is HAT. The Initial Developer of the
* Original Code is Bill Foote, with contributions from others
*/
/**
* This is JavaScript interface for heap analysis using HAT
* (Heap Analysis Tool). HAT classes are refered from
* this file. In particular, refer to classes in hat.model
* package.
*
* HAT model objects are wrapped as convenient script objects so that
* fields may be accessed in natural syntax. For eg. Java fields can be
* accessed with obj.field_name syntax and array elements can be accessed
* with array[index] syntax.
*/
// returns an enumeration that wraps elements of
// the input enumeration elements.
function wrapperEnumeration(e) {
hasMoreElements: function() {
return e.hasMoreElements();
},
nextElement: function() {
return wrapJavaValue(e.nextElement());
}
};
}
// returns an enumeration that filters out elements
// of input enumeration using the filter function.
var index = 0;
function findNext() {
var tmp;
while (e.hasMoreElements()) {
tmp = e.nextElement();
index++;
if (wrap) {
}
return;
}
}
}
hasMoreElements: function() {
findNext();
},
nextElement: function() {
// user may not have called hasMoreElements?
findNext();
}
throw "NoSuchElementException";
}
return res;
}
};
}
// enumeration that has no elements ..
hasMoreElements: function() {
return false;
},
nextElement: function() {
throw "NoSuchElementException";
}
};
if (root) {
return {
};
} else {
return null;
}
}
function JavaClassProto() {
return obj['wrapped-object'];
}
// return whether given class is subclass of this class or not
this.isSubclassOf = function(other) {
while (tmp != null) {
return true;
}
}
return false;
}
// return whether given class is superclass of this class or not
this.isSuperclassOf = function(other) {
return other.isSubclassOf(this);
}
// includes direct and indirect superclasses
this.superclasses = function() {
var res = new Array();
var tmp = this.superclass;
while (tmp != null) {
}
return res;
}
/**
* Returns an array containing subclasses of this class.
*
* @param indirect should include indirect subclasses or not.
* default is true.
*/
this.subclasses = function(indirect) {
var res = new Array();
for (var i in classes) {
if (indirect) {
}
}
return res;
}
}
var theJavaClassProto = new JavaClassProto();
// Script wrapper for HAT model objects, values.
// wraps a Java value as appropriate for script object
return null;
}
// map primitive values to closest JavaScript primitives
} else {
}
} else {
// wrap Java object as script object
return wrapJavaObject(thing);
}
}
// wrap Java object with appropriate script object
// HAT Java model object wrapper. Handles all cases
function javaObject(jobject) {
// FIXME: Do I need this? or can I assume that these would
// have been resolved already?
return null;
}
}
return new JavaObjectWrapper(jobject);
return new JavaClassWrapper(jobject);
return new JavaObjectArrayWrapper(jobject);
return new JavaValueArrayWrapper(jobject);
} else {
return jobject;
}
}
// returns wrapper for Java instances
function JavaObjectWrapper(instance) {
// instance fields can be accessed in natural syntax
return new JSAdapter() {
__getIds__ : function() {
for (var i in fields) {
}
return res;
},
for (var i in fields) {
}
name == 'wrapped-object';
},
for (var i in fields) {
return wrapJavaValue(things[i]);
}
}
if (name == 'class') {
} else if (name == 'toString') {
return function() {
}
} else if (name == 'wrapped-object') {
return instance;
}
return undefined;
}
}
}
// return wrapper for Java Class objects
// to access static fields of given Class cl, use
// cl.statics.<static-field-name> syntax
__getIds__ : function() {
for (var i in fields) {
}
return res;
},
for (var i in fields) {
return true;
}
}
},
for (var i in fields) {
}
}
return theJavaClassProto[name];
}
}
if (jclass.superclass != null) {
} else {
this.superclass = null;
}
this['wrapped-object'] = jclass;
}
// returns wrapper for Java object arrays
// array elements can be accessed in natural syntax
// also, 'length' property is supported.
return new JSAdapter() {
__getIds__ : function() {
res[i] = i;
}
return res;
},
return (typeof(name) == 'number' &&
},
if (typeof(name) == 'number' &&
} else if (name == 'length') {
} else if (name == 'class') {
} else if (name == 'toString') {
} else if (name == 'wrapped-object') {
return array;
} else {
return undefined;
}
}
}
}
// returns wrapper for Java primitive arrays
// array elements can be accessed in natural syntax
// also, 'length' property is supported.
return new JSAdapter() {
__getIds__ : function() {
r[i] = i;
}
return r;
},
return (typeof(name) == 'number' &&
},
if (typeof(name) == 'number' &&
}
if (name == 'length') {
} else if (name == 'toString') {
return function() { return array.valueString(true); }
} else if (name == 'wrapped-object') {
return array;
} else if (name == 'class') {
} else {
return undefined;
}
}
}
}
return javaObject(thing);
}
// unwrap a script object to corresponding HAT object
try {
} catch (e) {
}
}
return jobject;
}
/**
* readHeapDump parses a heap dump file and returns script wrapper object.
*
* @param file Heap dump file name
* @param stack flag to tell if allocation site traces are available
* @param refs flag to tell if backward references are needed or not
* @param debug debug level for HAT
* @return heap as a JavaScript object
*/
// default value of debug is 0
// by default, we assume no stack traces
// by default, backward references are resolved
// read the heap dump
// resolve it
// wrap Snapshot as convenient script object
return wrapHeapSnapshot(heap);
}
/**
* The result object supports the following methods:
*
* forEachClass -- calls a callback for each Java Class
* forEachObject -- calls a callback for each Java object
* findClass -- finds Java Class of given name
* findObject -- finds object from given object id
* objects -- returns all objects of given class as an enumeration
* classes -- returns all classes in the heap as an enumeration
* reachables -- returns all objects reachable from a given object
* livepaths -- returns an array of live paths because of which an
* object alive.
* describeRef -- returns description for a reference from a 'from'
* object to a 'to' object.
*/
if (type == "string") {
} else if (type == "object") {
} else {
throw "class expected";;
}
return clazz;
}
// return heap as a script object with useful methods.
return {
/**
* Class iteration: Calls callback function for each
* Java Class in the heap. Default callback function
* is 'print'. If callback returns true, the iteration
* is stopped.
*
* @param callback function to be called.
*/
forEachClass: function(callback) {
while (classes.hasMoreElements()) {
return;
}
},
/**
* Returns an Enumeration of all roots.
*/
roots: function() {
hasMoreElements: function() {
return e.hasMoreElements();
},
nextElement: function() {
return wrapRoot(e.nextElement());
}
};
},
/**
* Returns an Enumeration for all Java classes.
*/
classes: function() {
},
/**
* Object iteration: Calls callback function for each
* Java Object in the heap. Default callback function
* is 'print'.If callback returns true, the iteration
* is stopped.
*
* @param callback function to be called.
* @param clazz Class whose objects are retrieved.
* Optional, default is 'java.lang.Object'
* @param includeSubtypes flag to tell if objects of subtypes
* are included or not. optional, default is true.
*/
if (clazz) {
while (instances.hasNextElements()) {
return;
}
}
},
/**
* Returns an enumeration of Java objects in the heap.
*
* @param clazz Class whose objects are retrieved.
* Optional, default is 'java.lang.Object'
* @param includeSubtypes flag to tell if objects of subtypes
* are included or not. optional, default is true.
* @param where (optional) filter expression or function to
* filter the objects. The expression has to return true
* to include object passed to it in the result array.
* Built-in variable 'it' refers to the current object in
* filter expression.
*/
if (where) {
if (typeof(where) == 'string') {
}
}
if (clazz) {
if (where) {
} else {
return wrapperEnumeration(instances);
}
} else {
return emptyEnumeration;
}
},
/**
* Find Java Class of given name.
*
* @param name class name
*/
return wrapJavaValue(clazz);
},
/**
* Find Java Object from given object id
*
* @param id object id as string
*/
findObject: function(id) {
},
/**
* Returns an enumeration of objects in the finalizer
* queue waiting to be finalized.
*/
finalizables: function() {
return wrapperEnumeration(tmp);
},
/**
* Returns an array that contains objects referred from the
* given Java object directly or indirectly (i.e., all
* transitively referred objects are returned).
*
* @param jobject Java object whose reachables are returned.
*/
reachables: function (jobject) {
},
/**
* Returns array of paths of references by which the given
* Java object is live. Each path itself is an array of
* objects in the chain of references. Each path supports
* toHtml method that returns html description of the path.
*
* @param jobject Java object whose live paths are returned
* @param weak flag to indicate whether to include paths with
* weak references or not. default is false.
*/
weak = false;
}
var path = new Array();
// compute path array from refChain
while (tmp != null) {
}
function computeDescription(html) {
desc += " (from " +
}
desc += '->';
while (tmp != null) {
if (next != null) {
desc += " (" +
") ->";
}
}
return desc;
}
return new JSAdapter() {
__getIds__ : function() {
res[i] = i;
}
return res;
},
return (typeof(name) == 'number' &&
name == 'toString';
},
if (typeof(name) == 'number' &&
} else if (name == 'length') {
} else if (name == 'toHtml') {
return function() {
return computeDescription(true);
}
} else if (name == 'toString') {
return function() {
return computeDescription(false);
}
} else {
return undefined;
}
},
};
}
for (var i in refChains) {
}
return paths;
},
/**
* Return description string for reference from 'from' object
* to 'to' Java object.
*
* @param from source Java object
* @param to destination Java object
*/
},
};
}
// per-object functions
/**
* Returns allocation site trace (if available) of a Java object
*
* @param jobject object whose allocation site trace is returned
*/
try {
} catch (e) {
return null;
}
}
/**
* Returns Class object for given Java object
*
* @param jobject object whose Class object is returned
*/
}
/**
* Find referers (a.k.a in-coming references). Calls callback
* for each referrer of the given Java object. If the callback
* returns true, the iteration is stopped.
*
* @param callback function to call for each referer
* @param jobject object whose referers are retrieved
*/
while (refs.hasMoreElements()) {
return;
}
}
}
/**
* Compares two Java objects for object identity.
*
* @param o1, o2 objects to compare for identity
*/
}
/**
* Returns Java object id as string
*
* @param jobject object whose id is returned
*/
try {
} catch (e) {
return null;
}
}
/**
* Prints allocation site trace of given object
*
* @param jobject object whose allocation site trace is returned
*/
print("allocation site trace unavailable for " +
return;
}
for (var i in frames) {
}
}
/**
* Returns an enumeration of referrers of the given Java object.
*
* @param jobject Java object whose referrers are returned.
*/
try {
} catch (e) {
return emptyEnumeration;
}
}
/**
* Returns an array that contains objects referred from the
* given Java object.
*
* @param jobject Java object whose referees are returned.
*/
var res = new Array();
try {
},
return false;
},
mightExclude: function() {
return false;
}
});
} catch (e) {
}
}
return res;
}
/**
* Returns an array that contains objects referred from the
* given Java object directly or indirectly (i.e., all
* transitively referred objects are returned).
*
* @param jobject Java object whose reachables are returned.
* @param excludes optional comma separated list of fields to be
* removed in reachables computation. Fields are
* written as class_name.field_name form.
*/
excludes = null;
} else if (typeof(excludes) == 'string') {
var excludedFields = new Array();
while (st.hasMoreTokens()) {
}
isExcluded: function (field) {
for (var index in excludedFields) {
return true;
}
}
return false;
}
};
} else {
// nothing to filter...
excludes = null;
}
excludes = null;
}
for (var i in tmp) {
}
return res;
}
/**
* Returns whether 'from' object refers to 'to' object or not.
*
* @param from Java object that is source of the reference.
* @param to Java object that is destination of the reference.
*/
try {
return false;
}
for (var i in from) {
return true;
}
}
} catch (e) {
}
return false;
}
/**
* If rootset includes given jobject, return Root
* object explanining the reason why it is a root.
*
* @param jobject object whose Root is returned
*/
try {
} catch (e) {
return null;
}
}
/**
* Returns size of the given Java object
*
* @param jobject object whose size is returned
*/
try {
} catch (e) {
return null;
}
}
/**
* Returns String by replacing Unicode chars and
* HTML special chars (such as '<') with entities.
*
* @param str string to be encoded
*/
}
/**
* Returns HTML string for the given object.
*
* @param obj object for which HTML string is returned.
*/
if (obj == null) {
return "null";
}
return "undefined";
}
} else {
}
// script wrapped Java object
// special case for enumeration
var res = "[ ";
while (obj.hasMoreElements()) {
}
res += "]";
return res;
} else {
return obj;
}
} else if (obj instanceof Array) {
// script array
var res = "[ ";
for (var i in obj) {
res += ", ";
}
}
res += " ]";
return res;
} else {
// if the object has a toHtml function property
// just use that...
} else {
// script object
var res = "{ ";
for (var i in obj) {
}
res += "}";
return res;
}
}
} else {
// JavaScript primitive value
return obj;
}
}
/*
* Generic array/iterator/enumeration [or even object!] manipulation
* functions. These functions accept an array/iteration/enumeration
* and expression String or function. These functions iterate each
* element of array and apply the expression/function on each element.
*/
// private function to wrap an Iterator as an Enumeration
hasMoreElements: function() {
},
nextElement: function() {
}
};
} else {
return itr;
}
}
/**
* Converts an enumeration/iterator/object into an array
*
* @param obj enumeration/iterator/object
* @return array that contains values of enumeration/iterator/object
*/
var res = new Array();
while (obj.hasMoreElements()) {
}
return res;
} else if (obj instanceof Array) {
return obj;
} else {
var res = new Array();
}
return res;
}
}
/**
* Returns whether the given array/iterator/enumeration contains
* an element that satisfies the given boolean expression specified
* in code.
*
* @param array input array/iterator/enumeration that is iterated
* @param code expression string or function
* @return boolean result
*
* The code evaluated can refer to the following built-in variables.
*
* 'it' -> currently visited element
* 'index' -> index of the current element
* 'array' -> array that is being iterated
*/
if (typeof(func) != 'function') {
}
var index = 0;
while (array.hasMoreElements()) {
return true;
}
index++;
}
} else {
return true;
}
}
}
return false;
}
/**
* concatenates two arrays/iterators/enumerators.
*
* @param array1 array/iterator/enumeration
* @param array2 array/iterator/enumeration
*
* @return concatenated array or composite enumeration
*/
} else {
return undefined;
}
}
/**
* Returns the number of array/iterator/enumeration elements
* that satisfy the given boolean expression specified in code.
* The code evaluated can refer to the following built-in variables.
*
* @param array input array/iterator/enumeration that is iterated
* @param code expression string or function
* @return number of elements
*
* 'it' -> currently visited element
* 'index' -> index of the current element
* 'array' -> array that is being iterated
*/
}
if (typeof(func) != 'function') {
}
var result = 0;
var index = 0;
while (array.hasMoreElements()) {
result++;
}
index++;
}
} else {
result++;
}
}
}
return result;
}
/**
* filter function returns an array/enumeration that contains
* elements of the input array/iterator/enumeration that satisfy
* the given boolean expression. The boolean expression code can
* refer to the following built-in variables.
*
* @param array input array/iterator/enumeration that is iterated
* @param code expression string or function
* @return array/enumeration that contains the filtered elements
*
* 'it' -> currently visited element
* 'index' -> index of the current element
* 'array' -> array that is being iterated
* 'result' -> result array
*/
if (typeof(code) != 'function') {
}
} else {
var result = new Array();
}
}
return result;
}
}
/**
* Returns the number of elements of array/iterator/enumeration.
*
* @param array input array/iterator/enumeration that is iterated
*/
if (array instanceof Array) {
var cnt = 0;
while (array.hasMoreElements()) {
array.nextElement();
cnt++;
}
return cnt;
} else {
var cnt = 0;
cnt++;
}
return cnt;
}
}
/**
* Transforms the given object or array by evaluating given code
* on each element of the object or array. The code evaluated
* can refer to the following built-in variables.
*
* @param array input array/iterator/enumeration that is iterated
* @param code expression string or function
* @return array/enumeration that contains mapped values
*
* 'it' -> currently visited element
* 'index' -> index of the current element
* 'array' -> array that is being iterated
* 'result' -> result array
*
* map function returns an array/enumeration of values created
* by repeatedly calling code on each element of the input
*/
if(typeof(code) != 'function') {
}
var index = 0;
hasMoreElements: function() {
return array.hasMoreElements();
},
nextElement: function() {
}
};
return result;
} else {
var result = new Array();
}
return result;
}
}
// private function used by min, max functions
if (typeof(code) == 'string') {
}
if (! array.hasMoreElements()) {
return undefined;
}
while (array.hasMoreElements()) {
}
}
return res;
} else {
return undefined;
}
}
}
return res;
}
}
/**
* Returns the maximum element of the array/iterator/enumeration
*
* @param array input array/iterator/enumeration that is iterated
* @param code (optional) comparision expression or function
* by default numerical maximum is computed.
*/
}
}
/**
* Returns the minimum element of the array/iterator/enumeration
*
* @param array input array/iterator/enumeration that is iterated
* @param code (optional) comparision expression or function
* by default numerical minimum is computed.
*/
}
}
/**
* sort function sorts the input array. optionally accepts
* code to compare the elements. If code is not supplied,
* numerical sort is done.
*
* @param array input array/iterator/enumeration that is sorted
* @param code expression string or function
* @return sorted array
*
* The comparison expression can refer to the following
* built-in variables:
*
* 'lhs' -> 'left side' element
* 'rhs' -> 'right side' element
*/
// we need an array to sort, so convert non-arrays
// by default use numerical comparison
} else if (typeof(code) == 'string') {
}
}
/**
* Returns the sum of the elements of the array
*
* @param array input array that is summed.
* @param code optional expression used to map
* input elements before sum.
*/
}
var result = 0;
while (array.hasMoreElements()) {
}
} else {
}
}
return result;
}
/**
* Returns array of unique elements from the given input
*
* @param array from which unique elements are returned.
* @param code optional expression (or function) giving unique
* by default, objectid is used for uniqueness.
*/
} else if (typeof(code) == 'string') {
}
var tmp = new Object();
while (array.hasMoreElements()) {
}
} else {
}
}
var res = new Array();
}
return res;
}