feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
334
jdkSrc/jdk8/com/sun/tools/hat/internal/model/JavaObject.java
Normal file
334
jdkSrc/jdk8/com/sun/tools/hat/internal/model/JavaObject.java
Normal file
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user