Automated import from //branches/donutburger/...@140700,140700

This commit is contained in:
Andy McFadden
2009-03-24 18:15:57 -07:00
committed by The Android Open Source Project
parent d4c5f8919b
commit 07970839eb
5 changed files with 236 additions and 5 deletions

View File

@@ -20,17 +20,20 @@ import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
import org.apache.harmony.dalvik.ddmc.DdmServer;
import org.apache.harmony.dalvik.ddmc.DdmVmInternal;
import android.os.Debug;
import android.util.Config;
import android.util.Log;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Handle thread-related traffic.
* Handle native and virtual heap requests.
*/
public class DdmHandleHeap extends ChunkHandler {
public static final int CHUNK_HPIF = type("HPIF");
public static final int CHUNK_HPSG = type("HPSG");
public static final int CHUNK_HPDU = type("HPDU");
public static final int CHUNK_NHSG = type("NHSG");
public static final int CHUNK_HPGC = type("HPGC");
public static final int CHUNK_REAE = type("REAE");
@@ -49,6 +52,7 @@ public class DdmHandleHeap extends ChunkHandler {
public static void register() {
DdmServer.registerHandler(CHUNK_HPIF, mInstance);
DdmServer.registerHandler(CHUNK_HPSG, mInstance);
DdmServer.registerHandler(CHUNK_HPDU, mInstance);
DdmServer.registerHandler(CHUNK_NHSG, mInstance);
DdmServer.registerHandler(CHUNK_HPGC, mInstance);
DdmServer.registerHandler(CHUNK_REAE, mInstance);
@@ -80,6 +84,8 @@ public class DdmHandleHeap extends ChunkHandler {
return handleHPIF(request);
} else if (type == CHUNK_HPSG) {
return handleHPSGNHSG(request, false);
} else if (type == CHUNK_HPDU) {
return handleHPDU(request);
} else if (type == CHUNK_NHSG) {
return handleHPSGNHSG(request, true);
} else if (type == CHUNK_HPGC) {
@@ -97,7 +103,7 @@ public class DdmHandleHeap extends ChunkHandler {
}
/*
* Handle a "HeaP InFo request".
* Handle a "HeaP InFo" request.
*/
private Chunk handleHPIF(Chunk request) {
ByteBuffer in = wrapChunk(request);
@@ -136,6 +142,40 @@ public class DdmHandleHeap extends ChunkHandler {
}
}
/*
* Handle a "HeaP DUmp" request.
*
* This currently just returns a result code. We could pull up
* the entire contents of the file and return them, but hprof dump
* files can be a few megabytes.
*/
private Chunk handleHPDU(Chunk request) {
ByteBuffer in = wrapChunk(request);
byte result;
/* get the filename for the output file */
int len = in.getInt();
String fileName = getString(in, len);
if (Config.LOGD)
Log.d("ddm-heap", "Heap dump: file='" + fileName + "'");
try {
Debug.dumpHprofData(fileName);
result = 0;
} catch (UnsupportedOperationException uoe) {
Log.w("ddm-heap", "hprof dumps not supported in this VM");
result = -1;
} catch (IOException ioe) {
result = -1;
} catch (RuntimeException ioe) {
result = -1;
}
/* create a non-empty reply so the handler fires on completion */
byte[] reply = { result };
return new Chunk(CHUNK_HPDU, reply, 0, reply.length);
}
/*
* Handle a "HeaP Garbage Collection" request.
*/

View File

@@ -26,12 +26,13 @@ import android.os.Debug;
import java.nio.ByteBuffer;
/**
* Handle a HELO chunk.
* Handle "hello" messages and feature discovery.
*/
public class DdmHandleHello extends ChunkHandler {
public static final int CHUNK_HELO = type("HELO");
public static final int CHUNK_WAIT = type("WAIT");
public static final int CHUNK_FEAT = type("FEAT");
private static DdmHandleHello mInstance = new DdmHandleHello();
@@ -44,6 +45,7 @@ public class DdmHandleHello extends ChunkHandler {
*/
public static void register() {
DdmServer.registerHandler(CHUNK_HELO, mInstance);
DdmServer.registerHandler(CHUNK_FEAT, mInstance);
}
/**
@@ -73,12 +75,27 @@ public class DdmHandleHello extends ChunkHandler {
}
/**
* Handle a chunk of data. We're only registered for "HELO".
* Handle a chunk of data.
*/
public Chunk handleChunk(Chunk request) {
if (Config.LOGV)
Log.v("ddm-hello", "Handling " + name(request.type) + " chunk");
Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
int type = request.type;
if (type == CHUNK_HELO) {
return handleHELO(request);
} else if (type == CHUNK_FEAT) {
return handleFEAT(request);
} else {
throw new RuntimeException("Unknown packet "
+ ChunkHandler.name(type));
}
}
/*
* Handle introductory packet.
*/
private Chunk handleHELO(Chunk request) {
if (false)
return createFailChunk(123, "This is a test");
@@ -125,6 +142,34 @@ public class DdmHandleHello extends ChunkHandler {
return reply;
}
/*
* Handle request for list of supported features.
*/
private Chunk handleFEAT(Chunk request) {
// TODO: query the VM to ensure that support for these features
// is actually compiled in
final String[] features = {
"hprof-heap-dump", "method-trace-profiling"
};
if (Config.LOGD)
Log.d("ddm-heap", "Got feature list request");
int size = 4 + 4 * features.length;
for (int i = features.length-1; i >= 0; i--)
size += features[i].length() * 2;
ByteBuffer out = ByteBuffer.allocate(size);
out.order(ChunkHandler.CHUNK_ORDER);
out.putInt(features.length);
for (int i = features.length-1; i >= 0; i--) {
out.putInt(features[i].length());
putString(out, features[i]);
}
return new Chunk(CHUNK_FEAT, out);
}
/**
* Send up a WAIT chunk. The only currently defined value for "reason"
* is zero, which means "waiting for a debugger".

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2009 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.
*/
package android.ddm;
import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
import org.apache.harmony.dalvik.ddmc.DdmServer;
import android.os.Debug;
import android.util.Config;
import android.util.Log;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Handle profiling requests.
*/
public class DdmHandleProfiling extends ChunkHandler {
public static final int CHUNK_MPRS = type("MPRS");
public static final int CHUNK_MPRE = type("MPRE");
public static final int CHUNK_MPRQ = type("MPRQ");
private static DdmHandleProfiling mInstance = new DdmHandleProfiling();
/* singleton, do not instantiate */
private DdmHandleProfiling() {}
/**
* Register for the messages we're interested in.
*/
public static void register() {
DdmServer.registerHandler(CHUNK_MPRS, mInstance);
DdmServer.registerHandler(CHUNK_MPRE, mInstance);
DdmServer.registerHandler(CHUNK_MPRQ, mInstance);
}
/**
* Called when the DDM server connects. The handler is allowed to
* send messages to the server.
*/
public void connected() {}
/**
* Called when the DDM server disconnects. Can be used to disable
* periodic transmissions or clean up saved state.
*/
public void disconnected() {}
/**
* Handle a chunk of data.
*/
public Chunk handleChunk(Chunk request) {
if (Config.LOGV)
Log.v("ddm-heap", "Handling " + name(request.type) + " chunk");
int type = request.type;
if (type == CHUNK_MPRS) {
return handleMPRS(request);
} else if (type == CHUNK_MPRE) {
return handleMPRE(request);
} else if (type == CHUNK_MPRQ) {
return handleMPRQ(request);
} else {
throw new RuntimeException("Unknown packet "
+ ChunkHandler.name(type));
}
}
/*
* Handle a "Method PRofiling Start" request.
*/
private Chunk handleMPRS(Chunk request) {
ByteBuffer in = wrapChunk(request);
int bufferSize = in.getInt();
int flags = in.getInt();
int len = in.getInt();
String fileName = getString(in, len);
if (Config.LOGV)
Log.v("ddm-heap", "Method profiling start: filename='" + fileName
+ "', size=" + bufferSize + ", flags=" + flags);
try {
Debug.startMethodTracing(fileName, bufferSize, flags);
return null; // empty response
} catch (RuntimeException re) {
return createFailChunk(1, re.getMessage());
}
}
/*
* Handle a "Method PRofiling End" request.
*/
private Chunk handleMPRE(Chunk request) {
byte result;
try {
Debug.stopMethodTracing();
result = 0;
} catch (RuntimeException re) {
Log.w("ddm-heap", "Method profiling end failed: "
+ re.getMessage());
result = 1;
}
/* create a non-empty reply so the handler fires on completion */
byte[] reply = { result };
return new Chunk(CHUNK_MPRE, reply, 0, reply.length);
}
/*
* Handle a "Method PRofiling Query" request.
*/
private Chunk handleMPRQ(Chunk request) {
int result = Debug.isMethodTracingActive() ? 1 : 0;
/* create a non-empty reply so the handler fires on completion */
byte[] reply = { (byte) result };
return new Chunk(CHUNK_MPRQ, reply, 0, reply.length);
}
}

View File

@@ -50,6 +50,7 @@ public class DdmRegister {
DdmHandleThread.register();
DdmHandleHeap.register();
DdmHandleNativeHeap.register();
DdmHandleProfiling.register();
DdmHandleExit.register();
DdmServer.registrationComplete();

View File

@@ -363,6 +363,14 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo
VMDebug.startMethodTracing(pathName, bufferSize, flags);
}
/**
* Determine whether method tracing is currently active.
* @hide
*/
public static boolean isMethodTracingActive() {
return VMDebug.isMethodTracingActive();
}
/**
* Stop method tracing.
*/