jobjectArray PathsToClosestGcRootsAction::collectPathsToClosestGcRoots()

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