private void setDestinationRegisterTypeAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType registerType) { setPostRegisterTypeAndPropagateChanges(analyzedInstruction, analyzedInstruction.getDestinationRegister(), registerType); }
private void propagateParameterTypes(int parameterStartRegister) { int i=0; for (MethodParameter parameter: method.getParameters()) { if (TypeUtils.isWideType(parameter)) { setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getWideRegisterType(parameter, true)); setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getWideRegisterType(parameter, false)); } else { setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getRegisterType(classPath, parameter)); } } }
private void setPostRegisterTypeAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction, int registerNumber, @Nonnull RegisterType registerType) { BitSet changedInstructions = new BitSet(analyzedInstructions.size()); if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) { return; } propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions, false); propagateChanges(changedInstructions, registerNumber, false); if (registerType.category == RegisterType.LONG_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.LONG_HI_TYPE); } else if (registerType.category == RegisterType.DOUBLE_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.DOUBLE_HI_TYPE); } }
private void initializeRefAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction, int registerNumber, @Nonnull RegisterType registerType) { BitSet changedInstructions = new BitSet(analyzedInstructions.size()); if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) { return; } propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions, false); propagateChanges(changedInstructions, registerNumber, false); if (registerType.category == RegisterType.LONG_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.LONG_HI_TYPE); } else if (registerType.category == RegisterType.DOUBLE_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.DOUBLE_HI_TYPE); } }
private void analyzeInvokeDirectCommon(@Nonnull AnalyzedInstruction analyzedInstruction, int objectRegister) { // This handles the case of invoking a constructor on an uninitialized reference. This propagates the // initialized type for the object register, and also any known aliased registers. // // In some cases, unrelated uninitialized references may not have been propagated past this instruction. This // happens when propagating those types and the type of object register of this instruction isn't known yet. // In this case, we can't determine if the uninitialized reference being propagated in an alias of the object // register, so we don't stop propagation. // // We check for any of these unpropagated uninitialized references here and propagate them. if (analyzedInstruction.isInvokeInit()) { RegisterType uninitRef = analyzedInstruction.getPreInstructionRegisterType(objectRegister); if (uninitRef.category != RegisterType.UNINIT_REF && uninitRef.category != RegisterType.UNINIT_THIS) { assert analyzedInstruction.getSetRegisters().isEmpty(); return; } RegisterType initRef = RegisterType.getRegisterType(RegisterType.REFERENCE, uninitRef.type); for (int register: analyzedInstruction.getSetRegisters()) { RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register); if (registerType == uninitRef) { setPostRegisterTypeAndPropagateChanges(analyzedInstruction, register, initRef); } else { // This is unrelated uninitialized reference. propagate it as-is setPostRegisterTypeAndPropagateChanges(analyzedInstruction, register, registerType); } } } }
setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.UNINIT_THIS, classPath.getClass(method.getDefiningClass()))); } else { setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(method.getDefiningClass()))); setPostRegisterTypeAndPropagateChanges(startOfMethod, i, uninit);
private void setDestinationRegisterTypeAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType registerType) { setPostRegisterTypeAndPropagateChanges(analyzedInstruction, analyzedInstruction.getDestinationRegister(), registerType); }
private void setDestinationRegisterTypeAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction, @Nonnull RegisterType registerType) { setPostRegisterTypeAndPropagateChanges(analyzedInstruction, analyzedInstruction.getDestinationRegister(), registerType); }
private void propagateParameterTypes(int parameterStartRegister) { int i=0; for (MethodParameter parameter: method.getParameters()) { if (TypeUtils.isWideType(parameter)) { setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getWideRegisterType(parameter, true)); setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getWideRegisterType(parameter, false)); } else { setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getRegisterType(classPath, parameter)); } } }
private void propagateParameterTypes(int parameterStartRegister) { int i=0; for (MethodParameter parameter: method.getParameters()) { if (TypeUtils.isWideType(parameter)) { setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getWideRegisterType(parameter, true)); setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getWideRegisterType(parameter, false)); } else { setPostRegisterTypeAndPropagateChanges(startOfMethod, parameterStartRegister + i++, RegisterType.getRegisterType(classPath, parameter)); } } }
private void setPostRegisterTypeAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction, int registerNumber, @Nonnull RegisterType registerType) { BitSet changedInstructions = new BitSet(analyzedInstructions.size()); if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) { return; } propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions, false); propagateChanges(changedInstructions, registerNumber, false); if (registerType.category == RegisterType.LONG_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.LONG_HI_TYPE); } else if (registerType.category == RegisterType.DOUBLE_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.DOUBLE_HI_TYPE); } }
private void initializeRefAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction, int registerNumber, @Nonnull RegisterType registerType) { BitSet changedInstructions = new BitSet(analyzedInstructions.size()); if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) { return; } propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions, false); propagateChanges(changedInstructions, registerNumber, false); if (registerType.category == RegisterType.LONG_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.LONG_HI_TYPE); } else if (registerType.category == RegisterType.DOUBLE_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.DOUBLE_HI_TYPE); } }
private void setPostRegisterTypeAndPropagateChanges(@Nonnull AnalyzedInstruction analyzedInstruction, int registerNumber, @Nonnull RegisterType registerType) { BitSet changedInstructions = new BitSet(analyzedInstructions.size()); if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) { return; } propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions); //Using a for loop inside the while loop optimizes for the common case of the successors of an instruction //occurring after the instruction. Any successors that occur prior to the instruction will be picked up on //the next iteration of the while loop. //This could also be done recursively, but in large methods it would likely cause very deep recursion, //which requires the user to specify a larger stack size. This isn't really a problem, but it is slightly //annoying. while (!changedInstructions.isEmpty()) { for (int instructionIndex=changedInstructions.nextSetBit(0); instructionIndex>=0; instructionIndex=changedInstructions.nextSetBit(instructionIndex+1)) { changedInstructions.clear(instructionIndex); propagateRegisterToSuccessors(analyzedInstructions.valueAt(instructionIndex), registerNumber, changedInstructions); } } if (registerType.category == RegisterType.LONG_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.LONG_HI_TYPE); } else if (registerType.category == RegisterType.DOUBLE_LO) { checkWidePair(registerNumber, analyzedInstruction); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1, RegisterType.DOUBLE_HI_TYPE); } }
setPostRegisterTypeAndPropagateChanges(analyzedInstruction, objectRegister, RegisterType.getRegisterType(RegisterType.REFERENCE, objectRegisterType.type)); setPostRegisterTypeAndPropagateChanges(analyzedInstruction, i, registerType);
private void analyzeInvokeDirectCommon(@Nonnull AnalyzedInstruction analyzedInstruction, int objectRegister) { // This handles the case of invoking a constructor on an uninitialized reference. This propagates the // initialized type for the object register, and also any known aliased registers. // // In some cases, unrelated uninitialized references may not have been propagated past this instruction. This // happens when propagating those types and the type of object register of this instruction isn't known yet. // In this case, we can't determine if the uninitialized reference being propagated in an alias of the object // register, so we don't stop propagation. // // We check for any of these unpropagated uninitialized references here and propagate them. if (analyzedInstruction.isInvokeInit()) { RegisterType uninitRef = analyzedInstruction.getPreInstructionRegisterType(objectRegister); if (uninitRef.category != RegisterType.UNINIT_REF && uninitRef.category != RegisterType.UNINIT_THIS) { assert analyzedInstruction.getSetRegisters().isEmpty(); return; } RegisterType initRef = RegisterType.getRegisterType(RegisterType.REFERENCE, uninitRef.type); for (int register: analyzedInstruction.getSetRegisters()) { RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register); if (registerType == uninitRef) { setPostRegisterTypeAndPropagateChanges(analyzedInstruction, register, initRef); } else { // This is unrelated uninitialized reference. propagate it as-is setPostRegisterTypeAndPropagateChanges(analyzedInstruction, register, registerType); } } } }
setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.UNINIT_THIS, classPath.getClass(method.getDefiningClass()))); } else { setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(method.getDefiningClass()))); setPostRegisterTypeAndPropagateChanges(startOfMethod, i, uninit);
setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.UNINIT_THIS, classPath.getClass(method.getDefiningClass()))); } else { setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.REFERENCE, classPath.getClass(method.getDefiningClass()))); setPostRegisterTypeAndPropagateChanges(startOfMethod, i, uninit);