1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 Google Inc. 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.hit; 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.ByteArrayInputStream; 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.DataInputStream; 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Set; 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class ArrayInstance extends Instance { 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int mType; 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private int mNumEntries; 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project private byte[] mData; 27de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 28de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro public ArrayInstance(long id, StackTrace stack, int type, int numEntries, 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project byte[] data) { 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mId = id; 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mStack = stack; 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mType = type; 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mNumEntries = numEntries; 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mData = data; 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void resolveReferences(State state) { 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mType != Types.OBJECT) { 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 41de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mData holds a stream of object instance ids 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Spin through them all and list ourselves as a reference holder. 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idSize = Types.getTypeSize(mType); 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final int N = mNumEntries; 48de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArrayInputStream bais = new ByteArrayInputStream(mData); 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataInputStream dis = new DataInputStream(bais); 51de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < N; i++) { 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long id; 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idSize == 4) { 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = dis.readInt(); 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = dis.readLong(); 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Instance instance = state.findReference(id); 63de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instance != null) { 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instance.addParent(this); 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (java.io.IOException e) { 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project e.printStackTrace(); 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final int getSize() { 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return mData.length; 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final void visit(Set<Instance> resultSet, Filter filter) { 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // If we're in the set then we and our children have been visited 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (resultSet.contains(this)) { 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 84de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (null != filter) { 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (filter.accept(this)) { 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultSet.add(this); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project resultSet.add(this); 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mType != Types.OBJECT) { 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 96de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mData holds a stream of object instance ids 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Spin through them all and visit them 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idSize = Types.getTypeSize(mType); 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final int N = mNumEntries; 103de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArrayInputStream bais = new ByteArrayInputStream(mData); 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataInputStream dis = new DataInputStream(bais); 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project State state = mHeap.mState; 107de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < N; i++) { 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long id; 110de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idSize == 4) { 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = dis.readInt(); 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = dis.readLong(); 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 117de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project Instance instance = state.findReference(id); 119de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (instance != null) { 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project instance.visit(resultSet, filter); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (java.io.IOException e) { 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project e.printStackTrace(); 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final String getTypeName() { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return Types.getTypeName(mType) + "[" + mNumEntries + "]"; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public final String toString() { 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return String.format("%s@0x08x", getTypeName(), mId); 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project @Override 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project public String describeReferenceTo(long referent) { 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // If this isn't an object array then we can't refer to an object 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (mType != Types.OBJECT) { 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return super.describeReferenceTo(referent); 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 144de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int idSize = Types.getTypeSize(mType); 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project final int N = mNumEntries; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numRefs = 0; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project StringBuilder result = new StringBuilder("Elements ["); 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ByteArrayInputStream bais = new ByteArrayInputStream(mData); 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataInputStream dis = new DataInputStream(bais); 151de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Spin through all the objects and build up a string describing 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * all of the array elements that refer to the target object. 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (int i = 0; i < N; i++) { 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long id; 158de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project try { 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idSize == 4) { 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = dis.readInt(); 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = dis.readLong(); 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 165de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (id == referent) { 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project numRefs++; 168de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (numRefs > 1) { 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(", "); 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 172de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append(i); 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } catch (java.io.IOException e) { 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project e.printStackTrace(); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 179de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (numRefs == 0) { 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return super.describeReferenceTo(referent); 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result.append("]"); 185de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result.toString(); 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 189