From 810f09603d6ac38282f9a1b3d08e75bc4e3359b8 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 2 Mar 2017 16:28:39 +0300 Subject: [PATCH] capture speedup - request all frames in one request --- .../jdi/ThreadReferenceProxyImpl.java | 38 +++++++++++++++++++ .../debugger/memory/utils/StackFrameItem.java | 2 +- .../StackCapturingLineBreakpoint.java | 30 ++++++++------- 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java index a0731514fbbb..57c48968af84 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java @@ -207,6 +207,44 @@ public final class ThreadReferenceProxyImpl extends ObjectReferenceProxyImpl imp return myFrameCount; } + /** + * Same as frames(), but always force full frames refresh if not cached, + * this is useful when you need all frames but do not plan to invoke anything + * as only one request is sent + */ + @NotNull + public List forceFrames() throws EvaluateException { + DebuggerManagerThreadImpl.assertIsManagerThread(); + final ThreadReference threadRef = getThreadReference(); + try { + //LOG.assertTrue(threadRef.isSuspended()); + checkValid(); + + if (myFrames == null) { + try { + List frames = threadRef.frames(); + myFrameCount = frames.size(); + myFrames = new ArrayList<>(myFrameCount); + myFramesFromBottom.clear(); + int idx = 0; + for (StackFrame frame : frames) { + StackFrameProxyImpl frameProxy = new StackFrameProxyImpl(this, frame, myFrameCount - idx); + myFrames.add(frameProxy); + myFramesFromBottom.addFirst(frameProxy); + idx++; + } + } + catch (IncompatibleThreadStateException | InternalException e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + } + catch (ObjectCollectedException ignored) { + return Collections.emptyList(); + } + return myFrames; + } + @NotNull public List frames() throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); diff --git a/java/debugger/impl/src/com/intellij/debugger/memory/utils/StackFrameItem.java b/java/debugger/impl/src/com/intellij/debugger/memory/utils/StackFrameItem.java index 7fe6f8e9cd43..fb26c204e3b3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/memory/utils/StackFrameItem.java +++ b/java/debugger/impl/src/com/intellij/debugger/memory/utils/StackFrameItem.java @@ -74,7 +74,7 @@ public class StackFrameItem { ThreadReferenceProxyImpl threadReferenceProxy = suspendContext.getThread(); if (threadReferenceProxy != null) { List res = new ArrayList<>(); - for (StackFrameProxyImpl frame : threadReferenceProxy.frames()) { + for (StackFrameProxyImpl frame : threadReferenceProxy.forceFrames()) { try { List vars = null; if (withVars) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java index a0ab800e6985..96ae06329062 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/StackCapturingLineBreakpoint.java @@ -30,6 +30,7 @@ import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.DecompiledLocalVariable; import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.debugger.memory.utils.StackFrameItem; import com.intellij.debugger.settings.CapturePoint; import com.intellij.debugger.settings.DebuggerSettings; @@ -104,22 +105,25 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint { public boolean processLocatableEvent(SuspendContextCommandImpl action, LocatableEvent event) throws EventProcessingException { SuspendContextImpl suspendContext = action.getSuspendContext(); if (suspendContext != null) { - StackFrameProxyImpl frameProxy = suspendContext.getFrameProxy(); - if (frameProxy != null) { + ThreadReferenceProxyImpl thread = suspendContext.getThread(); + if (thread != null) { DebugProcessImpl process = suspendContext.getDebugProcess(); try { - Map> stacks = process.getUserData(CAPTURED_STACKS); - if (stacks == null) { - stacks = new CapturedStacksMap(); - process.putUserData(CAPTURED_STACKS, Collections.synchronizedMap(stacks)); - } - Value key = myCaptureEvaluator.evaluate(new EvaluationContextImpl(suspendContext, frameProxy)); - if (key instanceof ObjectReference) { - List frames = StackFrameItem.createFrames(suspendContext, true); - if (frames.size() > MAX_STACK_LENGTH) { - frames = frames.subList(0, MAX_STACK_LENGTH); + StackFrameProxyImpl frameProxy = ContainerUtil.getFirstItem(thread.forceFrames()); + if (frameProxy != null) { + Map> stacks = process.getUserData(CAPTURED_STACKS); + if (stacks == null) { + stacks = new CapturedStacksMap(); + process.putUserData(CAPTURED_STACKS, Collections.synchronizedMap(stacks)); + } + Value key = myCaptureEvaluator.evaluate(new EvaluationContextImpl(suspendContext, frameProxy)); + if (key instanceof ObjectReference) { + List frames = StackFrameItem.createFrames(suspendContext, true); + if (frames.size() > MAX_STACK_LENGTH) { + frames = frames.subList(0, MAX_STACK_LENGTH); + } + stacks.put(getKey((ObjectReference)key), frames); } - stacks.put(getKey((ObjectReference)key), frames); } } catch (EvaluateException e) {