1cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom/*
2cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * Copyright (C) 2010 The Android Open Source Project
3cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom *
4cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * you may not use this file except in compliance with the License.
6cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * You may obtain a copy of the License at
7cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom *
8cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom *
10cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * Unless required by applicable law or agreed to in writing, software
11cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * See the License for the specific language governing permissions and
14cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom * limitations under the License.
15cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom */
16cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
17cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrompackage dalvik.system.profiler;
18cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
19cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport java.io.IOException;
20cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport java.io.OutputStream;
21cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport java.io.PrintWriter;
22cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport java.util.ArrayList;
23cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport java.util.Collections;
24cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport java.util.Comparator;
25cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport java.util.Date;
26cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstromimport java.util.List;
27cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
28e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom/**
29e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom * AsciiHprofWriter produces hprof compatible text output for use with
30e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom * third party tools such as PerfAnal.
31e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom */
32e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrompublic final class AsciiHprofWriter {
33cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
34cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom    private final HprofData data;
35cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom    private final PrintWriter out;
36cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
37e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom    /**
38e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom     * Writes the provided data to the specified stream.
39e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom     */
40e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom    public static void write(HprofData data, OutputStream outputStream) throws IOException {
41e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom        new AsciiHprofWriter(data, outputStream).write();
42e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom    }
43e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom
44e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom    private AsciiHprofWriter(HprofData data, OutputStream outputStream) {
45cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        this.data = data;
46cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        this.out = new PrintWriter(outputStream);
47cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom    }
48cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
49e9af8901fc4ed7c05d085e2e492f5dcc857f0146Brian Carlstrom    private void write() throws IOException {
50cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        for (HprofData.ThreadEvent e : data.getThreadHistory()) {
51cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            out.println(e);
52cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        }
53cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
54cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        List<HprofData.Sample> samples
55cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom                = new ArrayList<HprofData.Sample>(data.getSamples());
56cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        Collections.sort(samples, SAMPLE_COMPARATOR);
57cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        int total = 0;
58cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        for (HprofData.Sample sample : samples) {
59cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            HprofData.StackTrace stackTrace = sample.stackTrace;
60cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            int count = sample.count;
61cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            total += count;
62cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            out.printf("TRACE %d: (thread=%d)\n",
63cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom                       stackTrace.stackTraceId,
64cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom                       stackTrace.threadId);
65cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            for (StackTraceElement e : stackTrace.stackFrames) {
66cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom                out.printf("\t%s\n", e);
67cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            }
68cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        }
69cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        Date now = new Date(data.getStartMillis());
70cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        // "CPU SAMPLES BEGIN (total = 826) Wed Jul 21 12:03:46 2010"
71cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        out.printf("CPU SAMPLES BEGIN (total = %d) %ta %tb %td %tT %tY\n",
72cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom                   total, now, now, now, now, now);
73cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        out.printf("rank   self  accum   count trace method\n");
74cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        int rank = 0;
75cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        double accum = 0;
76cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        for (HprofData.Sample sample : samples) {
77cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            rank++;
78cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            HprofData.StackTrace stackTrace = sample.stackTrace;
79cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            int count = sample.count;
80cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            double self = (double)count/(double)total;
81cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            accum += self;
82cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
83cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            // "   1 65.62% 65.62%     542 300302 java.lang.Long.parseLong"
84cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            out.printf("% 4d% 6.2f%%% 6.2f%% % 7d % 5d %s.%s\n",
85cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom                       rank, self*100, accum*100, count, stackTrace.stackTraceId,
86cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom                       stackTrace.stackFrames[0].getClassName(),
87cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom                       stackTrace.stackFrames[0].getMethodName());
88cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        }
89cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        out.printf("CPU SAMPLES END\n");
90cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        out.flush();
91cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom    }
92cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom
93cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom    private static final Comparator<HprofData.Sample> SAMPLE_COMPARATOR
94cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            = new Comparator<HprofData.Sample>() {
95cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        public int compare(HprofData.Sample s1, HprofData.Sample s2) {
96cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom            return s2.count - s1.count;
97cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom        }
98cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom    };
99cfa84a2aac159bb8a1763298882df7aa98f7fc6fBrian Carlstrom}
100