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