mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-02-05 08:06:56 +07:00
IJ-CR-3115: Add agent actions timeouts
(cherry picked from commit 4cbeb8a4a1755d5dbfba9e3d44205d3c090630d7) GitOrigin-RevId: 6225c47ce482c2ddba1a8fec98f11b8755f53700
This commit is contained in:
committed by
intellij-monorepo-bot
parent
720609b80c
commit
4e9e87fda7
@@ -9,11 +9,13 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.memory.agent.MemoryAgent;
|
||||
import com.intellij.debugger.memory.agent.MemoryAgentActionResult;
|
||||
import com.intellij.debugger.memory.agent.ui.RetainedSizeDialog;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.xdebugger.XDebuggerManager;
|
||||
import com.intellij.xdebugger.impl.XDebuggerManagerImpl;
|
||||
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
|
||||
@@ -46,11 +48,19 @@ public class CalculateRetainedSizeAction extends DebuggerTreeAction {
|
||||
try {
|
||||
EvaluationContextImpl evaluationContext = new EvaluationContextImpl(suspendContext, suspendContext.getFrameProxy());
|
||||
MemoryAgent memoryAgent = MemoryAgent.get(debugProcess);
|
||||
Pair<Long, ObjectReference[]> sizeAndHeldObjects = memoryAgent.estimateObjectSize(evaluationContext, reference);
|
||||
dialog.setHeldObjectsAndRetainedSize(
|
||||
Arrays.asList(sizeAndHeldObjects.getSecond()),
|
||||
sizeAndHeldObjects.getFirst()
|
||||
MemoryAgentActionResult<Pair<long[], ObjectReference[]>> result = memoryAgent.estimateObjectSize(
|
||||
evaluationContext, reference, Registry.get("debugger.memory.agent.action.timeout").asInteger()
|
||||
);
|
||||
if (result.executedSuccessfully()) {
|
||||
Pair<long[], ObjectReference[]> sizesAndHeldObjects = result.getResult();
|
||||
dialog.setHeldObjectsAndSizes(
|
||||
Arrays.asList(sizesAndHeldObjects.getSecond()),
|
||||
sizesAndHeldObjects.getFirst()[0],
|
||||
sizesAndHeldObjects.getFirst()[1]
|
||||
);
|
||||
} else {
|
||||
dialog.setCalculationTimeout();
|
||||
}
|
||||
}
|
||||
catch (EvaluateException e) {
|
||||
XDebuggerManagerImpl.NOTIFICATION_GROUP.createNotification(JavaDebuggerBundle.message("action.failed"), NotificationType.ERROR);
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.memory.agent;
|
||||
|
||||
import com.intellij.debugger.DebuggerContext;
|
||||
import com.intellij.debugger.JavaDebuggerBundle;
|
||||
import com.intellij.debugger.engine.ReferringObject;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.xdebugger.frame.XFullValueEvaluator;
|
||||
import com.intellij.xdebugger.frame.XValueNode;
|
||||
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
|
||||
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CalculationTimeoutReferringObject implements ReferringObject {
|
||||
@NotNull
|
||||
@Override
|
||||
public ValueDescriptorImpl createValueDescription(@NotNull Project project, @NotNull Value referee) {
|
||||
return new ValueDescriptorImpl(project, null) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Value calcValue(EvaluationContextImpl evaluationContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiExpression getDescriptorEvaluation(DebuggerContext context) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public final Function<XValueNode, XValueNode> getNodeCustomizer() {
|
||||
return node -> new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
|
||||
@Override
|
||||
public void applyPresentation(@Nullable Icon icon, @NotNull final XValuePresentation valuePresenter, boolean hasChildren) {
|
||||
node.setPresentation(icon, new XValuePresentation() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getSeparator() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderValue(@NotNull XValueTextRenderer renderer) {
|
||||
renderer.renderValue(JavaDebuggerBundle.message("debugger.memory.agent.timeout.error"));
|
||||
}
|
||||
}, hasChildren);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getNodeName(int order) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ObjectReference getReference() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.memory.agent;
|
||||
|
||||
import com.intellij.debugger.DebuggerContext;
|
||||
import com.intellij.debugger.engine.ReferringObject;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.xdebugger.frame.XFullValueEvaluator;
|
||||
import com.intellij.xdebugger.frame.XValueNode;
|
||||
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
|
||||
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CompoundRootReferringObject implements ReferringObject {
|
||||
private final MemoryAgentReferenceKind[] myKinds;
|
||||
|
||||
public CompoundRootReferringObject(MemoryAgentReferenceKind @NotNull[] kinds) {
|
||||
myKinds = ContainerUtil.set(kinds).toArray(new MemoryAgentReferenceKind[0]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ValueDescriptorImpl createValueDescription(@NotNull Project project, @NotNull Value referee) {
|
||||
return new ValueDescriptorImpl(project, null) {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value calcValue(EvaluationContextImpl evaluationContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiExpression getDescriptorEvaluation(DebuggerContext context) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public final Function<XValueNode, XValueNode> getNodeCustomizer() {
|
||||
return node -> new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
|
||||
@Override
|
||||
public void applyPresentation(@Nullable Icon icon, @NotNull final XValuePresentation valuePresenter, boolean hasChildren) {
|
||||
node.setPresentation(AllIcons.Nodes.Record, new XValuePresentation() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getSeparator() {
|
||||
return ": ";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderValue(@NotNull XValueTextRenderer renderer) {
|
||||
renderer.renderValue(Arrays.stream(myKinds).map(kind -> kind.toString() + " reference").collect(Collectors.joining(", ")));
|
||||
}
|
||||
}, hasChildren);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getNodeName(int order) {
|
||||
return "Root";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ObjectReference getReference() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import javax.swing.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class GCRootReferringObject implements ReferringObject {
|
||||
@NotNull private final MemoryAgentReferenceKind myKind;
|
||||
private final MemoryAgentReferenceKind myKind;
|
||||
|
||||
public GCRootReferringObject(@NotNull MemoryAgentReferenceKind kind) {
|
||||
this.myKind = kind;
|
||||
@@ -82,6 +82,11 @@ public class GCRootReferringObject implements ReferringObject {
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MemoryAgentReferenceKind getKind() {
|
||||
return myKind;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getNodeName(int order) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.memory.agent;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class JNILocalReferringObject extends GCRootReferringObject {
|
||||
private final long myTid;
|
||||
private final long myDepth;
|
||||
|
||||
public JNILocalReferringObject(@NotNull MemoryAgentReferenceKind kind,
|
||||
long tid, long depth) {
|
||||
super(kind);
|
||||
this.myTid = tid;
|
||||
this.myDepth = depth;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getAdditionalInfo() {
|
||||
return String.format("TID: %d DEPTH: %d", myTid, myDepth);
|
||||
}
|
||||
}
|
||||
@@ -33,22 +33,34 @@ public interface MemoryAgent {
|
||||
@NotNull
|
||||
MemoryAgentCapabilities capabilities();
|
||||
|
||||
Pair<Long, ObjectReference[]> estimateObjectSize(@NotNull EvaluationContextImpl evaluationContext, @NotNull ObjectReference reference) throws EvaluateException;
|
||||
|
||||
long[] estimateObjectsSizes(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ObjectReference> references)
|
||||
throws EvaluateException;
|
||||
|
||||
long[] getShallowSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException;
|
||||
|
||||
long[] getRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException;
|
||||
|
||||
Pair<long[], long[]> getShallowAndRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException;
|
||||
@NotNull
|
||||
MemoryAgentActionResult<Pair<long[], ObjectReference[]>> estimateObjectSize(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull ObjectReference reference,
|
||||
long timeoutInMillis) throws EvaluateException;
|
||||
|
||||
@NotNull
|
||||
ReferringObjectsInfo findPathsToClosestGCRoots(@NotNull EvaluationContextImpl evaluationContext, @NotNull ObjectReference reference,
|
||||
int pathsNumber, int objectsNumber)
|
||||
throws EvaluateException;
|
||||
MemoryAgentActionResult<long[]> estimateObjectsSizes(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ObjectReference> references,
|
||||
long timeoutInMillis) throws EvaluateException;
|
||||
|
||||
@NotNull
|
||||
MemoryAgentActionResult<long[]> getShallowSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException;
|
||||
|
||||
@NotNull
|
||||
MemoryAgentActionResult<long[]> getRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException;
|
||||
|
||||
@NotNull
|
||||
MemoryAgentActionResult<Pair<long[], long[]>> getShallowAndRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException;
|
||||
|
||||
@NotNull
|
||||
MemoryAgentActionResult<ReferringObjectsInfo> findPathsToClosestGCRoots(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull ObjectReference reference,
|
||||
int pathsNumber, int objectsNumber,
|
||||
long timeoutInMillis) throws EvaluateException;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.debugger.memory.agent;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MemoryAgentActionResult<T> {
|
||||
public enum ErrorCode {
|
||||
OK,
|
||||
TIMEOUT;
|
||||
|
||||
public static ErrorCode valueOf(int value) {
|
||||
return value == 0 ? OK : TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
private final ErrorCode myErrorCode;
|
||||
private final T myResult;
|
||||
|
||||
public MemoryAgentActionResult(@NotNull T result, @NotNull ErrorCode errorCode) {
|
||||
myErrorCode = errorCode;
|
||||
myResult = result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public T getResult() {
|
||||
return myResult;
|
||||
}
|
||||
|
||||
public boolean executedSuccessfully() {
|
||||
return myErrorCode != ErrorCode.TIMEOUT;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package com.intellij.debugger.memory.agent;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -18,64 +19,78 @@ class MemoryAgentImpl implements MemoryAgent {
|
||||
myCapabilities = capabilities;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Pair<Long, ObjectReference[]> estimateObjectSize(@NotNull EvaluationContextImpl evaluationContext, @NotNull ObjectReference reference)
|
||||
throws EvaluateException {
|
||||
public MemoryAgentActionResult<Pair<long[], ObjectReference[]>> estimateObjectSize(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull ObjectReference reference,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
if (!myCapabilities.canEstimateObjectSize()) {
|
||||
throw new UnsupportedOperationException("Memory agent can't estimate object size");
|
||||
}
|
||||
return MemoryAgentOperations.estimateObjectSize(evaluationContext, reference);
|
||||
|
||||
return MemoryAgentOperations.estimateObjectSize(evaluationContext, reference, timeoutInMillis);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public long[] estimateObjectsSizes(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ObjectReference> references)
|
||||
throws EvaluateException {
|
||||
public MemoryAgentActionResult<long[]> estimateObjectsSizes(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ObjectReference> references,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
if (!myCapabilities.canEstimateObjectsSizes()) {
|
||||
throw new UnsupportedOperationException("Memory agent can't estimate objects sizes");
|
||||
}
|
||||
|
||||
return MemoryAgentOperations.estimateObjectsSizes(evaluationContext, references);
|
||||
return MemoryAgentOperations.estimateObjectsSizes(evaluationContext, references, timeoutInMillis);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public long[] getShallowSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException {
|
||||
public MemoryAgentActionResult<long[]> getShallowSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
if (!myCapabilities.canGetShallowSizeByClasses()) {
|
||||
throw new UnsupportedOperationException("Memory agent can't get shallow size by classes");
|
||||
}
|
||||
|
||||
return MemoryAgentOperations.getShallowSizeByClasses(evaluationContext, classes);
|
||||
return MemoryAgentOperations.getShallowSizeByClasses(evaluationContext, classes, timeoutInMillis);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public long[] getRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException {
|
||||
public MemoryAgentActionResult<long[]> getRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
if (!myCapabilities.canGetRetainedSizeByClasses()) {
|
||||
throw new UnsupportedOperationException("Memory agent can't get retained size by classes");
|
||||
}
|
||||
|
||||
return MemoryAgentOperations.getRetainedSizeByClasses(evaluationContext, classes);
|
||||
return MemoryAgentOperations.getRetainedSizeByClasses(evaluationContext, classes, timeoutInMillis);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Pair<long[], long[]> getShallowAndRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException {
|
||||
public MemoryAgentActionResult<Pair<long[], long[]>> getShallowAndRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
if (!myCapabilities.canGetRetainedSizeByClasses() || !myCapabilities.canGetShallowSizeByClasses()) {
|
||||
throw new UnsupportedOperationException("Memory agent can't get shallow and retained size by classes");
|
||||
}
|
||||
|
||||
return MemoryAgentOperations.getShallowAndRetainedSizeByClasses(evaluationContext, classes);
|
||||
return MemoryAgentOperations.getShallowAndRetainedSizeByClasses(evaluationContext, classes, timeoutInMillis);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public @NotNull ReferringObjectsInfo findPathsToClosestGCRoots(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull ObjectReference reference,
|
||||
int pathsNumber, int objectsNumber) throws EvaluateException {
|
||||
public MemoryAgentActionResult<ReferringObjectsInfo> findPathsToClosestGCRoots(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull ObjectReference reference,
|
||||
int pathsNumber,
|
||||
int objectsNumber,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
if (!myCapabilities.canFindPathsToClosestGcRoots()) {
|
||||
throw new UnsupportedOperationException("Memory agent can't provide paths to closest gc roots");
|
||||
}
|
||||
|
||||
return MemoryAgentOperations.findPathsToClosestGCRoots(evaluationContext, reference, pathsNumber, objectsNumber);
|
||||
return MemoryAgentOperations.findPathsToClosestGCRoots(evaluationContext, reference, pathsNumber, objectsNumber, timeoutInMillis);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -26,57 +26,120 @@ final class MemoryAgentOperations {
|
||||
private static final Key<MemoryAgent> MEMORY_AGENT_KEY = Key.create("MEMORY_AGENT_KEY");
|
||||
private static final Logger LOG = Logger.getInstance(MemoryAgentOperations.class);
|
||||
|
||||
@NotNull
|
||||
static Pair<Long, ObjectReference[]> estimateObjectSize(@NotNull EvaluationContextImpl evaluationContext, @NotNull ObjectReference reference)
|
||||
throws EvaluateException {
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.ESTIMATE_OBJECT_SIZE, Collections.singletonList(reference));
|
||||
Pair<Long, List<ObjectReference>> pair = SizeAndHeldObjectsParser.INSTANCE.parse(result);
|
||||
return new Pair<>(pair.getFirst(), pair.getSecond().toArray(new ObjectReference[0]));
|
||||
private static LongValue getTimeoutValue(@NotNull EvaluationContextImpl evaluationContext, long timeoutInMillis) {
|
||||
return evaluationContext.getDebugProcess().getVirtualMachineProxy().mirrorOf(timeoutInMillis);
|
||||
}
|
||||
|
||||
static long @NotNull [] estimateObjectsSizes(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ObjectReference> references)
|
||||
throws EvaluateException {
|
||||
@NotNull
|
||||
static MemoryAgentActionResult<Pair<long[], ObjectReference[]>> estimateObjectSize(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull ObjectReference reference,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
LongValue timeoutValue = getTimeoutValue(evaluationContext, timeoutInMillis);
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.ESTIMATE_OBJECT_SIZE, Arrays.asList(reference, timeoutValue));
|
||||
Pair<MemoryAgentActionResult.ErrorCode, Value> errCodeAndResult = ErrorCodeParser.INSTANCE.parse(result);
|
||||
MemoryAgentActionResult.ErrorCode errCode = errCodeAndResult.getFirst();
|
||||
Pair<long[], ObjectReference[]> sizesAndObjects;
|
||||
if (errCode != MemoryAgentActionResult.ErrorCode.OK) {
|
||||
sizesAndObjects = new Pair<>(new long[0], new ObjectReference[0]);
|
||||
} else {
|
||||
Pair<Long[], ObjectReference[]> parsingResult = SizeAndHeldObjectsParser.INSTANCE.parse(errCodeAndResult.getSecond());
|
||||
sizesAndObjects = new Pair<>(
|
||||
Arrays.stream(parsingResult.getFirst()).mapToLong(Long::longValue).toArray(),
|
||||
parsingResult.getSecond()
|
||||
);
|
||||
}
|
||||
|
||||
return new MemoryAgentActionResult<>(sizesAndObjects, errCode);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static MemoryAgentActionResult<long[]> estimateObjectsSizes(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ObjectReference> references,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
LongValue timeoutValue = getTimeoutValue(evaluationContext, timeoutInMillis);
|
||||
ArrayReference array = wrapWithArray(evaluationContext, references);
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.ESTIMATE_OBJECTS_SIZE, Collections.singletonList(array));
|
||||
return LongArrayParser.INSTANCE.parse(result).stream().mapToLong(Long::longValue).toArray();
|
||||
}
|
||||
|
||||
static long @NotNull [] getShallowSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException {
|
||||
ArrayReference array = wrapWithArray(evaluationContext, ContainerUtil.map(classes, ReferenceType::classObject));
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.GET_SHALLOW_SIZE_BY_CLASSES, Collections.singletonList(array));
|
||||
return LongArrayParser.INSTANCE.parse(result).stream().mapToLong(Long::longValue).toArray();
|
||||
}
|
||||
|
||||
static long @NotNull [] getRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException {
|
||||
ArrayReference array = wrapWithArray(evaluationContext, ContainerUtil.map(classes, ReferenceType::classObject));
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.GET_RETAINED_SIZE_BY_CLASSES, Collections.singletonList(array));
|
||||
return LongArrayParser.INSTANCE.parse(result).stream().mapToLong(Long::longValue).toArray();
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.ESTIMATE_OBJECTS_SIZE, Arrays.asList(array, timeoutValue));
|
||||
Pair<MemoryAgentActionResult.ErrorCode, Value> errCodeAndResult = ErrorCodeParser.INSTANCE.parse(result);
|
||||
return new MemoryAgentActionResult<>(
|
||||
LongArrayParser.INSTANCE.parse(errCodeAndResult.getSecond()).stream().mapToLong(Long::longValue).toArray(),
|
||||
errCodeAndResult.getFirst()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static Pair<long[], long[]> getShallowAndRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext, @NotNull List<ReferenceType> classes)
|
||||
throws EvaluateException {
|
||||
static MemoryAgentActionResult<long[]> getShallowSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
LongValue timeoutValue = getTimeoutValue(evaluationContext, timeoutInMillis);
|
||||
ArrayReference array = wrapWithArray(evaluationContext, ContainerUtil.map(classes, ReferenceType::classObject));
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.GET_SHALLOW_AND_RETAINED_SIZE_BY_CLASSES, Collections.singletonList(array));
|
||||
Pair<List<Long>, List<Long>> pair = ShallowAndRetainedSizeParser.INSTANCE.parse(result);
|
||||
return new Pair<>(pair.getFirst().stream().mapToLong(Long::longValue).toArray(),
|
||||
pair.getSecond().stream().mapToLong(Long::longValue).toArray());
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.GET_SHALLOW_SIZE_BY_CLASSES, Arrays.asList(array, timeoutValue));
|
||||
Pair<MemoryAgentActionResult.ErrorCode, Value> errCodeAndResult = ErrorCodeParser.INSTANCE.parse(result);
|
||||
return new MemoryAgentActionResult<>(
|
||||
LongArrayParser.INSTANCE.parse(errCodeAndResult.getSecond()).stream().mapToLong(Long::longValue).toArray(),
|
||||
errCodeAndResult.getFirst()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static ReferringObjectsInfo findPathsToClosestGCRoots(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull ObjectReference reference, int pathsNumber,
|
||||
int objectsNumber) throws EvaluateException {
|
||||
static MemoryAgentActionResult<long[]> getRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
LongValue timeoutValue = getTimeoutValue(evaluationContext, timeoutInMillis);
|
||||
ArrayReference array = wrapWithArray(evaluationContext, ContainerUtil.map(classes, ReferenceType::classObject));
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.GET_RETAINED_SIZE_BY_CLASSES, Arrays.asList(array, timeoutValue));
|
||||
Pair<MemoryAgentActionResult.ErrorCode, Value> errCodeAndResult = ErrorCodeParser.INSTANCE.parse(result);
|
||||
return new MemoryAgentActionResult<>(
|
||||
LongArrayParser.INSTANCE.parse(errCodeAndResult.getSecond()).stream().mapToLong(Long::longValue).toArray(),
|
||||
errCodeAndResult.getFirst()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static MemoryAgentActionResult<Pair<long[], long[]>> getShallowAndRetainedSizeByClasses(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull List<ReferenceType> classes,
|
||||
long timeoutInMillis) throws EvaluateException {
|
||||
LongValue timeoutValue = getTimeoutValue(evaluationContext, timeoutInMillis);
|
||||
ArrayReference array = wrapWithArray(evaluationContext, ContainerUtil.map(classes, ReferenceType::classObject));
|
||||
Value result = callMethod(evaluationContext, MemoryAgentNames.Methods.GET_SHALLOW_AND_RETAINED_SIZE_BY_CLASSES, Arrays.asList(array, timeoutValue));
|
||||
Pair<MemoryAgentActionResult.ErrorCode, Value> errCodeAndResult = ErrorCodeParser.INSTANCE.parse(result);
|
||||
Pair<List<Long>, List<Long>> shallowAndRetainedSizes = ShallowAndRetainedSizeParser.INSTANCE.parse(errCodeAndResult.getSecond());
|
||||
return new MemoryAgentActionResult<>(
|
||||
new Pair<>(
|
||||
shallowAndRetainedSizes.getFirst().stream().mapToLong(Long::longValue).toArray(),
|
||||
shallowAndRetainedSizes.getSecond().stream().mapToLong(Long::longValue).toArray()
|
||||
),
|
||||
errCodeAndResult.getFirst()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static MemoryAgentActionResult<ReferringObjectsInfo> findPathsToClosestGCRoots(@NotNull EvaluationContextImpl evaluationContext,
|
||||
@NotNull ObjectReference reference, int pathsNumber,
|
||||
int objectsNumber, long timeoutInMillis) throws EvaluateException {
|
||||
LongValue timeoutValue = getTimeoutValue(evaluationContext, timeoutInMillis);
|
||||
IntegerValue pathsNumberValue = evaluationContext.getDebugProcess().getVirtualMachineProxy().mirrorOf(pathsNumber);
|
||||
IntegerValue objectsNumberValue = evaluationContext.getDebugProcess().getVirtualMachineProxy().mirrorOf(objectsNumber);
|
||||
Value value = callMethod(
|
||||
Value result = callMethod(
|
||||
evaluationContext,
|
||||
MemoryAgentNames.Methods.FIND_PATHS_TO_CLOSEST_GC_ROOTS,
|
||||
Arrays.asList(reference, pathsNumberValue, objectsNumberValue)
|
||||
Arrays.asList(reference, pathsNumberValue, objectsNumberValue, timeoutValue)
|
||||
);
|
||||
return GcRootsPathsParser.INSTANCE.parse(value);
|
||||
|
||||
Pair<MemoryAgentActionResult.ErrorCode, Value> errCodeAndResult = ErrorCodeParser.INSTANCE.parse(result);
|
||||
MemoryAgentActionResult.ErrorCode errCode = errCodeAndResult.getFirst();
|
||||
ReferringObjectsInfo returnValue;
|
||||
if (errCode != MemoryAgentActionResult.ErrorCode.OK) {
|
||||
returnValue = new ReferringObjectsInfo(
|
||||
Collections.singletonList(reference),
|
||||
Collections.singletonList(
|
||||
Collections.singletonList(new CalculationTimeoutReferringObject())
|
||||
)
|
||||
);
|
||||
} else {
|
||||
returnValue = GcRootsPathsParser.INSTANCE.parse(errCodeAndResult.getSecond());
|
||||
}
|
||||
|
||||
return new MemoryAgentActionResult<>(returnValue, errCodeAndResult.getFirst());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.debugger.engine.ReferringObject;
|
||||
import com.intellij.debugger.engine.ReferringObjectsProvider;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -49,6 +50,9 @@ public class MemoryAgentPathsToClosestGCRootsProvider implements ReferringObject
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
return memoryAgent.findPathsToClosestGCRoots(evaluationContext, value, myPathsToRequestLimit, myObjectsToRequestLimit);
|
||||
MemoryAgentActionResult<ReferringObjectsInfo> result = memoryAgent.findPathsToClosestGCRoots(
|
||||
evaluationContext, value, myPathsToRequestLimit, myObjectsToRequestLimit, Registry.get("debugger.memory.agent.action.timeout").asInteger()
|
||||
);
|
||||
return result.getResult();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,11 @@ public final class MemoryAgentUtil {
|
||||
return objects;
|
||||
}
|
||||
try {
|
||||
long[] sizes = agent.estimateObjectsSizes(context, ContainerUtil.map(objects, x -> x.getObjectReference()));
|
||||
long[] sizes = agent.estimateObjectsSizes(
|
||||
context,
|
||||
ContainerUtil.map(objects, x -> x.getObjectReference()),
|
||||
Registry.get("debugger.memory.agent.action.timeout").asInteger()
|
||||
).getResult();
|
||||
return IntStreamEx.range(0, objects.size())
|
||||
.mapToObj(i -> new SizedReferenceInfo(objects.get(i).getObjectReference(), sizes[i]))
|
||||
.reverseSorted(Comparator.comparing(x -> x.size()))
|
||||
@@ -194,7 +198,7 @@ public final class MemoryAgentUtil {
|
||||
}
|
||||
|
||||
return ApplicationManager.getApplication()
|
||||
.executeOnPooledThread(() -> new AgentExtractor().extract(detectAgentKind(jdkPath), getAgentDirectory()))
|
||||
.executeOnPooledThread(() -> AgentExtractor.INSTANCE.extract(detectAgentKind(jdkPath), getAgentDirectory()))
|
||||
.get(1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public class StackLocalReferringObject extends GCRootReferringObject {
|
||||
private final String myMethodName;
|
||||
|
||||
public StackLocalReferringObject(@NotNull MemoryAgentReferenceKind kind,
|
||||
String methodName,
|
||||
@NotNull String methodName,
|
||||
long tid, long depth) {
|
||||
super(kind);
|
||||
this.myTid = tid;
|
||||
@@ -20,8 +20,6 @@ public class StackLocalReferringObject extends GCRootReferringObject {
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getAdditionalInfo() {
|
||||
return String.format("%sTID: %d DEPTH: %d",
|
||||
myMethodName != null ? String.format("from method: \"%s\" ", myMethodName) : "",
|
||||
myTid, myDepth);
|
||||
return String.format("in method: \"%s\" TID: %d DEPTH: %d", myMethodName, myTid, myDepth);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import com.intellij.debugger.engine.ReferringObject
|
||||
import com.intellij.debugger.memory.agent.*
|
||||
import com.intellij.openapi.util.Pair
|
||||
import com.sun.jdi.*
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
object StringParser : ResultParser<String> {
|
||||
override fun parse(value: Value): String {
|
||||
@@ -85,15 +87,11 @@ object ObjectsReferencesInfoParser : ResultParser<ReferringObjectsInfo> {
|
||||
throw UnexpectedValueFormatException("Object references information should be represented by array")
|
||||
|
||||
val distinctIndices = mutableSetOf<Int>()
|
||||
val referenceInfos = mutableListOf<ReferringObject>()
|
||||
val referenceInfos = LinkedList<ReferringObject>()
|
||||
val rootReferenceKinds = mutableListOf<MemoryAgentReferenceKind>()
|
||||
for ((i, index) in indices.withIndex()) {
|
||||
if (index == -1) {
|
||||
referenceInfos.add(
|
||||
MemoryAgentReferringObjectCreator.createRootReferringObject(
|
||||
MemoryAgentReferenceKind.valueOf(kinds[i]),
|
||||
infos.getValue(i)
|
||||
)
|
||||
)
|
||||
rootReferenceKinds.add(MemoryAgentReferenceKind.valueOf(kinds[i]))
|
||||
} else if (!distinctIndices.contains(index)) {
|
||||
distinctIndices.add(index)
|
||||
referenceInfos.add(
|
||||
@@ -107,6 +105,9 @@ object ObjectsReferencesInfoParser : ResultParser<ReferringObjectsInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
if (rootReferenceKinds.isNotEmpty()) {
|
||||
referenceInfos.add(0, CompoundRootReferringObject(rootReferenceKinds.toTypedArray()))
|
||||
}
|
||||
result.add(referenceInfos)
|
||||
}
|
||||
|
||||
@@ -142,13 +143,25 @@ object ShallowAndRetainedSizeParser : ResultParser<Pair<List<Long>, List<Long>>>
|
||||
}
|
||||
}
|
||||
|
||||
object SizeAndHeldObjectsParser : ResultParser<Pair<Long, List<ObjectReference>>> {
|
||||
override fun parse(value: Value): Pair<Long, List<ObjectReference>> {
|
||||
object SizeAndHeldObjectsParser : ResultParser<Pair<Array<Long>, Array<ObjectReference>>> {
|
||||
override fun parse(value: Value): Pair<Array<Long>, Array<ObjectReference>> {
|
||||
if (value !is ArrayReference) throw UnexpectedValueFormatException("Array expected")
|
||||
if (value.length() < 2) throw UnexpectedValueFormatException("long and array of objects expected")
|
||||
return Pair(
|
||||
LongArrayParser.parse(value.getValue(0))[0],
|
||||
ObjectReferencesParser.parse(value.getValue(1))
|
||||
LongArrayParser.parse(value.getValue(0)).toTypedArray(),
|
||||
ObjectReferencesParser.parse(value.getValue(1)).toTypedArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
object ErrorCodeParser : ResultParser<Pair<MemoryAgentActionResult.ErrorCode, Value>> {
|
||||
override fun parse(value: Value): Pair<MemoryAgentActionResult.ErrorCode, Value> {
|
||||
if (value !is ArrayReference) throw UnexpectedValueFormatException("Array expected")
|
||||
return Pair(
|
||||
MemoryAgentActionResult.ErrorCode.valueOf(
|
||||
IntArrayParser.parse(value.getValue(0))[0]
|
||||
),
|
||||
value.getValue(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -173,12 +186,16 @@ object MemoryAgentReferringObjectCreator {
|
||||
value: Value?): GCRootReferringObject {
|
||||
return if (value == null) GCRootReferringObject(kind) else
|
||||
when (kind) {
|
||||
MemoryAgentReferenceKind.STACK_LOCAL,
|
||||
MemoryAgentReferenceKind.STACK_LOCAL -> {
|
||||
if (value !is ArrayReference) return GCRootReferringObject(kind)
|
||||
val methodName = StringArrayParser.parse(value.getValue(1))[0] ?: return GCRootReferringObject(kind)
|
||||
val longs = LongArrayParser.parse(value.getValue(0))
|
||||
StackLocalReferringObject(kind, methodName, longs[0], longs[1])
|
||||
}
|
||||
MemoryAgentReferenceKind.JNI_LOCAL -> {
|
||||
if (value !is ArrayReference) return GCRootReferringObject(kind)
|
||||
val longs = LongArrayParser.parse(value.getValue(0))
|
||||
val methodName = value.getValue(1)?.let { StringArrayParser.parse(it)[0] }
|
||||
StackLocalReferringObject(kind, methodName, longs[0], longs[1])
|
||||
JNILocalReferringObject(kind, longs[0], longs[1])
|
||||
}
|
||||
else -> GCRootReferringObject(kind)
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public class RetainedSizeDialog extends DialogWrapper {
|
||||
private final BorderLayoutPanel myPanel;
|
||||
private final NodeHighlighter myHighlighter;
|
||||
private final String myRootName;
|
||||
private final JBLabel myRetainedSizeLabel;
|
||||
private JBLabel myRetainedSizeLabel;
|
||||
|
||||
public RetainedSizeDialog(@NotNull Project project,
|
||||
XDebuggerEditorsProvider editorsProvider,
|
||||
@@ -78,20 +78,9 @@ public class RetainedSizeDialog extends DialogWrapper {
|
||||
myHeldObjects = new HashSet<>();
|
||||
myRootName = name;
|
||||
|
||||
JBPanel topPanel = new JBPanel<>();
|
||||
topPanel.setLayout(new VerticalFlowLayout());
|
||||
myRetainedSizeLabel = new JBLabel(JavaDebuggerBundle.message("action.calculate.retained.size.waiting.message"));
|
||||
topPanel.add(myRetainedSizeLabel);
|
||||
topPanel.add(
|
||||
new JBLabel(
|
||||
JavaDebuggerBundle.message("action.calculate.retained.size.info", myRootName),
|
||||
AllIcons.General.Information,
|
||||
SwingConstants.LEFT
|
||||
)
|
||||
);
|
||||
myPanel = JBUI.Panels.simplePanel()
|
||||
.addToCenter(ScrollPaneFactory.createScrollPane(myTree))
|
||||
.addToTop(topPanel);
|
||||
.addToTop(createTopPanel());
|
||||
|
||||
if (session != null) {
|
||||
session.addSessionListener(new XDebugSessionListener() {
|
||||
@@ -112,7 +101,11 @@ public class RetainedSizeDialog extends DialogWrapper {
|
||||
init();
|
||||
}
|
||||
|
||||
public void setHeldObjectsAndRetainedSize(@NotNull Collection<? extends ObjectReference> heldObjects, long retainedSize) {
|
||||
public void setCalculationTimeout() {
|
||||
myRetainedSizeLabel.setText(JavaDebuggerBundle.message("debugger.memory.agent.timeout.error"));
|
||||
}
|
||||
|
||||
public void setHeldObjectsAndSizes(@NotNull Collection<? extends ObjectReference> heldObjects, long shallowSize, long retainedSize) {
|
||||
myHeldObjects.clear();
|
||||
myHeldObjects.addAll(heldObjects);
|
||||
highlightLoadedChildren();
|
||||
@@ -120,6 +113,7 @@ public class RetainedSizeDialog extends DialogWrapper {
|
||||
JavaDebuggerBundle.message(
|
||||
"action.calculate.retained.size.text",
|
||||
myRootName,
|
||||
StringUtil.formatFileSize(shallowSize),
|
||||
StringUtil.formatFileSize(retainedSize)
|
||||
)
|
||||
);
|
||||
@@ -175,6 +169,22 @@ public class RetainedSizeDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JBPanel createTopPanel() {
|
||||
JBPanel panel = new JBPanel<>();
|
||||
panel.setLayout(new VerticalFlowLayout());
|
||||
myRetainedSizeLabel = new JBLabel(JavaDebuggerBundle.message("action.calculate.retained.size.waiting.message"));
|
||||
panel.add(myRetainedSizeLabel);
|
||||
panel.add(
|
||||
new JBLabel(
|
||||
JavaDebuggerBundle.message("action.calculate.retained.size.info", myRootName),
|
||||
AllIcons.General.Information,
|
||||
SwingConstants.LEFT
|
||||
)
|
||||
);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private class NodeHighlighter implements XDebuggerTreeListener {
|
||||
private boolean mySkipNotification;
|
||||
private final Map<Icon, Icon> myCachedIcons;
|
||||
@@ -188,10 +198,9 @@ public class RetainedSizeDialog extends DialogWrapper {
|
||||
public void nodeLoaded(@NotNull RestorableStateNode node, @NotNull String name) {
|
||||
if (!mySkipNotification && node instanceof XValueNodeImpl) {
|
||||
XValueNodeImpl nodeImpl = (XValueNodeImpl)node;
|
||||
if (myHeldObjects.contains(getObjectReference(nodeImpl))) {
|
||||
if (nodeImpl != nodeImpl.getTree().getRoot() && myHeldObjects.contains(getObjectReference(nodeImpl))) {
|
||||
XValuePresentation presentation = nodeImpl.getValuePresentation();
|
||||
Icon icon = nodeImpl.getIcon();
|
||||
if (presentation != null && icon != PlatformDebuggerImplIcons.PinToTop.UnpinnedItem) {
|
||||
if (presentation != null && nodeImpl.getIcon() != PlatformDebuggerImplIcons.PinToTop.UnpinnedItem) {
|
||||
highlightNode(nodeImpl);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user