1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

[265048] Currently, if asking for a stack depth with max depth of 0 (full) followed by another request with stack depth of 2, the MIStack service will send two request to GDB.

It is more efficient to only request a new stack depth if we need anything deeper than what we already know.  This is what we now do with a local stack depth cache.
This commit is contained in:
Marc Khouzam 2009-02-16 19:21:55 +00:00
parent d9c3aca1b8
commit 034c7b969e

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.dsf.mi.service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
@ -123,7 +124,46 @@ public class MIStack extends AbstractDsfService
} }
} }
/**
* Class to track stack depth requests for our internal cache
*/
private class StackDepthInfo {
// The maximum depth we requested
public int maxDepthRequested;
// The actual depth we received
public int returnedDepth;
StackDepthInfo(int requested, int returned) {
maxDepthRequested = requested;
returnedDepth = returned;
}
}
/**
* A HashMap for our StackDepth cache, that can clear based on a context.
*/
@SuppressWarnings("serial")
private class StackDepthHashMap<V,T> extends HashMap<V,T> {
public void clear(IDMContext context) {
final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(context, IMIExecutionDMContext.class);
if (execDmc != null) {
remove(execDmc.getThreadId());
} else {
clear();
};
}
}
private CommandCache fMICommandCache; private CommandCache fMICommandCache;
// Two commands such as
// -stack-info-depth 11
// -stack-info-depth 2
// would both be sent to GDB because the command cache sees them as different.
// This stackDepthCache allows us to know that if we already ask for a stack depth
// we can potentially re-use the answer.
StackDepthHashMap<Integer, StackDepthInfo> fStackDepthCache = new StackDepthHashMap<Integer, StackDepthInfo>();
private MIStoppedEvent fCachedStoppedEvent; private MIStoppedEvent fCachedStoppedEvent;
private IRunControl fRunControl; private IRunControl fRunControl;
@ -613,7 +653,7 @@ public class MIStack extends AbstractDsfService
} }
public void getStackDepth(IDMContext dmc, final int maxDepth, final DataRequestMonitor<Integer> rm) { public void getStackDepth(IDMContext dmc, final int maxDepth, final DataRequestMonitor<Integer> rm) {
IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class); final IMIExecutionDMContext execDmc = DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class);
if (execDmc != null) { if (execDmc != null) {
// Make sure the thread is stopped // Make sure the thread is stopped
if (!fRunControl.isSuspended(execDmc)) { if (!fRunControl.isSuspended(execDmc)) {
@ -622,6 +662,17 @@ public class MIStack extends AbstractDsfService
return; return;
} }
// Check our internal cache first because different commands can
// still be re-used.
StackDepthInfo cachedDepth = fStackDepthCache.get(execDmc.getThreadId());
if (cachedDepth != null) {
if (cachedDepth.maxDepthRequested == 0 || cachedDepth.maxDepthRequested >= maxDepth) {
rm.setData(cachedDepth.returnedDepth);
rm.done();
return;
}
}
MIStackInfoDepth depthCommand = null; MIStackInfoDepth depthCommand = null;
if (maxDepth > 0) depthCommand = new MIStackInfoDepth(execDmc, maxDepth); if (maxDepth > 0) depthCommand = new MIStackInfoDepth(execDmc, maxDepth);
else depthCommand = new MIStackInfoDepth(execDmc); else depthCommand = new MIStackInfoDepth(execDmc);
@ -631,6 +682,9 @@ public class MIStack extends AbstractDsfService
new DataRequestMonitor<MIStackInfoDepthInfo>(getExecutor(), rm) { new DataRequestMonitor<MIStackInfoDepthInfo>(getExecutor(), rm) {
@Override @Override
protected void handleSuccess() { protected void handleSuccess() {
// Store result in our internal cache
fStackDepthCache.put(execDmc.getThreadId(), new StackDepthInfo(maxDepth, getData().getDepth()));
rm.setData(getData().getDepth()); rm.setData(getData().getDepth());
rm.done(); rm.done();
} }
@ -651,6 +705,7 @@ public class MIStack extends AbstractDsfService
if (e.getReason() != StateChangeReason.STEP) { if (e.getReason() != StateChangeReason.STEP) {
fCachedStoppedEvent = null; fCachedStoppedEvent = null;
fMICommandCache.reset(); fMICommandCache.reset();
fStackDepthCache.clear();
} }
} }
@ -663,6 +718,7 @@ public class MIStack extends AbstractDsfService
public void eventDispatched(ISuspendedDMEvent e) { public void eventDispatched(ISuspendedDMEvent e) {
fMICommandCache.setContextAvailable(e.getDMContext(), true); fMICommandCache.setContextAvailable(e.getDMContext(), true);
fMICommandCache.reset(); fMICommandCache.reset();
fStackDepthCache.clear();
} }
@ -693,6 +749,7 @@ public class MIStack extends AbstractDsfService
*/ */
public void flushCache(IDMContext context) { public void flushCache(IDMContext context) {
fMICommandCache.reset(context); fMICommandCache.reset(context);
fStackDepthCache.clear(context);
} }
} }