use slightly faster concreteMethodByName instead of methodsByName where possible

This commit is contained in:
Egor.Ushakov
2016-11-09 20:48:23 +03:00
parent f474714d33
commit c55c68b210
6 changed files with 31 additions and 29 deletions
@@ -24,7 +24,6 @@ import com.intellij.psi.impl.PsiJavaParserFacadeImpl;
import com.sun.jdi.*;
import java.util.Collections;
import java.util.List;
/**
* @author Eugene Zhuravlev
@@ -59,14 +58,14 @@ public class BoxingEvaluator implements Evaluator{
final ClassType wrapperClass = (ClassType)process.findClass(context, wrapperTypeName, null);
final String methodSignature = "(" + JVMNameUtil.getPrimitiveSignature(value.type().name()) + ")L" + wrapperTypeName.replace('.', '/') + ";";
List<Method> methods = wrapperClass.methodsByName("valueOf", methodSignature);
if (methods.size() == 0) { // older JDK version
methods = wrapperClass.methodsByName(JVMNameUtil.CONSTRUCTOR_NAME, methodSignature);
Method method = wrapperClass.concreteMethodByName("valueOf", methodSignature);
if (method == null) { // older JDK version
method = wrapperClass.concreteMethodByName(JVMNameUtil.CONSTRUCTOR_NAME, methodSignature);
}
if (methods.size() == 0) {
if (method == null) {
throw new EvaluateException("Cannot construct wrapper object for value of type " + value.type() + ": Unable to find either valueOf() or constructor method");
}
return process.invokeMethod(context, wrapperClass, methods.get(0), Collections.singletonList(value));
return process.invokeMethod(context, wrapperClass, method, Collections.singletonList(value));
}
}
@@ -26,7 +26,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.util.containers.ContainerUtil;
import com.sun.jdi.ClassType;
import com.sun.jdi.Method;
import com.sun.jdi.StringReference;
@@ -64,7 +64,7 @@ class LiteralEvaluator implements Evaluator {
if (myValue instanceof String) {
StringReference str = vm.mirrorOf((String)myValue);
// intern
Method internMethod = ContainerUtil.getFirstItem(str.referenceType().methodsByName("intern", "()Ljava/lang/String;"));
Method internMethod = ((ClassType)str.referenceType()).concreteMethodByName("intern", "()Ljava/lang/String;");
if (internMethod != null) {
return context.getDebugProcess().invokeMethod(context, str, internMethod, Collections.emptyList());
}
@@ -29,7 +29,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
@@ -80,12 +79,12 @@ public class UnBoxingEvaluator implements Evaluator{
String conversionMethodSignature) throws EvaluateException {
final DebugProcessImpl process = context.getDebugProcess();
final ClassType wrapperClass = (ClassType)value.referenceType();
final List<Method> methods = wrapperClass.methodsByName(conversionMethodName, conversionMethodSignature);
if (methods.size() == 0) {
Method method = wrapperClass.concreteMethodByName(conversionMethodName, conversionMethodSignature);
if (method == null) {
throw new EvaluateException("Cannot convert to primitive value of type " + value.type() + ": Unable to find method " +
conversionMethodName + conversionMethodSignature);
}
return process.invokeMethod(context, value, methods.get(0), Collections.emptyList());
return process.invokeMethod(context, value, method, Collections.emptyList());
}
}
@@ -16,6 +16,7 @@
package com.intellij.debugger.jdi;
import com.intellij.Patches;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.jdi.VirtualMachineProxy;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.openapi.util.Ref;
@@ -23,7 +24,6 @@ import com.intellij.util.ReflectionUtil;
import com.intellij.util.ThrowableConsumer;
import com.intellij.util.containers.ContainerUtil;
import com.sun.jdi.*;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.*;
@@ -242,9 +242,12 @@ 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(vm.classesByName(owner));
ReferenceType cls = ContainerUtil.getFirstItem(vm.classesByName(owner.replace("/", ".")));
if (cls != null) {
cls.methodsByName(name, desc).stream().findFirst().ifPresent(methodRef::set);
Method method = DebuggerUtils.findMethod(cls, name, desc);
if (method != null) {
methodRef.setIfNull(method);
}
}
}
}, false);
@@ -262,14 +265,18 @@ public class MethodBytecodeUtil {
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
ReferenceType declaringType = method.declaringType();
ReferenceType cls = null;
if (declaringType.name().equals(owner.replace("/", "."))) {
owner = owner.replace("/", ".");
if (declaringType.name().equals(owner)) {
cls = declaringType;
}
else if (!"java/lang/AbstractMethodError".equals(owner)) {
else if (!"java.lang.AbstractMethodError".equals(owner)) {
cls = ContainerUtil.getFirstItem(vm.classesByName(owner));
}
if (cls != null) {
StreamEx.of(cls.methodsByName(name, desc)).findFirst().ifPresent(methodRef::set);
Method method = DebuggerUtils.findMethod(cls, name, desc);
if (method != null) {
methodRef.setIfNull(method);
}
}
}
}, false);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 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.
@@ -47,7 +47,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements ValueDescriptor{
@@ -235,11 +234,11 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
final ObjectReference exceptionObj = ex.getExceptionFromTargetVM();
if (exceptionObj != null && evaluationContext != null) {
try {
final ReferenceType refType = exceptionObj.referenceType();
final List<Method> methods = refType.methodsByName("getStackTrace", "()[Ljava/lang/StackTraceElement;");
if (methods.size() > 0) {
ClassType refType = (ClassType)exceptionObj.referenceType();
Method method = refType.concreteMethodByName("getStackTrace", "()[Ljava/lang/StackTraceElement;");
if (method != null) {
final DebugProcessImpl process = evaluationContext.getDebugProcess();
process.invokeMethod(evaluationContext, exceptionObj, methods.get(0), Collections.emptyList());
process.invokeMethod(evaluationContext, exceptionObj, method, Collections.emptyList());
// print to console as well
@@ -260,9 +259,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
}
}
}
catch (EvaluateException ignored) {
}
catch (ClassNotLoadedException ignored) {
catch (EvaluateException | ClassNotLoadedException ignored) {
}
catch (Throwable e) {
LOG.info(e); // catch all exceptions to ensure the method returns gracefully
@@ -133,8 +133,8 @@ public class ToStringRenderer extends NodeRendererImpl {
@SuppressWarnings({"HardCodedStringLiteral"})
private static boolean overridesToString(Type type) {
if (type instanceof ClassType) {
return ((ClassType)type).methodsByName("toString", "()Ljava/lang/String;").stream()
.anyMatch(method -> !CommonClassNames.JAVA_LANG_OBJECT.equals(method.declaringType().name()));
return !CommonClassNames.JAVA_LANG_OBJECT
.equals(((ClassType)type).concreteMethodByName("toString", "()Ljava/lang/String;").declaringType().name());
}
return false;
}