Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposed changes for MatCalcitePlugin 1.6.0 #28

Merged
merged 5 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions MatCalciteDependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.1</version>
<version>5.1.9</version>
<extensions>true</extensions>
<configuration>
<manifestLocation>META-INF</manifestLocation>
Expand Down Expand Up @@ -74,7 +74,7 @@
<pluginExecutionFilter>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<versionRange>5.1.1</versionRange>
<versionRange>5.1.9</versionRange>
<goals>
<goal>bundle</goal>
</goals>
Expand All @@ -89,7 +89,7 @@
<pluginExecutionFilter>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<versionRange>5.1.1</versionRange>
<versionRange>5.1.9</versionRange>
<goals>
<goal>manifest</goal>
</goals>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,31 +161,23 @@ public static List<?> asArray(Object r) {
return null;
}

try {
if (iObject instanceof IPrimitiveArray) {
IPrimitiveArray arrayObject = (IPrimitiveArray) iObject;
int length = arrayObject.getLength();
List<Object> result = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
result.add(arrayObject.getValueAt(i));
}
return result;
} else {
IObjectArray arrayObject = (IObjectArray) iObject;
ISnapshot snapshot = arrayObject.getSnapshot();
int length = arrayObject.getLength();
List<HeapReference> result = new ArrayList<>(length);
for (long objectAddress : arrayObject.getReferenceArray()) {
if (objectAddress != 0) {
result.add(HeapReference.valueOf(snapshot.getObject(snapshot.mapAddressToId(objectAddress))));
} else {
result.add(null);
}
}
return result;
if (iObject instanceof IPrimitiveArray) {
IPrimitiveArray arrayObject = (IPrimitiveArray) iObject;
int length = arrayObject.getLength();
List<Object> result = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
result.add(arrayObject.getValueAt(i));
}
} catch (SnapshotException e) {
throw new RuntimeException("Unable to extract references from array " + r, e);
return result;
} else {
IObjectArray arrayObject = (IObjectArray) iObject;
ISnapshot snapshot = arrayObject.getSnapshot();
int length = arrayObject.getLength();
List<HeapReference> result = new ArrayList<>(length);
for (long objectAddress : arrayObject.getReferenceArray()) {
result.add(resolveReference(snapshot, objectAddress));
}
return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
import org.eclipse.mat.inspections.collectionextract.CollectionExtractionUtils;
import org.eclipse.mat.inspections.collectionextract.ICollectionExtractor;
import org.eclipse.mat.snapshot.ISnapshot;
import org.eclipse.mat.snapshot.model.IArray;
import org.eclipse.mat.snapshot.model.IClass;
import org.eclipse.mat.snapshot.model.IObject;
import org.eclipse.mat.snapshot.model.PrettyPrinter;
import org.eclipse.mat.snapshot.model.*;

import java.util.Map;

Expand Down Expand Up @@ -168,10 +165,59 @@ public static Object getField(Object r, String fieldName) {
} else if (SpecialFields.CLASS.equalsIgnoreCase(fieldName)) {
return resolveReference(iObject.getClazz());
}
} else if (iObject instanceof IArray
&& fieldName.length() > 2
&& fieldName.charAt(0) == '['
&& fieldName.charAt(fieldName.length() - 1) == ']') {
try {
// Field name is '[<number>]' and target object is array.
// Initially such calls were routed to IObject.resolveValue, which accepts field names as '[<index>]' for arrays.
// However, this have two problems:
// 1. This doesn't work with primitive arrays (they always return null)
// 2. This doesn't correctly work with <null> values - MAT code doesn't handle 0 address properly in this case
// So, now we handle this case directly in our code
int index = Integer.parseInt(fieldName.substring(1, fieldName.length() - 1));
int length = ((IArray) iObject).getLength();
if (index >= 0 && index < length) {
if (iObject instanceof IPrimitiveArray) {
return ((IPrimitiveArray) iObject).getValueAt(index);
} else if (iObject instanceof IObjectArray) {
return resolveReference(iObject.getSnapshot(), ((IObjectArray) iObject).getReferenceArray()[index]);
}
} else {
return null;
}
} catch (NumberFormatException e) {
// fall down
}
}
return resolveReference(IObjectMethods.resolveSimpleValue(iObject, fieldName));
}

@SuppressWarnings("unused")
public static Object getStaticField(Object r, String name) {
HeapReference ref = ensureHeapReference(r);
if (ref == null) {
return null;
}

IObject iObject = ref.getIObject();
if (iObject instanceof IClass) {
IClass iClass = (IClass) iObject;
for (Field field : iClass.getStaticFields()) {
if (field.getName().equals(name)) {
Object value = field.getValue();
if (value instanceof IObject) {
return new HeapReference((IObject) value);
} else {
return value;
}
}
}
}
return null;
}

