summaryrefslogtreecommitdiff
path: root/tools/ahat/src/heapdump/AhatArrayInstance.java
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ahat/src/heapdump/AhatArrayInstance.java')
-rw-r--r--tools/ahat/src/heapdump/AhatArrayInstance.java213
1 files changed, 146 insertions, 67 deletions
diff --git a/tools/ahat/src/heapdump/AhatArrayInstance.java b/tools/ahat/src/heapdump/AhatArrayInstance.java
index 8d23276fde..50a4805bed 100644
--- a/tools/ahat/src/heapdump/AhatArrayInstance.java
+++ b/tools/ahat/src/heapdump/AhatArrayInstance.java
@@ -16,20 +16,20 @@
package com.android.ahat.heapdump;
-import com.android.tools.perflib.heap.ArrayInstance;
-import com.android.tools.perflib.heap.Instance;
import java.nio.charset.StandardCharsets;
import java.util.AbstractList;
import java.util.Collections;
import java.util.List;
public class AhatArrayInstance extends AhatInstance {
- // To save space, we store byte, character, and object arrays directly as
- // byte, character, and AhatInstance arrays respectively. This is especially
- // important for large byte arrays, such as bitmaps. All other array types
- // are stored as an array of objects, though we could potentially save space
- // by specializing those too. mValues is a list view of the underlying
- // array.
+ // To save space, we store arrays as primitive arrays or AhatInstance arrays
+ // and provide a wrapper over the arrays to expose a list of Values.
+ // This is especially important for large byte arrays, such as bitmaps.
+ // We keep a separate pointer to the underlying array in the case of byte or
+ // char arrays because they are sometimes useful to have.
+ // TODO: Have different subtypes of AhatArrayInstance to avoid the overhead
+ // of these extra pointers and cost in getReferences when the array type is
+ // not relevant?
private List<Value> mValues;
private byte[] mByteArray; // null if not a byte array.
private char[] mCharArray; // null if not a char array.
@@ -38,72 +38,151 @@ public class AhatArrayInstance extends AhatInstance {
super(id);
}
- @Override void initialize(AhatSnapshot snapshot, Instance inst, Site site) {
- super.initialize(snapshot, inst, site);
+ /**
+ * Initialize the array elements for a primitive boolean array.
+ */
+ void initialize(final boolean[] bools) {
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return bools.length;
+ }
- ArrayInstance array = (ArrayInstance)inst;
- switch (array.getArrayType()) {
- case OBJECT:
- Object[] objects = array.getValues();
- final AhatInstance[] insts = new AhatInstance[objects.length];
- for (int i = 0; i < objects.length; i++) {
- if (objects[i] != null) {
- Instance ref = (Instance)objects[i];
- insts[i] = snapshot.findInstance(ref.getId());
- }
- }
- mValues = new AbstractList<Value>() {
- @Override public int size() {
- return insts.length;
- }
+ @Override public Value get(int index) {
+ return Value.pack(bools[index]);
+ }
+ };
+ }
- @Override public Value get(int index) {
- return Value.pack(insts[index]);
- }
- };
- break;
-
- case CHAR:
- final char[] chars = array.asCharArray(0, array.getLength());
- mCharArray = chars;
- mValues = new AbstractList<Value>() {
- @Override public int size() {
- return chars.length;
- }
+ /**
+ * Initialize the array elements for a primitive char array.
+ */
+ void initialize(final char[] chars) {
+ mCharArray = chars;
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return chars.length;
+ }
- @Override public Value get(int index) {
- return Value.pack(chars[index]);
- }
- };
- break;
-
- case BYTE:
- final byte[] bytes = array.asRawByteArray(0, array.getLength());
- mByteArray = bytes;
- mValues = new AbstractList<Value>() {
- @Override public int size() {
- return bytes.length;
- }
+ @Override public Value get(int index) {
+ return Value.pack(chars[index]);
+ }
+ };
+ }
- @Override public Value get(int index) {
- return Value.pack(bytes[index]);
- }
- };
- break;
+ /**
+ * Initialize the array elements for a primitive float array.
+ */
+ void initialize(final float[] floats) {
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return floats.length;
+ }
- default:
- final Object[] values = array.getValues();
- mValues = new AbstractList<Value>() {
- @Override public int size() {
- return values.length;
- }
+ @Override public Value get(int index) {
+ return Value.pack(floats[index]);
+ }
+ };
+ }
- @Override public Value get(int index) {
- return Value.pack(values[index]);
- }
- };
- break;
+ /**
+ * Initialize the array elements for a primitive double array.
+ */
+ void initialize(final double[] doubles) {
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return doubles.length;
+ }
+
+ @Override public Value get(int index) {
+ return Value.pack(doubles[index]);
+ }
+ };
+ }
+
+ /**
+ * Initialize the array elements for a primitive byte array.
+ */
+ void initialize(final byte[] bytes) {
+ mByteArray = bytes;
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return bytes.length;
+ }
+
+ @Override public Value get(int index) {
+ return Value.pack(bytes[index]);
+ }
+ };
+ }
+
+ /**
+ * Initialize the array elements for a primitive short array.
+ */
+ void initialize(final short[] shorts) {
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return shorts.length;
+ }
+
+ @Override public Value get(int index) {
+ return Value.pack(shorts[index]);
+ }
+ };
+ }
+
+ /**
+ * Initialize the array elements for a primitive int array.
+ */
+ void initialize(final int[] ints) {
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return ints.length;
+ }
+
+ @Override public Value get(int index) {
+ return Value.pack(ints[index]);
+ }
+ };
+ }
+
+ /**
+ * Initialize the array elements for a primitive long array.
+ */
+ void initialize(final long[] longs) {
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return longs.length;
+ }
+
+ @Override public Value get(int index) {
+ return Value.pack(longs[index]);
+ }
+ };
+ }
+
+ /**
+ * Initialize the array elements for an instance array.
+ */
+ void initialize(final AhatInstance[] insts) {
+ mValues = new AbstractList<Value>() {
+ @Override public int size() {
+ return insts.length;
+ }
+
+ @Override public Value get(int index) {
+ return Value.pack(insts[index]);
+ }
+ };
+ }
+
+ @Override
+ protected long getExtraJavaSize() {
+ int length = getLength();
+ if (length == 0) {
+ return 0;
}
+
+ return Value.getType(mValues.get(0)).size * getLength();
}
/**