private static void parseCMSPhase()

in analysis/gc-log/src/main/java/org/eclipse/jifa/gclog/parser/PreUnifiedGenerationalGCLogParser.java [110:176]


    private static void parseCMSPhase(AbstractGCLogParser parser, ParseRuleContext context, String phaseName, String value) {
        GCModel model = parser.getModel();
        if (phaseName.startsWith("GC (")) {
            // "GC (CMS Final Remark)"
            phaseName = phaseName.substring(4, phaseName.length() - 1);
        } else if (phaseName.startsWith(" (")) {
            // " (concurrent mode interrupted)"
            phaseName = phaseName.substring(2, phaseName.length() - 1);
        }
        GCEventType phaseType = getGCEventType(phaseName);

        GCEvent phase = context.get(EVENT);
        if (phase == null) {
            // " (concurrent mode interrupted)"
            phase = new GCEvent();
            phase.setEventType(phaseType);
            GCEvent gc = model.getLastEventOfType(YOUNG_FULL_GC);
            if (gc == null) {
                return;
            }
            phase.setStartTime(gc.getStartTime());
            phase.setDuration(0);
        }

        GCEvent parent;
        if (phaseType == CMS_INITIAL_MARK) {
            parent = new GCEvent();
            parent.setEventType(CMS_CONCURRENT_MARK_SWEPT);
            parent.setStartTime(phase.getStartTime());
            model.putEvent(parent);
        } else {
            if (phaseType == WEAK_REFS_PROCESSING || phaseType == CMS_CLASS_UNLOADING ||
                    phaseType == CMS_SCRUB_STRING_TABLE || phaseType == CMS_SCRUB_SYMBOL_TABLE) {
                parent = model.getLastEventOfType(CMS_FULL);
            } else {
                parent = model.getLastEventOfType(CMS_CONCURRENT_MARK_SWEPT);
            }
            if (parent == null) {
                return;
            }
        }

        if (phaseType == CMS_FINAL_REMARK && parent.getLastPhaseOfType(CMS_FINAL_REMARK) != null) {
            // When we see the second cms final remark, this is actually the CMSScavengeBeforeRemark.
            // In current implementation, young gc must be put at the first level of event structure
            // otherwise it can not be correctly aggregated
            phase.setEventType(YOUNG_GC);
            phase.setCause(GCCause.CMS_FINAL_REMARK);
            phase.setTrue(GCEventBooleanType.IGNORE_PAUSE);
            model.putEvent(phase);
            ((AbstractPreUnifiedGCLogParser)parser).pushIfWaitingForCpuTime(phase);
            return;
        }

        GCEvent phaseStart = parent.getLastPhaseOfType(phaseType);
        if (phaseStart == null) {
            phase.setEventType(phaseType);
            model.addPhase(parent, phase);
            if (phaseType == CMS_CONCURRENT_INTERRUPTED || phaseType == CMS_CONCURRENT_FAILURE) {
                phase.setDuration(0);
            }
            ((AbstractPreUnifiedGCLogParser)parser).pushIfWaitingForCpuTime(phase);
        } else {
            copyPhaseDataToStart(phaseStart, phase);
            ((AbstractPreUnifiedGCLogParser)parser).pushIfWaitingForCpuTime(phaseStart);
        }
    }