protected void scanObjectsFromRootObj()

in src/application/org.openjdk.jmc.joverflow/src/main/java/org/openjdk/jmc/joverflow/stats/BreadthFirstHeapScanner.java [95:219]


	protected void scanObjectsFromRootObj(JavaHeapObject obj) {
		while (obj != null) {
			if (obj.setVisitedIfNot()) {
				currentProcessedObjNo++;
				if (cancelled) {
					throw new HprofParsingCancelledException.Runtime();
				}

				JavaClass clazz = obj.getClazz();

				if (clazz.isString()) {
					objHandler.handleString((JavaObject) obj);
				} else {
					if (obj instanceof JavaObject) {
						JavaObject javaObj = (JavaObject) obj;
						JavaThing[] fields = javaObj.getFields();

						CollectionInstanceDescriptor colDesc = objHandler.handleInstance(javaObj, fields);

						if (fields.length > 0 && obj.getClazz().hasReferenceFields()) {
							// Nullify various fields like those for auxiliary linked list in LinkedHashMap,
							// so that scanObjectFields does not have problems with long lists, etc.
							int[] bannedFieldIndices = clazz.getBannedFieldIndices();
							if (bannedFieldIndices != null) {
								for (int bannedFieldIdx : bannedFieldIndices) {
									fields[bannedFieldIdx] = null;
								}
							}

							if (colDesc != null) {
								// obj is a collection. Add its elements ("payload") to the nextFrontier,
								// and handle its internal implementation objects immediately.
								if (colDesc.getClassDescriptor().isMap()) {
									colDesc.iterateMap(new CollectionInstanceDescriptor.MapIteratorCallback() {
										@Override
										public boolean scanMapEntry(JavaHeapObject key, JavaHeapObject value) {
											pushCollectionElement(key);
											pushCollectionElement(value);
											return true;
										}

										@Override
										public boolean scanImplementationObject(JavaHeapObject implObj) {
											if (implObj.setVisitedIfNot()) {
												currentProcessedObjNo++;
												if (implObj instanceof JavaObject) {
													JavaObject implJavaObj = (JavaObject) implObj;
													objHandler.handleInstance(implJavaObj, implJavaObj.getFields());
												} else {
													// We set elements param to null to avoid overhead. They won't be
													// used by handler anyway, because array should be marked as
													// visitedAsCollectionImpl() by this time.
													objHandler.handleObjectArray((JavaObjectArray) implObj, null);
												}
												return true;
											} else {
												// Probably corrupted data - we shouldn't see a visited object
												return false;
											}
										}
									});
								} else {
									colDesc.iterateList(new CollectionInstanceDescriptor.ListIteratorCallback() {
										@Override
										public boolean scanListElement(JavaHeapObject element) {
											pushCollectionElement(element);
											return true;
										}

										@Override
										public boolean scanImplementationObject(JavaHeapObject implObj) {
											if (implObj.setVisitedIfNot()) {
												currentProcessedObjNo++;
												if (implObj instanceof JavaObject) {
													JavaObject implJavaObj = (JavaObject) implObj;
													objHandler.handleInstance(implJavaObj, implJavaObj.getFields());
												} else {
													objHandler.handleObjectArray((JavaObjectArray) implObj, null);
												}
												return true;
											} else {
												// Probably corrupted data - we shouldn't see a visited object
												return false;
											}
										}
									});
								}
								finishCollectionPush(obj);

								if (colDesc.hasExtraObjFields()) {
									colDesc.filterExtraObjFields(fields);
									pushFields(obj, fields, ParentType.INSTANCE);
								}

							} else {
								// An ordinary, non-collection object
								pushFields(obj, fields, ParentType.INSTANCE);
							}
						}
					} else if (obj instanceof JavaClass) {
						JavaThing[] staticFields = ((JavaClass) obj).getStaticValues();

						if (staticFields.length > 0) {
							pushFields(obj, staticFields, ParentType.CLAZZ);
						}
					} else if (obj instanceof JavaObjectArray) {
						JavaObjectArray objArray = (JavaObjectArray) obj;
						JavaHeapObject[] elements = objArray.getElements();
						objHandler.handleObjectArray(objArray, elements);

						if (elements.length > 0) {
							pushArrayElements(obj, elements);
						}
					} else {
						objHandler.handleValueArray((JavaValueArray) obj);
					}
				}
			}

			// Determine the next object to scan
			obj = getNextObjFromFrontier();
		}

		curFrontier = null;
	}