diff options
| -rw-r--r-- | tools/ahat/src/heapdump/AhatArrayInstance.java | 10 | ||||
| -rw-r--r-- | tools/ahat/src/heapdump/AhatSnapshot.java | 2 | ||||
| -rw-r--r-- | tools/ahat/src/heapdump/Value.java | 337 | ||||
| -rw-r--r-- | tools/ahat/test/DiffFieldsTest.java | 22 |
4 files changed, 318 insertions, 53 deletions
diff --git a/tools/ahat/src/heapdump/AhatArrayInstance.java b/tools/ahat/src/heapdump/AhatArrayInstance.java index 6d4485d4b9..4b18bf749d 100644 --- a/tools/ahat/src/heapdump/AhatArrayInstance.java +++ b/tools/ahat/src/heapdump/AhatArrayInstance.java @@ -58,8 +58,7 @@ public class AhatArrayInstance extends AhatInstance { } @Override public Value get(int index) { - AhatInstance obj = insts[index]; - return obj == null ? null : new Value(insts[index]); + return Value.pack(insts[index]); } }; break; @@ -73,7 +72,7 @@ public class AhatArrayInstance extends AhatInstance { } @Override public Value get(int index) { - return new Value(chars[index]); + return Value.pack(chars[index]); } }; break; @@ -87,7 +86,7 @@ public class AhatArrayInstance extends AhatInstance { } @Override public Value get(int index) { - return new Value(bytes[index]); + return Value.pack(bytes[index]); } }; break; @@ -100,8 +99,7 @@ public class AhatArrayInstance extends AhatInstance { } @Override public Value get(int index) { - Object obj = values[index]; - return obj == null ? null : new Value(obj); + return Value.pack(values[index]); } }; break; diff --git a/tools/ahat/src/heapdump/AhatSnapshot.java b/tools/ahat/src/heapdump/AhatSnapshot.java index 2f0b30d68d..fa41362cae 100644 --- a/tools/ahat/src/heapdump/AhatSnapshot.java +++ b/tools/ahat/src/heapdump/AhatSnapshot.java @@ -271,7 +271,7 @@ public class AhatSnapshot implements Diffable<AhatSnapshot> { if (value instanceof Instance) { value = findInstance(((Instance)value).getId()); } - return value == null ? null : new Value(value); + return Value.pack(value); } public void setBaseline(AhatSnapshot baseline) { diff --git a/tools/ahat/src/heapdump/Value.java b/tools/ahat/src/heapdump/Value.java index c1f30228e0..38a6815007 100644 --- a/tools/ahat/src/heapdump/Value.java +++ b/tools/ahat/src/heapdump/Value.java @@ -20,19 +20,71 @@ package com.android.ahat.heapdump; * Value represents a field value in a heap dump. The field value is either a * subclass of AhatInstance or a primitive Java type. */ -public class Value { - private Object mObject; +public abstract class Value { + public static Value pack(AhatInstance value) { + return value == null ? null : new InstanceValue(value); + } /** * Constructs a value from a generic Java Object. * The Object must either be a boxed Java primitive type or a subclass of * AhatInstance. The object must not be null. */ - public Value(Object object) { - // TODO: Check that the Object is either an AhatSnapshot or boxed Java - // primitive type? - assert object != null; - mObject = object; + public static Value pack(Object object) { + if (object == null) { + return null; + } else if (object instanceof AhatInstance) { + return Value.pack((AhatInstance)object); + } else if (object instanceof Boolean) { + return Value.pack(((Boolean)object).booleanValue()); + } else if (object instanceof Character) { + return Value.pack(((Character)object).charValue()); + } else if (object instanceof Float) { + return Value.pack(((Float)object).floatValue()); + } else if (object instanceof Double) { + return Value.pack(((Double)object).doubleValue()); + } else if (object instanceof Byte) { + return Value.pack(((Byte)object).byteValue()); + } else if (object instanceof Short) { + return Value.pack(((Short)object).shortValue()); + } else if (object instanceof Integer) { + return Value.pack(((Integer)object).intValue()); + } else if (object instanceof Long) { + return Value.pack(((Long)object).longValue()); + } + throw new IllegalArgumentException("AhatInstance or primitive type required"); + } + + public static Value pack(boolean value) { + return new BooleanValue(value); + } + + public static Value pack(char value) { + return new CharValue(value); + } + + public static Value pack(float value) { + return new FloatValue(value); + } + + public static Value pack(double value) { + return new DoubleValue(value); + } + + public static Value pack(byte value) { + return new ByteValue(value); + } + + public static Value pack(short value) { + return new ShortValue(value); + } + + public static Value pack(int value) { + return new IntValue(value); + } + + public static Value pack(long value) { + return new LongValue(value); } /** @@ -40,7 +92,7 @@ public class Value { * primitive value. */ public boolean isAhatInstance() { - return mObject instanceof AhatInstance; + return false; } /** @@ -48,9 +100,6 @@ public class Value { * Returns null if the Value represents a Java primitive value. */ public AhatInstance asAhatInstance() { - if (isAhatInstance()) { - return (AhatInstance)mObject; - } return null; } @@ -58,7 +107,7 @@ public class Value { * Returns true if the Value is an Integer. */ public boolean isInteger() { - return mObject instanceof Integer; + return false; } /** @@ -66,9 +115,6 @@ public class Value { * Returns null if the Value does not represent an Integer. */ public Integer asInteger() { - if (isInteger()) { - return (Integer)mObject; - } return null; } @@ -76,7 +122,7 @@ public class Value { * Returns true if the Value is an Long. */ public boolean isLong() { - return mObject instanceof Long; + return false; } /** @@ -84,9 +130,6 @@ public class Value { * Returns null if the Value does not represent an Long. */ public Long asLong() { - if (isLong()) { - return (Long)mObject; - } return null; } @@ -95,9 +138,6 @@ public class Value { * Returns null if the Value does not represent a Byte. */ public Byte asByte() { - if (mObject instanceof Byte) { - return (Byte)mObject; - } return null; } @@ -106,28 +146,255 @@ public class Value { * Returns null if the Value does not represent a Char. */ public Character asChar() { - if (mObject instanceof Character) { - return (Character)mObject; - } return null; } - public String toString() { - return mObject.toString(); + @Override + public abstract String toString(); + + public Value getBaseline() { + return this; } public static Value getBaseline(Value value) { - if (value == null || !value.isAhatInstance()) { - return value; + return value == null ? null : value.getBaseline(); + } + + @Override + public abstract boolean equals(Object other); + + private static class BooleanValue extends Value { + private boolean mBool; + + BooleanValue(boolean bool) { + mBool = bool; + } + + @Override + public String toString() { + return Boolean.toString(mBool); + } + + @Override public boolean equals(Object other) { + if (other instanceof BooleanValue) { + BooleanValue value = (BooleanValue)other; + return mBool == value.mBool; + } + return false; } - return new Value(value.asAhatInstance().getBaseline()); } - @Override public boolean equals(Object other) { - if (other instanceof Value) { - Value value = (Value)other; - return mObject.equals(value.mObject); + private static class ByteValue extends Value { + private byte mByte; + + ByteValue(byte b) { + mByte = b; + } + + @Override + public Byte asByte() { + return mByte; + } + + @Override + public String toString() { + return Byte.toString(mByte); + } + + @Override public boolean equals(Object other) { + if (other instanceof ByteValue) { + ByteValue value = (ByteValue)other; + return mByte == value.mByte; + } + return false; + } + } + + private static class CharValue extends Value { + private char mChar; + + CharValue(char c) { + mChar = c; + } + + @Override + public Character asChar() { + return mChar; + } + + @Override + public String toString() { + return Character.toString(mChar); + } + + @Override public boolean equals(Object other) { + if (other instanceof CharValue) { + CharValue value = (CharValue)other; + return mChar == value.mChar; + } + return false; + } + } + + private static class DoubleValue extends Value { + private double mDouble; + + DoubleValue(double d) { + mDouble = d; + } + + @Override + public String toString() { + return Double.toString(mDouble); + } + + @Override public boolean equals(Object other) { + if (other instanceof DoubleValue) { + DoubleValue value = (DoubleValue)other; + return mDouble == value.mDouble; + } + return false; + } + } + + private static class FloatValue extends Value { + private float mFloat; + + FloatValue(float f) { + mFloat = f; + } + + @Override + public String toString() { + return Float.toString(mFloat); + } + + @Override public boolean equals(Object other) { + if (other instanceof FloatValue) { + FloatValue value = (FloatValue)other; + return mFloat == value.mFloat; + } + return false; + } + } + + private static class InstanceValue extends Value { + private AhatInstance mInstance; + + InstanceValue(AhatInstance inst) { + assert(inst != null); + mInstance = inst; + } + + @Override + public boolean isAhatInstance() { + return true; + } + + @Override + public AhatInstance asAhatInstance() { + return mInstance; + } + + @Override + public String toString() { + return mInstance.toString(); + } + + @Override + public Value getBaseline() { + return InstanceValue.pack(mInstance.getBaseline()); + } + + @Override public boolean equals(Object other) { + if (other instanceof InstanceValue) { + InstanceValue value = (InstanceValue)other; + return mInstance.equals(value.mInstance); + } + return false; + } + } + + private static class IntValue extends Value { + private int mInt; + + IntValue(int i) { + mInt = i; + } + + @Override + public boolean isInteger() { + return true; + } + + @Override + public Integer asInteger() { + return mInt; + } + + @Override + public String toString() { + return Integer.toString(mInt); + } + + @Override public boolean equals(Object other) { + if (other instanceof IntValue) { + IntValue value = (IntValue)other; + return mInt == value.mInt; + } + return false; + } + } + + private static class LongValue extends Value { + private long mLong; + + LongValue(long l) { + mLong = l; + } + + @Override + public boolean isLong() { + return true; + } + + @Override + public Long asLong() { + return mLong; + } + + @Override + public String toString() { + return Long.toString(mLong); + } + + @Override public boolean equals(Object other) { + if (other instanceof LongValue) { + LongValue value = (LongValue)other; + return mLong == value.mLong; + } + return false; + } + } + + private static class ShortValue extends Value { + private short mShort; + + ShortValue(short s) { + mShort = s; + } + + @Override + public String toString() { + return Short.toString(mShort); + } + + @Override public boolean equals(Object other) { + if (other instanceof ShortValue) { + ShortValue value = (ShortValue)other; + return mShort == value.mShort; + } + return false; } - return false; } } diff --git a/tools/ahat/test/DiffFieldsTest.java b/tools/ahat/test/DiffFieldsTest.java index 6abdd47ef6..7dc519d60b 100644 --- a/tools/ahat/test/DiffFieldsTest.java +++ b/tools/ahat/test/DiffFieldsTest.java @@ -30,26 +30,26 @@ import static org.junit.Assert.assertNull; public class DiffFieldsTest { @Test public void normalMatchedDiffedFieldValues() { - FieldValue normal1 = new FieldValue("name", "type", new Value(1)); - FieldValue normal2 = new FieldValue("name", "type", new Value(2)); + FieldValue normal1 = new FieldValue("name", "type", Value.pack(1)); + FieldValue normal2 = new FieldValue("name", "type", Value.pack(2)); DiffedFieldValue x = DiffedFieldValue.matched(normal1, normal2); assertEquals("name", x.name); assertEquals("type", x.type); - assertEquals(new Value(1), x.current); - assertEquals(new Value(2), x.baseline); + assertEquals(Value.pack(1), x.current); + assertEquals(Value.pack(2), x.baseline); assertEquals(DiffedFieldValue.Status.MATCHED, x.status); } @Test public void nulledMatchedDiffedFieldValues() { - FieldValue normal = new FieldValue("name", "type", new Value(1)); + FieldValue normal = new FieldValue("name", "type", Value.pack(1)); FieldValue nulled = new FieldValue("name", "type", null); DiffedFieldValue x = DiffedFieldValue.matched(normal, nulled); assertEquals("name", x.name); assertEquals("type", x.type); - assertEquals(new Value(1), x.current); + assertEquals(Value.pack(1), x.current); assertNull(x.baseline); assertEquals(DiffedFieldValue.Status.MATCHED, x.status); @@ -57,18 +57,18 @@ public class DiffFieldsTest { assertEquals("name", y.name); assertEquals("type", y.type); assertNull(y.current); - assertEquals(new Value(1), y.baseline); + assertEquals(Value.pack(1), y.baseline); assertEquals(DiffedFieldValue.Status.MATCHED, y.status); } @Test public void normalAddedDiffedFieldValues() { - FieldValue normal = new FieldValue("name", "type", new Value(1)); + FieldValue normal = new FieldValue("name", "type", Value.pack(1)); DiffedFieldValue x = DiffedFieldValue.added(normal); assertEquals("name", x.name); assertEquals("type", x.type); - assertEquals(new Value(1), x.current); + assertEquals(Value.pack(1), x.current); assertEquals(DiffedFieldValue.Status.ADDED, x.status); } @@ -85,12 +85,12 @@ public class DiffFieldsTest { @Test public void normalDeletedDiffedFieldValues() { - FieldValue normal = new FieldValue("name", "type", new Value(1)); + FieldValue normal = new FieldValue("name", "type", Value.pack(1)); DiffedFieldValue x = DiffedFieldValue.deleted(normal); assertEquals("name", x.name); assertEquals("type", x.type); - assertEquals(new Value(1), x.baseline); + assertEquals(Value.pack(1), x.baseline); assertEquals(DiffedFieldValue.Status.DELETED, x.status); } |