in application/org.openjdk.jmc.joverflow/src/main/java/org/openjdk/jmc/joverflow/stats/InterimRefChainStack.java [353:421]
private CollapsedObj collapseLinkedListImpl(int startIdx, RefChainElement referer) {
JavaHeapObject javaHeapObj = (JavaHeapObject) refChain.get(startIdx);
if (!(javaHeapObj instanceof JavaObject)) {
return null;
}
int refChainLastIdx = refChain.size() - 1;
if (startIdx + 3 >= refChainLastIdx) {
return null;
}
int refChainIdx = startIdx;
int fieldIdx = ((IndexContainer) refChain.get(startIdx + 1)).get();
JavaClass elementClass = javaHeapObj.getClazz();
JavaClass llDefiningClass = elementClass.getDeclaringClassForField(fieldIdx);
while (true) {
int fieldIdx1 = ((IndexContainer) refChain.get(refChainIdx + 3)).get();
if (fieldIdx1 != fieldIdx) {
break;
}
javaHeapObj = (JavaHeapObject) refChain.get(refChainIdx + 2);
JavaClass elementClass1 = javaHeapObj.getClazz();
if (elementClass1.getDeclaringClassForField(fieldIdx) != llDefiningClass) {
break;
}
if (elementClass != null && elementClass1 != elementClass) {
elementClass = null;
}
refChainIdx += 2;
if (refChainIdx + 3 > refChainLastIdx) {
break;
}
}
if (refChainIdx == startIdx) {
return null;
}
JavaClass llClazz = elementClass != null ? elementClass : llDefiningClass;
// Check if we actually look at the same linked list that's already been there
if (referer instanceof RefChainElementImpl.InstanceFieldOrLinkedList) {
RefChainElementImpl.InstanceFieldOrLinkedList otherList = (RefChainElementImpl.InstanceFieldOrLinkedList) referer;
if (!otherList.isInstanceField() && otherList.getJavaClass() == llClazz
&& otherList.getFieldIdx() == fieldIdx) {
return new CollapsedObj(refChainIdx + 1, referer);
}
} else if (referer instanceof RefChainElementImpl.Collection) {
// This is intended to help stitch together things like java.util.LinkedList,
// which we first recognize as a collection, and then, when we see it from the
// middle, as a noncategorized linked list.
RefChainElementImpl.Collection otherCol = (RefChainElementImpl.Collection) referer;
CollectionClassDescriptor colDesc = colDescriptors.getClassDescriptor(otherCol.getJavaClass().getName());
if (colDesc != null && colDesc.isImplClassName(llClazz.getName())) {
// Let's now take a look at the last element - maybe it also belongs to this collection
// (though not technically to the linked list), like LinkedList$Entry.element
JavaHeapObject lastObj = (JavaHeapObject) refChain.get(refChainIdx + 2);
if (colDesc.isImplClassName(lastObj.getClazz().getName())) {
refChainIdx += 2;
}
int endIdx = refChainIdx + 1 < refChain.size() ? refChainIdx + 1 : refChainIdx;
return new CollapsedObj(endIdx, referer);
}
}
return new CollapsedObj(llClazz, fieldIdx, refChainIdx + 1, referer);
}