This tool is no longer required
Change-Id: I4738464d5eaa1c8a8f0619c1405efc726fd1a30a
This commit is contained in:
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class LooperTraceToTraceview {
|
||||
private static final int CURRENT_VERSION = 1;
|
||||
|
||||
private static class Entry {
|
||||
int traceId;
|
||||
long wallStart;
|
||||
long wallTime;
|
||||
long threadStart;
|
||||
long threadTime;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
System.out.println("Usage: java LooperTraceToTraceview <filename> <output>");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
File inputFile = new File(args[0]);
|
||||
FileInputStream fis = new FileInputStream(inputFile);
|
||||
DataInputStream in = new DataInputStream(new BufferedInputStream(fis));
|
||||
|
||||
int version = in.readInt();
|
||||
if (version != CURRENT_VERSION) {
|
||||
System.out.println("Only traces of version " + CURRENT_VERSION + " are supported");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
long wallStart = in.readLong();
|
||||
long threadStart = in.readLong();
|
||||
|
||||
int count = in.readInt();
|
||||
HashMap<String, Integer> names = new HashMap<String, Integer>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
readName(in, names);
|
||||
}
|
||||
|
||||
count = in.readInt();
|
||||
ArrayList<Entry> entries = new ArrayList<Entry>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
entries.add(readEntry(in));
|
||||
}
|
||||
|
||||
File outputFile = new File(args[1]);
|
||||
FileOutputStream fos = new FileOutputStream(outputFile);
|
||||
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(fos));
|
||||
|
||||
writeHeader(out, wallStart, names, entries);
|
||||
out.flush();
|
||||
|
||||
writeTraces(fos, out.size(), wallStart, threadStart, entries);
|
||||
|
||||
out.close();
|
||||
}
|
||||
|
||||
private static void writeTraces(FileOutputStream out, long offset, long wallStart,
|
||||
long threadStart, ArrayList<Entry> entries) throws IOException {
|
||||
|
||||
FileChannel channel = out.getChannel();
|
||||
|
||||
// Header
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(32);
|
||||
buffer.put("SLOW".getBytes());
|
||||
buffer = buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putShort((short) 3); // version
|
||||
buffer.putShort((short) 32); // offset to data
|
||||
buffer.putLong(wallStart); // start time in usec
|
||||
buffer.putShort((short) 14); // size of a record in bytes
|
||||
// padding to 32 bytes
|
||||
for (int i = 0; i < 32 - 18; i++) buffer.put((byte) 0);
|
||||
|
||||
buffer.flip();
|
||||
channel.position(offset).write(buffer);
|
||||
|
||||
buffer = ByteBuffer.allocateDirect(14).order(ByteOrder.LITTLE_ENDIAN);
|
||||
for (Entry entry : entries) {
|
||||
buffer.putShort((short) 1);
|
||||
buffer.putInt(entry.traceId); // entering method
|
||||
buffer.putInt((int) (entry.threadStart - threadStart));
|
||||
buffer.putInt((int) (entry.wallStart - wallStart));
|
||||
|
||||
buffer.flip();
|
||||
channel.write(buffer);
|
||||
buffer.clear();
|
||||
|
||||
buffer.putShort((short) 1);
|
||||
buffer.putInt(entry.traceId | 0x1); // exiting method
|
||||
buffer.putInt((int) (entry.threadStart + entry.threadTime - threadStart));
|
||||
buffer.putInt((int) (entry.wallStart + entry.wallTime - wallStart));
|
||||
|
||||
buffer.flip();
|
||||
channel.write(buffer);
|
||||
buffer.clear();
|
||||
}
|
||||
|
||||
channel.close();
|
||||
}
|
||||
|
||||
private static void writeHeader(DataOutputStream out, long start,
|
||||
HashMap<String, Integer> names, ArrayList<Entry> entries) throws IOException {
|
||||
|
||||
Entry last = entries.get(entries.size() - 1);
|
||||
long wallTotal = (last.wallStart + last.wallTime) - start;
|
||||
|
||||
startSection("version", out);
|
||||
addValue(null, "3", out);
|
||||
addValue("data-file-overflow", "false", out);
|
||||
addValue("clock", "dual", out);
|
||||
addValue("elapsed-time-usec", Long.toString(wallTotal), out);
|
||||
addValue("num-method-calls", Integer.toString(entries.size()), out);
|
||||
addValue("clock-call-overhead-nsec", "1", out);
|
||||
addValue("vm", "dalvik", out);
|
||||
|
||||
startSection("threads", out);
|
||||
addThreadId(1, "main", out);
|
||||
|
||||
startSection("methods", out);
|
||||
addMethods(names, out);
|
||||
|
||||
startSection("end", out);
|
||||
}
|
||||
|
||||
private static void addMethods(HashMap<String, Integer> names, DataOutputStream out)
|
||||
throws IOException {
|
||||
|
||||
for (Map.Entry<String, Integer> name : names.entrySet()) {
|
||||
out.writeBytes("0x" + String.format("%08x", name.getValue()) + "\tEventQueue\t" +
|
||||
name.getKey().replace('$', '_') + "\t()V\tLooper.java\t-2\n");
|
||||
}
|
||||
}
|
||||
|
||||
private static void addThreadId(int id, String name, DataOutputStream out) throws IOException {
|
||||
out.writeBytes(Integer.toString(id) + '\t' + name + '\n');
|
||||
}
|
||||
|
||||
private static void addValue(String name, String value, DataOutputStream out)
|
||||
throws IOException {
|
||||
|
||||
if (name != null) {
|
||||
out.writeBytes(name + "=");
|
||||
}
|
||||
out.writeBytes(value + '\n');
|
||||
}
|
||||
|
||||
private static void startSection(String name, DataOutputStream out) throws IOException {
|
||||
out.writeBytes("*" + name + '\n');
|
||||
}
|
||||
|
||||
private static void readName(DataInputStream in, HashMap<String, Integer> names)
|
||||
throws IOException {
|
||||
int id = 0x56000000 | (in.readShort() << 2);
|
||||
String name = in.readUTF();
|
||||
names.put(name, id);
|
||||
}
|
||||
|
||||
private static Entry readEntry(DataInputStream in) throws IOException {
|
||||
Entry entry = new Entry();
|
||||
entry.traceId = 0x56000000 | (in.readShort() << 2);
|
||||
entry.wallStart = in.readLong();
|
||||
entry.wallTime = in.readLong();
|
||||
entry.threadStart = in.readLong();
|
||||
entry.threadTime = in.readLong();
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
LooperProfiler is a simple tool to convert and display looper traces.
|
||||
7/15/2011
|
||||
|
||||
Note: LooperProfiler is a crude tool and needs more work.
|
||||
|
||||
Looper traces are generated by invoking ViewDebug.startLooperProfiling()
|
||||
and ViewDebug.stopLooperProfiling().
|
||||
|
||||
After profiling the file must be pulled from the device using adb pull.
|
||||
|
||||
To use this tool, compile the single .java file and run:
|
||||
java LooperTraceToTraceView myLooperTracesFile looperTraceViewFile
|
||||
|
||||
The run traceview looperTraceViewFile
|
||||
Reference in New Issue
Block a user