All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adrninistrator.javacg2.dto.frame.FrameSnapshotsOfIhs Maven / Gradle / Ivy

package com.adrninistrator.javacg2.dto.frame;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author adrninistrator
 * @date 2022/10/21
 * @description: 指令与对应的栈桢信息快照列表
 */
public class FrameSnapshotsOfIhs {

    /*
        指令对应的栈桢信息快照
        key
            指令位置
        value
            栈桢信息快照列表
     */
    private final Map> frameSnapshotOfIhsMap;

    public FrameSnapshotsOfIhs() {
        frameSnapshotOfIhsMap = new HashMap<>();
    }

    public List get(Integer position) {
        return frameSnapshotOfIhsMap.get(position);
    }

    /**
     * 添加信息快照
     *
     * @param position
     * @param addedStack
     * @param addedLocals
     * @param addedNonStaticFieldInfoMap
     * @param addedStaticFieldInfoMap
     * @return false: 已存在相同的信息快照,未添加 true: 不存在相同的信息快照,有添加
     */
    public boolean addSnapshot(int position,
                               JavaCG2OperandStack addedStack,
                               JavaCG2LocalVariables addedLocals,
                               FieldInformationMap addedNonStaticFieldInfoMap,
                               FieldInformationMap addedStaticFieldInfoMap) {
        List frameSnapshotEntryList = frameSnapshotOfIhsMap.get(position);
        if (frameSnapshotEntryList == null) {
            // 当前跳转目标指令处理过的栈桢信息快照为空,记录信息快照
            frameSnapshotEntryList = new ArrayList<>();
            frameSnapshotEntryList.add(new FrameSnapshotEntry(addedStack.copy(), addedLocals.copy(), addedNonStaticFieldInfoMap.copy(), addedStaticFieldInfoMap.copy()));
            frameSnapshotOfIhsMap.put(position, frameSnapshotEntryList);
            return true;
        }

        // 判断当前栈桢对应的信息快照是否存在相同的记录
        if (checkExistSnapshotLooseMode(frameSnapshotEntryList, addedStack, addedLocals, addedNonStaticFieldInfoMap, addedStaticFieldInfoMap)) {
            // 已存在相同的信息快照,未添加
            return false;
        }

        // 不存在相同的信息快照,需要添加
        frameSnapshotEntryList.add(new FrameSnapshotEntry(addedStack.copy(), addedLocals.copy(), addedNonStaticFieldInfoMap.copy(), addedStaticFieldInfoMap.copy()));
        return true;
    }

    /**
     * 判断当前栈桢对应的信息快照是否存在相同的记录,宽松模式
     *
     * @param frameSnapshotEntryList
     * @param addedStack
     * @param addedLocals
     * @param addedNonStaticFieldInfoMap
     * @param addedStaticFieldInfoMap
     * @return false: 不存在相同的信息快照 true: 已存在相同的信息快照
     */
    private boolean checkExistSnapshotLooseMode(List frameSnapshotEntryList,
                                                JavaCG2OperandStack addedStack,
                                                JavaCG2LocalVariables addedLocals,
                                                FieldInformationMap addedNonStaticFieldInfoMap,
                                                FieldInformationMap addedStaticFieldInfoMap) {
        int addedStackSize = addedStack.size();
        int addedLocalsSize = addedLocals.size();
        int addedNonStaticFieldInfoSize = addedNonStaticFieldInfoMap.size();
        int addedStaticFieldInfoSize = addedStaticFieldInfoMap.size();

        Set sameStackSeqSet = new HashSet<>(addedStackSize);
        Set sameLocalsSeqSet = new HashSet<>(addedLocalsSize);
        Set sameNonStaticFieldInfoNameSet = new HashSet<>(addedNonStaticFieldInfoSize);
        Set sameStaticFieldInfoNameSet = new HashSet<>(addedStaticFieldInfoSize);

        for (FrameSnapshotEntry frameSnapshotEntry : frameSnapshotEntryList) {
            /*
                以下处理时,每种类型都需要判断数量是否已相等,若不相等则需要进行比较
                进行比较后,可能需要添加的数据已存在,需要再判断数量是否已相等,若还是不相等才能认为暂不存在与需要添加的相同的数据
             */
            boolean equals = true;

            if (addedStackSize != sameStackSeqSet.size()) {
                // 操作数栈还不是每个元素都存在相同的信息,还需要比较
                JavaCG2OperandStack.compareLooseMode(frameSnapshotEntry.getStackSnapshot(), addedStack, sameStackSeqSet);
                if (addedStackSize != sameStackSeqSet.size()) {
                    equals = false;
                }
            }

            if (addedLocalsSize != sameLocalsSeqSet.size()) {
                // 本地变量还不是每个元素都存在相同的信息,还需要比较
                JavaCG2LocalVariables.compareLooseMode(frameSnapshotEntry.getLocalsSnapshot(), addedLocals, sameLocalsSeqSet);
                if (addedLocalsSize != sameLocalsSeqSet.size()) {
                    equals = false;
                }
            }

            if (addedNonStaticFieldInfoSize != sameNonStaticFieldInfoNameSet.size()) {
                // 本地变量还不是每个元素都存在相同的信息,还需要比较
                FieldInformationMap.compareLooseMode(frameSnapshotEntry.getNonStaticFieldInfoMap(), addedNonStaticFieldInfoMap, sameNonStaticFieldInfoNameSet);
                if (addedNonStaticFieldInfoSize != sameNonStaticFieldInfoNameSet.size()) {
                    equals = false;
                }
            }

            if (addedStaticFieldInfoSize != sameStaticFieldInfoNameSet.size()) {
                // 本地变量还不是每个元素都存在相同的信息,还需要比较
                FieldInformationMap.compareLooseMode(frameSnapshotEntry.getStaticFieldInfoMap(), addedStaticFieldInfoMap, sameStaticFieldInfoNameSet);
                if (addedStaticFieldInfoSize != sameStaticFieldInfoNameSet.size()) {
                    equals = false;
                }
            }

            if (equals) {
                // 已存在相同的信息快照
                return true;
            }
        }

        // 不存在相同的信息快照
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy