diff options
Diffstat (limited to 'org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java')
-rw-r--r-- | org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java index c6dcc0aa3..6b1a868d9 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/flow/FlowContext.java @@ -82,10 +82,10 @@ public class FlowContext implements TypeConstants { public TypeBinding[][] providedExpectedTypes = null; // record field references known to be non-null - // this array will never shrink, only grow. reset happens by nulling the first cell - // adding elements after reset ensures that the valid part of the array is always null-terminated + // this array will never shrink, only grow. reset happens by nulling expired entries + // this array grows in lock step with timesToLiveForNullCheckInfo, which controls expiration private Reference[] nullCheckedFieldReferences = null; - private int timeToLiveForNullCheckInfo = -1; + private int[] timesToLiveForNullCheckInfo = null; public static final int DEFER_NULL_DIAGNOSTIC = 0x1; public static final int PREEMPT_NULL_DIAGNOSTIC = 0x2; @@ -131,6 +131,7 @@ public FlowContext(FlowContext parent, ASTNode associatedNode) { this.initsOnFinally = parent.initsOnFinally; this.conditionalLevel = parent.conditionalLevel; this.nullCheckedFieldReferences = parent.nullCheckedFieldReferences; // re-use list if there is one + this.timesToLiveForNullCheckInfo = parent.timesToLiveForNullCheckInfo; } } @@ -141,33 +142,35 @@ public FlowContext(FlowContext parent, ASTNode associatedNode) { * @param timeToLive control how many expire events are needed to expire this information */ public void recordNullCheckedFieldReference(Reference reference, int timeToLive) { - this.timeToLiveForNullCheckInfo = timeToLive; if (this.nullCheckedFieldReferences == null) { // first entry: - this.nullCheckedFieldReferences = new Reference[2]; - this.nullCheckedFieldReferences[0] = reference; + this.nullCheckedFieldReferences = new Reference[] { reference, null }; + this.timesToLiveForNullCheckInfo = new int[] { timeToLive, -1 }; } else { int len = this.nullCheckedFieldReferences.length; // insert into first empty slot: for (int i=0; i<len; i++) { if (this.nullCheckedFieldReferences[i] == null) { this.nullCheckedFieldReferences[i] = reference; - if (i+1 < len) { - this.nullCheckedFieldReferences[i+1] = null; // lazily mark next as empty - } + this.timesToLiveForNullCheckInfo[i] = timeToLive; return; } } - // grow array: + // grow arrays: System.arraycopy(this.nullCheckedFieldReferences, 0, this.nullCheckedFieldReferences=new Reference[len+2], 0, len); + System.arraycopy(this.timesToLiveForNullCheckInfo, 0, this.timesToLiveForNullCheckInfo=new int[len+2], 0, len); this.nullCheckedFieldReferences[len] = reference; + this.timesToLiveForNullCheckInfo[len] = timeToLive; } } /** If a null checked field has been recorded recently, increase its time to live. */ public void extendTimeToLiveForNullCheckedField(int t) { - if (this.timeToLiveForNullCheckInfo > 0) - this.timeToLiveForNullCheckInfo += t; + if (this.timesToLiveForNullCheckInfo != null) { + for (int i = 0; i < this.timesToLiveForNullCheckInfo.length; i++) + if (this.timesToLiveForNullCheckInfo[i] > 0) + this.timesToLiveForNullCheckInfo[i] += t; + } } /** @@ -178,8 +181,9 @@ public void extendTimeToLiveForNullCheckedField(int t) { */ public void expireNullCheckedFieldInfo() { if (this.nullCheckedFieldReferences != null) { - if (--this.timeToLiveForNullCheckInfo == 0) { - this.nullCheckedFieldReferences[0] = null; // lazily wipe + for (int i = 0; i < this.nullCheckedFieldReferences.length; i++) { + if (--this.timesToLiveForNullCheckInfo[i] == 0) + this.nullCheckedFieldReferences[i] = null; } } } @@ -196,7 +200,7 @@ public boolean isNullcheckedFieldAccess(Reference reference) { for (int i=0; i<len; i++) { Reference checked = this.nullCheckedFieldReferences[i]; if (checked == null) { - return false; + continue; } if (checked.isEquivalent(reference)) { return true; |