mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[memory-agent] Update version: 0.0.7 and integrate new data format
This commit is contained in:
+3
-3
@@ -1,12 +1,12 @@
|
||||
<component name="libraryTable">
|
||||
<library name="debugger-memory-agent" type="repository">
|
||||
<properties maven-id="org.jetbrains.intellij.deps:debugger-memory-agent:0.0.5" />
|
||||
<properties maven-id="org.jetbrains.intellij.deps:debugger-memory-agent:0.0.7" />
|
||||
<CLASSES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-memory-agent/0.0.5/debugger-memory-agent-0.0.5.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-memory-agent/0.0.7/debugger-memory-agent-0.0.7.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-memory-agent/0.0.5/debugger-memory-agent-0.0.5-sources.jar!/" />
|
||||
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/intellij/deps/debugger-memory-agent/0.0.7/debugger-memory-agent-0.0.7-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
+2
-1
@@ -18,11 +18,12 @@ import com.sun.jdi.ObjectReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ShowGarbageCollectorRootsAction extends NativeAgentActionBase {
|
||||
private static final int DEFAULT_OBJECTS_LIMIT = 1000;
|
||||
@Override
|
||||
protected void perform(@NotNull MemoryAgent memoryAgent,
|
||||
@NotNull ObjectReference reference,
|
||||
@NotNull XValueNodeImpl node) throws EvaluateException {
|
||||
ReferringObjectsProvider roots = memoryAgent.canFindGcRoots() ? memoryAgent.findGcRoots(reference) : null;
|
||||
ReferringObjectsProvider roots = memoryAgent.canFindGcRoots() ? memoryAgent.findGcRoots(reference, DEFAULT_OBJECTS_LIMIT) : null;
|
||||
if (roots == null) {
|
||||
XDebuggerManagerImpl.NOTIFICATION_GROUP.createNotification("This feature is unavailable", NotificationType.INFORMATION);
|
||||
return;
|
||||
|
||||
@@ -106,7 +106,7 @@ public class AgentLoader {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReferringObjectsProvider findGcRoots(@NotNull ObjectReference reference) {
|
||||
public ReferringObjectsProvider findGcRoots(@NotNull ObjectReference reference, int limit) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,5 +23,5 @@ public interface MemoryAgent {
|
||||
boolean canFindGcRoots();
|
||||
|
||||
@Nullable
|
||||
ReferringObjectsProvider findGcRoots(@NotNull ObjectReference reference) throws EvaluateException;
|
||||
ReferringObjectsProvider findGcRoots(@NotNull ObjectReference reference, int limit) throws EvaluateException;
|
||||
}
|
||||
|
||||
@@ -11,13 +11,11 @@ import com.intellij.debugger.memory.agent.parsers.BooleanParser;
|
||||
import com.intellij.debugger.memory.agent.parsers.GcRootsPathsParser;
|
||||
import com.intellij.debugger.memory.agent.parsers.LongValueParser;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.sun.jdi.ClassType;
|
||||
import com.sun.jdi.Method;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
import com.sun.jdi.Value;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@@ -60,7 +58,7 @@ public class MemoryAgentImpl implements MemoryAgent {
|
||||
public long evaluateObjectSize(@NotNull ObjectReference reference) throws EvaluateException {
|
||||
if (!canEvaluateObjectSize()) throw new UnsupportedOperationException();
|
||||
Value result = callMethod(SIZE_OF_SINGLE_OBJECT_METHOD_NAME, Collections.singletonList(reference));
|
||||
return result != null ? new LongValueParser().parse(result) : -1;
|
||||
return result != null ? LongValueParser.INSTANCE.parse(result) : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -83,11 +81,12 @@ public class MemoryAgentImpl implements MemoryAgent {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ReferringObjectsProvider findGcRoots(@NotNull ObjectReference reference) throws EvaluateException {
|
||||
public ReferringObjectsProvider findGcRoots(@NotNull ObjectReference reference, int limit) throws EvaluateException {
|
||||
if (!canFindGcRoots()) throw new UnsupportedOperationException();
|
||||
|
||||
Value value = callMethod(GARBAGE_COLLECTOR_ROOTS_METHOD_NAME, Collections.singletonList(reference));
|
||||
return value == null ? null : new GcRootsPathsParser().parse(value);
|
||||
IntegerValue limitValue = myDebugProcess.getVirtualMachineProxy().mirrorOf(limit);
|
||||
Value value = callMethod(GARBAGE_COLLECTOR_ROOTS_METHOD_NAME, Arrays.asList(reference, limitValue));
|
||||
return value == null ? null : GcRootsPathsParser.INSTANCE.parse(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// Copyright 2000-2019 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;
|
||||
|
||||
public class UnexpectedValueFormatException extends RuntimeException {
|
||||
public UnexpectedValueFormatException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
// Copyright 2000-2019 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.parsers
|
||||
|
||||
import com.sun.jdi.BooleanValue
|
||||
import com.sun.jdi.Value
|
||||
|
||||
object BooleanParser : ResultParser<Boolean> {
|
||||
override fun parse(value: Value): Boolean {
|
||||
return (value as? BooleanValue)?.value() ?: false
|
||||
}
|
||||
}
|
||||
+7
-49
@@ -1,62 +1,20 @@
|
||||
// Copyright 2000-2019 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.parsers
|
||||
|
||||
import com.intellij.debugger.memory.agent.MemoryAgentReferringObjectProvider
|
||||
import com.intellij.debugger.engine.ReferringObjectsProvider
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.debugger.memory.agent.MemoryAgentReferringObjectProvider
|
||||
import com.intellij.debugger.memory.agent.UnexpectedValueFormatException
|
||||
import com.sun.jdi.ArrayReference
|
||||
import com.sun.jdi.IntegerValue
|
||||
import com.sun.jdi.ObjectReference
|
||||
import com.sun.jdi.Value
|
||||
import java.util.ArrayList
|
||||
|
||||
class GcRootsPathsParser : ResultParser<ReferringObjectsProvider> {
|
||||
private companion object {
|
||||
val LOG = Logger.getInstance(GcRootsPathsParser::class.java)
|
||||
}
|
||||
|
||||
object GcRootsPathsParser : ResultParser<ReferringObjectsProvider> {
|
||||
override fun parse(value: Value): ReferringObjectsProvider {
|
||||
if (value is ArrayReference) {
|
||||
LOG.assertTrue(value.length() == 2, "Array must represent 2 values: objects and backward references")
|
||||
val values = parseValues(value.getValue(0))
|
||||
val backwardReferences = parseBackwardReferences(value.getValue(1))
|
||||
if (value.length() != 2) throw UnexpectedValueFormatException("Array must represent 2 values: objects and backward references")
|
||||
val values = ObjectReferencesParser.parse(value.getValue(0))
|
||||
val backwardReferences = BackwardReferencesParser.parse(value.getValue(1))
|
||||
return MemoryAgentReferringObjectProvider(values, backwardReferences)
|
||||
}
|
||||
throw AssertionError("Incorrect result format: array of arrays is expected")
|
||||
}
|
||||
|
||||
private fun parseBackwardReferences(value: Value): List<List<Int>> {
|
||||
if (value is ArrayReference) {
|
||||
val result = ArrayList<List<Int>>()
|
||||
for (item in value.values) {
|
||||
if (item !is ArrayReference || "int" == item.type().name()) {
|
||||
throw AssertionError("Incorrect result format: int array expected")
|
||||
}
|
||||
val ints = item.values.map { x -> (x as IntegerValue).value() }
|
||||
result.add(ints)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
throw AssertionError("Incorrect result format: array with nested int arrays expected")
|
||||
}
|
||||
|
||||
private fun parseValues(value: Value): List<ObjectReference> {
|
||||
if (value is ArrayReference) {
|
||||
val result = ArrayList<ObjectReference>()
|
||||
for (item in value.values) {
|
||||
if (item !is ObjectReference) break
|
||||
result.add(item)
|
||||
}
|
||||
|
||||
if (result.size != value.length()) {
|
||||
throw AssertionError("All values should be object references but some of them are not")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
throw AssertionError("Incorrect result format: array with object references expected")
|
||||
throw UnexpectedValueFormatException("Array of arrays is expected")
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright 2000-2019 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.parsers
|
||||
|
||||
import com.sun.jdi.PrimitiveValue
|
||||
import com.sun.jdi.Value
|
||||
|
||||
class LongValueParser : ResultParser<Long> {
|
||||
override fun parse(value: Value): Long {
|
||||
if (value is PrimitiveValue) {
|
||||
return value.longValue()
|
||||
}
|
||||
|
||||
throw IllegalArgumentException("Unexpected argument. Primitive value is expected")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// Copyright 2000-2019 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.parsers
|
||||
|
||||
import com.intellij.debugger.memory.agent.UnexpectedValueFormatException
|
||||
import com.sun.jdi.*
|
||||
import java.util.ArrayList
|
||||
|
||||
object BooleanParser : ResultParser<Boolean> {
|
||||
override fun parse(value: Value): Boolean {
|
||||
return (value as? BooleanValue)?.value() ?: false
|
||||
}
|
||||
}
|
||||
|
||||
object LongValueParser : ResultParser<Long> {
|
||||
override fun parse(value: Value): Long {
|
||||
if (value is PrimitiveValue) {
|
||||
return value.longValue()
|
||||
}
|
||||
|
||||
throw UnexpectedValueFormatException("Primitive value is expected")
|
||||
}
|
||||
}
|
||||
|
||||
object ObjectReferencesParser : ResultParser<List<ObjectReference>> {
|
||||
override fun parse(value: Value): List<ObjectReference> {
|
||||
if (value is ArrayReference) {
|
||||
val result = ArrayList<ObjectReference>()
|
||||
for (item in value.values) {
|
||||
if (item !is ObjectReference) break
|
||||
result.add(item)
|
||||
}
|
||||
|
||||
if (result.size != value.length()) {
|
||||
throw UnexpectedValueFormatException(
|
||||
"All values should be object references but some of them are not")
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
throw UnexpectedValueFormatException("Array with object references expected")
|
||||
}
|
||||
}
|
||||
|
||||
object BackwardReferencesParser : ResultParser<List<List<Int>>> {
|
||||
override fun parse(value: Value): List<List<Int>> {
|
||||
if (value !is ArrayReference) throw UnexpectedValueFormatException("Array with nested arrays expected")
|
||||
|
||||
val result = ArrayList<List<Int>>()
|
||||
for (linksInfo in value.values) {
|
||||
if (linksInfo !is ArrayReference) throw UnexpectedValueFormatException("Object references information should be represented by array")
|
||||
val indices = IntArrayParser.parse(linksInfo.getValue(0))
|
||||
.distinct() // drop duplicates
|
||||
.filter { it != -1 } // drop gc roots
|
||||
// TODO: parse kinds and infos as well
|
||||
|
||||
result.add(indices)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
object IntArrayParser : ResultParser<List<Int>> {
|
||||
override fun parse(value: Value): List<Int> {
|
||||
if (value !is ArrayReference) throw UnexpectedValueFormatException("Array expected")
|
||||
val items = value.values
|
||||
if (items.isEmpty()) return emptyList()
|
||||
if (items[0] !is IntegerValue) throw UnexpectedValueFormatException("array elements should be integers")
|
||||
return items.map { it as IntegerValue }.map(IntegerValue::value)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user