HandleNativeHeappublic final class HandleNativeHeap extends ChunkHandler Handle thread status updates. |
Fields Summary |
---|
public static final int | CHUNK_NHGT | public static final int | CHUNK_NHSG | public static final int | CHUNK_NHST | public static final int | CHUNK_NHEN | private static final HandleNativeHeap | mInst |
Constructors Summary |
---|
private HandleNativeHeap()
|
Methods Summary |
---|
public void | clientDisconnected(Client client)Client went away.
| public void | clientReady(Client client)Client is ready.
| public void | handleChunk(Client client, int type, java.nio.ByteBuffer data, boolean isReply, int msgId)Chunk handler entry point.
Log.d("ddm-nativeheap", "handling " + ChunkHandler.name(type));
if (type == CHUNK_NHGT) {
handleNHGT(client, data);
} else if (type == CHUNK_NHST) {
// start chunk before any NHSG chunk(s)
client.getClientData().getNativeHeapData().clearHeapData();
} else if (type == CHUNK_NHEN) {
// end chunk after NHSG chunk(s)
client.getClientData().getNativeHeapData().sealHeapData();
} else if (type == CHUNK_NHSG) {
handleNHSG(client, data);
} else {
handleUnknownChunk(client, type, data, isReply, msgId);
}
client.update(Client.CHANGE_NATIVE_HEAP_DATA);
| private void | handleNHGT(Client client, java.nio.ByteBuffer data)
ClientData cd = client.getClientData();
Log.d("ddm-nativeheap", "NHGT: " + data.limit() + " bytes");
// TODO - process incoming data and save in "cd"
byte[] copy = new byte[data.limit()];
data.get(copy);
// clear the previous run
cd.clearNativeAllocationInfo();
ByteBuffer buffer = ByteBuffer.wrap(copy);
buffer.order(ByteOrder.LITTLE_ENDIAN);
// read the header
// typedef struct Header {
// uint32_t mapSize;
// uint32_t allocSize;
// uint32_t allocInfoSize;
// uint32_t totalMemory;
// uint32_t backtraceSize;
// };
int mapSize = buffer.getInt();
int allocSize = buffer.getInt();
int allocInfoSize = buffer.getInt();
int totalMemory = buffer.getInt();
int backtraceSize = buffer.getInt();
Log.d("ddms", "mapSize: " + mapSize);
Log.d("ddms", "allocSize: " + allocSize);
Log.d("ddms", "allocInfoSize: " + allocInfoSize);
Log.d("ddms", "totalMemory: " + totalMemory);
cd.setTotalNativeMemory(totalMemory);
// this means that updates aren't turned on.
if (allocInfoSize == 0)
return;
if (mapSize > 0) {
byte[] maps = new byte[mapSize];
buffer.get(maps, 0, mapSize);
parseMaps(cd, maps);
}
int iterations = allocSize / allocInfoSize;
for (int i = 0 ; i < iterations ; i++) {
NativeAllocationInfo info = new NativeAllocationInfo(
buffer.getInt() /* size */,
buffer.getInt() /* allocations */);
for (int j = 0 ; j < backtraceSize ; j++) {
long addr = ((long)buffer.getInt()) & 0x00000000ffffffffL;
info.addStackCallAddress(addr);;
}
cd.addNativeAllocation(info);
}
| private void | handleNHSG(Client client, java.nio.ByteBuffer data)
byte dataCopy[] = new byte[data.limit()];
data.rewind();
data.get(dataCopy);
data = ByteBuffer.wrap(dataCopy);
client.getClientData().getNativeHeapData().addHeapData(data);
if (true) {
return;
}
// WORK IN PROGRESS
// Log.e("ddm-nativeheap", "NHSG: ----------------------------------");
// Log.e("ddm-nativeheap", "NHSG: " + data.limit() + " bytes");
byte[] copy = new byte[data.limit()];
data.get(copy);
ByteBuffer buffer = ByteBuffer.wrap(copy);
buffer.order(ByteOrder.BIG_ENDIAN);
int id = buffer.getInt();
int unitsize = (int) buffer.get();
long startAddress = (long) buffer.getInt() & 0x00000000ffffffffL;
int offset = buffer.getInt();
int allocationUnitCount = buffer.getInt();
// Log.e("ddm-nativeheap", "id: " + id);
// Log.e("ddm-nativeheap", "unitsize: " + unitsize);
// Log.e("ddm-nativeheap", "startAddress: 0x" + Long.toHexString(startAddress));
// Log.e("ddm-nativeheap", "offset: " + offset);
// Log.e("ddm-nativeheap", "allocationUnitCount: " + allocationUnitCount);
// Log.e("ddm-nativeheap", "end: 0x" +
// Long.toHexString(startAddress + unitsize * allocationUnitCount));
// read the usage
while (buffer.position() < buffer.limit()) {
int eState = (int)buffer.get() & 0x000000ff;
int eLen = ((int)buffer.get() & 0x000000ff) + 1;
//Log.e("ddm-nativeheap", "solidity: " + (eState & 0x7) + " - kind: "
// + ((eState >> 3) & 0x7) + " - len: " + eLen);
}
// count += unitsize * allocationUnitCount;
// Log.e("ddm-nativeheap", "count = " + count);
| private void | parseMaps(ClientData cd, byte[] maps)
InputStreamReader input = new InputStreamReader(new ByteArrayInputStream(maps));
BufferedReader reader = new BufferedReader(input);
String line;
try {
// most libraries are defined on several lines, so we need to make sure we parse
// all the library lines and only add the library at the end
long startAddr = 0;
long endAddr = 0;
String library = null;
while ((line = reader.readLine()) != null) {
Log.d("ddms", "line: " + line);
if (line.length() < 16) {
continue;
}
try {
long tmpStart = Long.parseLong(line.substring(0, 8), 16);
long tmpEnd = Long.parseLong(line.substring(9, 17), 16);
/*
* only check for library addresses as defined in
* //device/config/prelink-linux-arm.map
*/
if (tmpStart >= 0x0000000080000000L && tmpStart <= 0x00000000BFFFFFFFL) {
int index = line.indexOf('/");
if (index == -1)
continue;
String tmpLib = line.substring(index);
if (library == null ||
(library != null && tmpLib.equals(library) == false)) {
if (library != null) {
cd.addNativeLibraryMapInfo(startAddr, endAddr, library);
Log.d("ddms", library + "(" + Long.toHexString(startAddr) +
" - " + Long.toHexString(endAddr) + ")");
}
// now init the new library
library = tmpLib;
startAddr = tmpStart;
endAddr = tmpEnd;
} else {
// add the new end
endAddr = tmpEnd;
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
if (library != null) {
cd.addNativeLibraryMapInfo(startAddr, endAddr, library);
Log.d("ddms", library + "(" + Long.toHexString(startAddr) +
" - " + Long.toHexString(endAddr) + ")");
}
} catch (IOException e) {
e.printStackTrace();
}
| public static void | register(MonitorThread mt)Register for the packets we expect to get from the client.
mt.registerChunkHandler(CHUNK_NHGT, mInst);
mt.registerChunkHandler(CHUNK_NHSG, mInst);
mt.registerChunkHandler(CHUNK_NHST, mInst);
mt.registerChunkHandler(CHUNK_NHEN, mInst);
| public static void | sendNHGT(Client client)Send an NHGT (Native Thread GeT) request to the client.
ByteBuffer rawBuf = allocBuffer(0);
JdwpPacket packet = new JdwpPacket(rawBuf);
ByteBuffer buf = getChunkDataBuf(rawBuf);
// no data in request message
finishChunkPacket(packet, CHUNK_NHGT, buf.position());
Log.d("ddm-nativeheap", "Sending " + name(CHUNK_NHGT));
client.sendAndConsume(packet, mInst);
rawBuf = allocBuffer(2);
packet = new JdwpPacket(rawBuf);
buf = getChunkDataBuf(rawBuf);
buf.put((byte)HandleHeap.WHEN_GC);
buf.put((byte)HandleHeap.WHAT_OBJ);
finishChunkPacket(packet, CHUNK_NHSG, buf.position());
Log.d("ddm-nativeheap", "Sending " + name(CHUNK_NHSG));
client.sendAndConsume(packet, mInst);
|
|