From 7af95c47ff86ce2194cf2a4b4dda449646a69420 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 8 Nov 2016 17:56:06 +0300 Subject: [PATCH] speedup method bpts calculation - cache classesByName --- .../intellij/debugger/actions/JumpToObjectAction.java | 2 +- .../com/intellij/debugger/jdi/MethodBytecodeUtil.java | 9 +++++---- .../intellij/debugger/jdi/VirtualMachineProxyImpl.java | 10 +++++++++- .../debugger/ui/breakpoints/MethodBreakpoint.java | 4 ++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java index cac1fd7a0add..85f164ec4e0e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java @@ -99,7 +99,7 @@ public class JumpToObjectAction extends DebuggerAction{ if (type instanceof ClassType) { ClassType clsType = (ClassType)type; - Method lambdaMethod = MethodBytecodeUtil.getLambdaMethod(clsType); + Method lambdaMethod = MethodBytecodeUtil.getLambdaMethod(clsType, debugProcess.getVirtualMachineProxy()); Location location = lambdaMethod != null ? ContainerUtil.getFirstItem(DebuggerUtilsEx.allLineLocations(lambdaMethod)) : null; if (location == null) { diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java b/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java index 965695595e81..669bfe956786 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/MethodBytecodeUtil.java @@ -16,6 +16,7 @@ package com.intellij.debugger.jdi; import com.intellij.Patches; +import com.intellij.debugger.engine.jdi.VirtualMachineProxy; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.openapi.util.Ref; import com.intellij.util.ReflectionUtil; @@ -232,7 +233,7 @@ public class MethodBytecodeUtil { } @Nullable - public static Method getLambdaMethod(ReferenceType clsType) { + public static Method getLambdaMethod(ReferenceType clsType, VirtualMachineProxy vm) { Ref methodRef = Ref.create(); if (DebuggerUtilsEx.isLambdaClassName(clsType.name())) { List applicableMethods = ContainerUtil.filter(clsType.methods(), m -> m.isPublic() && !m.isBridge()); @@ -240,7 +241,7 @@ public class MethodBytecodeUtil { visit(applicableMethods.get(0), new MethodVisitor(Opcodes.API_VERSION) { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - ReferenceType cls = ContainerUtil.getFirstItem(clsType.virtualMachine().classesByName(owner)); + ReferenceType cls = ContainerUtil.getFirstItem(vm.classesByName(owner)); if (cls != null) { cls.methodsByName(name, desc).stream().findFirst().ifPresent(methodRef::set); } @@ -252,7 +253,7 @@ public class MethodBytecodeUtil { } @Nullable - public static Method getBridgeTargetMethod(Method method) { + public static Method getBridgeTargetMethod(Method method, VirtualMachineProxy vm) { Ref methodRef = Ref.create(); if (method.isBridge()) { visit(method, new MethodVisitor(Opcodes.API_VERSION) { @@ -264,7 +265,7 @@ public class MethodBytecodeUtil { cls = declaringType; } else if (!"java/lang/AbstractMethodError".equals(owner)) { - cls = ContainerUtil.getFirstItem(method.virtualMachine().classesByName(owner)); + cls = ContainerUtil.getFirstItem(vm.classesByName(owner)); } if (cls != null) { StreamEx.of(cls.methodsByName(name, desc)).findFirst().ifPresent(methodRef::set); diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java index 5b80d5514371..ec48c6c5b860 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java @@ -30,6 +30,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ReflectionUtil; import com.intellij.util.ThreeState; import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.MultiMap; import com.sun.jdi.*; import com.sun.jdi.event.EventQueue; import com.sun.jdi.request.EventRequestManager; @@ -56,6 +57,7 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { private final Map myThreadGroups = new HashMap<>(); private boolean myAllThreadsDirty = true; private List myAllClasses; + private MultiMap myAllClassesByName; private Map> myNestedClassesCache = new HashMap<>(); public final Throwable mySuspendLogger = new Throwable(); @@ -96,7 +98,11 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { } public List classesByName(String s) { - return myVirtualMachine.classesByName(s); + if (myAllClassesByName == null) { + myAllClassesByName = new MultiMap<>(); + allClasses().forEach(t -> myAllClassesByName.putValue(t.name(), t)); + } + return (List)myAllClassesByName.get(s); } public List nestedTypes(ReferenceType refType) { @@ -641,6 +647,8 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { LOG.debug("VM cleared"); myAllClasses = null; + myAllClassesByName = null; + if (!myNestedClassesCache.isEmpty()) { myNestedClassesCache = new HashMap<>(myNestedClassesCache.size()); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java index c5a8f4954808..79191146c9f5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java @@ -166,7 +166,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter