Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java18
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/BreakpointCommand.java77
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java18
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java15
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java17
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java6
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepOverCommand.java6
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepReturnCommand.java4
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java18
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java11
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java48
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java3
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java2
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java7
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java113
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java1
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java41
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java95
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java237
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelSelectionPolicy.java8
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java117
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java33
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java270
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java539
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java58
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java41
-rw-r--r--plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java158
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java34
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOut.java32
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java38
-rw-r--r--plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java12
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFSourceLookupParticipant.java10
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java5
-rw-r--r--plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFStack.java5
34 files changed, 1118 insertions, 979 deletions
diff --git a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java
index 186e68555..9b6394973 100644
--- a/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java
+++ b/plugins/org.eclipse.tm.tcf.core/src/org/eclipse/tm/tcf/util/TCFDataCache.java
@@ -132,6 +132,24 @@ public abstract class TCFDataCache<V> implements Runnable {
}
/**
+ * If the cache is not valid, initiate data retrieval and
+ * add a client call-back to cache wait list.
+ * Client call-backs are activated when cache state changes.
+ * Call-backs are removed from waiting list after that.
+ * It is responsibility of clients to check if the state change was one they are waiting for.
+ * If the cache is valid do nothing and return true.
+ * @param cb - a call-back object
+ * @return true if the cache is already valid
+ */
+ public boolean validate(Runnable cb) {
+ if (!validate()) {
+ wait(cb);
+ return false;
+ }
+ return true;
+ }
+
+ /**
* End cache pending state.
* @param token - pending command handle.
* @param error - data retrieval error or null
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/BreakpointCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/BreakpointCommand.java
index ba9275fbf..22c83772d 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/BreakpointCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/BreakpointCommand.java
@@ -20,9 +20,11 @@ import org.eclipse.debug.ui.actions.IToggleBreakpointsTargetExtension;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.tm.internal.tcf.debug.model.TCFBreakpoint;
-import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
-import org.eclipse.tm.tcf.protocol.Protocol;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
+import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeStackFrame;
import org.eclipse.tm.tcf.services.IBreakpoints;
+import org.eclipse.tm.tcf.util.TCFDataCache;
+import org.eclipse.tm.tcf.util.TCFTask;
import org.eclipse.ui.IWorkbenchPart;
@@ -30,47 +32,50 @@ public class BreakpointCommand implements IToggleBreakpointsTargetExtension {
public boolean canToggleBreakpoints(IWorkbenchPart part, ISelection selection) {
if (selection.isEmpty()) return false;
- Object obj = ((IStructuredSelection)selection).getFirstElement();
- if (obj instanceof TCFNode) {
- final TCFNode node = (TCFNode)obj;
- if (node == null) return false;
- final boolean[] res = new boolean[1];
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- res[0] = node.getAddress() != null;
+ final Object obj = ((IStructuredSelection)selection).getFirstElement();
+ return new TCFTask<Boolean>() {
+ public void run() {
+ TCFDataCache<BigInteger> addr_cache = null;
+ if (obj instanceof TCFNodeExecContext) addr_cache = ((TCFNodeExecContext)obj).getAddress();
+ if (obj instanceof TCFNodeStackFrame) addr_cache = ((TCFNodeStackFrame)obj).getAddress();
+ if (addr_cache != null) {
+ if (!addr_cache.validate(this)) return;
+ done(addr_cache.getData() != null);
}
- });
- return res[0];
- }
- else {
- return false;
- }
+ else {
+ done(false);
+ }
+ }
+ }.getE();
}
public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException {
if (selection.isEmpty()) return;
- Object obj = ((IStructuredSelection)selection).getFirstElement();
- if (obj instanceof TCFNode) {
- final TCFNode node = (TCFNode)obj;
- if (node == null) return;
- final CoreException[] res = new CoreException[1];
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- try {
- BigInteger addr = node.getAddress();
- if (addr == null) return;
- Map<String,Object> m = new HashMap<String,Object>();
- m.put(IBreakpoints.PROP_ENABLED, Boolean.TRUE);
- m.put(IBreakpoints.PROP_LOCATION, addr.toString());
- new TCFBreakpoint(ResourcesPlugin.getWorkspace().getRoot(), m);
- }
- catch (CoreException x) {
- res[0] = x;
+ final Object obj = ((IStructuredSelection)selection).getFirstElement();
+ CoreException x = new TCFTask<CoreException>() {
+ public void run() {
+ try {
+ TCFDataCache<BigInteger> addr_cache = null;
+ if (obj instanceof TCFNodeExecContext) addr_cache = ((TCFNodeExecContext)obj).getAddress();
+ if (obj instanceof TCFNodeStackFrame) addr_cache = ((TCFNodeStackFrame)obj).getAddress();
+ if (addr_cache != null) {
+ if (!addr_cache.validate(this)) return;
+ BigInteger addr = addr_cache.getData();
+ if (addr != null) {
+ Map<String,Object> m = new HashMap<String,Object>();
+ m.put(IBreakpoints.PROP_ENABLED, Boolean.TRUE);
+ m.put(IBreakpoints.PROP_LOCATION, addr.toString());
+ new TCFBreakpoint(ResourcesPlugin.getWorkspace().getRoot(), m);
+ }
}
+ done(null);
+ }
+ catch (CoreException x) {
+ done(x);
}
- });
- if (res[0] != null) throw res[0];
- }
+ }
+ }.getE();
+ if (x != null) throw x;
}
public boolean canToggleLineBreakpoints(IWorkbenchPart part, ISelection selection) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java
index 236dfc30b..0b3899935 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/ResumeCommand.java
@@ -19,6 +19,7 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.debug.core.commands.IResumeHandler;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
@@ -26,6 +27,7 @@ import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
public class ResumeCommand implements IResumeHandler {
@@ -48,8 +50,9 @@ public class ResumeCommand implements IResumeHandler {
while (node != null && !node.isDisposed()) {
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- if (!node.validateNode(this)) return;
- ctx = ((TCFNodeExecContext)node).getRunContext().getData();
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
}
if (ctx == null) {
node = node.getParent();
@@ -59,8 +62,10 @@ public class ResumeCommand implements IResumeHandler {
break;
}
else {
- if (((TCFNodeExecContext)node).isSuspended() &&
- ctx.canResume(IRunControl.RM_RESUME)) res = true;
+ TCFDataCache<TCFContextState> state_cache = ((TCFNodeExecContext)node).getState();
+ if (!state_cache.validate(this)) return;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data != null && state_data.is_suspended && ctx.canResume(IRunControl.RM_RESUME)) res = true;
break;
}
}
@@ -84,8 +89,9 @@ public class ResumeCommand implements IResumeHandler {
while (node != null && !node.isDisposed()) {
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- if (!node.validateNode(this)) return;
- ctx = ((TCFNodeExecContext)node).getRunContext().getData();
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
}
if (ctx == null) {
node = node.getParent();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java
index 66726f50a..4a6face7f 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SignalsDialog.java
@@ -107,10 +107,7 @@ class SignalsDialog extends Dialog {
return new TCFTask<Signal[]>(channel) {
public void run() {
- if (!signal_state.validate()) {
- signal_state.wait(this);
- return;
- }
+ if (!signal_state.validate(this)) return;
if (signal_state.getError() != null) error(signal_state.getError());
else done(signal_state.getData().list);
}
@@ -212,10 +209,7 @@ class SignalsDialog extends Dialog {
@Override
protected boolean startDataRetrieval() {
- if (!signal_list.validate()) {
- signal_list.wait(this);
- return false;
- }
+ if (!signal_list.validate(this)) return false;
IProcesses prs = channel.getRemoteService(IProcesses.class);
final SignalList sigs = signal_list.getData();
if (prs == null || sigs == null) {
@@ -384,10 +378,7 @@ class SignalsDialog extends Dialog {
try {
final SignalState state = new TCFTask<SignalState>(channel) {
public void run() {
- if (!signal_state.validate()) {
- signal_state.wait(this);
- return;
- }
+ if (!signal_state.validate(this)) return;
if (signal_state.getError() != null) error(signal_state.getError());
else done(signal_state.getData());
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java
index 89a212bbd..cf0177022 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepCommand.java
@@ -18,6 +18,7 @@ import org.eclipse.debug.core.commands.IDebugCommandHandler;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
@@ -25,6 +26,7 @@ import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
abstract class StepCommand implements IDebugCommandHandler {
@@ -51,14 +53,18 @@ abstract class StepCommand implements IDebugCommandHandler {
while (node != null && !node.isDisposed()) {
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- if (!node.validateNode(this)) return;
- ctx = ((TCFNodeExecContext)node).getRunContext().getData();
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
}
if (ctx == null || !canExecute(ctx)) {
node = node.getParent();
}
else {
- if (((TCFNodeExecContext)node).isSuspended()) res = true;
+ TCFDataCache<TCFContextState> state_cache = ((TCFNodeExecContext)node).getState();
+ if (!state_cache.validate(this)) return;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data != null && state_data.is_suspended) res = true;
break;
}
}
@@ -82,8 +88,9 @@ abstract class StepCommand implements IDebugCommandHandler {
while (node != null && !node.isDisposed()) {
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- if (!node.validateNode(this)) return;
- ctx = ((TCFNodeExecContext)node).getRunContext().getData();
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
}
if (ctx == null || !canExecute(ctx)) {
node = node.getParent();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java
index 36284c264..24144247a 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepIntoCommand.java
@@ -51,21 +51,21 @@ public class StepIntoCommand extends StepCommand implements IStepIntoHandler {
@Override
protected TCFDataCache<TCFSourceRef> getLineInfo() {
- if (frame == null) frame = node.getTopFrame();
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
if (frame == null) return null;
return frame.getLineInfo();
}
@Override
protected TCFDataCache<StackTraceContext> getStackFrame() {
- if (frame == null) frame = node.getTopFrame();
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
if (frame == null) return null;
return frame.getStackTraceContext();
}
@Override
protected int getStackFrameIndex() {
- if (frame == null) frame = node.getTopFrame();
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
if (frame == null) return 0;
return frame.getFrameNo();
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepOverCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepOverCommand.java
index 68fd7e475..81a0880cb 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepOverCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepOverCommand.java
@@ -54,21 +54,21 @@ public class StepOverCommand extends StepCommand implements IStepOverHandler {
@Override
protected TCFDataCache<TCFSourceRef> getLineInfo() {
- if (frame == null) frame = node.getTopFrame();
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
if (frame == null) return null;
return frame.getLineInfo();
}
@Override
protected TCFDataCache<StackTraceContext> getStackFrame() {
- if (frame == null) frame = node.getTopFrame();
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
if (frame == null) return null;
return frame.getStackTraceContext();
}
@Override
protected int getStackFrameIndex() {
- if (frame == null) frame = node.getTopFrame();
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
if (frame == null) return 0;
return frame.getFrameNo();
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepReturnCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepReturnCommand.java
index b4558639c..68719dbbc 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepReturnCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/StepReturnCommand.java
@@ -51,14 +51,14 @@ public class StepReturnCommand extends StepCommand implements IStepReturnHandler
@Override
protected TCFDataCache<StackTraceContext> getStackFrame() {
- if (frame == null) frame = node.getTopFrame();
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
if (frame == null) return null;
return frame.getStackTraceContext();
}
@Override
protected int getStackFrameIndex() {
- if (frame == null) frame = node.getTopFrame();
+ if (frame == null) frame = node.getStackTrace().getTopFrame();
if (frame == null) return 0;
return frame.getFrameNo();
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java
index 441a6e59b..06a7554f8 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/SuspendCommand.java
@@ -19,6 +19,7 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.commands.IDebugCommandRequest;
import org.eclipse.debug.core.commands.IEnabledStateRequest;
import org.eclipse.debug.core.commands.ISuspendHandler;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFModel;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNode;
@@ -26,6 +27,7 @@ import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
public class SuspendCommand implements ISuspendHandler {
@@ -48,8 +50,9 @@ public class SuspendCommand implements ISuspendHandler {
while (node != null && !node.isDisposed()) {
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- if (!node.validateNode(this)) return;
- ctx = ((TCFNodeExecContext)node).getRunContext().getData();
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
}
if (ctx == null) {
node = node.getParent();
@@ -59,8 +62,10 @@ public class SuspendCommand implements ISuspendHandler {
break;
}
else {
- if (((TCFNodeExecContext)node).isRunning() &&
- ctx.canSuspend()) res = true;
+ TCFDataCache<TCFContextState> state_cache = ((TCFNodeExecContext)node).getState();
+ if (!state_cache.validate(this)) return;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data != null && !state_data.is_suspended && ctx.canSuspend()) res = true;
break;
}
}
@@ -84,8 +89,9 @@ public class SuspendCommand implements ISuspendHandler {
while (node != null && !node.isDisposed()) {
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- if (!node.validateNode(this)) return;
- ctx = ((TCFNodeExecContext)node).getRunContext().getData();
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
}
if (ctx == null) {
node = node.getParent();
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java
index 0783392db..2684ef519 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/commands/TerminateCommand.java
@@ -26,6 +26,7 @@ import org.eclipse.tm.internal.tcf.debug.ui.model.TCFNodeExecContext;
import org.eclipse.tm.internal.tcf.debug.ui.model.TCFRunnable;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.services.IRunControl;
+import org.eclipse.tm.tcf.util.TCFDataCache;
public class TerminateCommand implements ITerminateHandler {
@@ -47,8 +48,9 @@ public class TerminateCommand implements ITerminateHandler {
while (node != null && !node.isDisposed()) {
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- if (!node.validateNode(this)) return;
- ctx = ((TCFNodeExecContext)node).getRunContext().getData();
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
}
if (ctx != null && ctx.canTerminate()) {
res = true;
@@ -75,8 +77,9 @@ public class TerminateCommand implements ITerminateHandler {
while (node != null && !node.isDisposed()) {
IRunControl.RunControlContext ctx = null;
if (node instanceof TCFNodeExecContext) {
- if (!node.validateNode(this)) return;
- ctx = ((TCFNodeExecContext)node).getRunContext().getData();
+ TCFDataCache<IRunControl.RunControlContext> cache = ((TCFNodeExecContext)node).getRunContext();
+ if (!cache.validate(this)) return;
+ ctx = cache.getData();
}
if (ctx != null && ctx.canTerminate()) {
set.add(ctx);
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java
index c16f74869..6b249c266 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildren.java
@@ -29,6 +29,10 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
private final Map<String,TCFNode> node_pool = new LinkedHashMap<String,TCFNode>(32, 0.75f, true);
private boolean disposed;
+ private static final TCFNode[] EMPTY_NODE_ARRAY = new TCFNode[0];
+
+ private TCFNode[] array;
+
TCFChildren(IChannel channel) {
super(channel);
pool_margin = 0;
@@ -61,6 +65,7 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
void dispose(String id) {
node_pool.remove(id);
if (isValid()) {
+ array = null;
Map<String,TCFNode> data = getData();
if (data != null) data.remove(id);
}
@@ -99,6 +104,7 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
*/
@Override
public void set(IToken token, Throwable error, Map<String,TCFNode> data) {
+ array = null;
if (disposed) {
// A command can return data after the cache element has been disposed.
// Just ignore the data in such case.
@@ -121,6 +127,7 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
@Override
public void reset(Map<String,TCFNode> data) {
assert !disposed;
+ array = null;
if (data != null) {
super.reset(data);
addToPool(data);
@@ -131,6 +138,24 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
}
/**
+ * Invalidate the cache. If retrieval is in progress - let it continue.
+ */
+ @Override
+ public void reset() {
+ super.reset();
+ array = null;
+ }
+
+ /**
+ * Force cache to invalid state, cancel pending data retrieval if any.
+ */
+ @Override
+ public void cancel() {
+ super.cancel();
+ array = null;
+ }
+
+ /**
* Add a node to collection of children.
* @param n - a node.
*/
@@ -139,6 +164,7 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
assert node_pool.get(n.id) == null;
node_pool.put(n.id, n);
if (isValid()) {
+ array = null;
Map<String,TCFNode> data = getData();
if (data != null) data.put(n.id, n);
}
@@ -166,28 +192,16 @@ public abstract class TCFChildren extends TCFDataCache<Map<String,TCFNode>> {
}
/**
- * Return index of given child node.
- * @param n - a child node
- * @return - node index or -1 if node is not found in children list
- */
- int getIndexOf(TCFNode n) {
- TCFNode[] arr = toArray();
- for (int i = 0; i < arr.length; i++) {
- if (arr[i] == n) return i;
- }
- return -1;
- }
-
- /**
* Return current children nodes as an array.
* @return array of nodes.
*/
TCFNode[] toArray() {
assert isValid();
+ if (array != null) return array;
Map<String,TCFNode> data = getData();
- if (data == null) return new TCFNode[0];
- TCFNode[] arr = data.values().toArray(new TCFNode[data.size()]);
- Arrays.sort(arr);
- return arr;
+ if (data == null) return array = EMPTY_NODE_ARRAY;
+ array = data.values().toArray(new TCFNode[data.size()]);
+ Arrays.sort(array);
+ return array;
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java
index 59ac7ca1d..cbb2f1dab 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenExpressions.java
@@ -44,7 +44,6 @@ public class TCFChildrenExpressions extends TCFChildren {
reset();
if (g != generation) return;
node.addModelDelta(IModelDelta.CONTENT);
- node.model.fireModelChanged();
}
});
}
@@ -87,7 +86,7 @@ public class TCFChildrenExpressions extends TCFChildren {
for (final IExpression e : exp_manager.getExpressions()) {
String text = e.getExpressionText();
TCFNodeExpression n = findScript(text);
- if (n == null) add(n = new TCFNodeExpression(node, text, null, null, -1));
+ if (n == null) add(n = new TCFNodeExpression(node, text, null, null, -1, null));
n.setSortPosition(cnt++);
data.put(n.id, n);
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java
index b51c18924..f18aa9da9 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenLocalVariables.java
@@ -46,7 +46,7 @@ public class TCFChildrenLocalVariables extends TCFChildren {
data = new HashMap<String,TCFNode>();
for (String id : contexts) {
TCFNodeExpression n = (TCFNodeExpression)node.model.getNode(id);
- if (n == null) n = new TCFNodeExpression(node, null, null, id, -1);
+ if (n == null) n = new TCFNodeExpression(node, null, null, id, -1, null);
assert n.id.equals(id);
assert n.parent == node;
n.setSortPosition(cnt++);
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java
index 418e55241..d5bf9ec64 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenStackTrace.java
@@ -47,7 +47,7 @@ public class TCFChildrenStackTrace extends TCFChildren {
reset(null);
}
- TCFNodeStackFrame getTopFrame() {
+ public TCFNodeStackFrame getTopFrame() {
assert isValid();
return (TCFNodeStackFrame)node.model.getNode(top_frame_id);
}
@@ -64,10 +64,7 @@ public class TCFChildrenStackTrace extends TCFChildren {
protected boolean startDataRetrieval() {
final HashMap<String,TCFNode> data = new HashMap<String,TCFNode>();
TCFDataCache<TCFContextState> state = node.getState();
- if (!state.validate()) {
- state.wait(this);
- return false;
- }
+ if (!state.validate(this)) return false;
Throwable state_error = state.getError();
TCFContextState state_data = state.getData();
if (state_error != null || state_data == null || !state_data.is_suspended) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java
index 8f194580e..5eed50104 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFChildrenSubExpressions.java
@@ -13,7 +13,6 @@ package org.eclipse.tm.internal.tcf.debug.ui.model;
import java.util.HashMap;
import java.util.Map;
-import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.services.IExpressions;
import org.eclipse.tm.tcf.services.ISymbols;
import org.eclipse.tm.tcf.util.TCFDataCache;
@@ -74,49 +73,61 @@ public class TCFChildrenSubExpressions extends TCFChildren {
if (exp instanceof TCFNodeExpression) break;
exp = exp.parent;
}
- final TCFDataCache<ISymbols.Symbol> type = ((TCFNodeExpression)exp).getType();
- if (!type.validate()) {
- type.wait(this);
- return false;
- }
+ final TCFDataCache<IExpressions.Value> value_cache = ((TCFNodeExpression)exp).getValue();
+ if (!value_cache.validate(this)) return false;
+ final IExpressions.Value value_data = value_cache.getData();
final ISymbols syms = node.model.getLaunch().getService(ISymbols.class);
- final ISymbols.Symbol type_sym = type.getData();
- if (syms == null || type_sym == null) {
+ if (value_data == null || syms == null) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ final TCFDataCache<ISymbols.Symbol> type_cache = node.model.getSymbolInfoCache(
+ value_data.getExeContextID(), value_data.getTypeID());
+ if (type_cache == null) {
set(null, null, new HashMap<String,TCFNode>());
return true;
}
- ISymbols.TypeClass type_class = type_sym.getTypeClass();
+ if (!type_cache.validate(this)) return false;
+ final ISymbols.Symbol type_data = type_cache.getData();
+ if (type_data == null) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ ISymbols.TypeClass type_class = type_data.getTypeClass();
if (par_level > 0 && type_class != ISymbols.TypeClass.array) {
set(null, null, new HashMap<String,TCFNode>());
return true;
}
if (type_class == ISymbols.TypeClass.composite) {
- command = syms.getChildren(type_sym.getID(), new ISymbols.DoneGetChildren() {
- public void doneGetChildren(IToken token, Exception error, String[] contexts) {
- Map<String,TCFNode> data = null;
- if (command == token && error == null) {
- int cnt = 0;
- data = new HashMap<String,TCFNode>();
- for (String id : contexts) {
- TCFNodeExpression n = findField(id);
- if (n == null) n = new TCFNodeExpression(node, null, id, null, -1);
- n.setSortPosition(cnt++);
- data.put(n.id, n);
- }
- }
- set(token, error, data);
+ TCFDataCache<String[]> children_cache = node.model.getSymbolChildrenCache(type_data.getExeContextID(), type_data.getID());
+ if (children_cache == null) {
+ set(null, null, new HashMap<String,TCFNode>());
+ return true;
+ }
+ if (!children_cache.validate(this)) return false;
+ String[] children_data = children_cache.getData();
+ Map<String,TCFNode> data = null;
+ if (children_data != null) {
+ int cnt = 0;
+ data = new HashMap<String,TCFNode>();
+ for (String id : children_data) {
+ TCFNodeExpression n = findField(id);
+ if (n == null) n = new TCFNodeExpression(node, null, id, null, -1, type_data);
+ n.setSortPosition(cnt++);
+ data.put(n.id, n);
}
- });
- return false;
+ }
+ set(null, children_cache.getError(), data);
+ return true;
}
if (type_class == ISymbols.TypeClass.array) {
Map<String,TCFNode> data = new HashMap<String,TCFNode>();
int offs = par_level > 0 ? par_offs : 0;
- int size = par_level > 0 ? par_size : type_sym.getLength();
+ int size = par_level > 0 ? par_size : type_data.getLength();
if (size <= 100) {
for (int i = offs; i < offs + size; i++) {
TCFNodeExpression n = findIndex(i);
- if (n == null) n = new TCFNodeExpression(node, null, null, null, i);
+ if (n == null) n = new TCFNodeExpression(node, null, null, null, i, type_data);
n.setSortPosition(i);
data.put(n.id, n);
}
@@ -138,24 +149,40 @@ public class TCFChildrenSubExpressions extends TCFChildren {
if (type_class == ISymbols.TypeClass.pointer) {
Map<String,TCFNode> data = new HashMap<String,TCFNode>();
TCFDataCache<IExpressions.Value> value = ((TCFNodeExpression)exp).getValue();
- if (!value.validate()) {
- value.wait(this);
- return false;
- }
+ if (!value.validate(this)) return false;
IExpressions.Value v = value.getData();
if (v != null && !isNull(v.getValue())) {
- TCFDataCache<ISymbols.Symbol> base_type = node.model.getSymbolInfoCache(
- type_sym.getExeContextID(), type_sym.getBaseTypeID());
- if (!base_type.validate()) {
- base_type.wait(this);
- return false;
- }
- ISymbols.Symbol base_type_sym = base_type.getData();
- if (base_type_sym == null || base_type_sym.getSize() != 0) {
- TCFNodeExpression n = findIndex(0);
- if (n == null) n = new TCFNodeExpression(node, null, null, null, 0);
- n.setSortPosition(0);
- data.put(n.id, n);
+ TCFDataCache<ISymbols.Symbol> base_type_cache = node.model.getSymbolInfoCache(
+ type_data.getExeContextID(), type_data.getBaseTypeID());
+ if (base_type_cache != null) {
+ if (!base_type_cache.validate(this)) return false;
+ ISymbols.Symbol base_type_data = base_type_cache.getData();
+ if (base_type_data == null || base_type_data.getSize() != 0) {
+ if (base_type_data.getTypeClass() == ISymbols.TypeClass.composite) {
+ TCFDataCache<String[]> children_cache = node.model.getSymbolChildrenCache(
+ base_type_data.getExeContextID(), base_type_data.getID());
+ if (children_cache != null) {
+ if (!children_cache.validate(this)) return false;
+ String[] children_data = children_cache.getData();
+ if (children_data != null) {
+ int cnt = 0;
+ data = new HashMap<String,TCFNode>();
+ for (String id : children_data) {
+ TCFNodeExpression n = findField(id);
+ if (n == null) n = new TCFNodeExpression(node, null, id, null, -1, type_data);
+ n.setSortPosition(cnt++);
+ data.put(n.id, n);
+ }
+ }
+ }
+ }
+ else {
+ TCFNodeExpression n = findIndex(0);
+ if (n == null) n = new TCFNodeExpression(node, null, null, null, 0, type_data);
+ n.setSortPosition(0);
+ data.put(n.id, n);
+ }
+ }
}
}
set(null, null, data);
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java
index b6892e5fe..fad8df09b 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFDetailPane.java
@@ -83,7 +83,6 @@ public class TCFDetailPane implements IDetailPane {
}
private String getDetailText(ArrayList<TCFNode> nodes, Runnable done) {
- if (!TCFNode.validateNodes(nodes, done)) return null;
StringBuffer bf = new StringBuffer();
for (TCFNode n : nodes) {
if (n instanceof TCFNodeExpression) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
index 980d2fd08..538139f1b 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFMemoryBlockRetrieval.java
@@ -86,10 +86,7 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
expression_value = new TCFDataCache<IExpressions.Value>(channel) {
@Override
protected boolean startDataRetrieval() {
- if (!remote_expression.validate()) {
- remote_expression.wait(this);
- return false;
- }
+ if (!remote_expression.validate(this)) return false;
final IExpressions.Expression ctx = remote_expression.getData();
if (ctx == null) {
set(null, null, null);
@@ -107,23 +104,21 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
expression_type = new TCFDataCache<ISymbols.Symbol>(channel) {
@Override
protected boolean startDataRetrieval() {
- if (!expression_value.validate()) {
- expression_value.wait(this);
- return false;
+ if (!expression_value.validate(this)) return false;
+ IExpressions.Value val = expression_value.getData();
+ if (val == null) {
+ set(null, expression_value.getError(), null);
+ return true;
}
- String id = null;
- if (expression_value.getData() != null) id = expression_value.getData().getTypeID();
- ISymbols syms = launch.getService(ISymbols.class);
- if (id == null || syms == null) {
+ TCFDataCache<ISymbols.Symbol> type_cache = exec_ctx.getModel().getSymbolInfoCache(
+ val.getExeContextID(), val.getTypeID());
+ if (type_cache == null) {
set(null, null, null);
return true;
}
- command = syms.getContext(id, new ISymbols.DoneGetContext() {
- public void doneGetContext(IToken token, Exception error, ISymbols.Symbol sym) {
- set(token, error, sym);
- }
- });
- return false;
+ if (!type_cache.validate(this)) return false;
+ set(null, type_cache.getError(), type_cache.getData());
+ return true;
}
};
}
@@ -170,8 +165,10 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
if (exec_ctx.isDisposed()) {
error("Context is disposed");
}
- else if (exec_ctx.validateNode(this)) {
- IMemory.MemoryContext mem = exec_ctx.getMemoryContext().getData();
+ else {
+ TCFDataCache<IMemory.MemoryContext> cache = exec_ctx.getMemoryContext();
+ if (!cache.validate(this)) return;
+ IMemory.MemoryContext mem = cache.getData();
if (mem == null) {
error("Context does not provide memory access");
}
@@ -248,8 +245,10 @@ class TCFMemoryBlockRetrieval implements IMemoryBlockRetrievalExtension {
if (exec_ctx.isDisposed()) {
error("Context is disposed");
}
- else if (exec_ctx.validateNode(this)) {
- final IMemory.MemoryContext mem = exec_ctx.getMemoryContext().getData();
+ else {
+ TCFDataCache<IMemory.MemoryContext> cache = exec_ctx.getMemoryContext();
+ if (!cache.validate(this)) return;
+ final IMemory.MemoryContext mem = cache.getData();
if (mem == null) {
error("Context does not provide memory access");
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
index d23699e6e..e4d856680 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModel.java
@@ -18,7 +18,6 @@ import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.commands.IDisconnectHandler;
@@ -74,6 +73,7 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.graphics.Device;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
import org.eclipse.tm.internal.tcf.debug.ui.Activator;
@@ -223,7 +223,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
}
}
}
- fireModelChanged();
}
public void contextChanged(IMemory.MemoryContext[] contexts) {
@@ -237,7 +236,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
for (TCFDataCache<ISymbols.Symbol> s : m.values()) s.cancel();
}
}
- fireModelChanged();
}
public void contextRemoved(final String[] context_ids) {
@@ -249,7 +247,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onMemoryChanged(addr, size);
}
- fireModelChanged();
}
};
@@ -262,7 +259,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
((TCFNodeExecContext)node).onContainerResumed();
}
}
- fireModelChanged();
}
public void containerSuspended(String context, String pc, String reason,
@@ -277,7 +273,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextSuspended(pc, reason, params);
}
- fireModelChanged();
runSuspendTrigger(node);
}
@@ -294,7 +289,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
}
}
}
- fireModelChanged();
}
public void contextChanged(IRunControl.RunControlContext[] contexts) {
@@ -304,7 +298,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
((TCFNodeExecContext)node).onContextChanged(contexts[i]);
}
}
- fireModelChanged();
}
public void contextException(String context, String msg) {
@@ -312,7 +305,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextException(msg);
}
- fireModelChanged();
}
public void contextRemoved(final String[] context_ids) {
@@ -324,7 +316,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeExecContext) {
((TCFNodeExecContext)node).onContextResumed();
}
- fireModelChanged();
display.asyncExec(new Runnable() {
public void run() {
Activator.getAnnotationManager().onContextResumed(TCFModel.this, context);
@@ -339,7 +330,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
exe.onContextSuspended(pc, reason, params);
setDebugViewSelection(context, false);
}
- fireModelChanged();
runSuspendTrigger(node);
}
};
@@ -352,7 +342,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
((TCFNodeExecContext)node).onRegistersChanged();
}
}
- fireModelChanged();
}
public void registerChanged(String context) {
@@ -360,7 +349,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node instanceof TCFNodeRegister) {
((TCFNodeRegister)node).onValueChanged();
}
- fireModelChanged();
}
};
@@ -398,8 +386,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
while (n != null && !n.isDisposed()) {
if (n instanceof TCFNodeExecContext) {
TCFNodeExecContext e = (TCFNodeExecContext)n;
- if (!e.validateNode(this)) return;
- if (e.getMemoryContext() != null) {
+ TCFDataCache<IMemory.MemoryContext> cache = e.getMemoryContext();
+ if (!cache.validate(this)) return;
+ if (cache.getData() != null) {
o = mem_retrieval.get(e.id);
if (o == null) {
TCFMemoryBlockRetrieval m = new TCFMemoryBlockRetrieval(e);
@@ -502,24 +491,15 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
}
void onContextActionsDone() {
- fireModelChanged();
}
void onProxyInstalled(final IPresentationContext p, final TCFModelProxy mp) {
- Protocol.invokeLater(new Runnable() {
- public void run() {
- model_proxies.put(p, mp);
- }
- });
+ model_proxies.put(p, mp);
}
void onProxyDisposed(final IPresentationContext p) {
- Protocol.invokeAndWait(new Runnable() {
- public void run() {
- assert model_proxies.containsKey(p);
- model_proxies.remove(p);
- }
- });
+ assert model_proxies.containsKey(p);
+ model_proxies.remove(p);
}
private void onContextRemoved(final String[] context_ids) {
@@ -532,7 +512,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (node.parent == launch_node) close_channel = true;
}
}
- fireModelChanged();
if (close_channel) {
// Close debug session if the last context is removed:
onLastContextRemoved();
@@ -551,8 +530,9 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
public void run() {
if (launch_node == null) return;
if (launch_node.isDisposed()) return;
- if (!launch_node.validateNode(this)) return;
- if (launch_node.getContextCount() != 0) return;
+ TCFChildrenExecContext children = launch_node.getChildren();
+ if (!children.validate(this)) return;
+ if (children.size() != 0) return;
launch.onLastContextRemoved();
}
});
@@ -565,7 +545,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
void launchChanged() {
if (launch_node != null) {
launch_node.addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
- fireModelChanged();
}
else {
refreshLaunchView();
@@ -599,12 +578,6 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
mem_retrieval.remove(id);
}
- void fireModelChanged() {
- assert Protocol.isDispatchThread();
- if (launch.hasPendingContextActions()) return;
- for (TCFModelProxy p : model_proxies.values()) p.fireModelChanged();
- }
-
public Display getDisplay() {
return display;
}
@@ -625,6 +598,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
}
public TCFDataCache<ISymbols.Symbol> getSymbolInfoCache(String mem_id, final String sym_id) {
+ if (mem_id == null || sym_id == null) return null;
Map<String,TCFDataCache<ISymbols.Symbol>> m = symbols.get(mem_id);
if (m == null) symbols.put(mem_id, m = new HashMap<String,TCFDataCache<ISymbols.Symbol>>());
TCFDataCache<ISymbols.Symbol> s = m.get(sym_id);
@@ -648,6 +622,7 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
}
public TCFDataCache<String[]> getSymbolChildrenCache(String mem_id, final String sym_id) {
+ if (mem_id == null || sym_id == null) return null;
Map<String,TCFDataCache<String[]>> m = symbol_children.get(mem_id);
if (m == null) symbol_children.put(mem_id, m = new HashMap<String,TCFDataCache<String[]>>());
TCFDataCache<String[]> s = m.get(sym_id);
@@ -767,23 +742,20 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
TCFNode node = getNode(node_id);
if (node == null) return;
if (node.disposed) return;
- if (!node.validateNode(this)) return;
if (cnt != debug_view_selection_cnt) return;
if (node instanceof TCFNodeExecContext) {
- if (!((TCFNodeExecContext)node).isSuspended()) return;
- TCFNode frame = ((TCFNodeExecContext)node).getTopFrame();
- if (frame != null && !frame.disposed) {
- if (!frame.validateNode(this)) return;
- node = frame;
- }
+ TCFDataCache<TCFContextState> state_cache = ((TCFNodeExecContext)node).getState();
+ if (!state_cache.validate(this)) return;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data == null || !state_data.is_suspended) return;
+ TCFChildrenStackTrace stack_trace = ((TCFNodeExecContext)node).getStackTrace();
+ if (!stack_trace.validate(this)) return;
+ TCFNode frame = stack_trace.getTopFrame();
+ if (frame != null && !frame.disposed) node = frame;
}
for (TCFModelProxy proxy : model_proxies.values()) {
if (proxy.getPresentationContext().getId().equals(IDebugUIConstants.ID_DEBUG_VIEW)) {
- proxy.fireModelChanged();
- proxy.addDelta(node, IModelDelta.REVEAL);
- proxy.fireModelChanged();
- proxy.addDelta(node, IModelDelta.SELECT);
- proxy.fireModelChanged();
+ proxy.setSelection(node);
}
}
}
@@ -817,23 +789,24 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
if (element instanceof TCFNodeExecContext) {
TCFNodeExecContext node = (TCFNodeExecContext)element;
if (!node.disposed) {
- if (!node.validateNode(this)) return;
- if (node.isSuspended()) stack_frame = node.getTopFrame();
+ TCFDataCache<TCFContextState> state_cache = node.getState();
+ if (!state_cache.validate(this)) return;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data != null && state_data.is_suspended) {
+ TCFChildrenStackTrace stack_trace = ((TCFNodeExecContext)node).getStackTrace();
+ if (!stack_trace.validate(this)) return;
+ stack_frame = stack_trace.getTopFrame();
+ }
}
}
else if (element instanceof TCFNodeStackFrame) {
TCFNodeStackFrame node = (TCFNodeStackFrame)element;
- if (!node.disposed) {
- stack_frame = (TCFNodeStackFrame)element;
- }
+ if (!node.disposed) stack_frame = (TCFNodeStackFrame)element;
}
}
if (stack_frame != null) {
TCFDataCache<TCFSourceRef> line_info = stack_frame.getLineInfo();
- if (!line_info.validate()) {
- line_info.wait(this);
- return;
- }
+ if (!line_info.validate(this)) return;
String editor_id = null;
IEditorInput editor_input = null;
Throwable error = line_info.getError();
@@ -903,7 +876,13 @@ public class TCFModel implements IElementContentProvider, IElementLabelProvider,
});
}
+ /*
+ * Refresh Launch View.
+ * Normally the view is updated by sending deltas through model proxy.
+ * This method is used only when launch is not yet connected or already disconnected.
+ */
private void refreshLaunchView() {
+ // TODO: there should be a better way to refresh Launch View
final Throwable error = launch.getError();
if (error != null) launch.setError(null);
synchronized (Device.class) {
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java
index 95e09937a..879d96994 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelProxy.java
@@ -13,50 +13,168 @@ package org.eclipse.tm.internal.tcf.debug.ui.model;
import java.util.HashMap;
import java.util.Map;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.internal.ui.viewers.provisional.AbstractModelProxy;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
+import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
+import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.tm.tcf.protocol.Protocol;
-public class TCFModelProxy extends AbstractModelProxy implements IModelProxy {
+/**
+ * A model proxy represents a model for a specific presentation context and
+ * fires deltas to notify listeners of changes in the model.
+ */
+public class TCFModelProxy extends AbstractModelProxy implements IModelProxy, Runnable {
private static final int CONTENT_FLAGS =
IModelDelta.ADDED | IModelDelta.REMOVED |
IModelDelta.REPLACED | IModelDelta.INSERTED |
IModelDelta.CONTENT | IModelDelta.STATE;
+ private static final TCFNode[] EMPTY_NODE_ARRAY = new TCFNode[0];
+
private final TCFModel model;
- private final Map<TCFNode,Integer> deltas = new HashMap<TCFNode,Integer>();
+ private final Map<TCFNode,Integer> node2flags = new HashMap<TCFNode,Integer>();
+ private final Map<TCFNode,TCFNode[]> node2children = new HashMap<TCFNode,TCFNode[]>();
+ private final Map<TCFNode,ModelDelta> node2delta = new HashMap<TCFNode,ModelDelta>();
+
+ private TCFNode selection;
+ private boolean posted;
+ private boolean disposed;
+
+ private class ViewerUpdate implements IViewerUpdate {
+
+ IStatus status;
+
+ public Object getElement() {
+ return null;
+ }
+
+ public TreePath getElementPath() {
+ return null;
+ }
+
+ public IPresentationContext getPresentationContext() {
+ return TCFModelProxy.this.getPresentationContext();
+ }
+
+ public Object getViewerInput() {
+ return TCFModelProxy.this.getProxyViewer().getInput();
+ }
+
+ public void cancel() {
+ }
+
+ public void done() {
+ }
+
+ public IStatus getStatus() {
+ return status;
+ }
+
+ public boolean isCanceled() {
+ return false;
+ }
+
+ public void setStatus(IStatus status) {
+ this.status = status;
+ }
+ }
+
+ private class ChildrenCountUpdate extends ViewerUpdate implements IChildrenCountUpdate {
+
+ int count;
+
+ public void setChildCount(int count) {
+ this.count = count;
+
+ }
+ }
+
+ private class ChildrenUpdate extends ViewerUpdate implements IChildrenUpdate {
+
+ int length;
+ TCFNode[] children;
+
+ void setLength(int length) {
+ this.length = length;
+ this.children = new TCFNode[length];
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public int getOffset() {
+ return 0;
+ }
+
+ public void setChild(Object child, int offset) {
+ children[offset] = (TCFNode)child;
+ }
+ }
+
+ private final ChildrenCountUpdate children_count_update = new ChildrenCountUpdate();
+ private final ChildrenUpdate children_update = new ChildrenUpdate();
+
+ private TCFNode pending_node;
TCFModelProxy(TCFModel model) {
this.model = model;
}
- public synchronized void installed(Viewer viewer) {
+ public void installed(Viewer viewer) {
super.installed(viewer);
- IPresentationContext p = getPresentationContext();
- if (p != null) model.onProxyInstalled(p, this);
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ assert !disposed;
+ IPresentationContext p = getPresentationContext();
+ if (p != null) model.onProxyInstalled(p, TCFModelProxy.this);
+ }
+ });
}
- public synchronized void dispose() {
- IPresentationContext p = getPresentationContext();
- if (p != null) model.onProxyDisposed(p);
+ public void dispose() {
+ Protocol.invokeAndWait(new Runnable() {
+ public void run() {
+ assert !disposed;
+ IPresentationContext p = getPresentationContext();
+ if (p != null) model.onProxyDisposed(p);
+ disposed = true;
+ }
+ });
super.dispose();
}
void addDelta(TCFNode node, int flags) {
if (flags != 0) {
- Integer delta = deltas.get(node);
+ Integer delta = node2flags.get(node);
if (delta != null) {
- deltas.put(node, Integer.valueOf(delta.intValue() | flags));
+ node2flags.put(node, delta.intValue() | flags);
}
else {
- deltas.put(node, Integer.valueOf(flags));
+ node2flags.put(node, flags);
}
+ post();
+ }
+ }
+
+ void setSelection(TCFNode node) {
+ selection = node;
+ addDelta(node, IModelDelta.REVEAL);
+ }
+
+ void post() {
+ if (!posted) {
+ Protocol.invokeLater(this);
+ posted = true;
}
}
@@ -64,41 +182,92 @@ public class TCFModelProxy extends AbstractModelProxy implements IModelProxy {
return getViewer();
}
- private ModelDelta makeDelta(ModelDelta root, Map<TCFNode,ModelDelta> map, TCFNode node, int flags) {
- boolean content_only = (flags & ~CONTENT_FLAGS) == 0;
- ModelDelta delta = map.get(node);
+ private TCFNode[] getNodeChildren(TCFNode node) {
+ TCFNode[] res = node2children.get(node);
+ if (res == null) {
+ if (node.disposed) {
+ res = EMPTY_NODE_ARRAY;
+ }
+ else if (!node.getData(children_count_update, null)) {
+ pending_node = node;
+ res = EMPTY_NODE_ARRAY;
+ }
+ else {
+ children_update.setLength(children_count_update.count);
+ if (!node.getData(children_update, null)) {
+ assert false;
+ pending_node = node;
+ res = EMPTY_NODE_ARRAY;
+ }
+ else {
+ res = children_update.children;
+ }
+ }
+ node2children.put(node, res);
+ }
+ return res;
+ }
+
+ private int getNodeIndex(TCFNode node) {
+ TCFNode[] arr = getNodeChildren(node.parent);
+ for (int i = 0; i < arr.length; i++) {
+ if (arr[i] == node) return i;
+ }
+ return -1;
+ }
+
+ private ModelDelta makeDelta(ModelDelta root, TCFNode node, int flags) {
+ ModelDelta delta = node2delta.get(node);
if (delta == null) {
- IPresentationContext p = getPresentationContext();
if (node.parent == null) {
- if (content_only && (root.getFlags() & IModelDelta.CONTENT) != 0) return null;
- delta = root.addNode(model.getLaunch(), -1, flags, node.getChildrenCount(p));
+ delta = root.addNode(model.getLaunch(), -1, flags, getNodeChildren(node).length);
}
else {
- ModelDelta parent = makeDelta(root, map, node.parent, 0);
+ int parent_flags = 0;
+ Integer parent_flags_obj = node2flags.get(node.parent);
+ if (parent_flags_obj != null) parent_flags = parent_flags_obj;
+ if ((flags & ~CONTENT_FLAGS) == 0 && (parent_flags & IModelDelta.CONTENT) != 0) return null;
+ ModelDelta parent = makeDelta(root, node.parent, parent_flags);
if (parent == null) return null;
- if (content_only && (parent.getFlags() & IModelDelta.CONTENT) != 0) return null;
- delta = parent.addNode(
- node, node.parent.getNodeIndex(p, node),
- flags, node.getChildrenCount(p));
+ delta = parent.addNode(node, getNodeIndex(node), flags, getNodeChildren(node).length);
}
- map.put(node, delta);
- }
- else if (flags != 0) {
- delta.setFlags(delta.getFlags() | flags);
+ node2delta.put(node, delta);
}
+ assert delta.getFlags() == flags;
return delta;
}
- void fireModelChanged() {
+ public void run() {
+ posted = false;
assert Protocol.isDispatchThread();
- if (deltas.isEmpty()) return;
+ if (disposed) return;
+ if (node2flags.isEmpty()) return;
+ pending_node = null;
+ node2children.clear();
+ node2delta.clear();
ModelDelta root = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE);
- Map<TCFNode,ModelDelta> map = new HashMap<TCFNode,ModelDelta>();
- for (TCFNode node : deltas.keySet()) {
- makeDelta(root, map, node, deltas.get(node).intValue());
+ for (TCFNode node : node2flags.keySet()) makeDelta(root, node, node2flags.get(node));
+ if (pending_node == null) {
+ node2flags.clear();
+ if (!node2delta.isEmpty()) {
+ fireModelChanged(root);
+ node2delta.clear();
+ }
+ if (selection != null) {
+ root = new ModelDelta(DebugPlugin.getDefault().getLaunchManager(), IModelDelta.NO_CHANGE);
+ makeDelta(root, selection, IModelDelta.SELECT);
+ fireModelChanged(root);
+ node2delta.clear();
+ selection = null;
+ }
+ }
+ else if (pending_node.getData(children_count_update, this)) {
+ assert false;
+ post();
+ }
+ else {
+ posted = true;
}
- deltas.clear();
- if (map.isEmpty()) return;
- fireModelChanged(root);
+ node2children.clear();
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelSelectionPolicy.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelSelectionPolicy.java
index fce5e1472..b196b56db 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelSelectionPolicy.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFModelSelectionPolicy.java
@@ -15,6 +15,8 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
+import org.eclipse.tm.tcf.util.TCFDataCache;
import org.eclipse.tm.tcf.util.TCFTask;
class TCFModelSelectionPolicy implements IModelSelectionPolicy {
@@ -52,8 +54,10 @@ class TCFModelSelectionPolicy implements IModelSelectionPolicy {
TCFNode n = node;
while (n != null && !n.isDisposed()) {
if (n instanceof TCFNodeExecContext) {
- if (!n.validateNode(this)) return;
- if (((TCFNodeExecContext)n).isSuspended()) {
+ TCFDataCache<TCFContextState> cache = ((TCFNodeExecContext)n).getState();
+ if (!cache.validate(this)) return;
+ TCFContextState state = cache.getData();
+ if (state != null && state.is_suspended) {
done(true);
return;
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
index 8f08a8d50..0b668342a 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNode.java
@@ -10,9 +10,6 @@
*******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.ui.model;
-import java.math.BigInteger;
-import java.util.Collection;
-
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.Status;
@@ -22,7 +19,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdat
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
-import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
import org.eclipse.tm.tcf.protocol.IChannel;
import org.eclipse.tm.tcf.protocol.Protocol;
@@ -140,33 +136,6 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
}
/**
- * Get index of a node in this node children list
- * @param p - presentation context
- * @return node index or -1 if unknown
- */
- public int getNodeIndex(IPresentationContext p, TCFNode n) {
- return -1;
- }
-
- /**
- * Get children count of the node.
- * @param p - presentation context
- * @return children count or -1 if unknown
- */
- public int getChildrenCount(IPresentationContext p) {
- return -1;
- }
-
- /**
- * Return address of this node.
- * For executable contexts and stack frames address is current PC.
- * @return BigInteger - remote memory address that is associated with this node
- */
- public BigInteger getAddress() {
- return null;
- }
-
- /**
* Retrieve children count for a presentation context.
* @param result - children count update request.
*/
@@ -176,8 +145,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
if (!result.isCanceled()) {
IChannel channel = model.getLaunch().getChannel();
if (!disposed && channel.getState() == IChannel.STATE_OPEN) {
- if (!validateNode(this)) return;
- getData(result);
+ if (!getData(result, this)) return;
}
else {
result.setChildCount(0);
@@ -199,8 +167,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
if (!result.isCanceled()) {
IChannel channel = model.getLaunch().getChannel();
if (!disposed && channel.getState() == IChannel.STATE_OPEN) {
- if (!validateNode(this)) return;
- getData(result);
+ if (!getData(result, this)) return;
}
result.setStatus(Status.OK_STATUS);
}
@@ -219,8 +186,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
if (!result.isCanceled()) {
IChannel channel = model.getLaunch().getChannel();
if (!disposed && channel.getState() == IChannel.STATE_OPEN) {
- if (!validateNode(this)) return;
- getData(result);
+ if (!getData(result, this)) return;
}
else {
result.setHasChilren(false);
@@ -242,8 +208,7 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
if (!result.isCanceled()) {
IChannel channel = model.getLaunch().getChannel();
if (!disposed && channel.getState() == IChannel.STATE_OPEN) {
- if (!validateNode(this)) return;
- getData(result);
+ if (!getData(result, this)) return;
}
else {
result.setLabel("...", 0);
@@ -257,46 +222,53 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
/**
* Retrieve children count for a presentation context.
- * The node is validated before calling this method,
- * so the method should return cached data.
* The method is always called on TCF dispatch thread.
* @param result - children count update request.
+ * @param done - client call back interface, during data waiting it is
+ * called every time new portion of data becomes available.
+ * @return false if waiting data retrieval, true if all done.
*/
- protected void getData(IChildrenCountUpdate result) {
+ protected boolean getData(IChildrenCountUpdate result, Runnable done) {
result.setChildCount(0);
+ return true;
}
/**
* Retrieve children for a presentation context.
- * The node is validated before calling this method,
- * so the method should return cached data.
* The method is always called on TCF dispatch thread.
* @param result - children update request.
+ * @param done - client call back interface, during data waiting it is
+ * called every time new portion of data becomes available.
+ * @return false if waiting data retrieval, true if all done.
*/
- protected void getData(IChildrenUpdate result) {
+ protected boolean getData(IChildrenUpdate result, Runnable done) {
+ return true;
}
/**
* Check if the node has children in a presentation context.
- * The node is validated before calling this method,
- * so the method should return cached data.
* The method is always called on TCF dispatch thread.
* @param result - "has children" update request.
+ * @param done - client call back interface, during data waiting it is
+ * called every time new portion of data becomes available.
+ * @return false if waiting data retrieval, true if all done.
*/
- protected void getData(IHasChildrenUpdate result) {
+ protected boolean getData(IHasChildrenUpdate result, Runnable done) {
result.setHasChilren(false);
+ return true;
}
/**
* Retrieve node label for a presentation context.
- * The node is validated before calling this method,
- * so the method should return cached data.
* The method is always called on TCF dispatch thread.
* @param result - label update request.
+ * @param done - client call back interface, during data waiting it is
+ * called every time new portion of data becomes available.
+ * @return false if waiting data retrieval, true if all done.
*/
- protected void getData(ILabelUpdate result) {
- result.setImageDescriptor(ImageCache.getImageDescriptor(getImageName()), 0);
+ protected boolean getData(ILabelUpdate result, Runnable done) {
result.setLabel(id, 0);
+ return true;
}
/**
@@ -321,49 +293,8 @@ public abstract class TCFNode extends PlatformObject implements Comparable<TCFNo
}
/*--------------------------------------------------------------------------------------*/
- /* Node data retrieval state machine */
-
- /**
- * Validate node - retrieve and put into a cache missing data from remote peer.
- * The method should initiate retrieval of all data needed by TCFNode.update() methods.
- * Validation is done asynchronously. If the node is already valid,
- * the method should return true. Otherwise, it returns false,
- * adds 'done' into 'wait_list', and later call-backs from 'wait_list' are invoked.
- * Note: activation of call-back does not mean all data is retrieved,
- * it only means that node state changed, client should call validateNode() again,
- * until the method returns true.
- * @param done - call-back object to call when node state changes.
- * @return true if the node is already valid, false if validation is started.
- */
- public abstract boolean validateNode(Runnable done);
-
- /**
- * Clients can use this method to validate a collection of nodes.
- * Validation of multiple nodes is expensive and should be avoided
- * when possible.
- *
- * Validation is performed in background, and 'done' call-back is
- * activated when nodes state changes.
- *
- * @param nodes
- * @return true if all nodes are already valid, false if validation is started.
- */
- public static boolean validateNodes(Collection<TCFNode> nodes, Runnable done) {
- TCFNode pending = null;
- for (TCFNode n : nodes) {
- if (!n.validateNode(null)) pending = n;
- }
- if (pending != null && !pending.validateNode(done)) return false;
- return true;
- }
-
- /*--------------------------------------------------------------------------------------*/
/* Misc */
- protected String getImageName() {
- return null;
- }
-
public int compareTo(TCFNode n) {
return id.compareTo(n.id);
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java
index 6bd85d15f..adaf843ce 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeArrayPartition.java
@@ -17,7 +17,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
-import org.eclipse.tm.tcf.util.TCFDataCache;
public class TCFNodeArrayPartition extends TCFNode {
@@ -53,12 +52,15 @@ public class TCFNodeArrayPartition extends TCFNode {
}
@Override
- protected void getData(IChildrenCountUpdate result) {
+ protected boolean getData(IChildrenCountUpdate result, Runnable done) {
+ if (!children.validate(done)) return false;
result.setChildCount(children.size());
+ return true;
}
@Override
- protected void getData(IChildrenUpdate result) {
+ protected boolean getData(IChildrenUpdate result, Runnable done) {
+ if (!children.validate(done)) return false;
TCFNode[] arr = children.toArray();
int offset = 0;
int r_offset = result.getOffset();
@@ -69,16 +71,18 @@ public class TCFNodeArrayPartition extends TCFNode {
}
offset++;
}
+ return true;
}
@Override
- protected void getData(IHasChildrenUpdate result) {
- result.setHasChilren(children.size() > 0);
+ protected boolean getData(IHasChildrenUpdate result, Runnable done) {
+ result.setHasChilren(true);
+ return true;
}
@Override
- protected void getData(ILabelUpdate result) {
- result.setImageDescriptor(ImageCache.getImageDescriptor(getImageName()), 0);
+ protected boolean getData(ILabelUpdate result, Runnable done) {
+ result.setImageDescriptor(ImageCache.getImageDescriptor(ImageCache.IMG_ARRAY_PARTITION), 0);
String[] cols = result.getColumnIds();
String name = "[" + offs + ".." + (offs + size - 1) + "]";
if (cols == null || cols.length <= 1) {
@@ -95,6 +99,7 @@ public class TCFNodeArrayPartition extends TCFNode {
}
}
}
+ return true;
}
@Override
@@ -107,20 +112,6 @@ public class TCFNodeArrayPartition extends TCFNode {
}
@Override
- public boolean validateNode(Runnable done) {
- TCFDataCache<?> pending = null;
- if (!children.validate()) pending = children;
- if (pending == null) return true;
- pending.wait(done);
- return false;
- }
-
- @Override
- protected String getImageName() {
- return ImageCache.IMG_ARRAY_PARTITION;
- }
-
- @Override
public int compareTo(TCFNode n) {
TCFNodeArrayPartition p = (TCFNodeArrayPartition)n;
if (offs < p.offs) return -1;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
index 1c08fd9e4..3fea23382 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExecContext.java
@@ -11,6 +11,7 @@
package org.eclipse.tm.internal.tcf.debug.ui.model;
import java.math.BigInteger;
+import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -19,7 +20,6 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
@@ -46,6 +46,7 @@ public class TCFNodeExecContext extends TCFNode {
private final TCFDataCache<IRunControl.RunControlContext> run_context;
private final TCFDataCache<IProcesses.ProcessContext> prs_context;
private final TCFDataCache<TCFContextState> state;
+ private final TCFDataCache<BigInteger> address;
private final Map<BigInteger,TCFSourceRef> line_info_cache;
@@ -120,10 +121,7 @@ public class TCFNodeExecContext extends TCFNode {
@Override
protected boolean startDataRetrieval() {
assert command == null;
- if (!run_context.validate()) {
- run_context.wait(this);
- return false;
- }
+ if (!run_context.validate(this)) return false;
IRunControl.RunControlContext ctx = run_context.getData();
if (ctx == null || !ctx.hasState()) {
set(null, null, null);
@@ -142,6 +140,29 @@ public class TCFNodeExecContext extends TCFNode {
return false;
}
};
+ address = new TCFDataCache<BigInteger>(channel) {
+ @Override
+ protected boolean startDataRetrieval() {
+ if (!run_context.validate(this)) return false;
+ IRunControl.RunControlContext ctx = run_context.getData();
+ if (ctx == null || !ctx.hasState()) {
+ set(null, run_context.getError(), null);
+ return true;
+ }
+ if (!state.validate(this)) return false;
+ TCFContextState s = state.getData();
+ if (s == null) {
+ set(null, state.getError(), null);
+ return true;
+ }
+ if (s.suspend_pc == null) {
+ set(null, null, null);
+ return true;
+ }
+ set(null, null, new BigInteger(s.suspend_pc));
+ return true;
+ }
+ };
}
@Override
@@ -150,6 +171,7 @@ public class TCFNodeExecContext extends TCFNode {
prs_context.reset(null);
mem_context.reset(null);
state.reset(null);
+ address.reset(null);
children_exec.dispose();
children_stack.dispose();
super.dispose();
@@ -189,43 +211,8 @@ public class TCFNodeExecContext extends TCFNode {
return mem_context;
}
- public boolean isRunning() {
- assert Protocol.isDispatchThread();
- if (!run_context.isValid()) return false;
- IRunControl.RunControlContext ctx = run_context.getData();
- if (ctx == null || !ctx.hasState()) return false;
- if (!state.isValid()) return false;
- TCFContextState s = state.getData();
- return s != null && !s.is_suspended;
- }
-
- public boolean isSuspended() {
- assert Protocol.isDispatchThread();
- if (!run_context.isValid()) return false;
- IRunControl.RunControlContext ctx = run_context.getData();
- if (ctx == null || !ctx.hasState()) return false;
- if (!state.isValid()) return false;
- TCFContextState s = state.getData();
- return s != null && s.is_suspended;
- }
-
- @Override
- public BigInteger getAddress() {
- assert Protocol.isDispatchThread();
- if (!run_context.isValid()) return null;
- IRunControl.RunControlContext ctx = run_context.getData();
- if (ctx == null || !ctx.hasState()) return null;
- if (!state.isValid()) return null;
- TCFContextState s = state.getData();
- if (s == null) return null;
- if (s.suspend_pc == null) return null;
- return new BigInteger(s.suspend_pc);
- }
-
- public TCFNodeStackFrame getTopFrame() {
- assert Protocol.isDispatchThread();
- if (!children_stack.isValid()) return null;
- return children_stack.getTopFrame();
+ public TCFDataCache<BigInteger> getAddress() {
+ return address;
}
public TCFDataCache<TCFContextState> getState() {
@@ -241,77 +228,45 @@ public class TCFNodeExecContext extends TCFNode {
}
@Override
- public int getNodeIndex(IPresentationContext p, TCFNode n) {
- if (!run_context.isValid()) return -1;
- IRunControl.RunControlContext ctx = run_context.getData();
- if (ctx != null && ctx.hasState()) {
- if (!children_stack.isValid()) return -1;
- if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(p.getId())) {
- TCFNodeStackFrame frame = children_stack.getTopFrame();
- if (frame == null) return -1;
- return frame.getNodeIndex(p, n);
- }
- return children_stack.getIndexOf(n);
- }
- if (!children_exec.isValid()) return -1;
- return children_exec.getIndexOf(n);
- }
-
- @Override
- public int getChildrenCount(IPresentationContext p) {
- if (!run_context.isValid()) return -1;
- IRunControl.RunControlContext ctx = run_context.getData();
- if (ctx != null && ctx.hasState()) {
- if (!children_stack.isValid()) return -1;
- if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(p.getId())) {
- TCFNodeStackFrame frame = children_stack.getTopFrame();
- if (frame == null) return -1;
- return frame.getChildrenCount(p);
- }
- return children_stack.size();
- }
- if (!children_exec.isValid()) return -1;
- return children_exec.size();
- }
-
- @Override
- protected void getData(IChildrenCountUpdate result) {
+ protected boolean getData(IChildrenCountUpdate result, Runnable done) {
+ if (!run_context.validate(done)) return false;
IRunControl.RunControlContext ctx = run_context.getData();
if (ctx != null && ctx.hasState()) {
+ if (!children_stack.validate(done)) return false;
if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) {
TCFNodeStackFrame frame = children_stack.getTopFrame();
- if (frame == null) result.setChildCount(0);
- else frame.getData(result);
+ if (frame != null) return frame.getData(result, done);
+ result.setChildCount(0);
}
else {
result.setChildCount(children_stack.size());
}
}
else {
+ if (!children_exec.validate(done)) return false;
result.setChildCount(children_exec.size());
}
+ return true;
}
@Override
- protected void getData(IChildrenUpdate result) {
+ protected boolean getData(IChildrenUpdate result, Runnable done) {
TCFNode[] arr = null;
+ if (!run_context.validate(done)) return false;
IRunControl.RunControlContext ctx = run_context.getData();
if (ctx != null && ctx.hasState()) {
+ if (!children_stack.validate(done)) return false;
if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) {
TCFNodeStackFrame frame = children_stack.getTopFrame();
- if (frame == null) {
- arr = new TCFNode[0];
- }
- else {
- frame.getData(result);
- return;
- }
+ if (frame != null) return frame.getData(result, done);
+ arr = new TCFNode[0];
}
else {
arr = children_stack.toArray();
}
}
else {
+ if (!children_exec.validate(done)) return false;
arr = children_exec.toArray();
}
int offset = 0;
@@ -323,29 +278,36 @@ public class TCFNodeExecContext extends TCFNode {
}
offset++;
}
+ return true;
}
@Override
- protected void getData(IHasChildrenUpdate result) {
+ protected boolean getData(IHasChildrenUpdate result, Runnable done) {
+ if (!run_context.validate(done)) return false;
IRunControl.RunControlContext ctx = run_context.getData();
if (ctx != null && ctx.hasState()) {
+ if (!children_stack.validate(done)) return false;
if (!IDebugUIConstants.ID_DEBUG_VIEW.equals(result.getPresentationContext().getId())) {
TCFNodeStackFrame frame = children_stack.getTopFrame();
if (frame == null) result.setHasChilren(false);
- else frame.getData(result);
+ else if (!frame.getData(result, done)) return false;
}
else {
result.setHasChilren(children_stack.size() > 0);
}
}
else {
+ if (!children_exec.validate(done)) return false;
result.setHasChilren(children_exec.size() > 0);
}
+ return true;
}
+ @SuppressWarnings("unchecked")
@Override
- protected void getData(ILabelUpdate result) {
- result.setImageDescriptor(ImageCache.getImageDescriptor(getImageName()), 0);
+ protected boolean getData(ILabelUpdate result, Runnable done) {
+ if (!run_context.validate(done)) return false;
+ String image_name = null;
String label = id;
Throwable error = run_context.getError();
if (error != null) {
@@ -355,11 +317,35 @@ public class TCFNodeExecContext extends TCFNode {
else {
IRunControl.RunControlContext ctx = run_context.getData();
if (ctx != null) {
- if (isRunning()) {
+ if (!state.validate(done)) return false;
+ TCFContextState state_data = state.getData();
+ if (ctx.hasState()) {
+ // Thread
+ if (state_data != null && state_data.is_terminated) image_name = ImageCache.IMG_THREAD_TERMINATED;
+ else if (state_data != null && state_data.is_suspended) image_name = ImageCache.IMG_THREAD_SUSPENDED;
+ else image_name = ImageCache.IMG_THREAD_RUNNNIG;
+ }
+ else {
+ // Thread container (process)
+ Boolean b = hasSuspendedChildren(done);
+ if (b == null) return false;
+ if (b.booleanValue()) image_name = ImageCache.IMG_PROCESS_SUSPENDED;
+ else image_name = ImageCache.IMG_PROCESS_RUNNING;
+ }
+ if (state_data != null && !state_data.is_suspended) {
label += " (Running)";
}
- else if (isSuspended()) {
- String r = state.getData().suspend_reason;
+ else if (state_data != null && state_data.is_suspended) {
+ String r = state_data.suspend_reason;
+ if (state_data.suspend_params != null) {
+ Collection<String> ids = (Collection<String>)state_data.suspend_params.get(IRunControl.STATE_BREAKPOINT_IDS);
+ if (ids != null) {
+ for (String id : ids) {
+ String s = model.getLaunch().getContextActionBreakpoint(id);
+ if (s != null) r = s;
+ }
+ }
+ }
if (r != null) {
label += " (" + r + ")";
}
@@ -371,7 +357,9 @@ public class TCFNodeExecContext extends TCFNode {
if (file != null) label += " " + file;
}
}
+ result.setImageDescriptor(ImageCache.getImageDescriptor(image_name), 0);
result.setLabel(label, 0);
+ return true;
}
void onContextAdded(IRunControl.RunControlContext context) {
@@ -410,6 +398,7 @@ public class TCFNodeExecContext extends TCFNode {
if (!ctx.hasState()) return;
}
state.reset();
+ address.reset();
children_stack.onSuspended();
addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
}
@@ -434,6 +423,7 @@ public class TCFNodeExecContext extends TCFNode {
s.suspend_params = params;
state.reset(s);
children_stack.onSuspended();
+ address.reset();
resumed_cnt++;
addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
}
@@ -448,12 +438,10 @@ public class TCFNodeExecContext extends TCFNode {
if (cnt != resumed_cnt) return;
if (disposed) return;
children_stack.onResumed();
- if (!validateNode(this)) return;
addModelDelta(IModelDelta.CONTENT);
if (parent instanceof TCFNodeExecContext) {
((TCFNodeExecContext)parent).onChildResumedOrSuspended();
}
- model.fireModelChanged();
}
});
}
@@ -476,96 +464,34 @@ public class TCFNodeExecContext extends TCFNode {
addModelDelta(IModelDelta.CONTENT);
}
- @Override
- public boolean validateNode(Runnable done) {
- assert !disposed;
- TCFDataCache<?> pending = null;
-
- if (!mem_context.validate()) pending = mem_context;
- if (!run_context.validate()) pending = run_context;
- if (!prs_context.validate()) pending = prs_context;
- if (pending != null) {
- pending.wait(done);
- return false;
- }
-
- if (!state.validate()) pending = state;
- if (!children_exec.validate()) pending = children_exec;
- if (!children_stack.validate()) pending = children_stack;
- IRunControl.RunControlContext ctx = run_context.getData();
- if (ctx != null && !ctx.hasState()) {
- // Container need to validate children for
- // hasSuspendedChildren() method to return valid value.
- TCFDataCache<?> dt = validateChildrenState();
- if (dt != null) pending = dt;
- }
- if (pending != null) {
- pending.wait(done);
- return false;
- }
-
- TCFNodeStackFrame frame = children_stack.getTopFrame();
- if (frame != null && !frame.validateNode(done)) return false;
-
- return true;
- }
-
- // Validate children state for hasSuspendedChildren()
- // Return TCFDataCache to wait for if validation is pending.
- private TCFDataCache<?> validateChildrenState() {
- if (!children_exec.validate()) return children_exec;
- TCFDataCache<?> pending = null;
- for (TCFNode n : children_exec.getData().values()) {
- if (!(n instanceof TCFNodeExecContext)) continue;
- TCFNodeExecContext e = (TCFNodeExecContext)n;
- if (!e.run_context.validate()) {
- pending = e.run_context;
- continue;
- }
- IRunControl.RunControlContext ctx = e.run_context.getData();
- if (ctx == null) continue;
- if (ctx.hasState() && !e.state.validate()) pending = e.state;
- if (ctx.isContainer()) pending = e.validateChildrenState();
- }
- return pending;
- }
-
// Return true if at least one child is suspended
// The method will fail if node is not validated, see validateChildrenState()
- private boolean hasSuspendedChildren() {
+ private Boolean hasSuspendedChildren(Runnable done) {
+ if (!children_exec.validate(done)) return null;
Map<String,TCFNode> m = children_exec.getData();
if (m == null) return false;
for (TCFNode n : m.values()) {
if (!(n instanceof TCFNodeExecContext)) continue;
TCFNodeExecContext e = (TCFNodeExecContext)n;
+ if (!e.run_context.validate(done)) return null;
IRunControl.RunControlContext ctx = e.run_context.getData();
if (ctx == null) continue;
- if (ctx.hasState() && e.isSuspended()) return true;
- if (ctx.isContainer() && e.hasSuspendedChildren()) return true;
+ if (ctx.hasState()) {
+ TCFDataCache<TCFContextState> state_cache = e.getState();
+ if (!state_cache.validate(done)) return null;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data != null && state_data.is_suspended) return true;
+ }
+ if (ctx.isContainer()) {
+ Boolean b = e.hasSuspendedChildren(done);
+ if (b == null) return null;
+ if (b.booleanValue()) return true;
+ }
}
return false;
}
@Override
- protected String getImageName() {
- IRunControl.RunControlContext ctx = run_context.getData();
- if (ctx != null && ctx.hasState()) {
- // Thread
- TCFContextState s = state.getData();
- if (s != null && s.is_terminated) return ImageCache.IMG_THREAD_TERMINATED;
- if (s != null && s.is_suspended) return ImageCache.IMG_THREAD_SUSPENDED;
- return ImageCache.IMG_THREAD_RUNNNIG;
- }
- else if (ctx != null) {
- // Thread container (process)
- //if (terminated) return ImageCache.IMG_PROCESS_TERMINATED;
- if (hasSuspendedChildren()) return ImageCache.IMG_PROCESS_SUSPENDED;
- return ImageCache.IMG_PROCESS_RUNNING;
- }
- return super.getImageName();
- }
-
- @Override
public int compareTo(TCFNode n) {
if (n instanceof TCFNodeExecContext) {
TCFNodeExecContext f = (TCFNodeExecContext)n;
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
index e0be1e6be..3893ede6e 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeExpression.java
@@ -31,16 +31,23 @@ import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.tm.internal.tcf.debug.ui.Activator;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
+import org.eclipse.tm.tcf.core.Command;
import org.eclipse.tm.tcf.protocol.IChannel;
+import org.eclipse.tm.tcf.protocol.IErrorReport;
import org.eclipse.tm.tcf.protocol.IToken;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IExpressions;
+import org.eclipse.tm.tcf.services.IMemory;
import org.eclipse.tm.tcf.services.ISymbols;
+import org.eclipse.tm.tcf.services.IMemory.MemoryError;
import org.eclipse.tm.tcf.util.TCFDataCache;
import org.eclipse.tm.tcf.util.TCFTask;
public class TCFNodeExpression extends TCFNode implements IElementEditor {
+ // TODO: User commands: Display As Array, Cast To Type, Restore Original Type, Add Global Variables, Remove Global Variables
+ // TODO: enable Change Value user command
+
private final String script;
private final String field_id;
private final String var_id;
@@ -51,34 +58,22 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
private final TCFDataCache<IExpressions.Value> value;
private final TCFDataCache<ISymbols.Symbol> type;
private final TCFChildrenSubExpressions children;
+ private final TCFDataCache<String> type_name;
+ private final TCFDataCache<String> string;
private int sort_pos;
private static int expr_cnt;
- TCFNodeExpression(final TCFNode parent, final String script, final String field_id, final String var_id, final int index) {
+ TCFNodeExpression(final TCFNode parent, final String script,
+ String field_id, final String var_id, final int index, final ISymbols.Symbol parent_type) {
super(parent, var_id != null ? var_id : "Expr" + expr_cnt++);
assert script != null || field_id != null || var_id != null || index >= 0;
this.script = script;
this.field_id = field_id;
this.var_id = var_id;
+ this.field = field_id == null ? null : model.getSymbolInfoCache(parent_type.getExeContextID(), field_id);
this.index = index;
IChannel channel = model.getLaunch().getChannel();
- field = new TCFDataCache<ISymbols.Symbol>(channel) {
- @Override
- protected boolean startDataRetrieval() {
- ISymbols syms = model.getLaunch().getService(ISymbols.class);
- if (field_id == null || syms == null) {
- set(null, null, null);
- return true;
- }
- command = syms.getContext(field_id, new ISymbols.DoneGetContext() {
- public void doneGetContext(IToken token, Exception error, ISymbols.Symbol sym) {
- set(token, error, sym);
- }
- });
- return false;
- }
- };
text = new TCFDataCache<String>(channel) {
@Override
protected boolean startDataRetrieval() {
@@ -87,10 +82,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
return true;
}
if (var_id != null) {
- if (!expression.validate()) {
- expression.wait(this);
- return false;
- }
+ if (!expression.validate(this)) return false;
if (expression.getData() == null) {
set(null, expression.getError(), null);
return true;
@@ -106,20 +98,14 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
TCFNode n = parent;
while (n instanceof TCFNodeArrayPartition) n = n.parent;
TCFDataCache<String> t = ((TCFNodeExpression)n).getExpressionText();
- if (!t.validate()) {
- t.wait(this);
- return false;
- }
+ if (!t.validate(this)) return false;
String e = t.getData();
if (e == null) {
set(null, t.getError(), null);
return true;
}
- if (field_id != null) {
- if (!field.validate()) {
- field.wait(this);
- return false;
- }
+ if (field != null) {
+ if (!field.validate(this)) return false;
if (field.getData() == null) {
set(null, field.getError(), null);
return true;
@@ -129,7 +115,12 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
set(null, new Exception("Field nas no name"), null);
return true;
}
- e = "(" + e + ")." + name;
+ if (parent_type.getTypeClass() == ISymbols.TypeClass.pointer) {
+ e = "(" + e + ")->" + name;
+ }
+ else {
+ e = "(" + e + ")." + name;
+ }
}
else if (index == 0) {
e = "*(" + e + ")";
@@ -157,10 +148,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
});
}
else {
- if (!text.validate()) {
- text.wait(this);
- return false;
- }
+ if (!text.validate(this)) return false;
String e = text.getData();
if (e == null) {
set(null, text.getError(), null);
@@ -193,10 +181,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
value = new TCFDataCache<IExpressions.Value>(channel) {
@Override
protected boolean startDataRetrieval() {
- if (!expression.validate()) {
- expression.wait(this);
- return false;
- }
+ if (!expression.validate(this)) return false;
final IExpressions.Expression ctx = expression.getData();
if (ctx == null) {
set(null, null, null);
@@ -214,29 +199,254 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
type = new TCFDataCache<ISymbols.Symbol>(channel) {
@Override
protected boolean startDataRetrieval() {
- if (!value.validate()) {
- value.wait(this);
- return false;
- }
- IExpressions.Value v = value.getData();
- if (v == null) {
- set(null, null, null);
+ if (!value.validate(this)) return false;
+ IExpressions.Value val = value.getData();
+ if (val == null) {
+ set(null, value.getError(), null);
return true;
}
- String ctx_id = v.getExeContextID();
- String type_id = v.getTypeID();
- if (ctx_id == null || type_id == null) {
+ TCFDataCache<ISymbols.Symbol> type_cache = model.getSymbolInfoCache(
+ val.getExeContextID(), val.getTypeID());
+ if (type_cache == null) {
set(null, null, null);
return true;
}
- TCFDataCache<ISymbols.Symbol> s = model.getSymbolInfoCache(ctx_id, type_id);
- if (!s.validate()) {
- s.wait(this);
+ if (!type_cache.validate(this)) return false;
+ set(null, type_cache.getError(), type_cache.getData());
+ return true;
+ }
+ };
+ string = new TCFDataCache<String>(channel) {
+ IMemory.MemoryContext mem;
+ ISymbols.Symbol base_type_data;
+ boolean big_endian;
+ BigInteger addr;
+ byte[] buf;
+ int size;
+ int offs;
+ @Override
+ protected boolean startDataRetrieval() {
+ if (addr != null && size == 0) {
+ // data is ASCII string
+ if (buf == null) buf = new byte[256];
+ if (offs >= buf.length) {
+ byte[] tmp = new byte[buf.length * 2];
+ System.arraycopy(buf, 0, tmp, 0, buf.length);
+ buf = tmp;
+ }
+ command = mem.get(addr.add(BigInteger.valueOf(offs)), 1, buf, offs, 1, 0, new IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (error != null) {
+ String msg = "Cannot read string value: ";
+ if (error instanceof IErrorReport) {
+ msg += Command.toErrorString(((IErrorReport)error).getAttributes());
+ }
+ else {
+ msg += error.getLocalizedMessage();
+ }
+ set(command, null, msg);
+ }
+ else if (buf[offs] == 0 || offs >= 2048) {
+ StringBuffer bf = new StringBuffer();
+ bf.append('"');
+ for (int i = 0; i < offs; i++) {
+ int ch = buf[i] & 0xff;
+ if (ch >= ' ' && ch < 0x7f) {
+ bf.append((char)ch);
+ }
+ else {
+ switch (ch) {
+ case '\r': bf.append("\\r"); break;
+ case '\n': bf.append("\\n"); break;
+ case '\b': bf.append("\\b"); break;
+ case '\t': bf.append("\\t"); break;
+ case '\f': bf.append("\\f"); break;
+ default:
+ bf.append('\\');
+ bf.append((char)('0' + ch / 64));
+ bf.append((char)('0' + ch / 8 % 8));
+ bf.append((char)('0' + ch % 8));
+ }
+ }
+ }
+ if (buf[offs] == 0) bf.append('"');
+ else bf.append("...");
+ set(command, null, bf.toString());
+ }
+ else if (command == token) {
+ command = null;
+ offs++;
+ run();
+ }
+ }
+ });
return false;
}
- set(null, s.getError(), s.getData());
+ if (addr != null) {
+ // data is a struct
+ if (offs != size) {
+ if (buf == null || buf.length < size) buf = new byte[size];
+ command = mem.get(addr, 1, buf, 0, size, 0, new IMemory.DoneMemory() {
+ public void doneMemory(IToken token, MemoryError error) {
+ if (error != null) {
+ set(command, error, null);
+ }
+ else if (command == token) {
+ command = null;
+ offs = size;
+ run();
+ }
+ }
+ });
+ return false;
+ }
+ StringBuffer bf = new StringBuffer();
+ if (!appendCompositeValueText(bf, 1, base_type_data, buf, 0, size, big_endian, this)) return false;
+ set(null, null, bf.toString());
+ return true;
+ }
+ TCFNode n = parent;
+ while (n != null) {
+ if (n instanceof TCFNodeExecContext) {
+ TCFDataCache<IMemory.MemoryContext> mem_cache = ((TCFNodeExecContext)n).getMemoryContext();
+ if (!mem_cache.validate(this)) return false;
+ mem = mem_cache.getData();
+ if (mem != null) break;
+ }
+ n = n.parent;
+ }
+ if (mem != null) {
+ if (!type.validate(this)) return false;
+ ISymbols.Symbol type_data = type.getData();
+ if (type_data != null) {
+ switch (type_data.getTypeClass()) {
+ case pointer:
+ TCFDataCache<ISymbols.Symbol> base_type_cahce = model.getSymbolInfoCache(
+ type_data.getExeContextID(), type_data.getBaseTypeID());
+ if (base_type_cahce != null) {
+ if (!base_type_cahce.validate(this)) return false;
+ base_type_data = base_type_cahce.getData();
+ if (base_type_data != null) {
+ switch (base_type_data.getTypeClass()) {
+ case integer:
+ case cardinal:
+ if (base_type_data.getSize() != 1) break;
+ case composite:
+ if (base_type_data.getSize() == 0) break;
+ if (!value.validate(this)) return false;
+ IExpressions.Value v = value.getData();
+ if (v != null) {
+ byte[] data = v.getValue();
+ big_endian = v.isBigEndian();
+ BigInteger a = toBigInteger(data, 0, data.length, big_endian, false);
+ if (!a.equals(BigInteger.valueOf(0))) {
+ addr = a;
+ offs = 0;
+ size = 0;
+ if (base_type_data.getTypeClass() == ISymbols.TypeClass.composite) {
+ size = base_type_data.getSize();
+ }
+ Protocol.invokeLater(this);
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ set(null, null, null);
+ return true;
+ }
+ @Override
+ public void reset() {
+ super.reset();
+ addr = null;
+ }
+ };
+ type_name = new TCFDataCache<String>(channel) {
+ String name;
+ TCFDataCache<ISymbols.Symbol> type_cache;
+ @Override
+ protected boolean startDataRetrieval() {
+ if (name == null) type_cache = type;
+ if (!type_cache.validate(this)) return false;
+ String s = null;
+ boolean get_base_type = false;
+ ISymbols.Symbol t = type_cache.getData();
+ if (t != null) {
+ s = t.getName();
+ if (s != null && t.getTypeClass() == ISymbols.TypeClass.composite) {
+ s = "struct " + s;
+ }
+ if (s == null && t.getSize() == 0) s = "void";
+ if (s == null) {
+ switch (t.getTypeClass()) {
+ case integer:
+ switch (t.getSize()) {
+ case 1: s = "char"; break;
+ case 2: s = "short"; break;
+ case 4: s = "int"; break;
+ case 8: s = "long long"; break;
+ default: s = "<Integer>"; break;
+ }
+ break;
+ case cardinal:
+ switch (t.getSize()) {
+ case 1: s = "unsigned char"; break;
+ case 2: s = "unsigned short"; break;
+ case 4: s = "unsigned"; break;
+ case 8: s = "unsigned long long"; break;
+ default: s = "<Unsigned>"; break;
+ }
+ break;
+ case real:
+ switch (t.getSize()) {
+ case 4: s = "float"; break;
+ case 8: s = "double"; break;
+ default: s = "<Float>"; break;
+ }
+ break;
+ case pointer:
+ s = "*";
+ get_base_type = true;
+ break;
+ case array:
+ s = "[]";
+ get_base_type = true;
+ break;
+ case composite:
+ s = "<Structure>";
+ break;
+ case function:
+ s = "<Function>";
+ break;
+ }
+ }
+ }
+ if (s == null) name = "N/A";
+ else if (name == null) name = s;
+ else if (!get_base_type) name = s + " " + name;
+ else name = s + name;
+ if (get_base_type) {
+ type_cache = model.getSymbolInfoCache(t.getExeContextID(), t.getBaseTypeID());
+ if (type_cache == null) {
+ name = "N/A";
+ }
+ else {
+ Protocol.invokeLater(this);
+ return false;
+ }
+ }
+ set(null, null, name);
return true;
}
+ @Override
+ public void reset() {
+ super.reset();
+ name = null;
+ }
};
children = new TCFChildrenSubExpressions(this, 0, 0, 0);
}
@@ -245,6 +455,8 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
void dispose() {
value.reset(null);
type.reset(null);
+ type_name.reset(null);
+ string.reset(null);
children.reset(null);
children.dispose();
super.dispose();
@@ -270,6 +482,8 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
void onSuspended() {
value.reset();
type.reset();
+ type_name.reset();
+ string.reset();
children.reset();
children.onSuspended();
addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
@@ -299,10 +513,6 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
return value;
}
- TCFDataCache<ISymbols.Symbol> getType() {
- return type;
- }
-
private BigInteger toBigInteger(byte[] data, int offs, int size, boolean big_endian, boolean sign_extension) {
assert offs + size <= data.length;
byte[] temp = null;
@@ -389,52 +599,29 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
}
private void setTypeLabel(ILabelUpdate result, int col) {
- String s = null;
- ISymbols.Symbol t = type.getData();
- if (t != null) {
- s = t.getName();
- if (s == null && t.getSize() == 0) s = "<Void>";
- if (s == null) {
- switch (t.getTypeClass()) {
- case integer:
- s = "<Integer>";
- break;
- case cardinal:
- s = "<Unsigned>";
- break;
- case real:
- s = "<Float>";
- break;
- case pointer:
- s = "<Pointer>";
- break;
- case array:
- s = "<Array>";
- break;
- case composite:
- s = "<Structure>";
- break;
- case function:
- s = "<Function>";
- break;
- }
- }
- }
- if (s == null) s = "N/A";
- result.setLabel(s, col);
+ result.setLabel(type_name.getData(), col);
}
@Override
- protected void getData(ILabelUpdate result) {
- result.setImageDescriptor(ImageCache.getImageDescriptor(getImageName()), 0);
+ protected boolean getData(ILabelUpdate result, Runnable done) {
+ TCFDataCache<?> pending = null;
+ if (field != null && !field.validate()) pending = field;
+ if (!expression.validate()) pending = expression;
+ if (!value.validate()) pending = value;
+ if (!type.validate()) pending = type;
+ if (!type_name.validate()) pending = type_name;
+ if (!children.validate()) pending = children;
+ if (pending != null) {
+ pending.wait(done);
+ return false;
+ }
String name = null;
if (script != null) name = script;
if (name == null && index >= 0) name = "[" + index + "]";
- if (name == null && field_id != null && field.getData() != null) name = field.getData().getName();
+ if (name == null && field != null && field.getData() != null) name = field.getData().getName();
if (name == null && var_id != null && expression.getData() != null) name = expression.getData().getExpression();
Throwable error = expression.getError();
if (error == null) error = value.getError();
- if (error == null) error = type.getError();
String[] cols = result.getColumnIds();
if (error != null) {
if (cols == null || cols.length <= 1) {
@@ -447,7 +634,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
if (c.equals(TCFColumnPresentationExpression.COL_NAME)) {
result.setLabel(name, i);
}
- else if (c.equals(TCFColumnPresentationExpression.COL_TYPE) && type.getError() == null) {
+ else if (c.equals(TCFColumnPresentationExpression.COL_TYPE)) {
setTypeLabel(result, i);
}
else {
@@ -479,6 +666,8 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
}
}
}
+ result.setImageDescriptor(ImageCache.getImageDescriptor(ImageCache.IMG_VARIABLE), 0);
+ return true;
}
private void appendErrorText(StringBuffer bf, Throwable error) {
@@ -496,16 +685,10 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
}
}
- private boolean appendArrayValueText(StringBuffer bf, int level, ISymbols.Symbol t,
+ private boolean appendArrayValueText(StringBuffer bf, int level, ISymbols.Symbol type,
byte[] data, int offs, int size, boolean big_endian, Runnable done) {
assert offs + size <= data.length;
- TCFDataCache<ISymbols.Symbol> c = model.getSymbolInfoCache(t.getExeContextID(), t.getBaseTypeID());
- if (!c.validate()) {
- c.wait(done);
- return false;
- }
- ISymbols.Symbol b = c.getData();
- int length = t.getLength();
+ int length = type.getLength();
if (level == 0) {
if (size == length) {
try {
@@ -530,7 +713,6 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
bf.append('\n');
}
}
- if (b == null) return true;
bf.append('[');
if (length > 0) {
int elem_size = size / length;
@@ -540,7 +722,8 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
break;
}
if (n > 0) bf.append(", ");
- if (!appendValueText(bf, level + 1, b, data, offs + n * elem_size, elem_size, big_endian, done)) return false;
+ if (!appendValueText(bf, level + 1, type.getExeContextID(), type.getBaseTypeID(),
+ data, offs + n * elem_size, elem_size, big_endian, done)) return false;
}
}
bf.append(']');
@@ -548,87 +731,112 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
return true;
}
- private boolean appendCompositeValueText(StringBuffer bf, int level, ISymbols.Symbol t,
+ private boolean appendCompositeValueText(StringBuffer bf, int level, ISymbols.Symbol type,
byte[] data, int offs, int size, boolean big_endian, Runnable done) {
- TCFDataCache<String[]> c = model.getSymbolChildrenCache(t.getExeContextID(), t.getID());
- if (!c.validate()) {
- c.wait(done);
- return false;
+ TCFDataCache<String[]> children_cache = model.getSymbolChildrenCache(type.getExeContextID(), type.getID());
+ if (children_cache == null) {
+ bf.append("{...}");
+ return true;
+ }
+ if (!children_cache.validate(done)) return false;
+ String[] children_data = children_cache.getData();
+ if (children_data == null) {
+ bf.append("{...}");
+ return true;
}
- String[] ids = c.getData();
- if (ids == null) return true;
bf.append('{');
- for (String id : ids) {
- if (id != ids[0]) bf.append(", ");
- TCFDataCache<ISymbols.Symbol> s = model.getSymbolInfoCache(t.getExeContextID(), id);
- if (!s.validate()) {
- s.wait(done);
- return false;
- }
- ISymbols.Symbol f = s.getData();
- if (f == null || offs + f.getOffset() + f.getSize() > data.length) {
+ for (String id : children_data) {
+ if (id != children_data[0]) bf.append(", ");
+ TCFDataCache<ISymbols.Symbol> field_cache = model.getSymbolInfoCache(type.getExeContextID(), id);
+ if (!field_cache.validate(done)) return false;
+ ISymbols.Symbol field_data = field_cache.getData();
+ if (field_data == null || offs + field_data.getOffset() + field_data.getSize() > data.length) {
bf.append('?');
continue;
}
- bf.append(f.getName());
+ bf.append(field_data.getName());
bf.append('=');
- if (!appendValueText(bf, level + 1, f, data, offs + f.getOffset(), f.getSize(), big_endian, done)) return false;
+ if (!appendValueText(bf, level + 1, field_data.getExeContextID(), field_data.getTypeID(),
+ data, offs + field_data.getOffset(), field_data.getSize(), big_endian, done)) return false;
}
bf.append('}');
return true;
}
- private boolean appendValueText(StringBuffer bf, int level, ISymbols.Symbol t,
+ private boolean appendValueText(StringBuffer bf, int level, String ctx_id, String type_id,
byte[] data, int offs, int size, boolean big_endian, Runnable done) {
if (data == null) return true;
- switch (t.getTypeClass()) {
+ TCFDataCache<ISymbols.Symbol> type_cahce = model.getSymbolInfoCache(ctx_id, type_id);
+ if (!type_cahce.validate(done)) return false;
+ ISymbols.Symbol type_data = type_cahce.getData();
+ if (type_data == null) {
+ if (level == 0) {
+ bf.append("Hex: ");
+ bf.append(toNumberString(16, type_data, data, 0, data.length, big_endian));
+ bf.append("\n");
+ bf.append("Value type is not available\n");
+ }
+ else {
+ bf.append(toNumberString(16, type_data, data, 0, data.length, big_endian));
+ }
+ return true;
+ }
+ if (level == 0) {
+ if (!string.validate(done)) return false;
+ String s = string.getData();
+ if (s != null) {
+ bf.append(s);
+ bf.append("\n");
+ }
+ }
+ switch (type_data.getTypeClass()) {
case enumeration:
case integer:
case cardinal:
case real:
if (level == 0) {
bf.append("Size: ");
- bf.append(t.getSize());
- bf.append(t.getSize() == 1 ? " byte\n" : " bytes\n");
- if (t.getSize() == 0) break;
+ bf.append(type_data.getSize());
+ bf.append(type_data.getSize() == 1 ? " byte\n" : " bytes\n");
+ if (type_data.getSize() == 0) break;
bf.append("Dec: ");
- bf.append(toNumberString(10, t, data, offs, size, big_endian));
+ bf.append(toNumberString(10, type_data, data, offs, size, big_endian));
bf.append("\n");
bf.append("Oct: ");
- bf.append(toNumberString(8, t, data, offs, size, big_endian));
+ bf.append(toNumberString(8, type_data, data, offs, size, big_endian));
bf.append("\n");
bf.append("Hex: ");
- bf.append(toNumberString(16, t, data, offs, size, big_endian));
+ bf.append(toNumberString(16, type_data, data, offs, size, big_endian));
bf.append("\n");
}
- else if (t.getTypeClass() == ISymbols.TypeClass.cardinal) {
+ else if (type_data.getTypeClass() == ISymbols.TypeClass.cardinal) {
bf.append("0x");
- bf.append(toNumberString(16, t, data, offs, size, big_endian));
+ bf.append(toNumberString(16, type_data, data, offs, size, big_endian));
}
else {
- bf.append(toNumberString(10, t, data, offs, size, big_endian));
+ bf.append(toNumberString(10, type_data, data, offs, size, big_endian));
}
break;
case pointer:
case function:
if (level == 0) {
bf.append("Oct: ");
- bf.append(toNumberString(8, t, data, offs, size, big_endian));
+ bf.append(toNumberString(8, type_data, data, offs, size, big_endian));
bf.append("\n");
bf.append("Hex: ");
- bf.append(toNumberString(16, t, data, offs, size, big_endian));
+ bf.append(toNumberString(16, type_data, data, offs, size, big_endian));
bf.append("\n");
}
else {
bf.append("0x");
- bf.append(toNumberString(16, t, data, offs, size, big_endian));
+ bf.append(toNumberString(16, type_data, data, offs, size, big_endian));
}
break;
case array:
- if (!appendArrayValueText(bf, level, t, data, offs, size, big_endian, done)) return false;
+ if (!appendArrayValueText(bf, level, type_data, data, offs, size, big_endian, done)) return false;
break;
case composite:
- if (!appendCompositeValueText(bf, level, t, data, offs, size, big_endian, done)) return false;
+ if (!appendCompositeValueText(bf, level, type_data, data, offs, size, big_endian, done)) return false;
break;
default:
bf.append('?');
@@ -638,37 +846,33 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
}
String getDetailText(Runnable done) {
+ if (!expression.validate(done)) return null;
+ if (!value.validate(done)) return null;
StringBuffer bf = new StringBuffer();
appendErrorText(bf, expression.getError());
appendErrorText(bf, value.getError());
- appendErrorText(bf, type.getError());
if (bf.length() == 0) {
IExpressions.Value v = value.getData();
if (v != null) {
byte[] data = v.getValue();
boolean big_endian = v.isBigEndian();
- ISymbols.Symbol t = type.getData();
- if (t != null) {
- if (!appendValueText(bf, 0, t, data, 0, data.length, big_endian, done)) return null;
- }
- else {
- bf.append("Hex: ");
- bf.append(toNumberString(16, t, data, 0, data.length, big_endian));
- bf.append("\n");
- bf.append("Value type is not available\n");
- }
+ if (!appendValueText(bf, 0, v.getExeContextID(), v.getTypeID(),
+ data, 0, data.length, big_endian, done)) return null;
}
}
return bf.toString();
}
@Override
- protected void getData(IChildrenCountUpdate result) {
+ protected boolean getData(IChildrenCountUpdate result, Runnable done) {
+ if (!children.validate(done)) return false;
result.setChildCount(children.size());
+ return true;
}
@Override
- protected void getData(IChildrenUpdate result) {
+ protected boolean getData(IChildrenUpdate result, Runnable done) {
+ if (!children.validate(done)) return false;
TCFNode[] arr = children.toArray();
int offset = 0;
int r_offset = result.getOffset();
@@ -679,11 +883,14 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
}
offset++;
}
+ return true;
}
@Override
- protected void getData(IHasChildrenUpdate result) {
+ protected boolean getData(IHasChildrenUpdate result, Runnable done) {
+ if (!children.validate(done)) return false;
result.setHasChilren(children.size() > 0);
+ return true;
}
@Override
@@ -696,24 +903,6 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
}
@Override
- public boolean validateNode(Runnable done) {
- TCFDataCache<?> pending = null;
- if (!field.validate()) pending = field;
- if (!expression.validate()) pending = expression;
- if (!value.validate()) pending = value;
- if (!type.validate()) pending = type;
- if (!children.validate()) pending = children;
- if (pending == null) return true;
- pending.wait(done);
- return false;
- }
-
- @Override
- protected String getImageName() {
- return ImageCache.IMG_VARIABLE;
- }
-
- @Override
public int compareTo(TCFNode n) {
TCFNodeExpression e = (TCFNodeExpression)n;
if (sort_pos < e.sort_pos) return -1;
@@ -745,7 +934,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
done(node.script != null);
return;
}
- if (!node.validateNode(this)) return;
+ if (!node.expression.validate(this)) return;
if (node.expression.getData() != null && node.expression.getData().canAssign()) {
if (TCFColumnPresentationExpression.COL_HEX_VALUE.equals(property)) {
done(TCFNumberFormat.isValidHexNumber(node.toNumberString(16)) == null);
@@ -769,7 +958,7 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
done(node.script);
return;
}
- if (!node.validateNode(this)) return;
+ if (!node.value.validate(this)) return;
if (node.value.getData() != null) {
if (TCFColumnPresentationExpression.COL_HEX_VALUE.equals(property)) {
done(node.toNumberString(16));
@@ -803,13 +992,14 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
done(Boolean.TRUE);
return;
}
- if (!node.validateNode(this)) return;
+ if (!node.expression.validate(this)) return;
if (node.expression.getData() != null && node.expression.getData().canAssign()) {
byte[] bf = null;
int size = node.expression.getData().getSize();
boolean is_float = false;
boolean big_endian = false;
boolean signed = false;
+ if (!node.value.validate(this)) return;
IExpressions.Value eval = node.value.getData();
if (eval != null) {
switch(eval.getTypeClass()) {
@@ -847,7 +1037,6 @@ public class TCFNodeExpression extends TCFNode implements IElementEditor {
else {
node.value.reset();
node.addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
- node.model.fireModelChanged();
done(Boolean.TRUE);
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java
index f8779c235..3e446834b 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeLaunch.java
@@ -16,7 +16,6 @@ import java.util.Arrays;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IMemory;
import org.eclipse.tm.tcf.services.IRunControl;
@@ -32,10 +31,7 @@ public class TCFNodeLaunch extends TCFNode {
// Set initial selection in Debug View
Protocol.invokeLater(new Runnable() {
public void run() {
- if (!children.validate()) {
- children.wait(this);
- return;
- }
+ if (!children.validate(this)) return;
ArrayList<TCFNodeStackFrame> frames = new ArrayList<TCFNodeStackFrame>();
TCFNode[] arr = children.toArray();
Arrays.sort(arr);
@@ -54,20 +50,16 @@ public class TCFNodeLaunch extends TCFNode {
}
private boolean searchTopFrame(TCFNodeExecContext e, ArrayList<TCFNodeStackFrame> frames, Runnable r) {
- if (!e.validateNode(r)) return false;
- TCFNodeStackFrame f = e.getTopFrame();
+ TCFChildrenStackTrace stack_trace = e.getStackTrace();
+ if (!stack_trace.validate(r)) return false;
+ TCFNodeStackFrame f = stack_trace.getTopFrame();
if (f != null && !f.disposed) {
frames.add(f);
return true;
}
TCFChildrenExecContext c = e.getChildren();
- if (!c.validate()) {
- c.wait(r);
- return false;
- }
- TCFNode[] arr = c.toArray();
- Arrays.sort(arr);
- for (TCFNode n : arr) {
+ if (!c.validate(r)) return false;
+ for (TCFNode n : c.toArray()) {
if (!searchTopFrame((TCFNodeExecContext)n, frames, r)) return false;
if (frames.size() > 0) break;
}
@@ -86,24 +78,15 @@ public class TCFNodeLaunch extends TCFNode {
}
@Override
- public int getNodeIndex(IPresentationContext p, TCFNode n) {
- if (!children.isValid()) return -1;
- return children.getIndexOf(n);
- }
-
- @Override
- public int getChildrenCount(IPresentationContext p) {
- if (!children.isValid()) return -1;
- return children.size();
- }
-
- @Override
- protected void getData(IChildrenCountUpdate result) {
+ protected boolean getData(IChildrenCountUpdate result, Runnable done) {
+ if (!children.validate(done)) return false;
result.setChildCount(children.size());
+ return true;
}
@Override
- protected void getData(IChildrenUpdate result) {
+ protected boolean getData(IChildrenUpdate result, Runnable done) {
+ if (!children.validate(done)) return false;
TCFNode[] arr = children.toArray();
int offset = 0;
int r_offset = result.getOffset();
@@ -114,11 +97,14 @@ public class TCFNodeLaunch extends TCFNode {
}
offset++;
}
+ return true;
}
@Override
- protected void getData(IHasChildrenUpdate result) {
+ protected boolean getData(IHasChildrenUpdate result, Runnable done) {
+ if (!children.validate(done)) return false;
result.setHasChilren(children.size() > 0);
+ return true;
}
void onContextAdded(IRunControl.RunControlContext context) {
@@ -129,17 +115,7 @@ public class TCFNodeLaunch extends TCFNode {
children.onContextAdded(context);
}
- int getContextCount() {
- assert children.isValid();
- return children.size();
- }
-
- @Override
- public boolean validateNode(Runnable done) {
- if (!children.validate()) {
- children.wait(done);
- return false;
- }
- return true;
+ TCFChildrenExecContext getChildren() {
+ return children;
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java
index ae353f1ed..b7749e5fd 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeRegister.java
@@ -55,10 +55,7 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
value = new TCFDataCache<byte[]>(channel) {
@Override
protected boolean startDataRetrieval() {
- if (!context.validate()) {
- context.wait(this);
- return false;
- }
+ if (!context.validate(this)) return false;
IRegisters.RegistersContext ctx = context.getData();
if (ctx == null) {
set(null, null, null);
@@ -82,8 +79,14 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
}
@Override
- protected void getData(ILabelUpdate result) {
- result.setImageDescriptor(ImageCache.getImageDescriptor(getImageName()), 0);
+ protected boolean getData(ILabelUpdate result, Runnable done) {
+ TCFDataCache<?> pending = null;
+ if (!context.validate()) pending = context;
+ if (!value.validate()) pending = value;
+ if (pending != null) {
+ pending.wait(done);
+ return false;
+ }
IRegisters.RegistersContext ctx = context.getData();
Throwable error = context.getError();
if (error != null) {
@@ -140,6 +143,8 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
else {
result.setLabel(id, 0);
}
+ result.setImageDescriptor(ImageCache.getImageDescriptor(ImageCache.IMG_REGISTER), 0);
+ return true;
}
private void setLabel(ILabelUpdate result, int col, int radix) {
@@ -234,23 +239,6 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
}
- @Override
- public boolean validateNode(Runnable done) {
- TCFDataCache<?> pending = null;
- if (!context.validate()) pending = context;
- if (!value.validate()) pending = value;
- if (pending != null) {
- pending.wait(done);
- return false;
- }
- return true;
- }
-
- @Override
- protected String getImageName() {
- return ImageCache.IMG_REGISTER;
- }
-
public CellEditor getCellEditor(IPresentationContext context, String column_id, Object element, Composite parent) {
assert element == this;
if (TCFColumnPresentationRegister.COL_HEX_VALUE.equals(column_id)) {
@@ -268,7 +256,7 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
final TCFNodeRegister node = (TCFNodeRegister)element;
return new TCFTask<Boolean>() {
public void run() {
- if (!node.validateNode(this)) return;
+ if (!node.context.validate(this)) return;
if (node.context.getData() != null && node.context.getData().isWriteable()) {
if (TCFColumnPresentationRegister.COL_HEX_VALUE.equals(property)) {
done(TCFNumberFormat.isValidHexNumber(node.toNumberString(16)) == null);
@@ -288,7 +276,7 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
final TCFNodeRegister node = (TCFNodeRegister)element;
return new TCFTask<String>() {
public void run() {
- if (!node.validateNode(this)) return;
+ if (!node.value.validate(this)) return;
if (node.value.getData() != null) {
if (TCFColumnPresentationRegister.COL_HEX_VALUE.equals(property)) {
done(node.toNumberString(16));
@@ -310,7 +298,7 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
new TCFTask<Boolean>() {
public void run() {
try {
- if (!node.validateNode(this)) return;
+ if (!node.context.validate(this)) return;
IRegisters.RegistersContext ctx = node.context.getData();
if (ctx != null && ctx.isWriteable()) {
byte[] bf = null;
@@ -338,7 +326,6 @@ public class TCFNodeRegister extends TCFNode implements IElementEditor {
else {
node.value.reset();
node.addModelDelta(IModelDelta.STATE | IModelDelta.CONTENT);
- node.model.fireModelChanged();
done(Boolean.TRUE);
}
}
diff --git a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
index 85f273bb8..f5a67c76b 100644
--- a/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
+++ b/plugins/org.eclipse.tm.tcf.debug.ui/src/org/eclipse/tm/internal/tcf/debug/ui/model/TCFNodeStackFrame.java
@@ -18,9 +18,9 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
-import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.swt.graphics.RGB;
+import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
import org.eclipse.tm.internal.tcf.debug.model.TCFSourceRef;
import org.eclipse.tm.internal.tcf.debug.ui.ImageCache;
import org.eclipse.tm.tcf.protocol.IChannel;
@@ -40,6 +40,7 @@ public class TCFNodeStackFrame extends TCFNode {
private final TCFChildrenExpressions children_exps;
private final TCFDataCache<IStackTrace.StackTraceContext> stack_trace_context;
private final TCFDataCache<TCFSourceRef> line_info;
+ private final TCFDataCache<BigInteger> address;
TCFNodeStackFrame(final TCFNodeExecContext parent, final String id) {
super(parent, id);
@@ -51,7 +52,10 @@ public class TCFNodeStackFrame extends TCFNode {
@Override
protected boolean startDataRetrieval() {
assert command == null;
- if (!parent.isSuspended()) {
+ TCFDataCache<TCFContextState> parent_state_cache = parent.getState();
+ if (!parent_state_cache.validate(this)) return false;
+ TCFContextState parent_state_data = parent_state_cache.getData();
+ if (parent_state_data == null || !parent_state_data.is_suspended) {
set(null, null, null);
return true;
}
@@ -73,13 +77,11 @@ public class TCFNodeStackFrame extends TCFNode {
line_info = new TCFDataCache<TCFSourceRef>(channel) {
@Override
protected boolean startDataRetrieval() {
- if (!stack_trace_context.validate()) {
- stack_trace_context.wait(this);
- return false;
- }
- BigInteger n = getAddress();
+ if (!stack_trace_context.validate(this)) return false;
+ if (!address.validate(this)) return false;
+ BigInteger n = address.getData();
if (n == null) {
- set(null, null, null);
+ set(null, address.getError(), null);
return true;
}
IMemory.MemoryContext mem_ctx = null;
@@ -87,10 +89,7 @@ public class TCFNodeStackFrame extends TCFNode {
while (p != null) {
if (p instanceof TCFNodeExecContext) {
TCFDataCache<IMemory.MemoryContext> cache = ((TCFNodeExecContext)p).getMemoryContext();
- if (!cache.validate()) {
- cache.wait(this);
- return false;
- }
+ if (!cache.validate(this)) return false;
mem_ctx = cache.getData();
if (mem_ctx != null) break;
}
@@ -133,6 +132,32 @@ public class TCFNodeStackFrame extends TCFNode {
return false;
}
};
+ address = new TCFDataCache<BigInteger>(channel) {
+ @Override
+ protected boolean startDataRetrieval() {
+ if (!stack_trace_context.validate(this)) return false;
+ IStackTrace.StackTraceContext ctx = stack_trace_context.getData();
+ if (ctx != null) {
+ Number n = ctx.getInstructionAddress();
+ if (n instanceof BigInteger) {
+ set(null, null, (BigInteger)n);
+ return true;
+ }
+ if (n != null) {
+ set(null, null, new BigInteger(n.toString()));
+ return true;
+ }
+ }
+ if (frame_no == 0) {
+ TCFDataCache<BigInteger> addr_cache = parent.getAddress();
+ if (!addr_cache.validate(this)) return false;
+ set(null, addr_cache.getError(), addr_cache.getData());
+ return true;
+ }
+ set(null, stack_trace_context.getError(), null);
+ return true;
+ }
+ };
}
public int getFrameNo() {
@@ -152,6 +177,7 @@ public class TCFNodeStackFrame extends TCFNode {
void dispose() {
stack_trace_context.reset(null);
line_info.reset(null);
+ address.reset(null);
children_regs.dispose();
children_vars.dispose();
children_exps.dispose();
@@ -169,18 +195,8 @@ public class TCFNodeStackFrame extends TCFNode {
return stack_trace_context;
}
- @Override
- public BigInteger getAddress() {
- assert Protocol.isDispatchThread();
- if (!stack_trace_context.isValid()) return null;
- IStackTrace.StackTraceContext ctx = stack_trace_context.getData();
- if (ctx != null) {
- Number n = ctx.getInstructionAddress();
- if (n instanceof BigInteger) return (BigInteger)n;
- if (n != null) return new BigInteger(n.toString());
- }
- if (frame_no == 0) return parent.getAddress();
- return null;
+ public TCFDataCache<BigInteger> getAddress() {
+ return address;
}
public BigInteger getReturnAddress() {
@@ -196,65 +212,38 @@ public class TCFNodeStackFrame extends TCFNode {
}
@Override
- public int getNodeIndex(IPresentationContext p, TCFNode n) {
- if (IDebugUIConstants.ID_REGISTER_VIEW.equals(p.getId())) {
- if (!children_regs.isValid()) return -1;
- return children_regs.getIndexOf(n);
- }
- if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(p.getId())) {
- if (!children_vars.isValid()) return -1;
- return children_vars.getIndexOf(n);
- }
- if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(p.getId())) {
- if (!children_exps.isValid()) return -1;
- return children_exps.getIndexOf(n);
- }
- return 0;
- }
-
- @Override
- public int getChildrenCount(IPresentationContext p) {
- if (IDebugUIConstants.ID_REGISTER_VIEW.equals(p.getId())) {
- if (!children_regs.isValid()) return -1;
- return children_regs.size();
- }
- if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(p.getId())) {
- if (!children_vars.isValid()) return -1;
- return children_vars.size();
- }
- if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(p.getId())) {
- if (!children_exps.isValid()) return -1;
- return children_exps.size();
- }
- return 0;
- }
-
- @Override
- protected void getData(IChildrenCountUpdate result) {
+ protected boolean getData(IChildrenCountUpdate result, Runnable done) {
if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_regs.validate(done)) return false;
result.setChildCount(children_regs.size());
}
else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_vars.validate(done)) return false;
result.setChildCount(children_vars.size());
}
else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_exps.validate(done)) return false;
result.setChildCount(children_exps.size());
}
else {
result.setChildCount(0);
}
+ return true;
}
@Override
- protected void getData(IChildrenUpdate result) {
+ protected boolean getData(IChildrenUpdate result, Runnable done) {
TCFNode[] arr = null;
if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_regs.validate(done)) return false;
arr = children_regs.toArray();
}
else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_vars.validate(done)) return false;
arr = children_vars.toArray();
}
else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_exps.validate(done)) return false;
arr = children_exps.toArray();
}
else {
@@ -269,35 +258,48 @@ public class TCFNodeStackFrame extends TCFNode {
}
offset++;
}
+ return true;
}
@Override
- protected void getData(IHasChildrenUpdate result) {
+ protected boolean getData(IHasChildrenUpdate result, Runnable done) {
if (IDebugUIConstants.ID_REGISTER_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_regs.validate(done)) return false;
result.setHasChilren(children_regs.size() > 0);
}
else if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_vars.validate(done)) return false;
result.setHasChilren(children_vars.size() > 0);
}
else if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(result.getPresentationContext().getId())) {
+ if (!children_exps.validate(done)) return false;
result.setHasChilren(children_exps.size() > 0);
}
else {
result.setHasChilren(false);
}
+ return true;
}
@Override
- protected void getData(ILabelUpdate result) {
- result.setImageDescriptor(ImageCache.getImageDescriptor(getImageName()), 0);
- TCFChildrenStackTrace st = ((TCFNodeExecContext)parent).getStackTrace();
- if (st.getData().get(id) == null) {
+ protected boolean getData(ILabelUpdate result, Runnable done) {
+ String image_name = null;
+ TCFChildrenStackTrace stack_trace_cache = ((TCFNodeExecContext)parent).getStackTrace();
+ if (!stack_trace_cache.validate(done)) return false;
+ if (stack_trace_cache.getData().get(id) == null) {
result.setLabel("", 0);
}
else {
+ TCFDataCache<TCFContextState> state_cache = ((TCFNodeExecContext)parent).getState();
+ if (!state_cache.validate(done)) return false;
+ TCFContextState state_data = state_cache.getData();
+ if (state_data != null && state_data.is_suspended) image_name = ImageCache.IMG_STACK_FRAME_SUSPENDED;
+ else image_name = ImageCache.IMG_STACK_FRAME_RUNNING;
+ if (!stack_trace_context.validate(done)) return false;
+ if (!line_info.validate(done)) return false;
Throwable error = stack_trace_context.getError();
if (error == null) error = line_info.getError();
- if (error != null && ((TCFNodeExecContext)parent).isSuspended()) {
+ if (error != null && state_data != null && state_data.is_suspended) {
result.setForeground(new RGB(255, 0, 0), 0);
result.setLabel(error.getClass().getName() + ": " + error.getMessage(), 0);
}
@@ -315,6 +317,8 @@ public class TCFNodeStackFrame extends TCFNode {
}
}
}
+ result.setImageDescriptor(ImageCache.getImageDescriptor(image_name), 0);
+ return true;
}
private String makeHexAddrString(IMemory.MemoryContext m, Number n) {
@@ -337,6 +341,7 @@ public class TCFNodeStackFrame extends TCFNode {
void onSuspended() {
stack_trace_context.reset();
line_info.reset();
+ address.reset();
children_regs.onSuspended();
children_vars.onSuspended();
children_exps.onSuspended();
@@ -349,27 +354,6 @@ public class TCFNodeStackFrame extends TCFNode {
}
@Override
- public boolean validateNode(Runnable done) {
- TCFDataCache<?> pending = null;
- TCFChildrenStackTrace stack_trace = ((TCFNodeExecContext)parent).getStackTrace();
- if (!stack_trace.validate()) pending = stack_trace;
- if (!stack_trace_context.validate()) pending = stack_trace_context;
- if (!children_regs.validate()) pending = children_regs;
- if (!children_vars.validate()) pending = children_vars;
- if (!children_exps.validate()) pending = children_exps;
- if (!line_info.validate()) pending = line_info;
- if (pending == null) return true;
- pending.wait(done);
- return false;
- }
-
- @Override
- protected String getImageName() {
- if (((TCFNodeExecContext)parent).isRunning()) return ImageCache.IMG_STACK_FRAME_RUNNING;
- return ImageCache.IMG_STACK_FRAME_SUSPENDED;
- }
-
- @Override
public int compareTo(TCFNode n) {
if (n instanceof TCFNodeStackFrame) {
TCFNodeStackFrame f = (TCFNodeStackFrame)n;
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java
index 40735ad34..26e48c26d 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepInto.java
@@ -16,8 +16,6 @@ import org.eclipse.tm.tcf.util.TCFDataCache;
public abstract class TCFActionStepInto extends TCFAction implements IRunControl.RunControlListener {
- private static final long TIMEOUT = 10000;
-
private final boolean src_step;
private final IRunControl rc = launch.getService(IRunControl.class);
@@ -52,18 +50,8 @@ public abstract class TCFActionStepInto extends TCFAction implements IRunControl
exit(new Exception("Invalid context ID"));
return;
}
- if (!ctx.canResume(src_step ? IRunControl.RM_STEP_INTO_LINE : IRunControl.RM_STEP_INTO)) {
- Protocol.invokeLater(TIMEOUT, new Runnable() {
- public void run() {
- exit(new Exception("Time out"));
- }
- });
- }
- }
- if (!state.validate()) {
- state.wait(this);
- return;
}
+ if (!state.validate(this)) return;
if (!state.getData().is_suspended) {
exit(new Exception("Context is not suspended"));
return;
@@ -83,16 +71,14 @@ public abstract class TCFActionStepInto extends TCFAction implements IRunControl
return;
}
TCFDataCache<?> stack_trace = getStackTrace();
- if (!stack_trace.validate()) {
- stack_trace.wait(this);
+ if (!stack_trace.validate(this)) return;
+ if (stack_trace.getData() == null) {
+ exit(stack_trace.getError());
return;
}
if (source_ref == null) {
line_info = getLineInfo();
- if (!line_info.validate()) {
- line_info.wait(this);
- return;
- }
+ if (!line_info.validate(this)) return;
source_ref = line_info.getData();
if (source_ref == null) {
exit(new Exception("Line info not available"));
@@ -117,10 +103,7 @@ public abstract class TCFActionStepInto extends TCFAction implements IRunControl
}
if (step_cnt > 0) {
TCFDataCache<IStackTrace.StackTraceContext> frame = getStackFrame();
- if (!frame.validate()) {
- frame.wait(this);
- return;
- }
+ if (!frame.validate(this)) return;
Number addr = frame.getData().getInstructionAddress();
BigInteger pc = addr instanceof BigInteger ? (BigInteger)addr : new BigInteger(addr.toString());
if (pc == null || pc0 == null || pc1 == null) {
@@ -128,10 +111,7 @@ public abstract class TCFActionStepInto extends TCFAction implements IRunControl
return;
}
if (pc.compareTo(pc0) < 0 || pc.compareTo(pc1) >= 0) {
- if (!line_info.validate()) {
- line_info.wait(this);
- return;
- }
+ if (!line_info.validate(this)) return;
TCFSourceRef ref = line_info.getData();
if (ref != null && ref.area != null) {
if (isSameLine(source_ref.area, ref.area)) {
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOut.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOut.java
index d4c598c7f..962d913ea 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOut.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOut.java
@@ -6,7 +6,6 @@ import java.util.Map;
import org.eclipse.tm.internal.tcf.debug.model.TCFContextState;
import org.eclipse.tm.internal.tcf.debug.model.TCFLaunch;
import org.eclipse.tm.tcf.protocol.IToken;
-import org.eclipse.tm.tcf.protocol.Protocol;
import org.eclipse.tm.tcf.services.IBreakpoints;
import org.eclipse.tm.tcf.services.IRunControl;
import org.eclipse.tm.tcf.services.IStackTrace;
@@ -15,8 +14,6 @@ import org.eclipse.tm.tcf.util.TCFDataCache;
public abstract class TCFActionStepOut extends TCFAction implements IRunControl.RunControlListener {
- private static final long TIMEOUT = 10000;
-
private final IRunControl rc = launch.getService(IRunControl.class);
private final IBreakpoints bps = launch.getService(IBreakpoints.class);
@@ -46,18 +43,8 @@ public abstract class TCFActionStepOut extends TCFAction implements IRunControl.
exit(new Exception("Invalid context ID"));
return;
}
- if (!ctx.canResume(IRunControl.RM_STEP_OUT)) {
- Protocol.invokeLater(TIMEOUT, new Runnable() {
- public void run() {
- exit(new Exception("Time out"));
- }
- });
- }
- }
- if (!state.validate()) {
- state.wait(this);
- return;
}
+ if (!state.validate(this)) return;
if (!state.getData().is_suspended) {
exit(new Exception("Context is not suspended"));
return;
@@ -73,10 +60,7 @@ public abstract class TCFActionStepOut extends TCFAction implements IRunControl.
return;
}
TCFDataCache<?> stack_trace = getStackTrace();
- if (!stack_trace.validate()) {
- stack_trace.wait(this);
- return;
- }
+ if (!stack_trace.validate(this)) return;
if (getStackFrameIndex() < 0) {
// Stepped out of selected function
exit(null);
@@ -84,17 +68,16 @@ public abstract class TCFActionStepOut extends TCFAction implements IRunControl.
else if (bps != null && ctx.canResume(IRunControl.RM_RESUME)) {
if (bp == null) {
TCFDataCache<IStackTrace.StackTraceContext> frame = getStackFrame();
- if (!frame.validate()) {
- frame.wait(this);
- return;
- }
+ if (!frame.validate(this)) return;
Number addr = frame.getData().getReturnAddress();
if (addr == null) {
exit(new Exception("Unknown stack frame return address"));
return;
}
+ String id = "Step." + ctx.getID();
+ launch.addContextActionBreakpoint(id, "Step");
bp = new HashMap<String,Object>();
- bp.put(IBreakpoints.PROP_ID, "Step" + System.currentTimeMillis());
+ bp.put(IBreakpoints.PROP_ID, id);
bp.put(IBreakpoints.PROP_LOCATION, addr.toString());
bp.put(IBreakpoints.PROP_CONDITION, "$thread==\"" + ctx.getID() + "\"");
bp.put(IBreakpoints.PROP_ENABLED, Boolean.TRUE);
@@ -162,8 +145,7 @@ public abstract class TCFActionStepOut extends TCFAction implements IRunControl.
public void contextResumed(String context) {
}
- public void contextSuspended(String context, String pc, String reason,
- Map<String, Object> params) {
+ public void contextSuspended(String context, String pc, String reason, Map<String,Object> params) {
if (!context.equals(ctx.getID())) return;
exit(null);
}
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java
index 0d4a28ff0..d66383cd1 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/actions/TCFActionStepOver.java
@@ -18,8 +18,6 @@ import org.eclipse.tm.tcf.util.TCFDataCache;
public abstract class TCFActionStepOver extends TCFAction implements IRunControl.RunControlListener {
- private static final long TIMEOUT = 10000;
-
private final boolean src_step;
private final IRunControl rc = launch.getService(IRunControl.class);
private final IBreakpoints bps = launch.getService(IBreakpoints.class);
@@ -56,18 +54,8 @@ public abstract class TCFActionStepOver extends TCFAction implements IRunControl
exit(new Exception("Invalid context ID"));
return;
}
- if (!ctx.canResume(src_step ? IRunControl.RM_STEP_OVER_LINE : IRunControl.RM_STEP_OVER)) {
- Protocol.invokeLater(TIMEOUT, new Runnable() {
- public void run() {
- exit(new Exception("Time out"));
- }
- });
- }
- }
- if (!state.validate()) {
- state.wait(this);
- return;
}
+ if (!state.validate(this)) return;
if (!state.getData().is_suspended) {
exit(new Exception("Context is not suspended"));
return;
@@ -83,16 +71,10 @@ public abstract class TCFActionStepOver extends TCFAction implements IRunControl
return;
}
TCFDataCache<?> stack_trace = getStackTrace();
- if (!stack_trace.validate()) {
- stack_trace.wait(this);
- return;
- }
+ if (!stack_trace.validate(this)) return;
if (src_step && source_ref == null) {
line_info = getLineInfo();
- if (!line_info.validate()) {
- line_info.wait(this);
- return;
- }
+ if (!line_info.validate(this)) return;
source_ref = line_info.getData();
if (source_ref == null) {
exit(new Exception("Line info not available"));
@@ -125,17 +107,16 @@ public abstract class TCFActionStepOver extends TCFAction implements IRunControl
else if (bps != null && ctx.canResume(IRunControl.RM_RESUME)) {
if (bp == null) {
TCFDataCache<IStackTrace.StackTraceContext> frame = getStackFrame();
- if (!frame.validate()) {
- frame.wait(this);
- return;
- }
+ if (!frame.validate(this)) return;
Number addr = frame.getData().getInstructionAddress();
if (addr == null) {
exit(new Exception("Unknown PC address"));
return;
}
+ String id = "Step." + ctx.getID();
+ launch.addContextActionBreakpoint(id, "Step");
bp = new HashMap<String,Object>();
- bp.put(IBreakpoints.PROP_ID, "Step" + System.currentTimeMillis());
+ bp.put(IBreakpoints.PROP_ID, id);
bp.put(IBreakpoints.PROP_LOCATION, addr.toString());
bp.put(IBreakpoints.PROP_CONDITION, "$thread==\"" + ctx.getID() + "\"");
bp.put(IBreakpoints.PROP_ENABLED, Boolean.TRUE);
@@ -172,10 +153,7 @@ public abstract class TCFActionStepOver extends TCFAction implements IRunControl
assert src_step;
BigInteger pc = new BigInteger(state.getData().suspend_pc);
if (pc.compareTo(pc0) < 0 || pc.compareTo(pc1) >= 0) {
- if (!line_info.validate()) {
- line_info.wait(this);
- return;
- }
+ if (!line_info.validate(this)) return;
TCFSourceRef ref = line_info.getData();
if (ref != null && ref.area != null) {
if (isSameLine(source_ref.area, ref.area)) {
diff --git a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
index 4ee4715dc..113354bea 100644
--- a/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
+++ b/plugins/org.eclipse.tm.tcf.debug/src/org/eclipse/tm/internal/tcf/debug/model/TCFLaunch.java
@@ -82,8 +82,8 @@ public class TCFLaunch extends Launch {
private int process_exit_code;
private int context_action_cnt;
- private final HashMap<String,LinkedList<Runnable>> context_action_queue =
- new HashMap<String,LinkedList<Runnable>>();
+ private final HashMap<String,LinkedList<Runnable>> context_action_queue = new HashMap<String,LinkedList<Runnable>>();
+ private final HashMap<String,String> context_action_bps = new HashMap<String,String>();
private HashMap<String,String> stream_ids = new HashMap<String,String>();
@@ -678,7 +678,11 @@ public class TCFLaunch extends Launch {
}
}
- public boolean hasPendingContextActions() {
- return context_action_cnt > 0;
+ public void addContextActionBreakpoint(String id, String type) {
+ context_action_bps.put(id, type);
+ }
+
+ public String getContextActionBreakpoint(String id) {
+ return context_action_bps.get(id);
}
}
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFSourceLookupParticipant.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFSourceLookupParticipant.java
index 136a95efc..f3ff43613 100644
--- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFSourceLookupParticipant.java
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/launch/TCFDSFSourceLookupParticipant.java
@@ -30,14 +30,8 @@ public class TCFDSFSourceLookupParticipant extends TCFSourceLookupParticipant {
Protocol.invokeLater(new Runnable() {
public void run() {
TCFFrameDMC dmc = (TCFFrameDMC)object;
- if (!dmc.context_cache.validate()) {
- dmc.context_cache.wait(this);
- return;
- }
- if (!dmc.source_cache.validate()) {
- dmc.source_cache.wait(this);
- return;
- }
+ if (!dmc.context_cache.validate(this)) return;
+ if (!dmc.source_cache.validate(this)) return;
synchronized (res) {
TCFSourceRef ref = dmc.source_cache.getData();
if (ref != null) res[0] = ref.area;
diff --git a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java
index 7cf0d0731..fd3b85310 100644
--- a/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java
+++ b/plugins/org.eclipse.tm.tcf.dsf/src/org/eclipse/tm/internal/tcf/dsf/services/TCFDSFExecutionDMC.java
@@ -109,10 +109,7 @@ public abstract class TCFDSFExecutionDMC extends AbstractDMContext
@Override
public boolean startDataRetrieval() {
assert command == null;
- if (!run_control_context_cache.validate()) {
- run_control_state_cache.wait(this);
- return false;
- }
+ if (!run_control_context_cache.validate(this)) return false;
RunControlContext c = run_control_context_cache.getData();
if (c == null || !c.hasState()) {
reset(null);
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 f281fdb18..c7e10f766 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
@@ -81,10 +81,7 @@ public class TCFDSFStack extends AbstractDsfService implements IStack {
@Override
protected boolean startDataRetrieval() {
- if (!context_cache.validate()) {
- context_cache.wait(this);
- return false;
- }
+ if (!context_cache.validate(this)) return false;
IStackTrace.StackTraceContext ctx = context_cache.getData();
Number n = ctx.getInstructionAddress();
BigInteger a = null;

Back to the top