more robust evaluation: ensure that temp objects are not GC-d during evaluation

This commit is contained in:
Eugene Zhuravlev
2010-09-30 17:37:33 +04:00
parent f88b5db313
commit 138d96650a
13 changed files with 71 additions and 43 deletions

View File

@@ -1062,26 +1062,14 @@ public abstract class DebugProcessImpl implements DebugProcess {
public Value invokeInstanceMethod(final EvaluationContext evaluationContext, final ObjectReference objRef, final Method method,
final List args, final int invocationOptions) throws EvaluateException {
final ThreadReference thread = getEvaluationThread(evaluationContext);
InvokeCommand<Value> invokeCommand = new InvokeCommand<Value>(args) {
return new InvokeCommand<Value>(args) {
protected Value invokeMethod(int invokePolicy, final List args) throws InvocationException, ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException {
if (LOG.isDebugEnabled()) {
LOG.debug("Invoke " + method.name());
}
//try {
// if (!Patches.IBM_JDK_DISABLE_COLLECTION_BUG) {
// // ensure target object wil not be collected
// objRef.disableCollection();
// }
return objRef.invokeMethod(thread, method, args, invokePolicy | invocationOptions);
//}
//finally {
// if (!Patches.IBM_JDK_DISABLE_COLLECTION_BUG) {
// objRef.enableCollection();
// }
//}
return objRef.invokeMethod(thread, method, args, invokePolicy | invocationOptions);
}
};
return invokeCommand.start((EvaluationContextImpl)evaluationContext, method);
}.start((EvaluationContextImpl)evaluationContext, method);
}
private static ThreadReference getEvaluationThread(final EvaluationContext evaluationContext) throws EvaluateException {

View File

@@ -30,7 +30,7 @@ public class AssignmentEvaluator implements Evaluator{
public AssignmentEvaluator(Evaluator leftEvaluator, Evaluator rightEvaluator) {
myLeftEvaluator = leftEvaluator;
myRightEvaluator = rightEvaluator;
myRightEvaluator = new DisableGC(rightEvaluator);
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {

View File

@@ -39,8 +39,8 @@ class BinaryExpressionEvaluator implements Evaluator {
private final String myExpectedType; // a result of PsiType.getCanonicalText()
public BinaryExpressionEvaluator(Evaluator leftOperand, Evaluator rightOperand, IElementType opType, String expectedType) {
myLeftOperand = leftOperand;
myRightOperand = rightOperand;
myLeftOperand = new DisableGC(leftOperand);
myRightOperand = new DisableGC(rightOperand);
myOpType = opType;
myExpectedType = expectedType;
}

View File

@@ -33,7 +33,7 @@ public class BoxingEvaluator implements Evaluator{
private final Evaluator myOperand;
public BoxingEvaluator(Evaluator operand) {
myOperand = operand;
myOperand = new DisableGC(operand);
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2000-2010 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.sun.jdi.ObjectReference;
/**
* @author Eugene Zhuravlev
* Date: 9/30/10
*/
public class DisableGC implements Evaluator{
private final Evaluator myDelegate;
public DisableGC(Evaluator delegate) {
myDelegate = delegate;
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
final Object result = myDelegate.evaluate(context);
if (result instanceof ObjectReference) {
context.getSuspendContext().keep((ObjectReference)result);
}
return result;
}
public Modifier getModifier() {
return myDelegate.getModifier();
}
}

View File

@@ -194,7 +194,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
for (int i = 0; i < statements.length; i++) {
PsiStatement psiStatement = statements[i];
psiStatement.accept(this);
evaluators[i] = myResult;
evaluators[i] = new DisableGC(myResult);
myResult = null;
}
myResult = new BlockStatementEvaluator(evaluators);
@@ -852,7 +852,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
// cannot build evaluator
throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", psiExpression.getText()));
}
argumentEvaluators.add(myResult);
argumentEvaluators.add(new DisableGC(myResult));
}
PsiReferenceExpression methodExpr = expression.getMethodExpression();
@@ -1134,7 +1134,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
PsiExpression argExpression = argExpressions[idx];
argExpression.accept(this);
if (myResult != null) {
argumentEvaluators[idx] = myResult;
argumentEvaluators[idx] = new DisableGC(myResult);
}
else {
throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", argExpression.getText()));
@@ -1158,7 +1158,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
PsiExpression initializer = initializers[idx];
initializer.accept(this);
if (myResult != null) {
evaluators[idx] = handleUnaryNumericPromotion(initializer.getType(), myResult);
evaluators[idx] = new DisableGC(handleUnaryNumericPromotion(initializer.getType(), myResult));
}
else {
throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", initializer.getText()));

View File

@@ -38,10 +38,10 @@ public class ForStatementEvaluator implements Evaluator {
Evaluator updateEvaluator,
Evaluator bodyEvaluator,
String labelName) {
myInitializationEvaluator = initializationEvaluator;
myConditionEvaluator = conditionEvaluator;
myUpdateEvaluator = updateEvaluator;
myBodyEvaluator = bodyEvaluator;
myInitializationEvaluator = new DisableGC(initializationEvaluator);
myConditionEvaluator = new DisableGC(conditionEvaluator);
myUpdateEvaluator = new DisableGC(updateEvaluator);
myBodyEvaluator = new DisableGC(bodyEvaluator);
myLabelName = labelName;
}

View File

@@ -31,9 +31,9 @@ public class IfStatementEvaluator implements Evaluator {
private Modifier myModifier;
public IfStatementEvaluator(Evaluator conditionEvaluator, Evaluator thenEvaluator, Evaluator elseEvaluator) {
myConditionEvaluator = conditionEvaluator;
myThenEvaluator = thenEvaluator;
myElseEvaluator = elseEvaluator;
myConditionEvaluator = new DisableGC(conditionEvaluator);
myThenEvaluator = new DisableGC(thenEvaluator);
myElseEvaluator = new DisableGC(elseEvaluator);
}
public Modifier getModifier() {

View File

@@ -47,7 +47,7 @@ public class MethodEvaluator implements Evaluator {
private final Evaluator myObjectEvaluator;
public MethodEvaluator(Evaluator objectEvaluator, JVMName className, String methodName, JVMName signature, List argumentEvaluators) {
myObjectEvaluator = objectEvaluator;
myObjectEvaluator = new DisableGC(objectEvaluator);
myClassName = className;
myMethodName = methodName;
myMethodSignature = signature;

View File

@@ -31,7 +31,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.sun.jdi.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
class NewArrayInstanceEvaluator implements Evaluator {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.NewArrayInstanceEvaluator");
@@ -86,7 +86,7 @@ class NewArrayInstanceEvaluator implements Evaluator {
return arrayReference;
}
private void setInitialValues(ArrayReference arrayReference, Object[] values, EvaluationContextImpl context) throws EvaluateException {
private static void setInitialValues(ArrayReference arrayReference, Object[] values, EvaluationContextImpl context) throws EvaluateException {
ArrayType type = (ArrayType)arrayReference.referenceType();
DebugProcessImpl debugProcess = context.getDebugProcess();
try {
@@ -105,11 +105,7 @@ class NewArrayInstanceEvaluator implements Evaluator {
}
else {
if (values.length > 0) {
List list = new ArrayList(values.length);
for (int idx = 0; idx < values.length; idx++) {
list.add(values[idx]);
}
arrayReference.setValues(list);
arrayReference.setValues(new ArrayList(Arrays.asList(values)));
}
}
}

View File

@@ -26,8 +26,8 @@ public class PostfixOperationEvaluator implements Evaluator{
private Modifier myModifier;
public PostfixOperationEvaluator(Evaluator operandEvaluator, Evaluator incrementImpl) {
myOperandEvaluator = operandEvaluator;
myIncrementImpl = incrementImpl;
myOperandEvaluator = new DisableGC(operandEvaluator);
myIncrementImpl = new DisableGC(incrementImpl);
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {

View File

@@ -53,7 +53,7 @@ public class UnBoxingEvaluator implements Evaluator{
}
public UnBoxingEvaluator(Evaluator operand) {
myOperand = operand;
myOperand = new DisableGC(operand);
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {

View File

@@ -30,8 +30,8 @@ public class WhileStatementEvaluator implements Evaluator {
private final String myLabelName;
public WhileStatementEvaluator(Evaluator conditionEvaluator, Evaluator bodyEvaluator, String labelName) {
myConditionEvaluator = conditionEvaluator;
myBodyEvaluator = bodyEvaluator;
myConditionEvaluator = new DisableGC(conditionEvaluator);
myBodyEvaluator = new DisableGC(bodyEvaluator);
myLabelName = labelName;
}