@Override public void sawOpcode(int seen) { if (hasSideEffect(seen)) { reset(); } else if (stack.getStackDepth() == 0) { if (emptyStackLocations.size() > 1) { int first = emptyStackLocations.get(emptyStackLocations.size() - 2*n); int second = emptyStackLocations.get(emptyStackLocations.size() - n); int third = getPC(); if (third - second == second - first) { int endOfFirstSegment = prevOpcodeLocations.get(emptyStackLocations.size() - n); int endOfSecondSegment = oldPC; int opcodeAtEndOfFirst = getCodeByte(endOfFirstSegment); int opcodeAtEndOfSecond = getCodeByte(endOfSecondSegment); if (!isBranch(opcodeAtEndOfFirst) || !isBranch(opcodeAtEndOfSecond)) { continue; && !areOppositeBranches(opcodeAtEndOfFirst, opcodeAtEndOfSecond)) { continue; || (firstTarget.intValue() == getPC() && opcodeAtEndOfFirst != opcodeAtEndOfSecond); if(!compareCode(first, endOfFirstSegment, second, endOfSecondSegment, !identicalCheck)) { continue; SourceLineAnnotation firstSourceLine = SourceLineAnnotation.fromVisitedInstructionRange(getClassContext(), this, first, endOfFirstSegment - 1); SourceLineAnnotation secondSourceLine = SourceLineAnnotation.fromVisitedInstructionRange(getClassContext(), this, second, endOfSecondSegment - 1);
private boolean hasSideEffect(int seen) { if(seen == Const.INVOKEVIRTUAL || seen == Const.INVOKESPECIAL || seen == Const.INVOKEINTERFACE || seen == Const.INVOKESTATIC) { return noSideEffectMethods.is(getMethodDescriptorOperand(), MethodSideEffectStatus.SE, MethodSideEffectStatus.OBJ); } return isRegisterStore() || isReturn(seen) || isSwitch(seen) || seen == Const.INVOKEDYNAMIC || seen == Const.PUTFIELD || seen == Const.PUTSTATIC; }
methodGen = Global.getAnalysisCache().getMethodAnalysis(MethodGen.class, getMethodDescriptor()); } catch (CheckedAnalysisException e) { byte[] code = getCode().getCode(); for (int i = first; i < endOfFirstSegment; i++) { if (code[i] != code[i - first + second]) {
@Override public void sawBranchTo(int pc) { branchTargets.put(getPC(), pc); }
methodGen = Global.getAnalysisCache().getMethodAnalysis(MethodGen.class, getMethodDescriptor()); } catch (CheckedAnalysisException e) { byte[] code = getCode().getCode(); for (int i = first; i < endOfFirstSegment; i++) { if (code[i] != code[i - first + second]) {
@Override public void sawBranchTo(int pc) { branchTargets.put(getPC(), pc); }
@Override public void sawOpcode(int seen) { if (hasSideEffect(seen)) { reset(); } else if (stack.getStackDepth() == 0) { if (emptyStackLocations.size() > 1) { int first = emptyStackLocations.get(emptyStackLocations.size() - 2*n); int second = emptyStackLocations.get(emptyStackLocations.size() - n); int third = getPC(); if (third - second == second - first) { int endOfFirstSegment = prevOpcodeLocations.get(emptyStackLocations.size() - n); int endOfSecondSegment = oldPC; int opcodeAtEndOfFirst = getCodeByte(endOfFirstSegment); int opcodeAtEndOfSecond = getCodeByte(endOfSecondSegment); if (!isBranch(opcodeAtEndOfFirst) || !isBranch(opcodeAtEndOfSecond)) { continue; && !areOppositeBranches(opcodeAtEndOfFirst, opcodeAtEndOfSecond)) { continue; || (firstTarget.intValue() == getPC() && opcodeAtEndOfFirst != opcodeAtEndOfSecond); if(!compareCode(first, endOfFirstSegment, second, endOfSecondSegment, !identicalCheck)) { continue; SourceLineAnnotation firstSourceLine = SourceLineAnnotation.fromVisitedInstructionRange(getClassContext(), this, first, endOfFirstSegment - 1); SourceLineAnnotation secondSourceLine = SourceLineAnnotation.fromVisitedInstructionRange(getClassContext(), this, second, endOfSecondSegment - 1);
private boolean hasSideEffect(int seen) { if(seen == INVOKEVIRTUAL || seen == INVOKESPECIAL || seen == INVOKEINTERFACE || seen == INVOKESTATIC) { return noSideEffectMethods.is(getMethodDescriptorOperand(), MethodSideEffectStatus.SE, MethodSideEffectStatus.OBJ); } return isRegisterStore() || isReturn(seen) || isSwitch(seen) || seen == INVOKEDYNAMIC || seen == PUTFIELD || seen == PUTSTATIC; }