summaryrefslogtreecommitdiff
path: root/hit/src/com/android/hit/ArrayInstance.java
diff options
context:
space:
mode:
Diffstat (limited to 'hit/src/com/android/hit/ArrayInstance.java')
-rw-r--r--hit/src/com/android/hit/ArrayInstance.java188
1 files changed, 188 insertions, 0 deletions
diff --git a/hit/src/com/android/hit/ArrayInstance.java b/hit/src/com/android/hit/ArrayInstance.java
new file mode 100644
index 0000000..42e8803
--- /dev/null
+++ b/hit/src/com/android/hit/ArrayInstance.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.hit;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.util.Set;
+
+public class ArrayInstance extends Instance {
+ private int mType;
+ private int mNumEntries;
+ private byte[] mData;
+
+ public ArrayInstance(long id, StackTrace stack, int type, int numEntries,
+ byte[] data) {
+ mId = id;
+ mStack = stack;
+ mType = type;
+ mNumEntries = numEntries;
+ mData = data;
+ }
+
+ public final void resolveReferences(State state) {
+ if (mType != Types.OBJECT) {
+ return;
+ }
+
+ /*
+ * mData holds a stream of object instance ids
+ * Spin through them all and list ourselves as a reference holder.
+ */
+ int idSize = Types.getTypeSize(mType);
+ final int N = mNumEntries;
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(mData);
+ DataInputStream dis = new DataInputStream(bais);
+
+ for (int i = 0; i < N; i++) {
+ long id;
+
+ try {
+ if (idSize == 4) {
+ id = dis.readInt();
+ } else {
+ id = dis.readLong();
+ }
+
+ Instance instance = state.findReference(id);
+
+ if (instance != null) {
+ instance.addParent(this);
+ }
+ } catch (java.io.IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public final int getSize() {
+ return mData.length;
+ }
+
+ @Override
+ public final void visit(Set<Instance> resultSet, Filter filter) {
+ // If we're in the set then we and our children have been visited
+ if (resultSet.contains(this)) {
+ return;
+ }
+
+ if (null != filter) {
+ if (filter.accept(this)) {
+ resultSet.add(this);
+ }
+ } else {
+ resultSet.add(this);
+ }
+
+ if (mType != Types.OBJECT) {
+ return;
+ }
+
+ /*
+ * mData holds a stream of object instance ids
+ * Spin through them all and visit them
+ */
+ int idSize = Types.getTypeSize(mType);
+ final int N = mNumEntries;
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(mData);
+ DataInputStream dis = new DataInputStream(bais);
+ State state = mHeap.mState;
+
+ for (int i = 0; i < N; i++) {
+ long id;
+
+ try {
+ if (idSize == 4) {
+ id = dis.readInt();
+ } else {
+ id = dis.readLong();
+ }
+
+ Instance instance = state.findReference(id);
+
+ if (instance != null) {
+ instance.visit(resultSet, filter);
+ }
+ } catch (java.io.IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public final String getTypeName() {
+ return Types.getTypeName(mType) + "[" + mNumEntries + "]";
+ }
+
+ 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();
+ }
+}