| 1 19 20 package edu.umd.cs.findbugs.ba.npe; 21 22 import java.util.Collection ; 23 import java.util.Collections ; 24 import java.util.HashMap ; 25 import java.util.Iterator ; 26 import java.util.Map ; 27 28 import edu.umd.cs.findbugs.annotations.CheckForNull; 29 import edu.umd.cs.findbugs.annotations.NonNull; 30 import edu.umd.cs.findbugs.ba.Frame; 31 import edu.umd.cs.findbugs.ba.vna.ValueNumber; 32 import edu.umd.cs.findbugs.ba.vna.ValueNumberFrame; 33 import edu.umd.cs.findbugs.util.Strings; 34 import edu.umd.cs.findbugs.util.Util; 35 public class IsNullValueFrame extends Frame<IsNullValue> { 36 private IsNullConditionDecision decision; 37 private boolean trackValueNumbers; 38 private Map <ValueNumber, IsNullValue> knownValueMap; 39 40 public IsNullValueFrame(int numLocals, boolean trackValueNumbers) { 41 super(numLocals); 42 this.trackValueNumbers = trackValueNumbers; 43 if (trackValueNumbers) { 44 this.knownValueMap = new HashMap <ValueNumber, IsNullValue>(); 45 } 46 } 47 48 public void cleanStaleKnowledge(ValueNumberFrame vnaFrameAfter) { 49 if (vnaFrameAfter.isTop() && !isTop()) throw new IllegalArgumentException ("VNA frame is top"); 50 if (!trackValueNumbers) return; 51 for(Iterator <ValueNumber> i = knownValueMap.keySet().iterator(); i.hasNext(); ) { 52 ValueNumber v = i.next(); 53 if (vnaFrameAfter.getLoad(v) == null) { 54 if (IsNullValueAnalysis.DEBUG) 55 System.out.println("PURGING " + v); 56 i.remove(); 57 } 58 } 59 60 } 61 @Override  62 public void setTop() { 63 super.setTop(); 64 if (trackValueNumbers) { 65 knownValueMap.clear(); 66 } 67 decision = null; 68 } 69 public void toExceptionValues() { 70 for (int i = 0; i < getNumSlots(); ++i) 71 setValue(i, getValue(i).toExceptionValue()); 72 73 if (trackValueNumbers) { 74 Map <ValueNumber, IsNullValue> replaceMap = new HashMap <ValueNumber, IsNullValue>(); 75 for (Map.Entry <ValueNumber, IsNullValue> entry : knownValueMap.entrySet()) { 76 replaceMap.put(entry.getKey(), entry.getValue().toExceptionValue()); 77 } 78 this.knownValueMap = replaceMap; 79 } 80 } 81 82 public void setDecision(@CheckForNull IsNullConditionDecision decision) { 83 this.decision = decision; 84 } 85 86 public @CheckForNull IsNullConditionDecision getDecision() { 87 return decision; 88 } 89 90 public void setKnownValue(@NonNull ValueNumber valueNumber, @NonNull IsNullValue knownValue) { 91 assert trackValueNumbers; 92 if (valueNumber == null || knownValue == null ) throw new NullPointerException (); 93 knownValueMap.put(valueNumber, knownValue); 94 if (IsNullValueAnalysis.DEBUG) { 95 System.out.println("Updated information for " + valueNumber); 96 System.out.println(" now " + this); 97 } 98 } 99 public void useNewValueNumberForLoad(ValueNumber oldValueNumber, ValueNumber newValueNumber) { 100 if (oldValueNumber == null || newValueNumber == null) throw new NullPointerException (); 101 if (newValueNumber.equals(oldValueNumber) || !trackValueNumbers) return; 102 IsNullValue isNullValue = knownValueMap.get(oldValueNumber); 103 if (isNullValue != null) { 104 knownValueMap.put(newValueNumber, isNullValue); 105 knownValueMap.remove(oldValueNumber); 106 } 107 } 108 public IsNullValue getKnownValue(ValueNumber valueNumber) { 109 assert trackValueNumbers; 110 return knownValueMap.get(valueNumber); 111 } 112 113 public Collection <ValueNumber> getKnownValues() { 114 if (trackValueNumbers) { 115 return knownValueMap.keySet(); 116 } else { 117 return Collections.EMPTY_SET; 118 } 119 } 120 121 public Collection <Map.Entry <ValueNumber, IsNullValue>> getKnownValueMapEntrySet() { 122 if (trackValueNumbers) { 123 return knownValueMap.entrySet(); 124 } else { 125 return Collections.EMPTY_SET; 126 } 127 } 128 129 public void mergeKnownValuesWith(IsNullValueFrame otherFrame) { 130 assert trackValueNumbers; 131 if (IsNullValueAnalysis.DEBUG) { 132 System.out.println("merge"); 133 System.out.println(" " + this); 134 System.out.println(" with" + otherFrame); 135 } 136 Map <ValueNumber, IsNullValue> replaceMap = new HashMap <ValueNumber, IsNullValue>(); 137 for (Map.Entry <ValueNumber, IsNullValue> entry : knownValueMap.entrySet()) { 138 IsNullValue otherKnownValue = otherFrame.knownValueMap.get(entry.getKey()); 139 if (otherKnownValue == null) { 140 if (IsNullValueAnalysis.DEBUG) { 141 System.out.println("No match for " + entry.getKey()); 142 143 } 144 continue; 145 } 146 IsNullValue mergedValue = IsNullValue.merge(entry.getValue(), otherKnownValue); 147 replaceMap.put(entry.getKey(), mergedValue); 148 if (IsNullValueAnalysis.DEBUG && !mergedValue.equals(entry.getValue())) { 149 150 System.out.println("Updated information for " + entry.getKey()); 151 System.out.println(" was " + entry.getValue()); 152 System.out.println(" merged value " + mergedValue); 153 154 } 155 } 156 knownValueMap.clear(); 157 knownValueMap.putAll(replaceMap); 158 if (IsNullValueAnalysis.DEBUG) { 159 System.out.println("resulting in " + this); 160 161 } 162 } 163 164 167 @Override  168 public void copyFrom(Frame<IsNullValue> other) { 169 super.copyFrom(other); 170 decision = ((IsNullValueFrame)other).decision; 171 if (trackValueNumbers) { 172 knownValueMap = new HashMap <ValueNumber, IsNullValue>(((IsNullValueFrame)other).knownValueMap); 173 } 174 } 175 176 @Override  177 public boolean sameAs(Frame<IsNullValue> other) { 178 if (!(other instanceof IsNullValueFrame)) return false; 179 if (!super.sameAs(other)) return false; 180 IsNullValueFrame o2 = (IsNullValueFrame) other; 181 if (!Util.nullSafeEquals(decision, o2.decision)) return false; 182 if (trackValueNumbers && !Util.nullSafeEquals(knownValueMap, o2.knownValueMap)) return false; 183 184 return true; 185 } 186 @Override  187 public String toString() { 188 String result = super.toString(); 189 if (decision != null) { 190 result = result + ", [decision=" + decision.toString() + "]"; 191 } 192 if (knownValueMap != null) { 193 StringBuffer buf = new StringBuffer (); 195 buf.append("{"); 196 boolean first = true; 197 for (Map.Entry <ValueNumber, IsNullValue> entry : knownValueMap.entrySet()) { 198 if (!first) { 199 buf.append(", "); 200 } else { 201 first = false; 202 } 203 buf.append(Strings.trimComma(entry.getKey().toString())); 204 buf.append("->"); 205 buf.append(Strings.trimComma(entry.getValue().toString())); 206 } 207 buf.append("}"); 208 result += ", [known=" + buf.toString() + "]"; 209 } 210 return result; 211 } 212 213 217 public void downgradeOnControlSplit() { 218 final int numSlots = getNumSlots(); 219 for (int i = 0; i < numSlots; ++i) { 220 IsNullValue value = getValue(i); 221 value = value.downgradeOnControlSplit(); 222 setValue(i, value); 223 } 224 225 if (knownValueMap != null) { 226 for (Map.Entry <ValueNumber, IsNullValue> entry : knownValueMap.entrySet()) { 227 entry.setValue(entry.getValue().downgradeOnControlSplit()); 228 } 229 } 230 } 231 } 232 233 | Popular Tags |