diff options
Diffstat (limited to 'plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java')
-rw-r--r-- | plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java | 215 |
1 files changed, 124 insertions, 91 deletions
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java index 841ebe8ab..d3302f0c0 100644 --- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java +++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java @@ -29,6 +29,7 @@ import org.eclipse.dd.dsf.debug.service.IRunControl.StateChangeReason; import org.eclipse.dd.dsf.service.AbstractDsfService; import org.eclipse.dd.dsf.service.DsfServiceEventHandler; import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef; import org.eclipse.tm.internal.tcf.dsf.Activator; import org.eclipse.tm.tcf.protocol.IChannel; import org.eclipse.tm.tcf.protocol.IToken; @@ -45,16 +46,17 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { public final String id; public final TCFDSFExecutionDMC exe_dmc; - public final TCFDataCache<TCFFrameData> frame_data; + public final TCFDataCache<IStackTrace.StackTraceContext> context_cache; + public final TCFDataCache<TCFSourceRef> source_cache; int level; - TCFFrameData prev_data; + TCFSourceRef prev_data; public TCFFrameDMC(final TCFDSFExecutionDMC exe_dmc, final String id) { super(TCFDSFStack.this.getSession().getId(), new IDMContext[] { exe_dmc }); this.id = id; this.exe_dmc = exe_dmc; - frame_data = new TCFDataCache<TCFFrameData>(channel) { + context_cache = new TCFDataCache<IStackTrace.StackTraceContext>(channel) { @Override public boolean startDataRetrieval() { @@ -66,41 +68,53 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { command = tcf_stk_service.getContext(new String[]{ id }, new IStackTrace.DoneGetContext() { public void doneGetContext(IToken token, Exception err, IStackTrace.StackTraceContext[] context) { if (command != token) return; - TCFFrameData data = null; - TCFAddress a = null; - Number n = context[0].getInstructionAddress(); - if (n != null) a = new TCFAddress(n); - // Optimization: skip source position lookup if same address - if (prev_data != null && prev_data.address != null && prev_data.address.equals(a)) { - data = prev_data; - data.context = context[0]; - data.level = level; - } - else { - data = new TCFFrameData(); - data.context = context[0]; - data.address = a; - data.level = level; - if (!getSourcePos(data)) return; - } - set(token, err, prev_data = data); + IStackTrace.StackTraceContext ctx = null; + if (context != null && context.length > 0) ctx = context[0]; + set(token, err, ctx); } }); return false; } + }; + + source_cache = new TCFDataCache<TCFSourceRef>(channel) { + + @Override + protected boolean startDataRetrieval() { + if (!context_cache.validate()) { + context_cache.wait(this); + return false; + } + IStackTrace.StackTraceContext ctx = context_cache.getData(); + Number n = ctx.getInstructionAddress(); + BigInteger a = null; + if (n != null) a = new BigInteger(n.toString()); + // Optimization: skip source position lookup if same address + TCFSourceRef data = null; + if (prev_data != null && prev_data.address != null && prev_data.address.equals(a)) { + data = prev_data; + } + else { + data = new TCFSourceRef(); + data.address = a; + if (!getSourcePos(data)) return false; + } + set(null, null, prev_data = data); + return true; + } - private boolean getSourcePos(final TCFFrameData data) { + private boolean getSourcePos(final TCFSourceRef data) { if (tcf_lns_service == null) return true; if (data.address == null) return true; - BigInteger a1 = data.address.getValue(); - BigInteger a2 = data.address.add(1).getValue(); + BigInteger a1 = data.address; + BigInteger a2 = data.address.add(BigInteger.valueOf(1)); command = tcf_lns_service.mapToSource(exe_dmc.getTcfContextId(), a1, a2, new ILineNumbers.DoneMapToSource() { public void doneMapToSource(IToken token, Exception err, CodeArea[] areas) { if (command != token) return; if (areas != null && areas.length > 0) { for (ILineNumbers.CodeArea area : areas) { - if (data.code_area == null || area.start_line < data.code_area.start_line) { - data.code_area = area; + if (data.area == null || area.start_line < data.area.start_line) { + data.area = area; } } } @@ -140,12 +154,20 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { public static class TCFFrameData implements IFrameDMData { - public IStackTrace.StackTraceContext context; - public IAddress address; - public int level; - public String function; - public Throwable src_pos_error; - public ILineNumbers.CodeArea code_area; + public final IStackTrace.StackTraceContext context; + public final IAddress address; + public final int level; + public final String function; + public final ILineNumbers.CodeArea code_area; + + TCFFrameData(TCFFrameDMC dmc) { + context = dmc.context_cache.getData(); + TCFSourceRef ref = dmc.source_cache.getData(); + address = new TCFAddress(ref.address); + level = dmc.getLevel(); + function = null; + code_area = ref.area; + } public IAddress getAddress() { return address; @@ -191,6 +213,19 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { @Override public boolean startDataRetrieval() { assert command == null; + if (!dmc.run_control_context_cache.validate()) { + dmc.run_control_context_cache.wait(this); + return false; + } + if (dmc.run_control_context_cache.getError() != null) { + set(null, dmc.run_control_context_cache.getError(), null); + return true; + } + org.eclipse.tm.tcf.services.IRunControl.RunControlContext ctx = dmc.run_control_context_cache.getData(); + if (ctx == null || !ctx.hasState()) { + set(null, new Exception("DMC does not have a stack"), null); //$NON-NLS-1$ + return true; + } if (tcf_stk_service == null) { HashMap<String,TCFFrameDMC> data = new HashMap<String,TCFFrameDMC>(); top_frame_id = "TopFrame:" + dmc.getTcfContextId(); @@ -225,7 +260,10 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { void invalidateFrames() { reset(); - for (TCFFrameDMC dmc : frame_pool.values()) dmc.frame_data.reset(); + for (TCFFrameDMC dmc : frame_pool.values()) { + dmc.context_cache.reset(); + dmc.source_cache.reset(); + } } void dispose() { @@ -283,22 +321,35 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { public void getFrameData(final IFrameDMContext dmc, final DataRequestMonitor<IFrameDMData> rm) { if (dmc instanceof TCFFrameDMC) { final TCFFrameDMC frame_dmc = (TCFFrameDMC)dmc; - TCFDataCache<TCFFrameData> cache = frame_dmc.frame_data; - if (!cache.validate()) { - cache.wait(new Runnable() { + if (!frame_dmc.context_cache.validate()) { + frame_dmc.context_cache.wait(new Runnable() { public void run() { getFrameData(dmc, rm); } }); return; } - if (cache.getError() != null) { + if (frame_dmc.context_cache.getError() != null) { rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ + REQUEST_FAILED, "Data error", frame_dmc.context_cache.getError())); //$NON-NLS-1$ + rm.done(); + return; + } + if (!frame_dmc.source_cache.validate()) { + frame_dmc.source_cache.wait(new Runnable() { + public void run() { + getFrameData(dmc, rm); + } + }); + return; + } + if (frame_dmc.source_cache.getError() != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Data error", frame_dmc.source_cache.getError())); //$NON-NLS-1$ rm.done(); return; } - rm.setData(cache.getData()); + rm.setData(new TCFFrameData(frame_dmc)); rm.done(); } else { @@ -308,54 +359,32 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { } } - private TCFDataCache<?> createFramesCache(TCFDSFExecutionDMC exe, DataRequestMonitor<?> rm) { + public TCFDataCache<?> getFramesCache(TCFDSFExecutionDMC exe, DataRequestMonitor<?> rm) { if (tcf_stk_service == null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Stack trace service is not available", null)); //$NON-NLS-1$ - rm.done(); + if (rm != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + INVALID_HANDLE, "Stack trace service is not available", null)); //$NON-NLS-1$ + rm.done(); + } return null; } if (exe.isDisposed()) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ - rm.done(); - return null; - } - if (!exe.run_control_context_cache.validate()) { - return exe.run_control_context_cache; - } - if (exe.run_control_context_cache.getError() != null) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - REQUEST_FAILED, "Data error", exe.run_control_context_cache.getError())); //$NON-NLS-1$ - rm.done(); - return null; - } - org.eclipse.tm.tcf.services.IRunControl.RunControlContext ctx = exe.run_control_context_cache.getData(); - if (ctx == null || !ctx.hasState()) { - rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, - INVALID_HANDLE, "DMC does not have a stack", null)); //$NON-NLS-1$ - rm.done(); + if (rm != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + INVALID_HANDLE, "Disposed DMC", null)); //$NON-NLS-1$ + rm.done(); + } return null; } if (exe.stack_frames_cache == null) exe.stack_frames_cache = new FramesCache(channel, exe); - return exe.stack_frames_cache; - + return (FramesCache)exe.stack_frames_cache; } public void getFrames(final IDMContext dmc, final DataRequestMonitor<IFrameDMContext[]> rm) { if (dmc instanceof TCFDSFExecutionDMC) { TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc; - TCFDataCache<?> cache0 = createFramesCache(exe, rm); - if (cache0 == null) return; - if (cache0 != exe.stack_frames_cache) { - cache0.wait(new Runnable() { - public void run() { - getFrames(dmc, rm); - } - }); - return; - } - FramesCache cache = (FramesCache)cache0; + FramesCache cache = (FramesCache)getFramesCache(exe, rm); + if (cache == null) return; if (!cache.validate()) { cache.wait(new Runnable() { public void run() { @@ -399,17 +428,8 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { public void getStackDepth(final IDMContext dmc, final int maxDepth, final DataRequestMonitor<Integer> rm) { if (dmc instanceof TCFDSFExecutionDMC) { TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc; - TCFDataCache<?> cache0 = createFramesCache(exe, rm); - if (cache0 == null) return; - if (cache0 != exe.stack_frames_cache) { - cache0.wait(new Runnable() { - public void run() { - getStackDepth(dmc, maxDepth, rm); - } - }); - return; - } - FramesCache cache = (FramesCache)cache0; + FramesCache cache = (FramesCache)getFramesCache(exe, rm); + if (cache == null) return; if (!cache.validate()) { cache.wait(new Runnable() { public void run() { @@ -437,17 +457,22 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { public void getTopFrame(final IDMContext dmc, final DataRequestMonitor<IFrameDMContext> rm) { if (dmc instanceof TCFDSFExecutionDMC) { TCFDSFExecutionDMC exe = (TCFDSFExecutionDMC)dmc; - TCFDataCache<?> cache0 = createFramesCache(exe, rm); - if (cache0 == null) return; - if (cache0 != exe.stack_frames_cache) { - cache0.wait(new Runnable() { + FramesCache cache = (FramesCache)getFramesCache(exe, rm); + if (cache == null) return; + if (!cache.validate()) { + cache.wait(new Runnable() { public void run() { getTopFrame(dmc, rm); } }); return; } - FramesCache cache = (FramesCache)cache0; + if (cache.getError() != null) { + rm.setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, + REQUEST_FAILED, "Data error", cache.getError())); //$NON-NLS-1$ + rm.done(); + return; + } rm.setData(cache.createFrameDMC(cache.top_frame_id, 0)); rm.done(); } @@ -457,6 +482,14 @@ public class TCFDSFStack extends AbstractDsfService implements IStack { rm.done(); } } + + public TCFFrameDMC getTopFrame(TCFDSFExecutionDMC exe) { + FramesCache cache = (FramesCache)getFramesCache(exe, null); + assert cache != null; + assert cache.isValid(); + assert cache.getError() == null; + return cache.createFrameDMC(cache.top_frame_id, 0); + } public void getVariableData(IVariableDMContext variableDmc, DataRequestMonitor<IVariableDMData> rm) { // TODO model data for local variables |