|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
/* |
|
* 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; |
|
|
|
public abstract JavaClass getClazz(); |
|
public abstract int getSize(); |
|
public abstract long getId(); |
|
|
|
|
|
|
|
|
|
*/ |
|
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) { |
|
|
|
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]); |
|
} |
|
} |
|
|
|
|
|
referers = new JavaThing[map.size()]; |
|
map.keySet().toArray(referers); |
|
} |
|
referersLen = -1; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public String getIdString() { |
|
return Misc.toHex(getId()); |
|
} |
|
|
|
public String toString() { |
|
return getClazz().getName() + "@" + getIdString(); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public StackTrace getAllocatedFrom() { |
|
return getClazz().getSiteTrace(this); |
|
} |
|
|
|
public boolean isNew() { |
|
return getClazz().isNew(this); |
|
} |
|
|
|
void setNew(boolean flag) { |
|
getClazz().setNew(this, flag); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void visitReferencedObjects(JavaHeapObjectVisitor v) { |
|
v.visit(getClazz()); |
|
} |
|
|
|
void addReferenceFrom(JavaHeapObject other) { |
|
if (referersLen == 0) { |
|
referers = new JavaThing[1]; |
|
} 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); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public Root getRoot() { |
|
return getClazz().getRoot(this); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Enumeration getReferers() { |
|
if (referersLen != -1) { |
|
throw new RuntimeException("not resolved: " + getIdString()); |
|
} |
|
return new Enumeration() { |
|
|
|
private int num = 0; |
|
|
|
public boolean hasMoreElements() { |
|
return referers != null && num < referers.length; |
|
} |
|
|
|
public Object nextElement() { |
|
return referers[num++]; |
|
} |
|
}; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean refersOnlyWeaklyTo(Snapshot ss, JavaThing other) { |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public String describeReferenceTo(JavaThing target, Snapshot ss) { |
|
return "??"; |
|
} |
|
|
|
public boolean isHeapAllocated() { |
|
return true; |
|
} |
|
|
|
} |