public final String toString() {
return String.format("%s@0x08x", getTypeName(), mId);
}
+
+ @Override
+ public String describeReferenceTo(long referent) {
+ // If this isn't an object array then we can't refer to an object
+ if (mType != Types.OBJECT) {
+ return super.describeReferenceTo(referent);
+ }
+
+ int idSize = Types.getTypeSize(mType);
+ final int N = mNumEntries;
+ int numRefs = 0;
+ StringBuilder result = new StringBuilder("Elements [");
+ ByteArrayInputStream bais = new ByteArrayInputStream(mData);
+ DataInputStream dis = new DataInputStream(bais);
+
+ /*
+ * Spin through all the objects and build up a string describing
+ * all of the array elements that refer to the target object.
+ */
+ for (int i = 0; i < N; i++) {
+ long id;
+
+ try {
+ if (idSize == 4) {
+ id = dis.readInt();
+ } else {
+ id = dis.readLong();
+ }
+
+ if (id == referent) {
+ numRefs++;
+
+ if (numRefs > 1) {
+ result.append(", ");
+ }
+
+ result.append(i);
+ }
+ } catch (java.io.IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (numRefs == 0) {
+ return super.describeReferenceTo(referent);
+ }
+
+ result.append("]");
+
+ return result.toString();
+ }
}
public final String toString() {
return String.format("%s@0x%08x", getTypeName(), mId);
}
+
+ @Override
+ public String describeReferenceTo(long referent) {
+ ClassObj isa = mHeap.mState.findClass(mClassId);
+ int[] types = isa.mFieldTypes;
+ String[] fieldNames = isa.mFieldNames;
+ ByteArrayInputStream bais = new ByteArrayInputStream(mFieldValues);
+ DataInputStream dis = new DataInputStream(bais);
+ final int N = types.length;
+ StringBuilder result = new StringBuilder("Referenced in field(s):");
+ int numReferences = 0;
+
+ /*
+ * Spin through the list of fields, add info about the field
+ * references to the output text.
+ */
+ try {
+ for (int i = 0; i < N; i++) {
+ int type = types[i];
+ int size = Types.getTypeSize(type);
+
+ if (type == Types.OBJECT) {
+ long id;
+
+ if (size == 4) {
+ id = dis.readInt();
+ } else {
+ id = dis.readLong();
+ }
+
+ if (id == referent) {
+ numReferences++;
+ result.append("\n ");
+ result.append(fieldNames[i]);
+ }
+ } else {
+ dis.skipBytes(size);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ /*
+ * TODO: perform a similar loop over the static fields of isa
+ */
+
+ if (numReferences == 0) {
+ return super.describeReferenceTo(referent);
+ }
+
+ return result.toString();
+ }
}
return mParents;
}
+
+ /*
+ * If this object has a reference to the object identified by id, return
+ * a String describing the reference in detail.
+ */
+ public String describeReferenceTo(long id) {
+ return "No reference to 0x" + Long.toHexString(id);
+ }
}
import java.util.TreeSet;
public class Queries {
+ /*
+ * NOTES: Here's a list of the queries that can be done in hat and
+ * how you'd perform a similar query here in hit:
+ *
+ * hat hit
+ * ------------------------------------------------------------------------
+ * allClasses classes
+ * allClassesWithPlatform allClasses
+ * class findClass
+ * instances instancesOf
+ * allInstances allInstancesOf
+ * object findObject
+ * showRoots getRoots
+ * newInstances newInstances
+ *
+ * reachableFrom make a call to findObject to get the target
+ * parent object, this will give you an Instance.
+ * Then call visit(Set, Filter) on that to have
+ * it build the set of objects in its subgraph.
+ *
+ * rootsTo make a call to findObject on the leaf node
+ * in question, this will give you an Instance.
+ * Instances have an ArrayList of all of the
+ * parent objects that refer to it. You can
+ * follow those parent links until you hit an
+ * object whose parent is null or a ThreadObj.
+ * You've not successfully traced the paths to
+ * the roots.
+ */
+
private static final String DEFAULT_PACKAGE = "<default>";
/*
LOCAL_NO_STANDARD_LIBRARIES := true
LOCAL_DX_FLAGS := --core-library
+LOCAL_NO_EMMA_INSTRUMENT := true
+LOCAL_NO_EMMA_COMPILE := true
+
LOCAL_MODULE := core
include $(BUILD_JAVA_LIBRARY)
import com.ibm.icu4jni.common.ErrorCode;
// BEGIN android-removed
// import com.ibm.icu4jni.converters.NativeConverter;
-// ENd android-removed
+// END android-removed
import java.nio.CharBuffer;
if(ec == ErrorCode.U_BUFFER_OVERFLOW_ERROR){
return CoderResult.OVERFLOW;
}else if(ec==ErrorCode.U_INVALID_CHAR_FOUND){
- return CoderResult.unmappableForLength(data[INVALID_BYTES]);
+ return CoderResult.malformedForLength(data[INVALID_BYTES]);
}else if(ec==ErrorCode.U_ILLEGAL_CHAR_FOUND){
- return CoderResult.unmappableForLength(data[INVALID_BYTES]);
+ return CoderResult.malformedForLength(data[INVALID_BYTES]);
}
/* decoding action succeded */
return CoderResult.UNDERFLOW;
* @since Android 1.0
*/
public Type[] getGenericInterfaces() {
- GenericSignatureParser parser = new GenericSignatureParser();
+ GenericSignatureParser parser = new GenericSignatureParser(
+ VMStack.getCallingClassLoader2());
parser.parseForClass(this, getSignatureAttribute());
return Types.getClonedTypeArray(parser.interfaceTypes);
}
* @since Android 1.0
*/
public Type getGenericSuperclass() {
- GenericSignatureParser parser = new GenericSignatureParser();
+ GenericSignatureParser parser = new GenericSignatureParser(
+ VMStack.getCallingClassLoader2());
parser.parseForClass(this, getSignatureAttribute());
return Types.getType(parser.superclassType);
}
*/
@SuppressWarnings("unchecked")
public synchronized TypeVariable<Class<T>>[] getTypeParameters() {
- GenericSignatureParser parser = new GenericSignatureParser();
+ GenericSignatureParser parser = new GenericSignatureParser(
+ VMStack.getCallingClassLoader2());
parser.parseForClass(this, getSignatureAttribute());
return parser.formalTypeParameters.clone();
}
package java.lang.reflect;
+import dalvik.system.VMStack;
+
import java.lang.annotation.Annotation;
import org.apache.harmony.kernel.vm.StringUtils;
private synchronized void initGenericTypes() {
if (!genericTypesAreInitialized) {
String signatureAttribute = getSignatureAttribute();
- GenericSignatureParser parser = new GenericSignatureParser();
+ GenericSignatureParser parser = new GenericSignatureParser(
+ VMStack.getCallingClassLoader2());
parser.parseForConstructor(this, signatureAttribute);
formalTypeParameters = parser.formalTypeParameters;
genericParameterTypes = parser.parameterTypes;
package java.lang.reflect;
+import dalvik.system.VMStack;
+
import java.lang.annotation.Annotation;
import org.apache.harmony.luni.lang.reflect.GenericSignatureParser;
private synchronized void initGenericType() {
if (!genericTypesAreInitialized) {
String signatureAttribute = getSignatureAttribute();
- GenericSignatureParser parser = new GenericSignatureParser();
+ GenericSignatureParser parser = new GenericSignatureParser(
+ VMStack.getCallingClassLoader2());
parser.parseForField(this.declaringClass, signatureAttribute);
genericType = parser.fieldType;
if (genericType == null) {
package java.lang.reflect;
+import dalvik.system.VMStack;
+
import java.lang.annotation.Annotation;
import org.apache.harmony.kernel.vm.StringUtils;
private synchronized void initGenericTypes() {
if (!genericTypesAreInitialized) {
String signatureAttribute = getSignatureAttribute();
- GenericSignatureParser parser = new GenericSignatureParser();
+ GenericSignatureParser parser = new GenericSignatureParser(
+ VMStack.getCallingClassLoader2());
parser.parseForMethod(this, signatureAttribute);
formalTypeParameters = parser.formalTypeParameters;
genericParameterTypes = parser.parameterTypes;
public Type fieldType;
public ListOfTypes interfaceTypes;
public Type superclassType;
+ public ClassLoader loader;
GenericDeclaration genericDecl;
char[] buffer;
int pos;
+ public GenericSignatureParser(ClassLoader loader) {
+ this.loader = loader;
+ }
+
void setInput(GenericDeclaration genericDecl, String input) {
if (input != null) {
this.genericDecl = genericDecl;
ListOfTypes typeArgs = parseOptTypeArguments();
ImplForType parentType =
- new ImplForType(null, qualIdent.toString(), typeArgs);
+ new ImplForType(null, qualIdent.toString(), typeArgs, loader);
ImplForType type = parentType;
while (symbol == '.') {
scanIdentifier();
qualIdent.append("$").append(identifier); // FIXME: is "$" correct?
typeArgs = parseOptTypeArguments();
- type = new ImplForType(parentType, qualIdent.toString(), typeArgs);
+ type = new ImplForType(parentType, qualIdent.toString(), typeArgs,
+ loader);
}
expect(';');
private Type ownerTypeRes;
private Class rawType; // Already resolved.
private final String rawTypeName;
+ private ClassLoader loader;
public ImplForType(ImplForType ownerType, String rawTypeName,
- ListOfTypes args) {
+ ListOfTypes args, ClassLoader loader) {
this.ownerType0 = ownerType;
this.rawTypeName = rawTypeName;
this.args = args;
+ this.loader = loader;
}
public Class getRawType() {
if (rawType == null) {
- // TODO which ClassLoader to use?
- // Here the actual loading of the class has to be performed and the
- // Exceptions have to be re-thrown TypeNotPresent...
- // How to deal with member (nested) classes?
+ // Here the actual loading of the class has to be performed and the
+ // Exceptions have to be re-thrown TypeNotPresent...
+ // How to deal with member (nested) classes?
try {
- rawType = Class.forName(rawTypeName);
+ rawType = Class.forName(rawTypeName, false, loader);
} catch (ClassNotFoundException e) {
throw new TypeNotPresentException(rawTypeName, e);
}
* @since Android 1.0
*/
public final Buffer clear() {
- // BEGIN android-changed
- internalClear();
- // END android-changed
- return this;
- }
-
- // BEGIN android-added
- // We need a possibility to change the behavior of clear in some optimized
- // DirectByteBuffer adapters.
- void internalClear() {
position = 0;
mark = UNSET_MARK;
limit = capacity;
+ return this;
}
- // END android-added
/**
* Flips this buffer.
}
// BEGIN android-added
+ @Override
public IntBuffer put(int[] i, int off, int len) {
if (byteBuffer instanceof ReadWriteDirectByteBuffer) {
+ byteBuffer.limit(limit << 2);
+ byteBuffer.position(position << 2);
((ReadWriteDirectByteBuffer) byteBuffer).put(i, off, len);
this.position += len;
return this;
return super.put(i, off, len);
}
}
-
- @Override
- void internalClear() {
- if (byteBuffer instanceof ReadWriteDirectByteBuffer) {
- byteBuffer.clear();
- }
- super.internalClear();
- }
// END android-added
public IntBuffer slice() {
}
// BEGIN android-added
+ @Override
public ShortBuffer put(short[] s, int off, int len) {
if (byteBuffer instanceof ReadWriteDirectByteBuffer) {
+ byteBuffer.limit(limit << 1);
+ byteBuffer.position(position << 1);
((ReadWriteDirectByteBuffer) byteBuffer).put(s, off, len);
this.position += len;
return this;
return super.put(s, off, len);
}
}
-
- @Override
- void internalClear() {
- if (byteBuffer instanceof ReadWriteDirectByteBuffer) {
- byteBuffer.clear();
- }
- super.internalClear();
- }
// END android-added
public ShortBuffer slice() {
/**
* Construct a new, empty Attributes2Impl object.
*/
- public Attributes2Impl () { }
+ public Attributes2Impl () {
+ // BEGIN android-added
+ declared = new boolean[0];
+ specified = new boolean[0];
+ // END android-added
+ }
/**
int length = getLength ();
- if (length < specified.length) {
+ // BEGIN android-changed
+ if (length > specified.length) {
+ // END android-changed
boolean newFlags [];
newFlags = new boolean [length];
method = "setAttributes",
args = { Attributes.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testSetAttributes() {
// Ordinary case with Attributes2Impl
Attributes2Impl attrs = new Attributes2Impl();
args = { String.class, String.class, String.class, String.class,
String.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testAddAttribute() {
Attributes2Impl attrs = new Attributes2Impl();
method = "removeAttribute",
args = { int.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testRemoveAttribute() {
Attributes2Impl attrs = new Attributes2Impl(multi);
method = "Attributes2Impl",
args = { }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testAttributes2Impl() {
assertEquals(0, empty.getLength());
}
method = "Attributes2Impl",
args = { Attributes.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testAttributes2ImplAttributes() {
// Ordinary case with Attributes2Impl
Attributes2Impl attrs = new Attributes2Impl(multi);
method = "isDeclared",
args = { int.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testIsDeclaredInt() {
// Ordinary cases
assertEquals(false, multi.isDeclared(0));
method = "isDeclared",
args = { String.class, String.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testIsDeclaredStringString() {
// Ordinary cases
assertEquals(false, multi.isDeclared("http://some.uri", "foo"));
method = "isDeclared",
args = { String.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testIsDeclaredString() {
// Ordinary cases
assertEquals(false, multi.isDeclared("ns1:foo"));
method = "isSpecified",
args = { int.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testIsSpecifiedInt() {
// Ordinary cases
assertEquals(false, multi.isSpecified(1));
method = "isSpecified",
args = { String.class, String.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testIsSpecifiedStringString() {
// Ordinary cases
assertEquals(false, multi.isSpecified("http://some.uri", "bar"));
method = "isSpecified",
args = { String.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testIsSpecifiedString() {
// Ordinary cases
assertEquals(false, multi.isSpecified("ns1:bar"));
method = "setDeclared",
args = { int.class, boolean.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testSetDeclared() {
// Ordinary cases
multi.setSpecified(0, false);
method = "setSpecified",
args = { int.class, boolean.class }
)
- @KnownFailure("SAX2 RI of Attributes2Impl severely broken; needs fixing.")
public void testSetSpecified() {
// Ordinary cases
multi.setSpecified(0, false);