From f108afebe19fd6628883a21055dd650cd6c1d4ac Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 1 Mar 2017 19:58:27 +0300 Subject: [PATCH] capture speedup - cache evaluators --- .../debugger/engine/DebugProcessImpl.java | 6 +++ .../debugger/impl/ReloadClassesWorker.java | 9 ++-- .../StackCapturingLineBreakpoint.java | 43 ++++++++++++++----- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index 9fd65116ed31..da9e2e9781fc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -34,6 +34,7 @@ import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.debugger.ui.breakpoints.RunToCursorBreakpoint; +import com.intellij.debugger.ui.breakpoints.StackCapturingLineBreakpoint; import com.intellij.debugger.ui.breakpoints.StepIntoBreakpoint; import com.intellij.debugger.ui.tree.ValueDescriptor; import com.intellij.debugger.ui.tree.render.ArrayRenderer; @@ -1400,6 +1401,11 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb } } + public void onHotSwapFinished() { + getPositionManager().clearCache(); + StackCapturingLineBreakpoint.clearCaches(this); + } + @NotNull public SuspendManager getSuspendManager() { return mySuspendManager; diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java b/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java index a8b378254760..30c36592d990 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/ReloadClassesWorker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,10 @@ package com.intellij.debugger.impl; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.DebuggerManagerEx; -import com.intellij.debugger.engine.*; +import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebuggerManagerThreadImpl; +import com.intellij.debugger.engine.JavaExecutionStack; +import com.intellij.debugger.engine.SuspendContextImpl; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.openapi.diagnostic.Logger; @@ -165,7 +168,7 @@ class ReloadClassesWorker { processException(e); } - debugProcess.getPositionManager().clearCache(); + debugProcess.onHotSwapFinished(); DebuggerContextImpl context = myDebuggerSession.getContextManager().getContext(); SuspendContextImpl suspendContext = context.getSuspendContext(); 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 ea58e14e33ca..43585d6bfa77 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 @@ -43,6 +43,7 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.WeakHashMap; import com.sun.jdi.*; import com.sun.jdi.event.LocatableEvent; import one.util.streamex.StreamEx; @@ -84,8 +85,8 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint { myProperties.myClassPattern = myCapturePoint.myClassName; myProperties.myMethodName = myCapturePoint.myMethodName; - myCaptureEvaluator = new MyEvaluator(myCapturePoint.myCaptureKeyExpression, false); - myInsertEvaluator = new MyEvaluator(myCapturePoint.myInsertKeyExpression, false); + myCaptureEvaluator = new MyEvaluator(myCapturePoint.myCaptureKeyExpression); + myInsertEvaluator = new MyEvaluator(myCapturePoint.myInsertKeyExpression); } @NotNull @@ -162,6 +163,17 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint { } } + public static void clearCaches(DebugProcessImpl debugProcess) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + List bpts = debugProcess.getUserData(CAPTURE_BREAKPOINTS); + if (!ContainerUtil.isEmpty(bpts)) { + bpts.forEach(b -> { + b.myCaptureEvaluator.clearCache(); + b.myInsertEvaluator.clearCache(); + }); + } + } + @Override public void createRequest(DebugProcessImpl debugProcess) { if (!StringUtil.isEmpty(getClassName())) { @@ -238,11 +250,11 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint { private static class MyEvaluator { private final String myExpression; - private final boolean myCached; private ExpressionEvaluator myEvaluator; private final boolean myNeedKeepValue; + private final WeakHashMap myEvaluatorCache = new WeakHashMap<>(); - public MyEvaluator(String expression, boolean cached) { + public MyEvaluator(String expression) { myExpression = expression; int paramId = DecompiledLocalVariable.getParamId(myExpression); boolean paramEvaluator = paramId > -1; @@ -258,25 +270,29 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint { return argumentValues.get(paramId); } }); - cached = true; } myNeedKeepValue = !paramEvaluator; - myCached = cached; } @Nullable Value evaluate(final EvaluationContext context) throws EvaluateException { - if ((!myCached || myEvaluator == null) && !StringUtil.isEmpty(myExpression)) { - myEvaluator = ApplicationManager.getApplication().runReadAction( - (ThrowableComputable)() -> { + ExpressionEvaluator evaluator = myEvaluator; + if (evaluator == null) { + @SuppressWarnings("ConstantConditions") + Location location = context.getFrameProxy().location(); + evaluator = myEvaluatorCache.get(location); + if (evaluator == null && !StringUtil.isEmpty(myExpression)) { + evaluator = ApplicationManager.getApplication().runReadAction((ThrowableComputable)() -> { SourcePosition sourcePosition = ContextUtil.getSourcePosition(context); PsiElement contextElement = ContextUtil.getContextElement(sourcePosition); return EvaluatorBuilderImpl.build( new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myExpression), contextElement, sourcePosition, context.getProject()); }); + myEvaluatorCache.put(location, evaluator); + } } - if (myEvaluator != null) { - Value value = myEvaluator.evaluate(context); + if (evaluator != null) { + Value value = evaluator.evaluate(context); if (myNeedKeepValue) { DebuggerUtilsEx.keep(value, context); } @@ -284,5 +300,10 @@ public class StackCapturingLineBreakpoint extends WildcardMethodBreakpoint { } return null; } + + void clearCache() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myEvaluatorCache.clear(); + } } }