in src/roots/paths_to_closest_gc_roots.cpp [253:289]
jobjectArray PathsToClosestGcRootsAction::collectPathsToClosestGcRoots(jlong start, jint number, jint objectsNumber) {
std::queue<jlong> queue;
std::unordered_map<jlong, jlong> prevTag;
std::unordered_set<jlong> foundRootsSet;
std::vector<jlong> foundRoots;
jlong tag = start;
queue.push(tag);
prevTag[tag] = tag;
progressManager.updateProgress(80, "Calculating paths to closest GC roots...");
while (!queue.empty() && number > foundRoots.size()) {
if (shouldStopExecution()) return getEmptyArray(env);
tag = queue.front();
queue.pop();
for (ReferenceInfo *info : GcTag::pointerToGcTag(tag)->backRefs) {
jlong parentTag = info->getTag();
if (isValidGcRoot(parentTag, info->getKind()) &&
foundRootsSet.insert(tag).second) {
foundRoots.push_back(tag);
} else if (parentTag != -1 && prevTag.insert(std::make_pair(parentTag, tag)).second) {
queue.push(parentTag);
}
if (foundRoots.size() >= number) {
break;
}
}
}
if (shouldStopExecution()) return getEmptyArray(env);
progressManager.updateProgress(90, "Packing result...");
return foundRoots.empty() ?
createResultObject(env, jvmti, std::vector<jlong>{start}) :
createResultObjectForGcRootsPaths(env, jvmti, foundRoots, prevTag, start, objectsNumber);
}