private CollapsedObj collapseLinkedListImpl()

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);
	}