IDEA-163730 Incorrect value of logic operation stringVar == "value" - cache string literal references on our side

This commit is contained in:
Egor.Ushakov
2016-11-11 13:30:40 +03:00
parent ec55819285
commit de4ecc0117
2 changed files with 24 additions and 8 deletions
@@ -62,15 +62,17 @@ class LiteralEvaluator implements Evaluator {
return DebuggerUtilsEx.createValue(vm, myExpectedType, ((Number)myValue).longValue());
}
if (myValue instanceof String) {
StringReference str = vm.mirrorOf((String)myValue);
// intern starting from jdk 7
if (vm.versionHigher("1.7")) {
Method internMethod = ((ClassType)str.referenceType()).concreteMethodByName("intern", "()Ljava/lang/String;");
if (internMethod != null) {
return context.getDebugProcess().invokeMethod(context, str, internMethod, Collections.emptyList());
return vm.mirrorOfStringLiteral(((String)myValue), () -> {
StringReference str = vm.mirrorOf((String)myValue);
// intern starting from jdk 7
if (vm.versionHigher("1.7")) {
Method internMethod = ((ClassType)str.referenceType()).concreteMethodByName("intern", "()Ljava/lang/String;");
if (internMethod != null) {
return (StringReference)context.getDebugProcess().invokeMethod(context, str, internMethod, Collections.emptyList());
}
}
}
return str;
return str;
});
}
throw EvaluateExceptionUtil
.createEvaluateException(DebuggerBundle.message("evaluation.error.unknown.expression.type", myExpectedType));
@@ -25,6 +25,7 @@ import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.jdi.VirtualMachineProxy;
import com.intellij.debugger.impl.DebuggerUtilsImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ReflectionUtil;
@@ -52,6 +53,8 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy {
// cached data
private final Map<ObjectReference, ObjectReferenceProxyImpl> myObjectReferenceProxies = new HashMap<>();
private final Map<String, StringReference> myStringLiteralCache = new HashMap<>();
@NotNull
private Map<ThreadReference, ThreadReferenceProxyImpl> myAllThreads = new HashMap<>();
private final Map<ThreadGroupReference, ThreadGroupReferenceProxyImpl> myThreadGroups = new HashMap<>();
@@ -328,6 +331,17 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy {
return myVirtualMachine.mirrorOf(s);
}
public StringReference mirrorOfStringLiteral(String s, DebuggerUtilsImpl.SupplierThrowing<StringReference, EvaluateException> generator)
throws EvaluateException {
StringReference reference = myStringLiteralCache.get(s);
if (reference != null && !reference.isCollected()) {
return reference;
}
reference = generator.get();
myStringLiteralCache.put(s, reference);
return reference;
}
public Process process() {
return myVirtualMachine.process();
}