@SuppressWarnings("unused")
public static long getAddress(Object r) {
HeapReference ref = ensureHeapReference(r);
Expand Down Expand Up @@ -200,7 +246,6 @@ public static Object getDominator(Object r) {
} catch (SnapshotException e) {
throw new RuntimeException("Cannot obtain immediate dominator object for " + r, e);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.github.vlsi.mat.calcite.HeapReference;

import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.snapshot.ISnapshot;
import org.eclipse.mat.snapshot.model.IObject;

import java.lang.reflect.Method;
Expand All @@ -11,6 +13,18 @@ protected static Object resolveReference(Object value) {
return value instanceof IObject ? HeapReference.valueOf((IObject) value) : value;
}

protected static HeapReference resolveReference(ISnapshot snapshot, long address) {
if (address == 0) {
// Eclipse MAT always returns "SystemClassLoader" for address=0, so we return null instead
return null;
}
try {
return HeapReference.valueOf(snapshot.getObject(snapshot.mapAddressToId(address)));
} catch (SnapshotException e) {
return null;
}
}

protected static HeapReference ensureHeapReference(Object r) {
return r instanceof HeapReference ? (HeapReference) r : null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.apache.calcite.schema.ImplementableFunction;
import org.apache.calcite.schema.ScalarFunction;
import org.apache.calcite.schema.impl.ReflectiveFunctionBase;
import org.eclipse.mat.SnapshotException;
import org.eclipse.mat.snapshot.ISnapshot;

import java.lang.reflect.Constructor;
Expand All @@ -36,11 +35,7 @@ public SnapshotFunctions(int snapshotId) {

@SuppressWarnings("unused")
public HeapReference getReference(String address) {
try {
return HeapReference.valueOf(snapshot.getObject(snapshot.mapAddressToId(Long.decode(address))));
} catch (SnapshotException e) {
throw new RuntimeException("Cannot get object by address '" + address + "'", e);
}
return HeapFunctionsBase.resolveReference(snapshot, Long.decode(address));
}

public static Multimap<String, Function> createAll(ISnapshot snapshot) {
Expand All @@ -49,19 +44,19 @@ public static Multimap<String, Function> createAll(ISnapshot snapshot) {
return builder.build();
}

private static Function getFunction(ISnapshot snapshot, String name, Class... argumentClasses) {
private static Function getFunction(ISnapshot snapshot, String name, Class<?> ... argumentClasses) {
return new SnapshotFunction(snapshot, getMethod(SnapshotFunctions.class, name, argumentClasses));
}

private static Method getMethod(Class<?> cls, String name, Class... argumentClasses) {
private static Method getMethod(Class<?> cls, String name, Class<?> ... argumentClasses) {
try {
return cls.getMethod(name, argumentClasses);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}

private static <T> Constructor<T> getConstructor(Class<T> cls, Class... argumentClasses) {
private static <T> Constructor<T> getConstructor(Class<T> cls, Class<?> ... argumentClasses) {
try {
return cls.getConstructor(argumentClasses);
} catch (NoSuchMethodException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,18 @@ public void selectShallow() throws SQLException {
public void selectThisMapField() throws SQLException {
returnsInOrder("select count(this['table'][0]) count_first_entry from java.util.HashMap",
"count_first_entry",
"71");
"18");
}

@Test
public void selectThisMapFieldMatSyntax() throws SQLException {
returnsInOrder("select count(this['table.[0]']) count_first_entry from java.util.HashMap",
"count_first_entry",
"71");
// This is actually incorrect, as IObject.resolveValue handle null values in array as reference to first Object on
// heap (i.e. System ClassLoader). The previous test (@selectThisMapField) handles null values correctly (as we
// do it directly in our code), so the correct result should be 18, but as we testing Mat syntax here (handled by
// Mat itself), so we just accept its behavior.
}

@Test
Expand All @@ -232,7 +236,19 @@ public void selectRetainedSizeFunction() throws SQLException {
"114976");
}

@Test
public void testGetField() throws SQLException {
returnsInOrder("select getField(lm.this, 'initializationDone') a, getField(lm.rootLogger, 'levelValue') b, getField(lm.this, 'listenerMap')['size'] c from java.util.logging.LogManager lm",
"a|b|c",
"true|800|0");
}

@Test
public void testGetStaticField() throws SQLException {
returnsInOrder("select c.name, getStaticField(c.this, 'serialVersionUID') serialVersionUID from java.lang.Class c where c.name = 'java.util.HashMap'",
"name|serialVersionUID",
"java.util.HashMap|362498820763181265");
}

@Test
public void testReadme() throws SQLException {
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ Heap schema
getSize | size of referenced collection, map or count of non-null elements in array
getByKey | extracts value for given string representation of key for referenced map
getField | obtains value of field with specified name for referenced object
getStaticField | obtains value of static field with specified name for referenced class
getStringContent | pretty prints object representation

The following table functions are supported:
Expand Down