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.ByteArrayOutputStream;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.DataInputStream;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.InputStream;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.EOFException;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.IOException;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.HashMap;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class HprofParser
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int STRING_IN_UTF8             =   0x01;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int LOAD_CLASS                 =   0x02;
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int UNLOAD_CLASS               =   0x03;   //  unused
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int STACK_FRAME                =   0x04;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int STACK_TRACE                =   0x05;
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ALLOC_SITES                =   0x06;   //  unused
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int HEAP_SUMMARY               =   0x07;
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int START_THREAD               =   0x0a;   //  unused
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int END_THREAD                 =   0x0b;   //  unused
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int HEAP_DUMP                  =   0x0c;
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int HEAP_DUMP_SEGMENT          =   0x1c;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int HEAP_DUMP_END              =   0x2c;
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int CPU_SAMPLES                =   0x0d;   //  unused
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int CONTROL_SETTINGS           =   0x0e;   //  unused
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_UNKNOWN               =   0xff;
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_JNI_GLOBAL            =   0x01;
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_JNI_LOCAL             =   0x02;
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_JAVA_FRAME            =   0x03;
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_NATIVE_STACK          =   0x04;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_STICKY_CLASS          =   0x05;
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_THREAD_BLOCK          =   0x06;
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_MONITOR_USED          =   0x07;
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_THREAD_OBJECT         =   0x08;
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_CLASS_DUMP            =   0x20;
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_INSTANCE_DUMP         =   0x21;
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_OBJECT_ARRAY_DUMP     =   0x22;
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_PRIMITIVE_ARRAY_DUMP  =   0x23;
56de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Android format addition
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Specifies information about which heap certain objects came from.
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * When a sub-tag of this type appears in a HPROF_HEAP_DUMP or
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * HPROF_HEAP_DUMP_SEGMENT record, entries that follow it will be
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * associated with the specified heap.  The HEAP_DUMP_INFO data is reset
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * at the end of the HEAP_DUMP[_SEGMENT].  Multiple HEAP_DUMP_INFO entries
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * may appear in a single HEAP_DUMP[_SEGMENT].
66de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Format:
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     u1: Tag value (0xFE)
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     u4: heap ID
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *     ID: heap name string ID
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_HEAP_DUMP_INFO        =   0xfe;
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_INTERNED_STRING       =   0x89;
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_FINALIZING            =   0x8a;
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_DEBUGGER              =   0x8b;
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_REFERENCE_CLEANUP     =   0x8c;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_VM_INTERNAL           =   0x8d;
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_JNI_MONITOR           =   0x8e;
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_UNREACHABLE           =   0x90;
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ROOT_PRIMITIVE_ARRAY_NODATA=   0xc3;
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    DataInputStream mInput;
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int mIdSize;
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    State mState;
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    byte[] mFieldBuffer = new byte[8];
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * These are only needed while parsing so are not kept as part of the
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * heap data.
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HashMap<Long, String> mStrings = new HashMap<Long, String>();
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    HashMap<Long, String> mClassNames = new HashMap<Long, String>();
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public HprofParser(DataInputStream in) {
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mInput = in;
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public final State parse() {
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        State state = new State();
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState = state;
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String  s = readNullTerminatedString();
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            DataInputStream in = mInput;
106de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            mIdSize = in.readInt();
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Types.setIdSize(mIdSize);
109de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            in.readLong();  //  Timestamp, ignored for now
111de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            while (true) {
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int tag = in.readUnsignedByte();
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int timestamp = in.readInt();
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int length = in.readInt();
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                switch (tag) {
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case STRING_IN_UTF8:
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        loadString(length - 4);
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        break;
121de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case LOAD_CLASS:
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        loadClass();
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        break;
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case STACK_FRAME:
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        loadStackFrame();
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        break;
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case STACK_TRACE:
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        loadStackTrace();
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        break;
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case HEAP_DUMP:
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        loadHeapDump(length);
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        mState.setToDefaultHeap();
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        break;
138de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    case HEAP_DUMP_SEGMENT:
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        loadHeapDump(length);
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        mState.setToDefaultHeap();
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        break;
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    default:
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        skipFully(length);
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (EOFException eof) {
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //  this is fine
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (Exception e) {
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            e.printStackTrace();
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.resolveReferences();
156de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return state;
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String readNullTerminatedString() throws IOException {
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuilder s = new StringBuilder();
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DataInputStream in = mInput;
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int c = in.read(); c != 0; c = in.read()) {
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            s.append((char) c);
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
167de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return s.toString();
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private long readId() throws IOException {
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (mIdSize) {
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1: return mInput.readUnsignedByte();
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2: return mInput.readUnsignedShort();
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 4: return ((long) mInput.readInt()) & 0x00000000ffffffffL;
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 8: return mInput.readLong();
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
178de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new IllegalArgumentException("ID Length must be 1, 2, 4, or 8");
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String readUTF8(int length) throws IOException {
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] b = new byte[length];
184de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mInput.read(b);
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new String(b, "utf-8");
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void loadString(int length) throws IOException {
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String string = readUTF8(length);
193de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mStrings.put(id, string);
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void loadClass() throws IOException {
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DataInputStream in = mInput;
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int serial = in.readInt();
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackTrace = in.readInt();              //  unused
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String name = mStrings.get(readId());
203de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mClassNames.put(id, name);
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void loadStackFrame() throws IOException {
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String methodName = mStrings.get(readId());
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String methodSignature = mStrings.get(readId());
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String sourceFile = mStrings.get(readId());
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int serial = mInput.readInt();
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int lineNumber = mInput.readInt();
214de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
215de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        StackFrame frame = new StackFrame(id, methodName, methodSignature,
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            sourceFile, serial, lineNumber);
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addStackFrame(frame);
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void loadStackTrace() throws IOException {
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int serialNumber = mInput.readInt();
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int threadSerialNumber = mInput.readInt();
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        final int numFrames = mInput.readInt();
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackFrame[] frames = new StackFrame[numFrames];
226de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < numFrames; i++) {
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            frames[i] = mState.getStackFrame(readId());
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
230de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
231de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        StackTrace trace = new StackTrace(serialNumber, threadSerialNumber,
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            frames);
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addStackTrace(trace);
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void loadHeapDump(int length) throws IOException {
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DataInputStream in = mInput;
239de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (length > 0) {
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int tag = in.readUnsignedByte();
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            length--;
243de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            switch (tag) {
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_UNKNOWN:
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.UNKNOWN);
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
248de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_JNI_GLOBAL:
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.NATIVE_STATIC);
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    readId();   //  ignored
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= mIdSize;
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
254de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_JNI_LOCAL:
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadJniLocal();
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
258de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_JAVA_FRAME:
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadJavaFrame();
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
262de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_NATIVE_STACK:
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadNativeStack();
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
266de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_STICKY_CLASS:
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.SYSTEM_CLASS);
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
270de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_THREAD_BLOCK:
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadThreadBlock();
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
274de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_MONITOR_USED:
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.BUSY_MONITOR);
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
278de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_THREAD_OBJECT:
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadThreadObject();
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
282de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_CLASS_DUMP:
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadClassDump();
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
286de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_INSTANCE_DUMP:
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadInstanceDump();
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
290de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_OBJECT_ARRAY_DUMP:
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadObjectArrayDump();
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
294de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_PRIMITIVE_ARRAY_DUMP:
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadPrimitiveArrayDump();
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_PRIMITIVE_ARRAY_NODATA:
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    System.err.println("+--- PRIMITIVE ARRAY NODATA DUMP");
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadPrimitiveArrayDump();
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new IllegalArgumentException(
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        "Don't know how to load a nodata array");
305de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_HEAP_DUMP_INFO:
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    int heapId = mInput.readInt();
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    long heapNameId = readId();
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    String heapName = mStrings.get(heapNameId);
310de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    mState.setHeapTo(heapId, heapName);
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= 4 + mIdSize;
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
314de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_INTERNED_STRING:
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.INTERNED_STRING);
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
318de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_FINALIZING:
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.FINALIZING);
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
322de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_DEBUGGER:
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.DEBUGGER);
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
326de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_REFERENCE_CLEANUP:
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.REFERENCE_CLEANUP);
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
330de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_VM_INTERNAL:
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.VM_INTERNAL);
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
334de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_JNI_MONITOR:
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadJniMonitor();
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
338de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                case ROOT_UNREACHABLE:
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    length -= loadBasicObj(RootType.UNREACHABLE);
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    break;
342de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                default:
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    throw new IllegalArgumentException(
345de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro                        "loadHeapDump loop with unknown tag " + tag
346de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro                        + " with " + mInput.available()
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        + " bytes possibly remaining");
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
351de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadJniLocal() throws IOException {
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int threadSerialNumber = mInput.readInt();
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackFrameNumber = mInput.readInt();
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ThreadObj thread = mState.getThread(threadSerialNumber);
357de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        StackTrace trace = mState.getStackTraceAtDepth(thread.mStackTrace,
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            stackFrameNumber);
359de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        RootObj root = new RootObj(RootType.NATIVE_LOCAL, id,
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            threadSerialNumber, trace);
361de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        root.setHeap(mState.mCurrentHeap);
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addRoot(root);
364de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4 + 4;
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadJavaFrame() throws IOException {
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int threadSerialNumber = mInput.readInt();
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackFrameNumber = mInput.readInt();
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ThreadObj thread = mState.getThread(threadSerialNumber);
373de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        StackTrace trace = mState.getStackTraceAtDepth(thread.mStackTrace,
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            stackFrameNumber);
375de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        RootObj root = new RootObj(RootType.JAVA_LOCAL, id, threadSerialNumber,
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            trace);
377de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        root.setHeap(mState.mCurrentHeap);
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addRoot(root);
380de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4 + 4;
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
383de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadNativeStack() throws IOException {
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int threadSerialNumber = mInput.readInt();
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ThreadObj thread = mState.getThread(threadSerialNumber);
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackTrace trace = mState.getStackTrace(thread.mStackTrace);
389de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        RootObj root = new RootObj(RootType.NATIVE_STACK, id,
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            threadSerialNumber, trace);
391de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        root.setHeap(mState.mCurrentHeap);
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addRoot(root);
394de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4;
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadBasicObj(RootType type) throws IOException {
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        RootObj root = new RootObj(type, id);
401de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        root.setHeap(mState.mCurrentHeap);
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addRoot(root);
404de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize;
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadThreadBlock() throws IOException {
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int threadSerialNumber = mInput.readInt();
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ThreadObj thread = mState.getThread(threadSerialNumber);
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackTrace stack = mState.getStackTrace(thread.mStackTrace);
413de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        RootObj root = new RootObj(RootType.THREAD_BLOCK, id,
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            threadSerialNumber, stack);
415de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        root.setHeap(mState.mCurrentHeap);
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addRoot(root);
418de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4;
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadThreadObject() throws IOException {
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int threadSerialNumber = mInput.readInt();
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackSerialNumber = mInput.readInt();
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ThreadObj thread = new ThreadObj(id, stackSerialNumber);
427de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addThread(thread, threadSerialNumber);
429de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4 + 4;
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadClassDump() throws IOException {
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int bytesRead = 0;
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DataInputStream in = mInput;
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackSerialNumber = in.readInt();
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackTrace stack = mState.getStackTrace(stackSerialNumber);
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long superClassId = readId();
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long classLoaderId = readId();
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long signersId = readId();
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long protectionDomainId = readId();
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long reserved1 = readId();
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long reserved2 = readId();
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int instanceSize = in.readInt();
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        bytesRead = (7 * mIdSize) + 4 + 4;
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //  Skip over the constant pool
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int numEntries = in.readUnsignedShort();
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        bytesRead += 2;
452de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < numEntries; i++) {
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            in.readUnsignedShort();
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bytesRead += 2 + skipValue();
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //  Static fields
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        numEntries = in.readUnsignedShort();
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        bytesRead += 2;
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] staticFieldNames = new String[numEntries];
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int[] staticFieldTypes = new int[numEntries];
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ByteArrayOutputStream staticFieldValues = new ByteArrayOutputStream();
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] buffer = mFieldBuffer;
466de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < numEntries; i++) {
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            staticFieldNames[i] = mStrings.get(readId());
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int fieldType = in.readByte();
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int fieldSize = Types.getTypeSize(fieldType);
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            staticFieldTypes[i] = fieldType;
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            in.readFully(buffer, 0, fieldSize);
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            staticFieldValues.write(buffer, 0, fieldSize);
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bytesRead += mIdSize + 1 + fieldSize;
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
479de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //  Instance fields
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        numEntries = in.readUnsignedShort();
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        bytesRead += 2;
483de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] names = new String[numEntries];
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int[] types = new int[numEntries];
486de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < numEntries; i++) {
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            long fieldName = readId();
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int type = in.readUnsignedByte();
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            names[i] = mStrings.get(fieldName);
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            types[i] = type;
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            bytesRead += mIdSize + 1;
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
496de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassObj theClass = new ClassObj(id, stack, mClassNames.get(id));
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        theClass.setStaticFieldNames(staticFieldNames);
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        theClass.setStaticFieldTypes(staticFieldTypes);
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        theClass.setStaticFieldValues(staticFieldValues.toByteArray());
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        theClass.setSuperclassId(superClassId);
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        theClass.setFieldNames(names);
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        theClass.setFieldTypes(types);
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        theClass.setSize(instanceSize);
507de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        theClass.setHeap(mState.mCurrentHeap);
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addClass(id, theClass);
511de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return bytesRead;
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadInstanceDump() throws IOException {
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackId = mInput.readInt();
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackTrace stack = mState.getStackTrace(stackId);
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long classId = readId();
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int remaining = mInput.readInt();
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ClassInstance instance = new ClassInstance(id, stack, classId);
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        instance.loadFieldData(mInput, remaining);
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        instance.setHeap(mState.mCurrentHeap);
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addInstance(id, instance);
526de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4 + mIdSize + 4 + remaining;
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadObjectArrayDump() throws IOException {
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackId = mInput.readInt();
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackTrace stack = mState.getStackTrace(stackId);
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int numElements = mInput.readInt();
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long classId = readId();
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int totalBytes = numElements * mIdSize;
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] data = new byte[totalBytes];
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String className = mClassNames.get(classId);
539de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mInput.readFully(data);
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
542de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        ArrayInstance array = new ArrayInstance(id, stack, Types.OBJECT,
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            numElements, data);
544de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        array.mClassId = classId;
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        array.setHeap(mState.mCurrentHeap);
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addInstance(id, array);
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4 + 4 + mIdSize + totalBytes;
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
551de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadPrimitiveArrayDump() throws IOException {
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackId = mInput.readInt();
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StackTrace stack = mState.getStackTrace(stackId);
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int numElements = mInput.readInt();
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int type = mInput.readUnsignedByte();
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int size = Types.getTypeSize(type);
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int totalBytes = numElements * size;
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] data = new byte[totalBytes];
561de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mInput.readFully(data);
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
564de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        ArrayInstance array = new ArrayInstance(id, stack, type, numElements,
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            data);
566de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        array.setHeap(mState.mCurrentHeap);
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addInstance(id, array);
569de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4 + 4 + 1 + totalBytes;
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int loadJniMonitor() throws IOException {
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long id = readId();
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int threadSerialNumber = mInput.readInt();
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int stackDepth = mInput.readInt();
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ThreadObj thread = mState.getThread(threadSerialNumber);
578de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        StackTrace trace = mState.getStackTraceAtDepth(thread.mStackTrace,
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            stackDepth);
580de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro        RootObj root = new RootObj(RootType.NATIVE_MONITOR, id,
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            threadSerialNumber, trace);
582de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        root.setHeap(mState.mCurrentHeap);
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        mState.addRoot(root);
585de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mIdSize + 4 + 4;
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private int skipValue() throws IOException {
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int type = mInput.readUnsignedByte();
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int size = Types.getTypeSize(type);
592de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        skipFully(size);
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return size + 1;
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * BufferedInputStream will not skip(int) the entire requested number
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * of bytes if it extends past the current buffer boundary.  So, this
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * routine is needed to actually skip over the requested number of bytes
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * using as many iterations as needed.
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void skipFully(long numBytes) throws IOException {
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        while (numBytes > 0) {
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            long skipped = mInput.skip(numBytes);
607de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            numBytes -= skipped;
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
612