diff options
author | Andy McFadden <fadden@android.com> | 2010-01-26 07:37:22 -0800 |
---|---|---|
committer | Andy McFadden <fadden@android.com> | 2010-01-27 14:42:51 -0800 |
commit | 99cb03c8593d49efdf70cba8adc84231789dae07 (patch) | |
tree | f1314b91a72538b2b5945105d75be8d0487c0b4f /ddms | |
parent | c76fb53baf9b393f06c70bbb0b671dd1792802ac (diff) | |
download | sdk-99cb03c8593d49efdf70cba8adc84231789dae07.zip sdk-99cb03c8593d49efdf70cba8adc84231789dae07.tar.gz sdk-99cb03c8593d49efdf70cba8adc84231789dae07.tar.bz2 |
Strawman support for streaming method profiling.
This will send MPSS/MPSE packets instead of MPRS/MPRE when the client VM
supports them. At least, it would if the property check weren't
hard-wired to false, which is done because the MPSE handling in DDMS is
incomplete (currently just dumps the first 100 chars so you can see that
it really got something).
For bug 2160407.
Diffstat (limited to 'ddms')
3 files changed, 81 insertions, 4 deletions
diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java index d05fa14..52c9506 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java @@ -241,13 +241,22 @@ public class Client { } public void toggleMethodProfiling() { + boolean canStream = false; //mClientData.hasFeature(ClientData.FEATURE_PROFILING_STREAMING); try { if (mClientData.getMethodProfilingStatus() == MethodProfilingStatus.ON) { - HandleProfiling.sendMPRE(this); + if (canStream) { + HandleProfiling.sendMPSE(this); + } else { + HandleProfiling.sendMPRE(this); + } } else { - String file = "/sdcard/" + mClientData.getClientDescription().replaceAll("\\:.*", "") + - ".trace"; - HandleProfiling.sendMPRS(this, file, 8*1024*1024, 0 /*flags*/); + if (canStream) { + HandleProfiling.sendMPSS(this, 8*1024*1024, 0 /*flags*/); + } else { + String file = "/sdcard/" + mClientData.getClientDescription().replaceAll("\\:.*", "") + + ".trace"; + HandleProfiling.sendMPRS(this, file, 8*1024*1024, 0 /*flags*/); + } } } catch (IOException e) { Log.w("ddms", "Toggle method profiling failed"); diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java b/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java index 356f5d0..53e1352 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/ClientData.java @@ -124,6 +124,12 @@ public class ClientData { public final static String FEATURE_PROFILING = "method-trace-profiling"; // $NON-NLS-1$ /** + * String for feature enabling direct streaming of method profiling data + * @see #hasFeature(String) + */ + public final static String FEATURE_PROFILING_STREAMING = "method-trace-profiling-streaming"; // $NON-NLS-1$ + + /** * String for feature allowing to dump hprof files * @see #hasFeature(String) */ diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java index 3b69973..fcc1d26 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/HandleProfiling.java @@ -29,6 +29,8 @@ final class HandleProfiling extends ChunkHandler { public static final int CHUNK_MPRS = type("MPRS"); public static final int CHUNK_MPRE = type("MPRE"); + public static final int CHUNK_MPSS = type("MPSS"); + public static final int CHUNK_MPSE = type("MPSE"); public static final int CHUNK_MPRQ = type("MPRQ"); public static final int CHUNK_FAIL = type("FAIL"); @@ -41,6 +43,7 @@ final class HandleProfiling extends ChunkHandler { */ public static void register(MonitorThread mt) { mt.registerChunkHandler(CHUNK_MPRE, mInst); + mt.registerChunkHandler(CHUNK_MPSE, mInst); mt.registerChunkHandler(CHUNK_MPRQ, mInst); } @@ -67,6 +70,8 @@ final class HandleProfiling extends ChunkHandler { if (type == CHUNK_MPRE) { handleMPRE(client, data); + } else if (type == CHUNK_MPSE) { + handleMPSE(client, data); } else if (type == CHUNK_MPRQ) { handleMPRQ(client, data); } else if (type == CHUNK_FAIL) { @@ -160,6 +165,63 @@ final class HandleProfiling extends ChunkHandler { } /** + * Send a MPSS (Method Profiling Streaming Start) request to the client. + * + * The arguments to this method will eventually be passed to + * android.os.Debug.startMethodTracing() on the device. + * + * @param bufferSize is the desired buffer size in bytes (8MB is good) + * @param flags see startMethodTracing() docs; use 0 for default behavior + */ + public static void sendMPSS(Client client, int bufferSize, + int flags) throws IOException { + + ByteBuffer rawBuf = allocBuffer(2*4); + JdwpPacket packet = new JdwpPacket(rawBuf); + ByteBuffer buf = getChunkDataBuf(rawBuf); + + buf.putInt(bufferSize); + buf.putInt(flags); + + finishChunkPacket(packet, CHUNK_MPSS, buf.position()); + Log.d("ddm-prof", "Sending " + name(CHUNK_MPSS) + + "', size=" + bufferSize + ", flags=" + flags); + client.sendAndConsume(packet, mInst); + + // send a status query. this ensure that the status is properly updated if for some + // reason starting the tracing failed. + sendMPRQ(client); + } + + /** + * Send a MPSE (Method Profiling Streaming End) request to the client. + */ + public static void sendMPSE(Client client) throws IOException { + ByteBuffer rawBuf = allocBuffer(0); + JdwpPacket packet = new JdwpPacket(rawBuf); + ByteBuffer buf = getChunkDataBuf(rawBuf); + + // no data + + finishChunkPacket(packet, CHUNK_MPSE, buf.position()); + Log.d("ddm-prof", "Sending " + name(CHUNK_MPSE)); + client.sendAndConsume(packet, mInst); + } + + /** + * Handle incoming profiling data. The MPSE packet includes the + * complete .trace file. + */ + private void handleMPSE(Client client, ByteBuffer data) { + // TODO + byte[] stuff = new byte[Math.min(100, data.capacity())]; + data.get(stuff, 0, stuff.length); + String sample = new String(stuff); + Log.e("ddm-prof", "GOT MPSE (" + data.capacity() + " bytes): '" + + sample + "' ..."); + } + + /** * Send a MPRQ (Method PRofiling Query) request to the client. */ public static void sendMPRQ(Client client) throws IOException { |